├── .codecov.yml ├── .editorconfig ├── .github ├── ISSUE_TEMPLATE │ ├── ---1-report-an-issue.md │ ├── ---2-feature-request.md │ └── config.yml ├── pull_request_template.md └── workflows │ ├── ci.yml │ ├── release-automated.yml │ └── release-manual-docs.yml ├── .gitignore ├── .javadoc ├── .releaserc ├── commit.hbs ├── footer.hbs ├── header.hbs └── template.hbs ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── PATENTS ├── README.md ├── bolts-tasks ├── README.md ├── build.gradle └── src │ ├── main │ └── java │ │ └── com │ │ └── parse │ │ └── boltsinternal │ │ ├── AggregateException.java │ │ ├── AndroidExecutors.java │ │ ├── BoltsExecutors.java │ │ ├── CancellationToken.java │ │ ├── CancellationTokenRegistration.java │ │ ├── CancellationTokenSource.java │ │ ├── Capture.java │ │ ├── Continuation.java │ │ ├── ExecutorException.java │ │ ├── Task.java │ │ ├── TaskCompletionSource.java │ │ ├── UnobservedErrorNotifier.java │ │ └── UnobservedTaskException.java │ └── test │ └── java │ └── com │ └── parse │ └── boltsinternal │ ├── CancellationTest.java │ └── TaskTest.java ├── build.gradle ├── coroutines ├── .gitignore ├── README.md ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── com │ └── parse │ └── coroutines │ ├── ParseCloudCoroutinesExtensions.kt │ ├── ParseObjectCoroutinesExtensions.kt │ ├── ParseObjectCoroutinesWriteExtensions.kt │ ├── ParseQueryCoroutinesBuilder.kt │ ├── ParseQueryCoroutinesExtensions.kt │ ├── ParseQueryOperation.kt │ ├── ParseQueryOperationImpl.kt │ ├── ParseTaskExtensions.kt │ └── ParseUserCoroutinesExtensions.kt ├── facebook ├── README.md ├── build.gradle └── src │ ├── main │ ├── AndroidManifest.xml │ └── java │ │ └── com │ │ └── parse │ │ └── facebook │ │ ├── FacebookController.java │ │ └── ParseFacebookUtils.java │ └── test │ └── java │ └── com │ └── parse │ └── facebook │ ├── FacebookControllerTest.java │ ├── ParseFacebookUtilsTest.java │ └── TestUtils.java ├── fcm ├── .gitignore ├── README.md ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── com │ └── parse │ └── fcm │ ├── ParseFCM.java │ └── ParseFirebaseMessagingService.java ├── google ├── .gitignore ├── README.md ├── build.gradle └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── com │ └── parse │ └── google │ └── ParseGoogleUtils.kt ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── jitpack.yml ├── ktx ├── .gitignore ├── README.md ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── com │ └── parse │ └── ktx │ ├── ParseObject.kt │ ├── ParseQuery.kt │ └── delegates │ ├── BooleanParseDelegate.kt │ ├── BytesParseDelegate.kt │ ├── DoubleParseDelegate.kt │ ├── EnumParseDelegate.kt │ ├── FloatParseDelegate.kt │ ├── IntParseDelegate.kt │ ├── JsonArrayParseDelegate.kt │ ├── JsonObjectParseDelegate.kt │ ├── ListParseDelegate.kt │ ├── LongParseDelegate.kt │ ├── MapParseDelegate.kt │ ├── ParseDelegate.kt │ ├── ParseRelationDelegate.kt │ ├── SafeParseDelegate.kt │ └── StringParseDelegate.kt ├── package-lock.json ├── package.json ├── parse ├── build.gradle ├── release-proguard.pro └── src │ ├── main │ ├── AndroidManifest.xml │ └── java │ │ └── com │ │ └── parse │ │ ├── AbstractQueryController.java │ │ ├── AuthenticationCallback.java │ │ ├── CacheQueryController.java │ │ ├── CachedCurrentInstallationController.java │ │ ├── CachedCurrentUserController.java │ │ ├── ConfigCallback.java │ │ ├── ConnectivityNotifier.java │ │ ├── CountCallback.java │ │ ├── DeleteCallback.java │ │ ├── EventuallyPin.java │ │ ├── FileObjectStore.java │ │ ├── FindCallback.java │ │ ├── FunctionCallback.java │ │ ├── GetCallback.java │ │ ├── GetDataCallback.java │ │ ├── GetDataStreamCallback.java │ │ ├── GetFileCallback.java │ │ ├── InstallationId.java │ │ ├── KnownParseObjectDecoder.java │ │ ├── Lists.java │ │ ├── LocalIdManager.java │ │ ├── LocationCallback.java │ │ ├── LocationNotifier.java │ │ ├── LockSet.java │ │ ├── LogInCallback.java │ │ ├── LogOutCallback.java │ │ ├── ManifestInfo.java │ │ ├── NetworkObjectController.java │ │ ├── NetworkQueryController.java │ │ ├── NetworkSessionController.java │ │ ├── NetworkUserController.java │ │ ├── NoObjectsEncoder.java │ │ ├── Numbers.java │ │ ├── OfflineObjectStore.java │ │ ├── OfflineQueryController.java │ │ ├── OfflineQueryLogic.java │ │ ├── OfflineSQLiteOpenHelper.java │ │ ├── OfflineStore.java │ │ ├── PLog.java │ │ ├── Parse.java │ │ ├── ParseACL.java │ │ ├── ParseAddOperation.java │ │ ├── ParseAddUniqueOperation.java │ │ ├── ParseAnalytics.java │ │ ├── ParseAnalyticsController.java │ │ ├── ParseAnonymousUtils.java │ │ ├── ParseAuthenticationManager.java │ │ ├── ParseByteArrayHttpBody.java │ │ ├── ParseCacheDirMigrationUtils.java │ │ ├── ParseCallback1.java │ │ ├── ParseCallback2.java │ │ ├── ParseClassName.java │ │ ├── ParseCloud.java │ │ ├── ParseCloudCodeController.java │ │ ├── ParseCommandCache.java │ │ ├── ParseConfig.java │ │ ├── ParseConfigController.java │ │ ├── ParseCorePlugins.java │ │ ├── ParseCountingByteArrayHttpBody.java │ │ ├── ParseCountingFileHttpBody.java │ │ ├── ParseCountingUriHttpBody.java │ │ ├── ParseCurrentConfigController.java │ │ ├── ParseCurrentInstallationController.java │ │ ├── ParseCurrentUserController.java │ │ ├── ParseDateFormat.java │ │ ├── ParseDecoder.java │ │ ├── ParseDefaultACLController.java │ │ ├── ParseDeleteOperation.java │ │ ├── ParseDigestUtils.java │ │ ├── ParseEncoder.java │ │ ├── ParseEventuallyQueue.java │ │ ├── ParseException.java │ │ ├── ParseExecutors.java │ │ ├── ParseFieldOperation.java │ │ ├── ParseFieldOperations.java │ │ ├── ParseFile.java │ │ ├── ParseFileController.java │ │ ├── ParseFileHttpBody.java │ │ ├── ParseFileRequest.java │ │ ├── ParseFileUtils.java │ │ ├── ParseGeoPoint.java │ │ ├── ParseHttpClient.java │ │ ├── ParseIOUtils.java │ │ ├── ParseImpreciseDateFormat.java │ │ ├── ParseIncrementOperation.java │ │ ├── ParseInstallation.java │ │ ├── ParseJSONUtils.java │ │ ├── ParseKeyValueCache.java │ │ ├── ParseMulticastDelegate.java │ │ ├── ParseNotificationManager.java │ │ ├── ParseObject.java │ │ ├── ParseObjectCoder.java │ │ ├── ParseObjectController.java │ │ ├── ParseObjectCurrentCoder.java │ │ ├── ParseObjectCurrentController.java │ │ ├── ParseObjectParcelDecoder.java │ │ ├── ParseObjectParcelEncoder.java │ │ ├── ParseObjectStore.java │ │ ├── ParseObjectSubclassingController.java │ │ ├── ParseOperationSet.java │ │ ├── ParseParcelDecoder.java │ │ ├── ParseParcelEncoder.java │ │ ├── ParsePin.java │ │ ├── ParsePinningEventuallyQueue.java │ │ ├── ParsePlugins.java │ │ ├── ParsePolygon.java │ │ ├── ParsePush.java │ │ ├── ParsePushBroadcastReceiver.java │ │ ├── ParsePushChannelsController.java │ │ ├── ParsePushController.java │ │ ├── ParseQuery.java │ │ ├── ParseQueryController.java │ │ ├── ParseRESTAnalyticsCommand.java │ │ ├── ParseRESTCloudCommand.java │ │ ├── ParseRESTCommand.java │ │ ├── ParseRESTConfigCommand.java │ │ ├── ParseRESTFileCommand.java │ │ ├── ParseRESTObjectBatchCommand.java │ │ ├── ParseRESTObjectCommand.java │ │ ├── ParseRESTPushCommand.java │ │ ├── ParseRESTQueryCommand.java │ │ ├── ParseRESTSessionCommand.java │ │ ├── ParseRESTUserCommand.java │ │ ├── ParseRelation.java │ │ ├── ParseRelationOperation.java │ │ ├── ParseRemoveOperation.java │ │ ├── ParseRequest.java │ │ ├── ParseRole.java │ │ ├── ParseSQLiteDatabase.java │ │ ├── ParseSQLiteOpenHelper.java │ │ ├── ParseSession.java │ │ ├── ParseSessionController.java │ │ ├── ParseSetOperation.java │ │ ├── ParseTaskUtils.java │ │ ├── ParseTextUtils.java │ │ ├── ParseTraverser.java │ │ ├── ParseUriHttpBody.java │ │ ├── ParseUser.java │ │ ├── ParseUserController.java │ │ ├── ParseUserCurrentCoder.java │ │ ├── PointerEncoder.java │ │ ├── PointerOrLocalIdEncoder.java │ │ ├── ProgressCallback.java │ │ ├── PushHistory.java │ │ ├── PushRouter.java │ │ ├── RequestPasswordResetCallback.java │ │ ├── SaveCallback.java │ │ ├── SendCallback.java │ │ ├── SignUpCallback.java │ │ ├── TaskQueue.java │ │ ├── TaskStackBuilderHelper.java │ │ ├── WeakValueHashMap.java │ │ └── http │ │ ├── ParseHttpBody.java │ │ ├── ParseHttpRequest.java │ │ └── ParseHttpResponse.java │ └── test │ └── java │ └── com │ └── parse │ ├── CachedCurrentInstallationControllerTest.java │ ├── CachedCurrentUserControllerTest.java │ ├── EventuallyPinTest.java │ ├── FileObjectStoreTest.java │ ├── InstallationIdTest.java │ ├── ListsTest.java │ ├── LocalIdManagerTest.java │ ├── NetworkObjectControllerTest.java │ ├── NetworkQueryControllerTest.java │ ├── NetworkSessionControllerTest.java │ ├── NetworkUserControllerTest.java │ ├── OfflineObjectStoreTest.java │ ├── OfflineQueryControllerTest.java │ ├── OfflineQueryLogicTest.java │ ├── ParseACLTest.java │ ├── ParseAnalyticsControllerTest.java │ ├── ParseAnalyticsTest.java │ ├── ParseAuthenticationManagerTest.java │ ├── ParseByteArrayHttpBodyTest.java │ ├── ParseCacheDirMigrationUtilsTest.java │ ├── ParseClientConfigurationTest.java │ ├── ParseCloudCodeControllerTest.java │ ├── ParseCloudTest.java │ ├── ParseCoderTest.java │ ├── ParseConfigControllerTest.java │ ├── ParseConfigTest.java │ ├── ParseCorePluginsTest.java │ ├── ParseCountingByteArrayHttpBodyTest.java │ ├── ParseCountingFileHttpBodyTest.java │ ├── ParseCountingUriHttpBodyTest.java │ ├── ParseCurrentConfigControllerTest.java │ ├── ParseDateFormatTest.java │ ├── ParseDecoderTest.java │ ├── ParseDefaultACLControllerTest.java │ ├── ParseDigestUtilsTest.java │ ├── ParseEncoderTest.java │ ├── ParseFileControllerTest.java │ ├── ParseFileHttpBodyTest.java │ ├── ParseFileRequestTest.java │ ├── ParseFileStateTest.java │ ├── ParseFileTest.java │ ├── ParseFileUtilsTest.java │ ├── ParseGeoPointTest.java │ ├── ParseHttpClientTest.java │ ├── ParseHttpRequestTest.java │ ├── ParseHttpResponseTest.java │ ├── ParseImpreciseDateFormatTest.java │ ├── ParseInstallationTest.java │ ├── ParseKeyValueCacheTest.java │ ├── ParseMatchers.java │ ├── ParseObjectCurrentCoderTest.java │ ├── ParseObjectStateTest.java │ ├── ParseObjectTest.java │ ├── ParseOkHttpClientTest.java │ ├── ParsePolygonTest.java │ ├── ParsePushBroadcastReceiverTest.java │ ├── ParsePushControllerTest.java │ ├── ParsePushStateTest.java │ ├── ParsePushTest.java │ ├── ParseQueryStateTest.java │ ├── ParseQueryTest.java │ ├── ParseRESTCommandTest.java │ ├── ParseRESTQueryCommandTest.java │ ├── ParseRESTUserCommandTest.java │ ├── ParseRelationTest.java │ ├── ParseRequestTest.java │ ├── ParseRoleTest.java │ ├── ParseSessionTest.java │ ├── ParseTaskUtilsTest.java │ ├── ParseTestUtils.java │ ├── ParseTextUtilsTest.java │ ├── ParseUriHttpBodyTest.java │ ├── ParseUserCurrentCoderTest.java │ ├── ParseUserTest.java │ ├── PointerEncoderTest.java │ ├── ResetPluginsParseTest.java │ ├── SubclassTest.java │ ├── TaskQueueTestHelper.java │ └── TestHelper.java ├── release.config.js ├── rxjava ├── .gitignore ├── README.md ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── com │ └── parse │ └── rxjava │ └── Extensions.kt ├── settings.gradle └── twitter ├── README.md ├── build.gradle └── src ├── main ├── AndroidManifest.xml ├── java │ └── com │ │ └── parse │ │ └── twitter │ │ ├── AsyncCallback.java │ │ ├── OAuth1FlowDialog.java │ │ ├── OAuth1FlowException.java │ │ ├── ParseTwitterUtils.java │ │ ├── Twitter.java │ │ └── TwitterController.java └── res │ └── layout │ └── parse_twitter_dialog_login.xml └── test └── java └── com └── parse └── twitter ├── ParseTwitterUtilsTest.java └── TwitterControllerTest.java /.codecov.yml: -------------------------------------------------------------------------------- 1 | coverage: 2 | precision: 2 3 | round: down 4 | range: "65...100" 5 | 6 | status: 7 | project: 8 | default: 9 | target: 65% 10 | patch: yes 11 | changes: no 12 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*.{java, kt, kts, xml}] 4 | indent_style = space 5 | indent_size = 4 6 | charset = utf-8 7 | end_of_line = lf 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.{java, kt, kts}] 12 | max_line_length = 165 13 | disabled_rules = no-wildcard-imports -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/---1-report-an-issue.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "\U0001F41B Report an issue" 3 | about: A feature is not working as expected. 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | ### New Issue Checklist 11 | 16 | 17 | - [ ] I am not disclosing a [vulnerability](https://github.com/parse-community/Parse-SDK-Android/security/policy). 18 | - [ ] I am not just asking a [question](https://github.com/parse-community/.github/blob/main/SUPPORT.md). 19 | - [ ] I have searched through [existing issues](https://github.com/parse-community/Parse-SDK-Android/issues?q=is%3Aissue). 20 | - [ ] I can reproduce the issue with the latest version of [Parse Server](https://github.com/parse-community/parse-server/releases) and the [Parse Android SDK](https://github.com/parse-community/Parse-SDK-Android/releases). 21 | 22 | ### Issue Description 23 | 24 | 25 | ### Steps to reproduce 26 | 27 | 28 | ### Actual Outcome 29 | 30 | 31 | ### Expected Outcome 32 | 33 | 34 | ### Environment 35 | 36 | 37 | Parse Android SDK 38 | - SDK version: `FILL_THIS_OUT` 39 | - Operating system version: `FILL_THIS_OUT` 40 | 41 | Server 42 | - Parse Server version: `FILL_THIS_OUT` 43 | - Operating system: `FILL_THIS_OUT` 44 | - Local or remote host (AWS, Azure, Google Cloud, Heroku, Digital Ocean, etc): `FILL_THIS_OUT` 45 | 46 | Database 47 | - System (MongoDB or Postgres): `FILL_THIS_OUT` 48 | - Database version: `FILL_THIS_OUT` 49 | - Local or remote host (MongoDB Atlas, mLab, AWS, Azure, Google Cloud, etc): `FILL_THIS_OUT` 50 | 51 | ### Logs 52 | 55 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/---2-feature-request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "\U0001F4A1 Request a feature" 3 | about: Suggest new functionality or an enhancement of existing functionality. 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | ### New Feature / Enhancement Checklist 11 | 16 | 17 | - [ ] I am not disclosing a [vulnerability](https://github.com/parse-community/Parse-SDK-Android/security/policy). 18 | - [ ] I am not just asking a [question](https://github.com/parse-community/.github/blob/main/SUPPORT.md). 19 | - [ ] I have searched through [existing issues](https://github.com/parse-community/Parse-SDK-Android/issues?q=is%3Aissue). 20 | 21 | ### Current Limitation 22 | 23 | 24 | ### Feature / Enhancement Description 25 | 26 | 27 | ### Example Use Case 28 | 29 | 30 | ### Alternatives / Workarounds 31 | 32 | 33 | ### 3rd Party References 34 | 35 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: 🙋🏽‍♀️ Getting help with code 4 | url: https://stackoverflow.com/questions/tagged/parse-platform 5 | about: Get help with code-level questions on Stack Overflow. 6 | - name: 🙋 Getting general help 7 | url: https://community.parseplatform.org 8 | about: Get help with other questions on our Community Forum. 9 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ### New Pull Request Checklist 2 | 7 | 8 | - [ ] I am not disclosing a [vulnerability](https://github.com/parse-community/Parse-SDK-Android/blob/master/SECURITY.md). 9 | - [ ] I am creating this PR in reference to an [issue](https://github.com/parse-community/Parse-SDK-Android/issues?q=is%3Aissue). 10 | 11 | ### Issue Description 12 | 13 | 14 | Closes: FILL_THIS_OUT 15 | 16 | ### Approach 17 | 18 | 19 | ### TODOs before merging 20 | 24 | 25 | - [ ] Add tests 26 | - [ ] Add changes to documentation (guides, repository pages, in-code descriptions) 27 | -------------------------------------------------------------------------------- /.github/workflows/release-automated.yml: -------------------------------------------------------------------------------- 1 | name: release-automated 2 | on: 3 | push: 4 | branches: [ master, release, alpha, beta ] 5 | jobs: 6 | publish-docs: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v4 10 | with: 11 | fetch-depth: 0 12 | - name: Set up JDK 11 13 | uses: actions/setup-java@v4 14 | with: 15 | java-version: '11' 16 | distribution: 'adopt' 17 | - name: Generate Javadoc 18 | run: javadoc @.javadoc || true 19 | - name: Deploy GitHub Pages 20 | uses: JamesIves/github-pages-deploy-action@4.1.5 21 | with: 22 | token: ${{ secrets.GITHUB_TOKEN }} 23 | branch: gh-pages 24 | clean: true 25 | folder: doc 26 | target-folder: api 27 | dry-run: false 28 | release: 29 | runs-on: ubuntu-latest 30 | outputs: 31 | current_tag: ${{ steps.tag.outputs.current_tag }} 32 | steps: 33 | - uses: actions/checkout@v4 34 | with: 35 | persist-credentials: false 36 | - uses: actions/setup-node@v4 37 | with: 38 | node-version: 16 39 | - run: npm ci 40 | - run: npx semantic-release 41 | env: 42 | GH_TOKEN: ${{ secrets.RELEASE_GITHUB_TOKEN }} 43 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 44 | -------------------------------------------------------------------------------- /.github/workflows/release-manual-docs.yml: -------------------------------------------------------------------------------- 1 | # Trigger this workflow only to manually publish API docs; this should only be used 2 | # in extraordinary circumstances as this is done automatically as part of the 3 | # automated release workflow. 4 | 5 | name: release-manual-docs 6 | on: workflow_dispatch 7 | jobs: 8 | publish-docs: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v4 12 | with: 13 | fetch-depth: 0 14 | - name: Set up JDK 11 15 | uses: actions/setup-java@v4 16 | with: 17 | java-version: '11' 18 | distribution: 'adopt' 19 | - name: Generate Javadoc 20 | run: javadoc @.javadoc || true 21 | - name: Deploy GitHub Pages 22 | uses: JamesIves/github-pages-deploy-action@4.1.5 23 | with: 24 | token: ${{ secrets.GITHUB_TOKEN }} 25 | branch: gh-pages 26 | clean: true 27 | folder: doc 28 | target-folder: api 29 | dry-run: false 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # files for the dex VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # generated files 12 | bin/ 13 | gen/ 14 | 15 | # Local configuration file (sdk path, etc) 16 | local.properties 17 | 18 | # Android Studio 19 | .idea 20 | *.iml 21 | *.ipr 22 | *.iws 23 | classes 24 | gen-external-apklibs 25 | 26 | # Gradle 27 | .gradle 28 | build 29 | 30 | # Other 31 | .metadata 32 | */bin/* 33 | */gen/* 34 | testData 35 | testCache 36 | server.config 37 | docs/ 38 | 39 | # Jacoco 40 | jacoco.exec 41 | 42 | # VSC 43 | .project 44 | 45 | # Node 46 | node_modules/ 47 | npm-debug.log 48 | *.hprof 49 | -------------------------------------------------------------------------------- /.javadoc: -------------------------------------------------------------------------------- 1 | -d doc 2 | -sourcepath parse/src/main/java/:fcm/src/main/java/:facebook/src/main/java/:twitter/src/main/java/ com.parse 3 | -subpackages com.parse.fcm:com.parse.http:com.parse.facebook:com.parse.twitter 4 | -public 5 | --ignore-source-errors 6 | -Xmaxerrs 1 7 | -------------------------------------------------------------------------------- /.releaserc/commit.hbs: -------------------------------------------------------------------------------- 1 | *{{#if scope}} **{{scope}}:** 2 | {{~/if}} {{#if subject}} 3 | {{~subject}} 4 | {{~else}} 5 | {{~header}} 6 | {{~/if}} 7 | 8 | {{~!-- commit link --}} {{#if @root.linkReferences~}} 9 | ([{{shortHash}}]( 10 | {{~#if @root.repository}} 11 | {{~#if @root.host}} 12 | {{~@root.host}}/ 13 | {{~/if}} 14 | {{~#if @root.owner}} 15 | {{~@root.owner}}/ 16 | {{~/if}} 17 | {{~@root.repository}} 18 | {{~else}} 19 | {{~@root.repoUrl}} 20 | {{~/if}}/ 21 | {{~@root.commit}}/{{hash}})) 22 | {{~else}} 23 | {{~shortHash}} 24 | {{~/if}} 25 | 26 | {{~!-- commit references --}} 27 | {{~#if references~}} 28 | , closes 29 | {{~#each references}} {{#if @root.linkReferences~}} 30 | [ 31 | {{~#if this.owner}} 32 | {{~this.owner}}/ 33 | {{~/if}} 34 | {{~this.repository}}#{{this.issue}}]( 35 | {{~#if @root.repository}} 36 | {{~#if @root.host}} 37 | {{~@root.host}}/ 38 | {{~/if}} 39 | {{~#if this.repository}} 40 | {{~#if this.owner}} 41 | {{~this.owner}}/ 42 | {{~/if}} 43 | {{~this.repository}} 44 | {{~else}} 45 | {{~#if @root.owner}} 46 | {{~@root.owner}}/ 47 | {{~/if}} 48 | {{~@root.repository}} 49 | {{~/if}} 50 | {{~else}} 51 | {{~@root.repoUrl}} 52 | {{~/if}}/ 53 | {{~@root.issue}}/{{this.issue}}) 54 | {{~else}} 55 | {{~#if this.owner}} 56 | {{~this.owner}}/ 57 | {{~/if}} 58 | {{~this.repository}}#{{this.issue}} 59 | {{~/if}}{{/each}} 60 | {{~/if}} 61 | 62 | -------------------------------------------------------------------------------- /.releaserc/footer.hbs: -------------------------------------------------------------------------------- 1 | {{#if noteGroups}} 2 | {{#each noteGroups}} 3 | 4 | ### {{title}} 5 | 6 | {{#each notes}} 7 | * {{#if commit.scope}}**{{commit.scope}}:** {{/if}}{{text}} ([{{commit.shortHash}}]({{commit.shortHash}})) 8 | {{/each}} 9 | {{/each}} 10 | 11 | {{/if}} 12 | -------------------------------------------------------------------------------- /.releaserc/header.hbs: -------------------------------------------------------------------------------- 1 | {{#if isPatch~}} 2 | ## 3 | {{~else~}} 4 | # 5 | {{~/if}} {{#if @root.linkCompare~}} 6 | [{{version}}]( 7 | {{~#if @root.repository~}} 8 | {{~#if @root.host}} 9 | {{~@root.host}}/ 10 | {{~/if}} 11 | {{~#if @root.owner}} 12 | {{~@root.owner}}/ 13 | {{~/if}} 14 | {{~@root.repository}} 15 | {{~else}} 16 | {{~@root.repoUrl}} 17 | {{~/if~}} 18 | /compare/{{previousTag}}...{{currentTag}}) 19 | {{~else}} 20 | {{~version}} 21 | {{~/if}} 22 | {{~#if title}} "{{title}}" 23 | {{~/if}} 24 | {{~#if date}} ({{date}}) 25 | {{/if}} 26 | -------------------------------------------------------------------------------- /.releaserc/template.hbs: -------------------------------------------------------------------------------- 1 | {{> header}} 2 | 3 | {{#each commitGroups}} 4 | 5 | {{#if title}} 6 | ### {{title}} 7 | 8 | {{/if}} 9 | {{#each commits}} 10 | {{> commit root=@root}} 11 | {{/each}} 12 | {{/each}} 13 | 14 | {{> footer}} 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD License 2 | 3 | For Parse Android SDK software 4 | 5 | Copyright (c) 2015-present, Parse, LLC. All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without modification, 8 | are permitted provided that the following conditions are met: 9 | 10 | * Redistributions of source code must retain the above copyright notice, this 11 | list of conditions and the following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the above copyright notice, 14 | this list of conditions and the following disclaimer in the documentation 15 | and/or other materials provided with the distribution. 16 | 17 | * Neither the name Parse nor the names of its contributors may be used to 18 | endorse or promote products derived from this software without specific 19 | prior written permission. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 22 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 23 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 25 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 28 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | ----- 33 | 34 | As of April 5, 2017, Parse, LLC has transferred this code to the parse-community organization, and will no longer be contributing to or distributing this code. 35 | -------------------------------------------------------------------------------- /PATENTS: -------------------------------------------------------------------------------- 1 | Additional Grant of Patent Rights Version 2 2 | 3 | "Software" means the Parse Android SDK software distributed by Parse, LLC. 4 | 5 | Parse, LLC. ("Parse") hereby grants to each recipient of the Software 6 | ("you") a perpetual, worldwide, royalty-free, non-exclusive, irrevocable 7 | (subject to the termination provision below) license under any Necessary 8 | Claims, to make, have made, use, sell, offer to sell, import, and otherwise 9 | transfer the Software. For avoidance of doubt, no license is granted under 10 | Parse’s rights in any patent claims that are infringed by (i) modifications 11 | to the Software made by you or any third party or (ii) the Software in 12 | combination with any software or other technology. 13 | 14 | The license granted hereunder will terminate, automatically and without notice, 15 | if you (or any of your subsidiaries, corporate affiliates or agents) initiate 16 | directly or indirectly, or take a direct financial interest in, any Patent 17 | Assertion: (i) against Parse or any of its subsidiaries or corporate 18 | affiliates, (ii) against any party if such Patent Assertion arises in whole or 19 | in part from any software, technology, product or service of Parse or any of 20 | its subsidiaries or corporate affiliates, or (iii) against any party relating 21 | to the Software. Notwithstanding the foregoing, if Parse or any of its 22 | subsidiaries or corporate affiliates files a lawsuit alleging patent 23 | infringement against you in the first instance, and you respond by filing a 24 | patent infringement counterclaim in that lawsuit against that party that is 25 | unrelated to the Software, the license granted hereunder will not terminate 26 | under section (i) of this paragraph due to such counterclaim. 27 | 28 | A "Necessary Claim" is a claim of a patent owned by Parse that is 29 | necessarily infringed by the Software standing alone. 30 | 31 | A "Patent Assertion" is any lawsuit or other action alleging direct, indirect, 32 | or contributory infringement or inducement to infringe any patent, including a 33 | cross-claim or counterclaim. 34 | 35 | ----- 36 | 37 | As of April 5, 2017, Parse, LLC has transferred this code to the parse-community organization, and will no longer be contributing to or distributing this code. 38 | -------------------------------------------------------------------------------- /bolts-tasks/README.md: -------------------------------------------------------------------------------- 1 | ## bolts-tasks 2 | Fork of [Bolts-Android](https://github.com/BoltsFramework/Bolts-Android), since it is no longer 3 | really maintained/supported. Moving it here gives us the control over the dependency and allow us to shift 4 | to other async solutions, such as Kotlin coroutines, long-term. 5 | -------------------------------------------------------------------------------- /bolts-tasks/build.gradle: -------------------------------------------------------------------------------- 1 | // Copyright (c) Facebook, Inc. and its affiliates. 2 | // 3 | // This source code is licensed under the MIT license found in the/ 4 | // LICENSE file in the root directory of this source tree. 5 | 6 | apply plugin: 'java-library' 7 | apply plugin: 'maven-publish' 8 | 9 | dependencies { 10 | compileOnly 'com.google.android:android:4.1.1.4' 11 | testImplementation "junit:junit:$rootProject.ext.junitVersion" 12 | } 13 | 14 | java { 15 | sourceCompatibility = JavaVersion.VERSION_1_8 16 | targetCompatibility = JavaVersion.VERSION_1_8 17 | } 18 | 19 | javadoc.options.addStringOption('Xdoclint:none', '-quiet') 20 | 21 | task sourcesJar(type: Jar) { 22 | archiveClassifier.set('sources') 23 | from sourceSets.main.allJava 24 | } 25 | 26 | task javadocJar(type: Jar, dependsOn: javadoc) { 27 | archiveClassifier.set('javadoc') 28 | from javadoc.destinationDir 29 | } 30 | 31 | artifacts { 32 | archives sourcesJar 33 | archives javadocJar 34 | } 35 | 36 | //region Publishing 37 | 38 | afterEvaluate { 39 | publishing { 40 | publications { 41 | boltsPublication(MavenPublication) { 42 | from components.java 43 | } 44 | } 45 | } 46 | } 47 | 48 | //endregion 49 | 50 | //region Code Coverage 51 | 52 | apply plugin: 'jacoco' 53 | 54 | jacocoTestReport { 55 | group = "Reporting" 56 | description = "Generate Jacoco coverage reports after running tests." 57 | reports { 58 | xml.enabled true 59 | html.enabled true 60 | } 61 | } 62 | 63 | //endregion 64 | -------------------------------------------------------------------------------- /bolts-tasks/src/main/java/com/parse/boltsinternal/CancellationTokenRegistration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | package com.parse.boltsinternal; 8 | 9 | import java.io.Closeable; 10 | 11 | /** 12 | * Represents a callback delegate that has been registered with a {@link CancellationToken}. 13 | * 14 | * @see CancellationToken#register(Runnable) 15 | */ 16 | public class CancellationTokenRegistration implements Closeable { 17 | 18 | private final Object lock = new Object(); 19 | private CancellationTokenSource tokenSource; 20 | private Runnable action; 21 | private boolean closed; 22 | 23 | /* package */ CancellationTokenRegistration( 24 | CancellationTokenSource tokenSource, Runnable action) { 25 | this.tokenSource = tokenSource; 26 | this.action = action; 27 | } 28 | 29 | /** Unregisters the callback runnable from the cancellation token. */ 30 | @Override 31 | public void close() { 32 | synchronized (lock) { 33 | if (closed) { 34 | return; 35 | } 36 | 37 | closed = true; 38 | tokenSource.unregister(this); 39 | tokenSource = null; 40 | action = null; 41 | } 42 | } 43 | 44 | /* package */ void runAction() { 45 | synchronized (lock) { 46 | throwIfClosed(); 47 | action.run(); 48 | close(); 49 | } 50 | } 51 | 52 | private void throwIfClosed() { 53 | if (closed) { 54 | throw new IllegalStateException("Object already closed"); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /bolts-tasks/src/main/java/com/parse/boltsinternal/Capture.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | package com.parse.boltsinternal; 8 | 9 | /** 10 | * Provides a class that can be used for capturing variables in an anonymous class implementation. 11 | * 12 | * @param 13 | */ 14 | public class Capture { 15 | private T value; 16 | 17 | public Capture() {} 18 | 19 | public Capture(T value) { 20 | this.value = value; 21 | } 22 | 23 | public T get() { 24 | return value; 25 | } 26 | 27 | public void set(T value) { 28 | this.value = value; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /bolts-tasks/src/main/java/com/parse/boltsinternal/Continuation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | package com.parse.boltsinternal; 8 | 9 | /** 10 | * A function to be called after a task completes. 11 | * 12 | *

If you wish to have the Task from a Continuation that does not return a Task be cancelled then 13 | * throw a {@link java.util.concurrent.CancellationException} from the Continuation. 14 | * 15 | * @see Task 16 | */ 17 | public interface Continuation { 18 | TContinuationResult then(Task task) throws Exception; 19 | } 20 | -------------------------------------------------------------------------------- /bolts-tasks/src/main/java/com/parse/boltsinternal/ExecutorException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | package com.parse.boltsinternal; 8 | 9 | /** 10 | * This is a wrapper class for emphasizing that task failed due to bad {@code Executor}, rather than 11 | * the continuation block it self. 12 | */ 13 | public class ExecutorException extends RuntimeException { 14 | 15 | public ExecutorException(Exception e) { 16 | super("An exception was thrown by an Executor", e); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /bolts-tasks/src/main/java/com/parse/boltsinternal/UnobservedErrorNotifier.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | package com.parse.boltsinternal; 8 | 9 | /** 10 | * This class is used to retain a faulted task until either its error is observed or it is 11 | * finalized. If it is finalized with a task, then the uncaught exception handler is exected with an 12 | * UnobservedTaskException. 13 | */ 14 | class UnobservedErrorNotifier { 15 | private Task task; 16 | 17 | public UnobservedErrorNotifier(Task task) { 18 | this.task = task; 19 | } 20 | 21 | @Override 22 | protected void finalize() throws Throwable { 23 | try { 24 | Task faultedTask = this.task; 25 | if (faultedTask != null) { 26 | Task.UnobservedExceptionHandler ueh = Task.getUnobservedExceptionHandler(); 27 | if (ueh != null) { 28 | ueh.unobservedException( 29 | faultedTask, new UnobservedTaskException(faultedTask.getError())); 30 | } 31 | } 32 | } finally { 33 | super.finalize(); 34 | } 35 | } 36 | 37 | public void setObserved() { 38 | task = null; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /bolts-tasks/src/main/java/com/parse/boltsinternal/UnobservedTaskException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | package com.parse.boltsinternal; 8 | 9 | /** Used to signify that a Task's error went unobserved. */ 10 | public class UnobservedTaskException extends RuntimeException { 11 | public UnobservedTaskException(Throwable cause) { 12 | super(cause); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = "1.7.10" 3 | ext.jacocoVersion = '0.8.12' 4 | repositories { 5 | google() 6 | mavenCentral() 7 | } 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:7.1.3' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | classpath "org.jacoco:org.jacoco.core:$jacocoVersion" 12 | classpath "com.dicedmelon.gradle:jacoco-android:0.1.5" 13 | classpath "io.freefair.gradle:android-gradle-plugins:4.2.0-m1" 14 | classpath "com.diffplug.spotless:spotless-plugin-gradle:5.17.1" 15 | } 16 | } 17 | 18 | plugins { 19 | id "com.github.ben-manes.versions" version "0.28.0" 20 | id "com.diffplug.spotless" version "5.17.1" 21 | } 22 | 23 | allprojects { 24 | repositories { 25 | google() 26 | mavenCentral() 27 | } 28 | 29 | apply plugin: "com.diffplug.spotless" 30 | 31 | spotless { 32 | java { 33 | target '**/*.java' 34 | googleJavaFormat().aosp() 35 | removeUnusedImports() 36 | trimTrailingWhitespace() 37 | indentWithSpaces() 38 | endWithNewline() 39 | } 40 | kotlin { 41 | target '**/*.kt' 42 | ktlint().userData(["disabled_rules": "no-wildcard-imports"]) 43 | trimTrailingWhitespace() 44 | indentWithSpaces() 45 | endWithNewline() 46 | } 47 | format 'misc', { 48 | target '**/*.gradle', '**/*.md', '**/.gitignore' 49 | indentWithSpaces() 50 | trimTrailingWhitespace() 51 | endWithNewline() 52 | } 53 | 54 | format 'xml', { 55 | target '**/*.xml' 56 | indentWithSpaces() 57 | trimTrailingWhitespace() 58 | endWithNewline() 59 | } 60 | } 61 | } 62 | 63 | ext { 64 | compileSdkVersion = 31 65 | 66 | minSdkVersion = 21 67 | targetSdkVersion = 31 68 | 69 | mockitoCoreVersion = '4.6.1' 70 | junitVersion = "4.13.2" 71 | jupiterVersion = "5.6.0" 72 | robolectricVersion = "4.7" 73 | } 74 | -------------------------------------------------------------------------------- /coroutines/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /coroutines/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "com.android.library" 2 | apply plugin: "kotlin-android" 3 | apply plugin: "maven-publish" 4 | apply plugin: "io.freefair.android-javadoc-jar" 5 | apply plugin: "io.freefair.android-sources-jar" 6 | 7 | android { 8 | compileSdkVersion rootProject.ext.compileSdkVersion 9 | 10 | defaultConfig { 11 | minSdkVersion rootProject.ext.minSdkVersion 12 | targetSdkVersion rootProject.ext.targetSdkVersion 13 | } 14 | 15 | lintOptions { 16 | abortOnError false 17 | } 18 | 19 | buildTypes { 20 | debug { 21 | testCoverageEnabled = true 22 | buildConfigField("String","PARSE_VERSION","\"${version}\"") 23 | } 24 | release { 25 | minifyEnabled false 26 | testCoverageEnabled = false 27 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 28 | buildConfigField("String","PARSE_VERSION","\"${version}\"") 29 | } 30 | } 31 | 32 | compileOptions { 33 | sourceCompatibility JavaVersion.VERSION_1_8 34 | targetCompatibility JavaVersion.VERSION_1_8 35 | } 36 | 37 | kotlinOptions { 38 | jvmTarget = "1.8" 39 | } 40 | } 41 | 42 | ext { 43 | coroutinesVersion = "1.6.1" 44 | } 45 | 46 | dependencies { 47 | api "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" 48 | api "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion" 49 | api "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutinesVersion" 50 | implementation project(":parse") 51 | } 52 | 53 | afterEvaluate { 54 | publishing { 55 | publications { 56 | release(MavenPublication) { 57 | from components.release 58 | } 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /coroutines/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | -keepnames class kotlinx.coroutines.internal.MainDispatcherFactory {} 2 | -keepnames class kotlinx.coroutines.CoroutineExceptionHandler {} 3 | -keepclassmembernames class kotlinx.** { 4 | volatile ; 5 | } -------------------------------------------------------------------------------- /coroutines/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /coroutines/src/main/java/com/parse/coroutines/ParseCloudCoroutinesExtensions.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("ParseCloudCoroutinesExtensions") 2 | 3 | package com.parse.coroutines 4 | 5 | import com.parse.ParseCloud 6 | import kotlin.coroutines.resume 7 | import kotlin.coroutines.resumeWithException 8 | import kotlin.coroutines.suspendCoroutine 9 | 10 | suspend fun callCloudFunction(functionName: String, params: Map): T { 11 | return suspendCoroutine { continuation -> 12 | ParseCloud.callFunctionInBackground(functionName, params) { result, e -> 13 | if (e == null) continuation.resume(result) 14 | else continuation.resumeWithException(e) 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /coroutines/src/main/java/com/parse/coroutines/ParseObjectCoroutinesExtensions.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("ParseObjectCoroutinesExtensions") 2 | 3 | package com.parse.coroutines 4 | 5 | import com.parse.ParseObject 6 | import kotlin.coroutines.resume 7 | import kotlin.coroutines.resumeWithException 8 | import kotlin.coroutines.suspendCoroutine 9 | 10 | suspend fun ParseObject.suspendFetch(): T { 11 | return suspendCoroutine { continuation -> 12 | 13 | fetchInBackground { obj, e -> 14 | if (e == null) continuation.resume(obj) 15 | else continuation.resumeWithException(e) 16 | } 17 | } 18 | } 19 | 20 | suspend fun ParseObject.suspendFetchIfNeeded(): T { 21 | return suspendCoroutine { continuation -> 22 | 23 | fetchIfNeededInBackground { obj, e -> 24 | if (e == null) continuation.resume(obj) 25 | else continuation.resumeWithException(e) 26 | } 27 | } 28 | } 29 | 30 | suspend fun ParseObject.fetchFromLocal(): T { 31 | return suspendCoroutine { continuation -> 32 | 33 | fetchFromLocalDatastoreInBackground { obj, e -> 34 | if (e == null) continuation.resume(obj) 35 | else continuation.resumeWithException(e) 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /coroutines/src/main/java/com/parse/coroutines/ParseObjectCoroutinesWriteExtensions.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("ParseObjectCoroutinesWriteExtensions") 2 | 3 | package com.parse.coroutines 4 | 5 | import com.parse.ParseObject 6 | import kotlin.coroutines.resume 7 | import kotlin.coroutines.resumeWithException 8 | import kotlin.coroutines.suspendCoroutine 9 | 10 | suspend fun ParseObject.suspendSave() { 11 | return suspendCoroutine { continuation -> 12 | saveInBackground { 13 | if (it == null) continuation.resume(Unit) 14 | else continuation.resumeWithException(it) 15 | } 16 | } 17 | } 18 | 19 | suspend fun ParseObject.suspendPin() { 20 | return suspendCoroutine { continuation -> 21 | pinInBackground { 22 | if (it == null) continuation.resume(Unit) 23 | else continuation.resumeWithException(it) 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /coroutines/src/main/java/com/parse/coroutines/ParseQueryCoroutinesBuilder.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("ParseQueryCoroutinesBuilder") 2 | 3 | package com.parse.coroutines 4 | 5 | import com.parse.ParseObject 6 | import com.parse.ParseQuery 7 | import kotlinx.coroutines.CoroutineScope 8 | import kotlinx.coroutines.Job 9 | import kotlinx.coroutines.launch 10 | import kotlin.coroutines.CoroutineContext 11 | import kotlin.coroutines.EmptyCoroutineContext 12 | 13 | fun CoroutineScope.launchQuery( 14 | query: ParseQuery, 15 | context: CoroutineContext = EmptyCoroutineContext, 16 | block: suspend ParseQueryOperation.() -> Unit 17 | ): Job { 18 | return launch(context) { 19 | block.invoke(ParseQueryOperationImpl(query)) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /coroutines/src/main/java/com/parse/coroutines/ParseQueryOperation.kt: -------------------------------------------------------------------------------- 1 | package com.parse.coroutines 2 | 3 | interface ParseQueryOperation { 4 | suspend fun find(): List 5 | suspend fun get(id: String): T 6 | suspend fun first(): T 7 | suspend fun count(): Int 8 | } 9 | -------------------------------------------------------------------------------- /coroutines/src/main/java/com/parse/coroutines/ParseQueryOperationImpl.kt: -------------------------------------------------------------------------------- 1 | package com.parse.coroutines 2 | 3 | import com.parse.ParseObject 4 | import com.parse.ParseQuery 5 | 6 | class ParseQueryOperationImpl(private val query: ParseQuery) : 7 | ParseQueryOperation { 8 | 9 | override suspend fun find(): List = query.findInternal() 10 | 11 | override suspend fun get(id: String): T = query.getInternal(id) 12 | 13 | override suspend fun first(): T = query.firstInternal() 14 | 15 | override suspend fun count(): Int = query.countInternal() 16 | } 17 | -------------------------------------------------------------------------------- /coroutines/src/main/java/com/parse/coroutines/ParseTaskExtensions.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("ParseTaskExtensions") 2 | @file:Suppress("unused") 3 | 4 | package com.parse.coroutines 5 | 6 | import com.parse.boltsinternal.Task 7 | import kotlinx.coroutines.CoroutineDispatcher 8 | import kotlinx.coroutines.Dispatchers 9 | import kotlinx.coroutines.withContext 10 | import kotlin.coroutines.resume 11 | import kotlin.coroutines.resumeWithException 12 | import kotlin.coroutines.suspendCoroutine 13 | 14 | @Suppress("BlockingMethodInNonBlockingContext") 15 | suspend fun Task.suspendGet(dispatcher: CoroutineDispatcher = Dispatchers.IO) = withContext(dispatcher) { 16 | return@withContext suspendCoroutine { continuation -> 17 | waitForCompletion() 18 | if (isFaulted) continuation.resumeWithException(error) 19 | else continuation.resume(result) 20 | } 21 | } 22 | 23 | @Suppress("BlockingMethodInNonBlockingContext") 24 | suspend fun Task.suspendRun(dispatcher: CoroutineDispatcher = Dispatchers.IO) = withContext(dispatcher) { 25 | return@withContext suspendCoroutine { continuation -> 26 | waitForCompletion() 27 | if (isFaulted) continuation.resumeWithException(error) 28 | else continuation.resume(Unit) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /coroutines/src/main/java/com/parse/coroutines/ParseUserCoroutinesExtensions.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("ParseUserCoroutinesExtensions") 2 | 3 | package com.parse.coroutines 4 | 5 | import com.parse.ParseUser 6 | import kotlin.coroutines.resume 7 | import kotlin.coroutines.resumeWithException 8 | import kotlin.coroutines.suspendCoroutine 9 | 10 | suspend fun ParseUser.suspendSignUp(): ParseUser { 11 | return suspendCoroutine { continuation -> 12 | signUpInBackground { e -> 13 | if (e == null) continuation.resume(this) 14 | else continuation.resumeWithException(e) 15 | } 16 | } 17 | } 18 | 19 | suspend fun parseLogIn(username: String, password: String): ParseUser { 20 | return suspendCoroutine { continuation -> 21 | ParseUser.logInInBackground(username, password) { user, e -> 22 | if (e == null) continuation.resume(user) 23 | else continuation.resumeWithException(e) 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /facebook/README.md: -------------------------------------------------------------------------------- 1 | # Parse Facebook Utils for Android 2 | A utility library to authenticate `ParseUser`s with the Facebook SDK. 3 | 4 | ## Dependency 5 | 6 | After including JitPack: 7 | ```gradle 8 | dependencies { 9 | implementation "com.github.parse-community.Parse-SDK-Android:facebook:latest.version.here" 10 | } 11 | ``` 12 | 13 | ## Usage 14 | Extensive docs can be found in the [guide](https://docs.parseplatform.org/android/guide/#facebook-users). The basic steps are: 15 | ```java 16 | // in Application.onCreate(); or somewhere similar 17 | ParseFacebookUtils.initialize(context); 18 | ``` 19 | Within the activity where your user is going to log in with Facebook, include the following: 20 | ```java 21 | @Override 22 | protected void onActivityResult(int requestCode, int resultCode, Intent data) { 23 | super.onActivityResult(requestCode, resultCode, data); 24 | ParseFacebookUtils.onActivityResult(requestCode, resultCode, data); 25 | } 26 | ``` 27 | Then elsewhere, when your user taps the login button: 28 | ```java 29 | ParseFacebookUtils.logInWithReadPermissionsInBackground(this, permissions, new LogInCallback() { 30 | @Override 31 | public void done(ParseUser user, ParseException err) { 32 | if (user == null) { 33 | Log.d("MyApp", "Uh oh. The user cancelled the Facebook login."); 34 | } else if (user.isNew()) { 35 | Log.d("MyApp", "User signed up and logged in through Facebook!"); 36 | } else { 37 | Log.d("MyApp", "User logged in through Facebook!"); 38 | } 39 | } 40 | }); 41 | ``` 42 | 43 | ## License 44 | Copyright (c) 2015-present, Parse, LLC. 45 | All rights reserved. 46 | 47 | This source code is licensed under the BSD-style license found in the 48 | LICENSE file in the root directory of this source tree. An additional grant 49 | of patent rights can be found in the PATENTS file in the same directory. 50 | -------------------------------------------------------------------------------- /facebook/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "com.android.library" 2 | apply plugin: "maven-publish" 3 | apply plugin: "io.freefair.android-javadoc-jar" 4 | apply plugin: "io.freefair.android-sources-jar" 5 | 6 | android { 7 | compileSdkVersion rootProject.ext.compileSdkVersion 8 | 9 | defaultConfig { 10 | minSdkVersion rootProject.ext.minSdkVersion 11 | targetSdkVersion rootProject.ext.targetSdkVersion 12 | } 13 | 14 | lintOptions { 15 | abortOnError false 16 | } 17 | 18 | buildTypes { 19 | debug { 20 | testCoverageEnabled = true 21 | buildConfigField("String","PARSE_VERSION","\"${version}\"") 22 | } 23 | release { 24 | minifyEnabled false 25 | testCoverageEnabled = false 26 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 27 | buildConfigField("String","PARSE_VERSION","\"${version}\"") 28 | } 29 | } 30 | 31 | compileOptions { 32 | sourceCompatibility JavaVersion.VERSION_1_8 33 | targetCompatibility JavaVersion.VERSION_1_8 34 | } 35 | } 36 | 37 | dependencies { 38 | api "com.facebook.android:facebook-login:[13.2.0, 17.0.0[" 39 | implementation project(":parse") 40 | 41 | testImplementation "junit:junit:$rootProject.ext.junitVersion" 42 | testImplementation "org.mockito:mockito-core:$rootProject.ext.mockitoCoreVersion" 43 | testImplementation "org.mockito:mockito-inline:$rootProject.ext.mockitoCoreVersion" 44 | testImplementation "org.robolectric:robolectric:$rootProject.ext.robolectricVersion" 45 | } 46 | 47 | afterEvaluate { 48 | publishing { 49 | publications { 50 | release(MavenPublication) { 51 | from components.release 52 | } 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /facebook/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 9 | 10 | -------------------------------------------------------------------------------- /facebook/src/test/java/com/parse/facebook/TestUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse.facebook; 10 | 11 | import com.facebook.AccessToken; 12 | import com.facebook.AccessTokenSource; 13 | 14 | /** package */ 15 | class TestUtils { 16 | static AccessToken newAccessToken() { 17 | return new AccessToken( 18 | "test_token", 19 | "test_application_id", 20 | "test_id", 21 | null, 22 | null, 23 | null, 24 | AccessTokenSource.DEVICE_AUTH, 25 | null, 26 | null, 27 | null); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /fcm/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /fcm/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "com.android.library" 2 | apply plugin: "maven-publish" 3 | apply plugin: "io.freefair.android-javadoc-jar" 4 | apply plugin: "io.freefair.android-sources-jar" 5 | 6 | android { 7 | compileSdkVersion rootProject.ext.compileSdkVersion 8 | 9 | defaultConfig { 10 | minSdkVersion rootProject.ext.minSdkVersion 11 | targetSdkVersion rootProject.ext.targetSdkVersion 12 | } 13 | 14 | lintOptions { 15 | abortOnError false 16 | } 17 | 18 | buildTypes { 19 | debug { 20 | testCoverageEnabled = true 21 | buildConfigField("String","PARSE_VERSION","\"${version}\"") 22 | } 23 | release { 24 | minifyEnabled false 25 | testCoverageEnabled = false 26 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 27 | buildConfigField("String","PARSE_VERSION","\"${version}\"") 28 | } 29 | } 30 | 31 | compileOptions { 32 | sourceCompatibility JavaVersion.VERSION_1_8 33 | targetCompatibility JavaVersion.VERSION_1_8 34 | } 35 | 36 | } 37 | 38 | dependencies { 39 | api 'com.google.firebase:firebase-messaging:23.0.7' 40 | implementation project(":parse") 41 | } 42 | 43 | afterEvaluate { 44 | publishing { 45 | publications { 46 | release(MavenPublication) { 47 | from components.release 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /fcm/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /fcm/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /fcm/src/main/java/com/parse/fcm/ParseFCM.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse.fcm; 10 | 11 | import com.parse.PLog; 12 | import com.parse.ParseInstallation; 13 | 14 | public class ParseFCM { 15 | 16 | static final String TAG = "ParseFCM"; 17 | 18 | private static final String PUSH_TYPE = "gcm"; // Backwards compatability with Parse servers 19 | 20 | /** 21 | * You can call this manually if you are overriding the {@link 22 | * com.google.firebase.messaging.FirebaseMessagingService} fetching the token via {@link 23 | * com.google.firebase.messaging.FirebaseMessagingService#onNewToken(String)} 24 | * 25 | * @param token the token 26 | */ 27 | public static void register(String token) { 28 | PLog.d(ParseFCM.TAG, "Updating FCM token"); 29 | ParseInstallation installation = ParseInstallation.getCurrentInstallation(); 30 | if (installation != null && token != null) { 31 | installation.setDeviceToken(token); 32 | // even though this is FCM, calling it gcm will work on the backend 33 | installation.setPushType(PUSH_TYPE); 34 | installation.saveInBackground( 35 | e -> { 36 | if (e == null) { 37 | PLog.d(ParseFCM.TAG, "FCM token saved to installation"); 38 | } else { 39 | PLog.e(ParseFCM.TAG, "FCM token upload failed", e); 40 | } 41 | }); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /fcm/src/main/java/com/parse/fcm/ParseFirebaseMessagingService.java: -------------------------------------------------------------------------------- 1 | package com.parse.fcm; 2 | 3 | import androidx.annotation.NonNull; 4 | import com.google.firebase.messaging.FirebaseMessagingService; 5 | import com.google.firebase.messaging.RemoteMessage; 6 | import com.parse.PLog; 7 | import com.parse.PushRouter; 8 | import org.json.JSONException; 9 | import org.json.JSONObject; 10 | 11 | public class ParseFirebaseMessagingService extends FirebaseMessagingService { 12 | 13 | @Override 14 | public void onNewToken(@NonNull String token) { 15 | super.onNewToken(token); 16 | ParseFCM.register(token); 17 | } 18 | 19 | @Override 20 | public void onMessageReceived(@NonNull RemoteMessage remoteMessage) { 21 | super.onMessageReceived(remoteMessage); 22 | PLog.d(ParseFCM.TAG, "onMessageReceived"); 23 | 24 | String pushId = remoteMessage.getData().get("push_id"); 25 | String timestamp = remoteMessage.getData().get("time"); 26 | String dataString = remoteMessage.getData().get("data"); 27 | String channel = remoteMessage.getData().get("channel"); 28 | 29 | JSONObject data = null; 30 | if (dataString != null) { 31 | try { 32 | data = new JSONObject(dataString); 33 | } catch (JSONException e) { 34 | PLog.e( 35 | ParseFCM.TAG, 36 | "Ignoring push because of JSON exception while processing: " + dataString, 37 | e); 38 | return; 39 | } 40 | } 41 | 42 | PushRouter.getInstance().handlePush(pushId, timestamp, channel, data); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /google/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /google/README.md: -------------------------------------------------------------------------------- 1 | # Parse Google Utils for Android 2 | A utility library to authenticate `ParseUser`s with the Google SDK. 3 | 4 | ## Dependency 5 | 6 | After including JitPack: 7 | ```gradle 8 | dependencies { 9 | implementation "com.github.parse-community.Parse-SDK-Android:google:latest.version.here" 10 | } 11 | ``` 12 | 13 | ## Usage 14 | Here we will show the basic steps for logging in/signing up with Google. First: 15 | ```java 16 | // in Application.onCreate(); or somewhere similar 17 | ParseGoogleUtils.initialize(getString(R.string.default_web_client_id)); 18 | ``` 19 | If you have already configured [Firebase](https://firebase.google.com/docs/android/setup) in your project, the above will work. Otherwise, you might instead need to replace `getString(R.id.default_web_client_id` with a web configured OAuth 2.0 API client ID. 20 | 21 | Within the activity where your user is going to log in with Google, include the following: 22 | ```java 23 | @Override 24 | protected void onActivityResult(int requestCode, int resultCode, Intent data) { 25 | super.onActivityResult(requestCode, resultCode, data); 26 | ParseGoogleUtils.onActivityResult(requestCode, resultCode, data); 27 | } 28 | ``` 29 | Then elsewhere, when your user taps the login button: 30 | ```java 31 | ParseGoogleUtils.logInWithReadPermissionsInBackground(this, permissions, new LogInCallback() { 32 | @Override 33 | public void done(ParseUser user, ParseException err) { 34 | if (user == null) { 35 | Log.d("MyApp", "Uh oh. The user cancelled the Google login."); 36 | } else if (user.isNew()) { 37 | Log.d("MyApp", "User signed up and logged in through Google!"); 38 | } else { 39 | Log.d("MyApp", "User logged in through Google!"); 40 | } 41 | } 42 | }); 43 | ``` 44 | 45 | ## License 46 | Copyright (c) 2015-present, Parse, LLC. 47 | All rights reserved. 48 | 49 | This source code is licensed under the BSD-style license found in the 50 | LICENSE file in the root directory of this source tree. An additional grant 51 | of patent rights can be found in the PATENTS file in the same directory. 52 | -------------------------------------------------------------------------------- /google/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "com.android.library" 2 | apply plugin: "kotlin-android" 3 | apply plugin: "maven-publish" 4 | apply plugin: "io.freefair.android-javadoc-jar" 5 | apply plugin: "io.freefair.android-sources-jar" 6 | 7 | android { 8 | compileSdkVersion rootProject.ext.compileSdkVersion 9 | 10 | defaultConfig { 11 | minSdkVersion rootProject.ext.minSdkVersion 12 | targetSdkVersion rootProject.ext.targetSdkVersion 13 | } 14 | 15 | lintOptions { 16 | abortOnError false 17 | } 18 | 19 | compileOptions { 20 | sourceCompatibility JavaVersion.VERSION_1_8 21 | targetCompatibility JavaVersion.VERSION_1_8 22 | } 23 | 24 | buildTypes { 25 | debug { 26 | testCoverageEnabled = true 27 | buildConfigField("String","PARSE_VERSION","\"${version}\"") 28 | } 29 | release { 30 | minifyEnabled false 31 | testCoverageEnabled = false 32 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 33 | buildConfigField("String","PARSE_VERSION","\"${version}\"") 34 | } 35 | } 36 | 37 | kotlinOptions { 38 | jvmTarget = "1.8" 39 | } 40 | } 41 | 42 | dependencies { 43 | api "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" 44 | api "com.google.android.gms:play-services-auth:20.2.0" 45 | api "androidx.activity:activity-ktx:1.5.1" 46 | api "androidx.fragment:fragment-ktx:1.5.2" 47 | implementation project(":parse") 48 | } 49 | 50 | afterEvaluate { 51 | publishing { 52 | publications { 53 | release(MavenPublication) { 54 | from components.release 55 | } 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /google/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | version = 4.3.0 2 | android.enableJetifier = true 3 | android.useAndroidX = true 4 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parse-community/Parse-SDK-Android/d6926f3dbffb2c2abfb8bb70895eda5601011b36/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sat Apr 16 09:27:50 CEST 2022 2 | distributionBase=GRADLE_USER_HOME 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip 4 | distributionPath=wrapper/dists 5 | zipStorePath=wrapper/dists 6 | zipStoreBase=GRADLE_USER_HOME 7 | -------------------------------------------------------------------------------- /jitpack.yml: -------------------------------------------------------------------------------- 1 | jdk: 2 | - openjdk11 3 | -------------------------------------------------------------------------------- /ktx/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /ktx/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "com.android.library" 2 | apply plugin: "kotlin-android" 3 | apply plugin: "maven-publish" 4 | apply plugin: "io.freefair.android-javadoc-jar" 5 | apply plugin: "io.freefair.android-sources-jar" 6 | 7 | android { 8 | compileSdkVersion rootProject.ext.compileSdkVersion 9 | 10 | defaultConfig { 11 | minSdkVersion rootProject.ext.minSdkVersion 12 | targetSdkVersion rootProject.ext.targetSdkVersion 13 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 14 | } 15 | 16 | lintOptions { 17 | abortOnError false 18 | } 19 | 20 | buildTypes { 21 | debug { 22 | testCoverageEnabled = true 23 | buildConfigField("String","PARSE_VERSION","\"${version}\"") 24 | } 25 | release { 26 | minifyEnabled false 27 | testCoverageEnabled = false 28 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 29 | buildConfigField("String","PARSE_VERSION","\"${version}\"") 30 | } 31 | } 32 | 33 | compileOptions { 34 | sourceCompatibility JavaVersion.VERSION_1_8 35 | targetCompatibility JavaVersion.VERSION_1_8 36 | } 37 | 38 | kotlinOptions { 39 | jvmTarget = "1.8" 40 | } 41 | } 42 | 43 | dependencies { 44 | api "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" 45 | implementation project(":parse") 46 | } 47 | 48 | afterEvaluate { 49 | publishing { 50 | publications { 51 | release(MavenPublication) { 52 | from components.release 53 | } 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /ktx/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /ktx/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /ktx/src/main/java/com/parse/ktx/delegates/BooleanParseDelegate.kt: -------------------------------------------------------------------------------- 1 | @file:Suppress("unused", "NOTHING_TO_INLINE") 2 | 3 | package com.parse.ktx.delegates 4 | 5 | import com.parse.ParseObject 6 | import kotlin.reflect.KProperty 7 | 8 | /** 9 | * A [Boolean] property delegation for [ParseObject]. 10 | */ 11 | class BooleanParseDelegate(private val name: String?) { 12 | 13 | operator fun getValue(parseObject: ParseObject, property: KProperty<*>): Boolean { 14 | return parseObject.getBoolean(name ?: property.name) 15 | } 16 | 17 | operator fun setValue(parseObject: ParseObject, property: KProperty<*>, value: Boolean) { 18 | parseObject.put(name ?: property.name, value) 19 | } 20 | } 21 | 22 | /** 23 | * Returns a [Boolean] property delegate for [ParseObject]s. This uses [ParseObject.getBoolean] 24 | * and [ParseObject.put]. 25 | */ 26 | inline fun booleanAttribute(name: String? = null) = BooleanParseDelegate(name) 27 | -------------------------------------------------------------------------------- /ktx/src/main/java/com/parse/ktx/delegates/BytesParseDelegate.kt: -------------------------------------------------------------------------------- 1 | @file:Suppress("unused", "NOTHING_TO_INLINE") 2 | 3 | package com.parse.ktx.delegates 4 | 5 | import com.parse.ParseObject 6 | import com.parse.ktx.putOrIgnore 7 | import kotlin.reflect.KProperty 8 | 9 | /** 10 | * A [ByteArray] property delegation for [ParseObject]. 11 | */ 12 | class BytesParseDelegate(private val name: String?) { 13 | 14 | operator fun getValue(parseObject: ParseObject, property: KProperty<*>): ByteArray? { 15 | return parseObject.getBytes(name ?: property.name) 16 | } 17 | 18 | operator fun setValue(parseObject: ParseObject, property: KProperty<*>, value: ByteArray?) { 19 | parseObject.putOrIgnore(name ?: property.name, value) 20 | } 21 | } 22 | 23 | /** 24 | * Returns a [ByteArray] property delegate for [ParseObject]s. This uses [ParseObject.getBytes] 25 | * and [ParseObject.putOrIgnore]. 26 | */ 27 | inline fun bytesAttribute(name: String? = null) = BytesParseDelegate(name) 28 | -------------------------------------------------------------------------------- /ktx/src/main/java/com/parse/ktx/delegates/DoubleParseDelegate.kt: -------------------------------------------------------------------------------- 1 | @file:Suppress("unused", "NOTHING_TO_INLINE") 2 | 3 | package com.parse.ktx.delegates 4 | 5 | import com.parse.ParseObject 6 | import kotlin.reflect.KProperty 7 | 8 | /** 9 | * A [Double] property delegation for [ParseObject]. 10 | */ 11 | class DoubleParseDelegate(private val name: String?) { 12 | 13 | operator fun getValue(parseObject: ParseObject, property: KProperty<*>): Double { 14 | return parseObject.getDouble(name ?: property.name) 15 | } 16 | 17 | operator fun setValue(parseObject: ParseObject, property: KProperty<*>, value: Double) { 18 | parseObject.put(name ?: property.name, value) 19 | } 20 | } 21 | 22 | /** 23 | * Returns a [Double] property delegate for [ParseObject]s. This uses [ParseObject.getDouble] 24 | * and [ParseObject.put]. 25 | */ 26 | inline fun doubleAttribute(name: String? = null) = DoubleParseDelegate(name) 27 | -------------------------------------------------------------------------------- /ktx/src/main/java/com/parse/ktx/delegates/EnumParseDelegate.kt: -------------------------------------------------------------------------------- 1 | @file:Suppress("unused") 2 | 3 | package com.parse.ktx.delegates 4 | 5 | import com.parse.ParseObject 6 | import kotlin.reflect.KProperty 7 | 8 | /** 9 | * A [Enum] property delegation for [ParseObject]. 10 | * 11 | * This implementation save enum's name in lower case on parse-server and when try retrieve it 12 | * convert again to upper case to find correspondent local enum. 13 | */ 14 | class EnumParseDelegate>( 15 | private val name: String?, 16 | private val default: T?, 17 | private val enumClass: Class 18 | ) { 19 | 20 | operator fun getValue(parseObject: ParseObject, property: KProperty<*>): T { 21 | return try { 22 | java.lang.Enum.valueOf( 23 | enumClass, 24 | parseObject.getString(name ?: property.name)!!.uppercase() 25 | ) 26 | } catch (e: Exception) { 27 | default ?: throw e 28 | } 29 | } 30 | 31 | operator fun setValue(parseObject: ParseObject, property: KProperty<*>, t: T) { 32 | parseObject.put(name ?: property.name, t.name.lowercase()) 33 | } 34 | } 35 | 36 | /** 37 | * Returns a [Enum] property delegate for [ParseObject]s. This uses custom implementation for get 38 | * to retrieve a local version of the your enum and [ParseObject.put]. 39 | */ 40 | inline fun > enumAttribute(default: T? = null) = 41 | EnumParseDelegate(null, default, T::class.java) 42 | 43 | /** 44 | * Returns a [Enum] property delegate for [ParseObject]s. This uses custom implementation for get 45 | * to retrieve a local version of the your enum and [ParseObject.put]. 46 | */ 47 | inline fun > enumAttribute(name: String? = null, default: T? = null) = 48 | EnumParseDelegate(name, default, T::class.java) 49 | -------------------------------------------------------------------------------- /ktx/src/main/java/com/parse/ktx/delegates/FloatParseDelegate.kt: -------------------------------------------------------------------------------- 1 | @file:Suppress("unused", "NOTHING_TO_INLINE") 2 | 3 | package com.parse.ktx.delegates 4 | 5 | import com.parse.ParseObject 6 | import kotlin.reflect.KProperty 7 | 8 | /** 9 | * A [Float] property delegation for [ParseObject]. 10 | */ 11 | class FloatParseDelegate(private val name: String?) { 12 | 13 | operator fun getValue(parseObject: ParseObject, property: KProperty<*>): Float { 14 | return parseObject.getDouble(name ?: property.name).toFloat() 15 | } 16 | 17 | operator fun setValue(parseObject: ParseObject, property: KProperty<*>, value: Float) { 18 | parseObject.put(name ?: property.name, value) 19 | } 20 | } 21 | 22 | /** 23 | * Returns a [Float] property delegate for [ParseObject]s. This uses a custom implementation for get 24 | * and [ParseObject.put]. 25 | */ 26 | inline fun floatAttribute(name: String? = null) = FloatParseDelegate(name) 27 | -------------------------------------------------------------------------------- /ktx/src/main/java/com/parse/ktx/delegates/IntParseDelegate.kt: -------------------------------------------------------------------------------- 1 | @file:Suppress("unused", "NOTHING_TO_INLINE") 2 | 3 | package com.parse.ktx.delegates 4 | 5 | import com.parse.ParseObject 6 | import kotlin.reflect.KProperty 7 | 8 | /** 9 | * A [Int] property delegation for [ParseObject]. 10 | */ 11 | class IntParseDelegate(private val name: String?) { 12 | 13 | operator fun getValue(parseObject: ParseObject, property: KProperty<*>): Int { 14 | return parseObject.getInt(name ?: property.name) 15 | } 16 | 17 | operator fun setValue(parseObject: ParseObject, property: KProperty<*>, value: Int) { 18 | parseObject.put(name ?: property.name, value) 19 | } 20 | } 21 | 22 | /** 23 | * Returns a [Int] property delegate for [ParseObject]s. This uses [ParseObject.getInt] 24 | * and [ParseObject.put]. 25 | */ 26 | inline fun intAttribute(name: String? = null) = IntParseDelegate(name) 27 | -------------------------------------------------------------------------------- /ktx/src/main/java/com/parse/ktx/delegates/JsonArrayParseDelegate.kt: -------------------------------------------------------------------------------- 1 | @file:Suppress("unused", "NOTHING_TO_INLINE") 2 | 3 | package com.parse.ktx.delegates 4 | 5 | import com.parse.ParseObject 6 | import com.parse.ktx.putOrIgnore 7 | import org.json.JSONArray 8 | import kotlin.reflect.KProperty 9 | 10 | /** 11 | * A [JSONArray] property delegation for [ParseObject]. 12 | */ 13 | class JsonArrayParseDelegate(private val name: String?) { 14 | 15 | operator fun getValue(parseObject: ParseObject, property: KProperty<*>): JSONArray? { 16 | return parseObject.getJSONArray(name ?: property.name) 17 | } 18 | 19 | operator fun setValue(parseObject: ParseObject, property: KProperty<*>, value: JSONArray?) { 20 | parseObject.putOrIgnore(name ?: property.name, value) 21 | } 22 | } 23 | 24 | /** 25 | * Returns a [JSONArray] property delegate for [ParseObject]s. This uses [ParseObject.getDouble] 26 | * and [ParseObject.putOrIgnore]. 27 | */ 28 | inline fun jsonArrayAttribute(name: String? = null) = JsonArrayParseDelegate(name) 29 | -------------------------------------------------------------------------------- /ktx/src/main/java/com/parse/ktx/delegates/JsonObjectParseDelegate.kt: -------------------------------------------------------------------------------- 1 | @file:Suppress("unused", "NOTHING_TO_INLINE") 2 | 3 | package com.parse.ktx.delegates 4 | 5 | import com.parse.ParseObject 6 | import com.parse.ktx.putOrIgnore 7 | import org.json.JSONObject 8 | import kotlin.reflect.KProperty 9 | 10 | /** 11 | * A [JSONObject] property delegation for [ParseObject]. 12 | */ 13 | class JsonObjectParseDelegate(private val name: String?) { 14 | 15 | operator fun getValue(parseObject: ParseObject, property: KProperty<*>): JSONObject? { 16 | return parseObject.getJSONObject(name ?: property.name) 17 | } 18 | 19 | operator fun setValue(parseObject: ParseObject, property: KProperty<*>, value: JSONObject?) { 20 | parseObject.putOrIgnore(name ?: property.name, value) 21 | } 22 | } 23 | 24 | /** 25 | * Returns a [JSONObject] property delegate for [ParseObject]s. This uses [ParseObject.getJSONObject] 26 | * and [ParseObject.putOrIgnore]. 27 | */ 28 | fun jsonObjectAttribute(name: String? = null) = JsonObjectParseDelegate(name) 29 | -------------------------------------------------------------------------------- /ktx/src/main/java/com/parse/ktx/delegates/ListParseDelegate.kt: -------------------------------------------------------------------------------- 1 | @file:Suppress("unused", "NOTHING_TO_INLINE") 2 | 3 | package com.parse.ktx.delegates 4 | 5 | import com.parse.ParseObject 6 | import com.parse.ktx.putOrIgnore 7 | import kotlin.reflect.KProperty 8 | 9 | /** 10 | * A [List] property delegation for [ParseObject]. 11 | */ 12 | class ListParseDelegate(private val name: String?) { 13 | 14 | operator fun getValue(parseObject: ParseObject, property: KProperty<*>): MutableList? { 15 | return parseObject.getList(name ?: property.name) as? MutableList 16 | } 17 | 18 | operator fun setValue( 19 | parseObject: ParseObject, 20 | property: KProperty<*>, 21 | value: MutableList? 22 | ) { 23 | parseObject.putOrIgnore(name ?: property.name, value) 24 | } 25 | } 26 | 27 | /** 28 | * Returns a [List] property delegate for [ParseObject]s. This uses [ParseObject.getList] 29 | * and [ParseObject.putOrIgnore]. 30 | */ 31 | inline fun listAttribute(name: String? = null) = ListParseDelegate(null) 32 | -------------------------------------------------------------------------------- /ktx/src/main/java/com/parse/ktx/delegates/LongParseDelegate.kt: -------------------------------------------------------------------------------- 1 | @file:Suppress("unused", "NOTHING_TO_INLINE") 2 | 3 | package com.parse.ktx.delegates 4 | 5 | import com.parse.ParseObject 6 | import kotlin.reflect.KProperty 7 | 8 | /** 9 | * A [Long] property delegation for [ParseObject]. 10 | */ 11 | class LongParseDelegate(private val name: String?) { 12 | 13 | operator fun getValue(parseObject: ParseObject, property: KProperty<*>): Long { 14 | return parseObject.getLong(name ?: property.name) 15 | } 16 | 17 | operator fun setValue(parseObject: ParseObject, property: KProperty<*>, value: Long) { 18 | parseObject.put(name ?: property.name, value) 19 | } 20 | } 21 | 22 | /** 23 | * Returns a [Long] property delegate for [ParseObject]s. This uses [ParseObject.getLong] 24 | * and [ParseObject.put]. 25 | */ 26 | inline fun longAttribute(name: String? = null) = LongParseDelegate(name) 27 | -------------------------------------------------------------------------------- /ktx/src/main/java/com/parse/ktx/delegates/MapParseDelegate.kt: -------------------------------------------------------------------------------- 1 | @file:Suppress("unused", "NOTHING_TO_INLINE") 2 | 3 | package com.parse.ktx.delegates 4 | 5 | import com.parse.ParseObject 6 | import com.parse.ktx.putOrIgnore 7 | import kotlin.reflect.KProperty 8 | 9 | /** 10 | * A [Map] property delegation for [ParseObject]. 11 | */ 12 | class MapParseDelegate(private val name: String?) { 13 | 14 | operator fun getValue( 15 | parseObject: ParseObject, 16 | property: KProperty<*> 17 | ): MutableMap? { 18 | return parseObject.getMap(name ?: property.name) as? MutableMap 19 | } 20 | 21 | operator fun setValue( 22 | parseObject: ParseObject, 23 | property: KProperty<*>, 24 | value: MutableMap? 25 | ) { 26 | parseObject.putOrIgnore(name ?: property.name, value) 27 | } 28 | } 29 | 30 | /** 31 | * Returns a [Map] property delegate for [ParseObject]s. This uses [ParseObject.getMap] 32 | * and [ParseObject.putOrIgnore]. 33 | */ 34 | inline fun mapAttribute(name: String? = null) = MapParseDelegate(name) 35 | -------------------------------------------------------------------------------- /ktx/src/main/java/com/parse/ktx/delegates/ParseDelegate.kt: -------------------------------------------------------------------------------- 1 | @file:Suppress("unused", "NOTHING_TO_INLINE") 2 | 3 | package com.parse.ktx.delegates 4 | 5 | import com.parse.ParseObject 6 | import com.parse.ktx.getAs 7 | import com.parse.ktx.putOrIgnore 8 | import kotlin.reflect.KProperty 9 | 10 | /** 11 | * A generic property delegation for [ParseObject]. 12 | */ 13 | class ParseDelegate(private val name: String?) { 14 | 15 | @Suppress("UNCHECKED_CAST") 16 | operator fun getValue(parseObject: ParseObject, property: KProperty<*>): T { 17 | return parseObject.getAs(name ?: property.name) 18 | } 19 | 20 | operator fun setValue(parseObject: ParseObject, property: KProperty<*>, value: T) { 21 | parseObject.putOrIgnore(name ?: property.name, value) 22 | } 23 | } 24 | 25 | /** 26 | * Returns a generic property delegate for [ParseObject]s. This uses [ParseObject.getAs] 27 | * and [ParseObject.putOrIgnore]. 28 | */ 29 | inline fun attribute(name: String? = null) = ParseDelegate(name) 30 | -------------------------------------------------------------------------------- /ktx/src/main/java/com/parse/ktx/delegates/ParseRelationDelegate.kt: -------------------------------------------------------------------------------- 1 | @file:Suppress("unused", "NOTHING_TO_INLINE") 2 | 3 | package com.parse.ktx.delegates 4 | 5 | import com.parse.ParseObject 6 | import com.parse.ParseRelation 7 | import kotlin.reflect.KProperty 8 | 9 | /** 10 | * A [ParseRelation] property delegation for [ParseObject]. 11 | */ 12 | class ParseRelationDelegate(private val name: String?) { 13 | 14 | operator fun getValue(parseObject: ParseObject, property: KProperty<*>): ParseRelation { 15 | return parseObject.getRelation(name ?: property.name) 16 | } 17 | } 18 | 19 | /** 20 | * Returns a [ParseRelation] property delegate for [ParseObject]s. 21 | * This uses [ParseObject.getRelation]. 22 | */ 23 | inline fun relationAttribute(name: String? = null) = 24 | ParseRelationDelegate(name) 25 | -------------------------------------------------------------------------------- /ktx/src/main/java/com/parse/ktx/delegates/SafeParseDelegate.kt: -------------------------------------------------------------------------------- 1 | @file:Suppress("unused", "NOTHING_TO_INLINE") 2 | 3 | package com.parse.ktx.delegates 4 | 5 | import com.parse.ParseObject 6 | import com.parse.ktx.putOrRemove 7 | import org.json.JSONObject 8 | import kotlin.reflect.KProperty 9 | 10 | /** 11 | * A generic property delegation for [ParseObject], and give some checks to avoid throw some 12 | * exceptions. 13 | */ 14 | class SafeParseDelegate(private val name: String?) { 15 | 16 | @Suppress("UNCHECKED_CAST") 17 | operator fun getValue(parseObject: ParseObject, property: KProperty<*>): T? { 18 | val name = name ?: property.name 19 | val value = if (parseObject.has(name)) { 20 | parseObject.get(name) 21 | } else { 22 | null 23 | } 24 | return if (JSONObject.NULL == value) { 25 | null 26 | } else { 27 | value as? T? 28 | } 29 | } 30 | 31 | operator fun setValue(parseObject: ParseObject, property: KProperty<*>, t: T?) { 32 | parseObject.putOrRemove(property.name, t) 33 | } 34 | } 35 | 36 | /** 37 | * Returns a generic property delegate for [ParseObject]s. This uses a custom get implementation 38 | * and [ParseObject.putOrRemove]. 39 | */ 40 | inline fun safeAttribute(name: String? = null) = SafeParseDelegate(name) 41 | -------------------------------------------------------------------------------- /ktx/src/main/java/com/parse/ktx/delegates/StringParseDelegate.kt: -------------------------------------------------------------------------------- 1 | @file:Suppress("unused", "NOTHING_TO_INLINE") 2 | 3 | package com.parse.ktx.delegates 4 | 5 | import com.parse.ParseObject 6 | import com.parse.ktx.getAs 7 | import kotlin.reflect.KProperty 8 | 9 | /** 10 | * A [String] property delegation for [ParseObject]. 11 | */ 12 | class StringParseDelegate( 13 | private val name: String?, 14 | private val filter: (String) -> String 15 | ) { 16 | 17 | operator fun getValue(parseObject: ParseObject, property: KProperty<*>): S { 18 | return parseObject.getAs(name ?: property.name) 19 | } 20 | 21 | operator fun setValue(parseObject: ParseObject, property: KProperty<*>, value: S) { 22 | if (value != null) { 23 | parseObject.put(name ?: property.name, filter.invoke(value)) 24 | } 25 | } 26 | } 27 | 28 | /** 29 | * Returns a nullable [String] property delegate for [ParseObject]s. This uses [ParseObject.getAs] 30 | * and a custom implementation for set. 31 | */ 32 | inline fun nullableStringAttribute( 33 | name: String? = null, 34 | noinline filter: (String) -> String = { it } 35 | ) = StringParseDelegate(name, filter) 36 | 37 | /** 38 | * Returns a [String] property delegate for [ParseObject]s. This uses [ParseObject.getAs] 39 | * and a custom implementation for set. 40 | */ 41 | inline fun stringAttribute( 42 | name: String? = null, 43 | noinline filter: (String) -> String = { it } 44 | ) = StringParseDelegate(name, filter) 45 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "parse-sdk-android", 3 | "version": "4.3.0", 4 | "repository": { 5 | "type": "git", 6 | "url": "git+https://github.com/parse-community/Parse-SDK-Android.git" 7 | }, 8 | "devDependencies": { 9 | "semantic-release": "19.0.3", 10 | "@semantic-release/changelog": "6.0.0", 11 | "@semantic-release/commit-analyzer": "9.0.2", 12 | "@semantic-release/git": "10.0.1", 13 | "@semantic-release/release-notes-generator": "10.0.3", 14 | "gradle-semantic-release-plugin": "1.7.3" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /parse/release-proguard.pro: -------------------------------------------------------------------------------- 1 | -keep @com.parse.ParseClassName class com.parse.* 2 | -keepnames class com.parse.** { *; } 3 | -keepclassmembers public class * extends com.parse.** { 4 | public (...); 5 | } 6 | 7 | # Required for Parse 8 | -keepattributes *Annotation* 9 | -keepattributes Signature 10 | 11 | # Retracing stacktraces 12 | -keepattributes LineNumberTable,SourceFile 13 | -renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /parse/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 9 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/AbstractQueryController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import com.parse.boltsinternal.Task; 12 | 13 | /** 14 | * {@code AbstractParseQueryController} is an abstract implementation of {@link 15 | * ParseQueryController}, which implements {@link ParseQueryController#getFirstAsync}. 16 | */ 17 | abstract class AbstractQueryController implements ParseQueryController { 18 | 19 | @Override 20 | public Task getFirstAsync( 21 | ParseQuery.State state, ParseUser user, Task cancellationToken) { 22 | return findAsync(state, user, cancellationToken) 23 | .continueWith( 24 | task -> { 25 | if (task.isFaulted()) { 26 | throw task.getError(); 27 | } 28 | if (task.getResult() != null && task.getResult().size() > 0) { 29 | return task.getResult().get(0); 30 | } 31 | throw new ParseException( 32 | ParseException.OBJECT_NOT_FOUND, "no results found for query"); 33 | }); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/AuthenticationCallback.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import java.util.Map; 12 | 13 | /** Provides a general interface for delegation of third party authentication callbacks. */ 14 | public interface AuthenticationCallback { 15 | /** 16 | * Called when restoring third party authentication credentials that have been serialized, such 17 | * as session keys, etc. 18 | * 19 | *

Note: This will be executed on a background thread. 20 | * 21 | * @param authData The auth data for the provider. This value may be {@code null} when unlinking 22 | * an account. 23 | * @return {@code true} iff the {@code authData} was successfully synchronized or {@code false} 24 | * if user should no longer be associated because of bad {@code authData}. 25 | */ 26 | boolean onRestore(Map authData); 27 | } 28 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/ConfigCallback.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | /** 12 | * A {@code ConfigCallback} is used to run code after {@link ParseConfig#getInBackground()} is used 13 | * to fetch a new configuration object from the server in a background thread. 14 | * 15 | *

The easiest way to use a {@code ConfigCallback} is through an anonymous inner class. Override 16 | * the {@code done} function to specify what the callback should do after the fetch is complete. The 17 | * {@code done} function will be run in the UI thread, while the fetch happens in a background 18 | * thread. This ensures that the UI does not freeze while the fetch happens. 19 | * 20 | *

21 | * 22 | *

23 |  * ParseConfig.getInBackground(new ConfigCallback() {
24 |  *   public void done(ParseConfig config, ParseException e) {
25 |  *     if (e == null) {
26 |  *       configFetchSuccess(object);
27 |  *     } else {
28 |  *       configFetchFailed(e);
29 |  *     }
30 |  *   }
31 |  * });
32 |  * 
33 | */ 34 | public interface ConfigCallback extends ParseCallback2 { 35 | /** 36 | * Override this function with the code you want to run after the fetch is complete. 37 | * 38 | * @param config A new {@code ParseConfig} instance from the server, or {@code null} if it did 39 | * not succeed. 40 | * @param e The exception raised by the fetch, or {@code null} if it succeeded. 41 | */ 42 | @Override 43 | void done(ParseConfig config, ParseException e); 44 | } 45 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/CountCallback.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | /** 12 | * A {@code CountCallback} is used to run code after a {@link ParseQuery} is used to count objects 13 | * matching a query in a background thread. 14 | * 15 | *

The easiest way to use a {@code CountCallback} is through an anonymous inner class. Override 16 | * the {@code done} function to specify what the callback should do after the count is complete. The 17 | * {@code done} function will be run in the UI thread, while the count happens in a background 18 | * thread. This ensures that the UI does not freeze while the fetch happens. 19 | * 20 | *

For example, this sample code counts objects of class {@code "MyClass"}. It calls a different 21 | * function depending on whether the count succeeded or not. 22 | * 23 | *

24 | * 25 | *

26 |  * ParseQuery<ParseObject> query = ParseQuery.getQuery("MyClass");
27 |  * query.countInBackground(new CountCallback() {
28 |  *   public void done(int count, ParseException e) {
29 |  *     if (e == null) {
30 |  *       objectsWereCountedSuccessfully(count);
31 |  *     } else {
32 |  *       objectCountingFailed();
33 |  *     }
34 |  *   }
35 |  * });
36 |  * 
37 | */ 38 | // FYI, this does not extend ParseCallback2 since the first param is `int`, which can't be used 39 | // in a generic. 40 | public interface CountCallback { 41 | /** 42 | * Override this function with the code you want to run after the count is complete. 43 | * 44 | * @param count The number of objects matching the query, or -1 if it failed. 45 | * @param e The exception raised by the count, or null if it succeeded. 46 | */ 47 | void done(int count, ParseException e); 48 | } 49 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/DeleteCallback.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | /** 12 | * A {@code DeleteCallback} is used to run code after saving a {@link ParseObject} in a background 13 | * thread. 14 | * 15 | *

The easiest way to use a {@code DeleteCallback} is through an anonymous inner class. Override 16 | * the {@code done} function to specify what the callback should do after the delete is complete. 17 | * The {@code done} function will be run in the UI thread, while the delete happens in a background 18 | * thread. This ensures that the UI does not freeze while the delete happens. 19 | * 20 | *

For example, this sample code deletes the object {@code myObject} and calls a different 21 | * function depending on whether the save succeeded or not. 22 | * 23 | *

24 | * 25 | *

26 |  * myObject.deleteInBackground(new DeleteCallback() {
27 |  *   public void done(ParseException e) {
28 |  *     if (e == null) {
29 |  *       myObjectWasDeletedSuccessfully();
30 |  *     } else {
31 |  *       myObjectDeleteDidNotSucceed();
32 |  *     }
33 |  *   }
34 |  * });
35 |  * 
36 | */ 37 | public interface DeleteCallback extends ParseCallback1 { 38 | /** 39 | * Override this function with the code you want to run after the delete is complete. 40 | * 41 | * @param e The exception raised by the delete, or {@code null} if it succeeded. 42 | */ 43 | @Override 44 | void done(ParseException e); 45 | } 46 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/FindCallback.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import java.util.List; 12 | 13 | /** 14 | * A {@code FindCallback} is used to run code after a {@link ParseQuery} is used to fetch a list of 15 | * {@link ParseObject}s in a background thread. 16 | * 17 | *

The easiest way to use a {@code FindCallback} is through an anonymous inner class. Override 18 | * the {@code done} function to specify what the callback should do after the fetch is complete. The 19 | * {@code done} function will be run in the UI thread, while the fetch happens in a background 20 | * thread. This ensures that the UI does not freeze while the fetch happens. 21 | * 22 | *

For example, this sample code fetches all objects of class {@code "MyClass"}. It calls a 23 | * different function depending on whether the fetch succeeded or not. 24 | * 25 | *

26 | * 27 | *

28 |  * ParseQuery<ParseObject> query = ParseQuery.getQuery("MyClass");
29 |  * query.findInBackground(new FindCallback<ParseObject>() {
30 |  *   public void done(List<ParseObject> objects, ParseException e) {
31 |  *     if (e == null) {
32 |  *       objectsWereRetrievedSuccessfully(objects);
33 |  *     } else {
34 |  *       objectRetrievalFailed();
35 |  *     }
36 |  *   }
37 |  * });
38 |  * 
39 | */ 40 | public interface FindCallback 41 | extends ParseCallback2, ParseException> { 42 | /** 43 | * Override this function with the code you want to run after the fetch is complete. 44 | * 45 | * @param objects The objects that were retrieved, or null if it did not succeed. 46 | * @param e The exception raised by the save, or null if it succeeded. 47 | */ 48 | @Override 49 | void done(List objects, ParseException e); 50 | } 51 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/FunctionCallback.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | /** 12 | * A {@code FunctionCallback} is used to run code after {@link ParseCloud#callFunction} is used to 13 | * run a Cloud Function in a background thread. 14 | * 15 | *

The easiest way to use a {@code FunctionCallback} is through an anonymous inner class. 16 | * Override the {@code done} function to specify what the callback should do after the cloud 17 | * function is complete. The {@code done} function will be run in the UI thread, while the fetch 18 | * happens in a background thread. This ensures that the UI does not freeze while the fetch happens. 19 | * 20 | *

For example, this sample code calls a cloud function {@code "MyFunction"} with {@code params} 21 | * and calls a different function depending on whether the function succeeded. 22 | * 23 | *

24 | * 25 | *

26 |  * ParseCloud.callFunctionInBackground("MyFunction"new, params, FunctionCallback() {
27 |  *   public void done(ParseObject object, ParseException e) {
28 |  *     if (e == null) {
29 |  *       cloudFunctionSucceeded(object);
30 |  *     } else {
31 |  *       cloudFunctionFailed();
32 |  *     }
33 |  *   }
34 |  * });
35 |  * 
36 | * 37 | * @param The type of object returned by the Cloud Function. 38 | */ 39 | public interface FunctionCallback extends ParseCallback2 { 40 | /** 41 | * Override this function with the code you want to run after the cloud function is complete. 42 | * 43 | * @param object The object that was returned by the cloud function. 44 | * @param e The exception raised by the cloud call, or {@code null} if it succeeded. 45 | */ 46 | @Override 47 | void done(T object, ParseException e); 48 | } 49 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/GetCallback.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | /** 12 | * A {@code GetCallback} is used to run code after a {@link ParseQuery} is used to fetch a {@link 13 | * ParseObject} in a background thread. 14 | * 15 | *

The easiest way to use a {@code GetCallback} is through an anonymous inner class. Override the 16 | * {@code done} function to specify what the callback should do after the fetch is complete. The 17 | * {@code done} function will be run in the UI thread, while the fetch happens in a background 18 | * thread. This ensures that the UI does not freeze while the fetch happens. 19 | * 20 | *

For example, this sample code fetches an object of class {@code "MyClass"} and id {@code 21 | * myId}. It calls a different function depending on whether the fetch succeeded or not. 22 | * 23 | *

24 | * 25 | *

26 |  * ParseQuery<ParseObject> query = ParseQuery.getQuery("MyClass");
27 |  * query.getInBackground(myId, new GetCallback<ParseObject>() {
28 |  *   public void done(ParseObject object, ParseException e) {
29 |  *     if (e == null) {
30 |  *       objectWasRetrievedSuccessfully(object);
31 |  *     } else {
32 |  *       objectRetrievalFailed();
33 |  *     }
34 |  *   }
35 |  * });
36 |  * 
37 | */ 38 | public interface GetCallback extends ParseCallback2 { 39 | /** 40 | * Override this function with the code you want to run after the fetch is complete. 41 | * 42 | * @param object The object that was retrieved, or {@code null} if it did not succeed. 43 | * @param e The exception raised by the fetch, or {@code null} if it succeeded. 44 | */ 45 | @Override 46 | void done(T object, ParseException e); 47 | } 48 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/GetDataCallback.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | /** 12 | * A {@code GetDataCallback} is used to run code after a {@link ParseFile} fetches its data on a 13 | * background thread. 14 | * 15 | *

The easiest way to use a {@code GetDataCallback} is through an anonymous inner class. Override 16 | * the {@code done} function to specify what the callback should do after the fetch is complete. The 17 | * {@code done} function will be run in the UI thread, while the fetch happens in a background 18 | * thread. This ensures that the UI does not freeze while the fetch happens. 19 | * 20 | *

21 | * 22 | *

23 |  * file.getDataInBackground(new GetDataCallback() {
24 |  *   public void done(byte[] data, ParseException e) {
25 |  *     // ...
26 |  *   }
27 |  * });
28 |  * 
29 | */ 30 | public interface GetDataCallback extends ParseCallback2 { 31 | /** 32 | * Override this function with the code you want to run after the fetch is complete. 33 | * 34 | * @param data The data that was retrieved, or {@code null} if it did not succeed. 35 | * @param e The exception raised by the fetch, or {@code null} if it succeeded. 36 | */ 37 | @Override 38 | void done(byte[] data, ParseException e); 39 | } 40 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/GetDataStreamCallback.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import java.io.InputStream; 12 | 13 | /** 14 | * A {@code GetDataStreamCallback} is used to run code after a {@link ParseFile} fetches its data on 15 | * a background thread. 16 | * 17 | *

The easiest way to use a {@code GetDataStreamCallback} is through an anonymous inner class. 18 | * Override the {@code done} function to specify what the callback should do after the fetch is 19 | * complete. The {@code done} function will be run in the UI thread, while the fetch happens in a 20 | * background thread. This ensures that the UI does not freeze while the fetch happens. 21 | * 22 | *

23 | * 24 | *

25 |  * file.getDataStreamInBackground(new GetDataStreamCallback() {
26 |  *   public void done(InputSteam input, ParseException e) {
27 |  *     // ...
28 |  *   }
29 |  * });
30 |  * 
31 | */ 32 | public interface GetDataStreamCallback extends ParseCallback2 { 33 | /** 34 | * Override this function with the code you want to run after the fetch is complete. 35 | * 36 | * @param input The data that was retrieved, or {@code null} if it did not succeed. 37 | * @param e The exception raised by the fetch, or {@code null} if it succeeded. 38 | */ 39 | @Override 40 | void done(InputStream input, ParseException e); 41 | } 42 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/GetFileCallback.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import java.io.File; 12 | 13 | /** 14 | * A {@code GetFileCallback} is used to run code after a {@link ParseFile} fetches its data on a 15 | * background thread. 16 | * 17 | *

The easiest way to use a {@code GetFileCallback} is through an anonymous inner class. Override 18 | * the {@code done} function to specify what the callback should do after the fetch is complete. The 19 | * {@code done} function will be run in the UI thread, while the fetch happens in a background 20 | * thread. This ensures that the UI does not freeze while the fetch happens. 21 | * 22 | *

23 | * 24 | *

25 |  * file.getFileInBackground(new GetFileCallback() {
26 |  *   public void done(File file, ParseException e) {
27 |  *     // ...
28 |  *   }
29 |  * });
30 |  * 
31 | */ 32 | public interface GetFileCallback extends ParseCallback2 { 33 | /** 34 | * Override this function with the code you want to run after the fetch is complete. 35 | * 36 | * @param file The data that was retrieved, or {@code null} if it did not succeed. 37 | * @param e The exception raised by the fetch, or {@code null} if it succeeded. 38 | */ 39 | @Override 40 | void done(File file, ParseException e); 41 | } 42 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/KnownParseObjectDecoder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import java.util.Map; 12 | 13 | /** 14 | * A subclass of ParseDecoder which can keep ParseObject that has been 15 | * fetched instead of creating a new instance. 16 | */ 17 | class KnownParseObjectDecoder extends ParseDecoder { 18 | private final Map fetchedObjects; 19 | 20 | public KnownParseObjectDecoder(Map fetchedObjects) { 21 | super(); 22 | this.fetchedObjects = fetchedObjects; 23 | } 24 | 25 | /** 26 | * If the object has been fetched, the fetched object will be returned. Otherwise a new created 27 | * object will be returned. 28 | */ 29 | @Override 30 | protected ParseObject decodePointer(String className, String objectId) { 31 | if (fetchedObjects != null && fetchedObjects.containsKey(objectId)) { 32 | return fetchedObjects.get(objectId); 33 | } 34 | return super.decodePointer(className, objectId); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/LocationCallback.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | /** 12 | * A {@code LocationCallback} is used to run code after a Location has been fetched by {@link 13 | * com.parse.ParseGeoPoint#getCurrentLocationInBackground(long, android.location.Criteria)}. 14 | * 15 | *

The easiest way to use a {@code LocationCallback} is through an anonymous inner class. 16 | * Override the {@code done} function to specify what the callback should do after the location has 17 | * been fetched. The {@code done} function will be run in the UI thread, while the location check 18 | * happens in a background thread. This ensures that the UI does not freeze while the fetch happens. 19 | * 20 | *

For example, this sample code defines a timeout for fetching the user's current location, and 21 | * provides a callback. Within the callback, the success and failure cases are handled differently. 22 | * 23 | *

24 | * 25 | *

26 |  * ParseGeoPoint.getCurrentLocationAsync(1000, new LocationCallback() {
27 |  *   public void done(ParseGeoPoint geoPoint, ParseException e) {
28 |  *     if (e == null) {
29 |  *       // do something with your new ParseGeoPoint
30 |  *     } else {
31 |  *       // handle your error
32 |  *       e.printStackTrace();
33 |  *     }
34 |  *   }
35 |  * });
36 |  * 
37 | */ 38 | public interface LocationCallback extends ParseCallback2 { 39 | /** 40 | * Override this function with the code you want to run after the location fetch is complete. 41 | * 42 | * @param geoPoint The {@link ParseGeoPoint} returned by the location fetch. 43 | * @param e The exception raised by the location fetch, or {@code null} if it succeeded. 44 | */ 45 | @Override 46 | void done(ParseGeoPoint geoPoint, ParseException e); 47 | } 48 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/LockSet.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import java.util.Collection; 12 | import java.util.Set; 13 | import java.util.TreeSet; 14 | import java.util.WeakHashMap; 15 | import java.util.concurrent.locks.Lock; 16 | 17 | class LockSet { 18 | private static final WeakHashMap stableIds = new WeakHashMap<>(); 19 | private static long nextStableId = 0L; 20 | 21 | private final Set locks; 22 | 23 | public LockSet(Collection locks) { 24 | this.locks = 25 | new TreeSet<>( 26 | (lhs, rhs) -> { 27 | Long lhsId = getStableId(lhs); 28 | Long rhsId = getStableId(rhs); 29 | return lhsId.compareTo(rhsId); 30 | }); 31 | this.locks.addAll(locks); 32 | } 33 | 34 | private static Long getStableId(Lock lock) { 35 | synchronized (stableIds) { 36 | if (stableIds.containsKey(lock)) { 37 | return stableIds.get(lock); 38 | } 39 | long id = nextStableId++; 40 | stableIds.put(lock, id); 41 | return id; 42 | } 43 | } 44 | 45 | public void lock() { 46 | for (Lock l : locks) { 47 | l.lock(); 48 | } 49 | } 50 | 51 | public void unlock() { 52 | for (Lock l : locks) { 53 | l.unlock(); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/LogInCallback.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | /** 12 | * A {@code LogInCallback} is used to run code after logging in a user. 13 | * 14 | *

The easiest way to use a {@code LogInCallback} is through an anonymous inner class. Override 15 | * the {@code done} function to specify what the callback should do after the login is complete. The 16 | * {@code done} function will be run in the UI thread, while the login happens in a background 17 | * thread. This ensures that the UI does not freeze while the save happens. 18 | * 19 | *

For example, this sample code logs in a user and calls a different function depending on 20 | * whether the login succeeded or not. 21 | * 22 | *

23 | * 24 | *

25 |  * ParseUser.logInInBackground("username", "password", new LogInCallback() {
26 |  *   public void done(ParseUser user, ParseException e) {
27 |  *     if (e == null && user != null) {
28 |  *       loginSuccessful();
29 |  *     } else if (user == null) {
30 |  *       usernameOrPasswordIsInvalid();
31 |  *     } else {
32 |  *       somethingWentWrong();
33 |  *     }
34 |  *   }
35 |  * });
36 |  * 
37 | */ 38 | public interface LogInCallback extends ParseCallback2 { 39 | /** 40 | * Override this function with the code you want to run after the save is complete. 41 | * 42 | * @param user The user that logged in, if the username and password is valid. 43 | * @param e The exception raised by the login, or {@code null} if it succeeded. 44 | */ 45 | @Override 46 | void done(ParseUser user, ParseException e); 47 | } 48 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/LogOutCallback.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | /** 12 | * A {@code LogOutCallback} is used to run code after logging out a user. 13 | * 14 | *

The easiest way to use a {@code LogOutCallback} is through an anonymous inner class. Override 15 | * the {@code done} function to specify what the callback should do after the login is complete. The 16 | * {@code done} function will be run in the UI thread, while the login happens in a background 17 | * thread. This ensures that the UI does not freeze while the save happens. 18 | * 19 | *

For example, this sample code logs out a user and calls a different function depending on 20 | * whether the log out succeeded or not. 21 | * 22 | *

23 | * 24 | *

25 |  * ParseUser.logOutInBackground(new LogOutCallback() {
26 |  *   public void done(ParseException e) {
27 |  *     if (e == null) {
28 |  *       logOutSuccessful();
29 |  *     } else {
30 |  *       somethingWentWrong();
31 |  *     }
32 |  *   }
33 |  * });
34 |  * 
35 | */ 36 | public interface LogOutCallback extends ParseCallback1 { 37 | /** 38 | * Override this function with the code you want to run after the save is complete. 39 | * 40 | * @param e The exception raised by the log out, or {@code null} if it succeeded. 41 | */ 42 | @Override 43 | void done(ParseException e); 44 | } 45 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/NoObjectsEncoder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import org.json.JSONObject; 12 | 13 | /** Throws an exception if someone attempts to encode a {@code ParseObject}. */ 14 | class NoObjectsEncoder extends ParseEncoder { 15 | 16 | // This class isn't really a Singleton, but since it has no state, it's more efficient to get 17 | // the 18 | // default instance. 19 | private static final NoObjectsEncoder INSTANCE = new NoObjectsEncoder(); 20 | 21 | public static NoObjectsEncoder get() { 22 | return INSTANCE; 23 | } 24 | 25 | @Override 26 | public JSONObject encodeRelatedObject(ParseObject object) { 27 | throw new IllegalArgumentException("ParseObjects not allowed here"); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/OfflineQueryController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import com.parse.boltsinternal.Task; 12 | import java.util.List; 13 | 14 | class OfflineQueryController extends AbstractQueryController { 15 | 16 | private final OfflineStore offlineStore; 17 | private final ParseQueryController networkController; 18 | 19 | public OfflineQueryController(OfflineStore store, ParseQueryController network) { 20 | offlineStore = store; 21 | networkController = network; 22 | } 23 | 24 | @Override 25 | public Task> findAsync( 26 | ParseQuery.State state, ParseUser user, Task cancellationToken) { 27 | if (state.isFromLocalDatastore()) { 28 | return offlineStore.findFromPinAsync(state.pinName(), state, user); 29 | } else { 30 | return networkController.findAsync(state, user, cancellationToken); 31 | } 32 | } 33 | 34 | @Override 35 | public Task countAsync( 36 | ParseQuery.State state, ParseUser user, Task cancellationToken) { 37 | if (state.isFromLocalDatastore()) { 38 | return offlineStore.countFromPinAsync(state.pinName(), state, user); 39 | } else { 40 | return networkController.countAsync(state, user, cancellationToken); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/ParseAnalyticsController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import com.parse.boltsinternal.Task; 12 | import java.util.Map; 13 | import org.json.JSONObject; 14 | 15 | class ParseAnalyticsController { 16 | 17 | /* package for test */ final ParseEventuallyQueue eventuallyQueue; 18 | 19 | public ParseAnalyticsController(ParseEventuallyQueue eventuallyQueue) { 20 | this.eventuallyQueue = eventuallyQueue; 21 | } 22 | 23 | public Task trackEventInBackground( 24 | final String name, Map dimensions, String sessionToken) { 25 | ParseRESTCommand command = 26 | ParseRESTAnalyticsCommand.trackEventCommand(name, dimensions, sessionToken); 27 | 28 | Task eventuallyTask = eventuallyQueue.enqueueEventuallyAsync(command, null); 29 | return eventuallyTask.makeVoid(); 30 | } 31 | 32 | public Task trackAppOpenedInBackground(String pushHash, String sessionToken) { 33 | ParseRESTCommand command = 34 | ParseRESTAnalyticsCommand.trackAppOpenedCommand(pushHash, sessionToken); 35 | 36 | Task eventuallyTask = eventuallyQueue.enqueueEventuallyAsync(command, null); 37 | return eventuallyTask.makeVoid(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/ParseByteArrayHttpBody.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import com.parse.http.ParseHttpBody; 12 | import java.io.ByteArrayInputStream; 13 | import java.io.IOException; 14 | import java.io.InputStream; 15 | import java.io.OutputStream; 16 | import java.io.UnsupportedEncodingException; 17 | 18 | class ParseByteArrayHttpBody extends ParseHttpBody { 19 | /* package */ final byte[] content; 20 | /* package */ final InputStream contentInputStream; 21 | 22 | public ParseByteArrayHttpBody(String content, String contentType) 23 | throws UnsupportedEncodingException { 24 | this(content.getBytes("UTF-8"), contentType); 25 | } 26 | 27 | public ParseByteArrayHttpBody(byte[] content, String contentType) { 28 | super(contentType, content.length); 29 | this.content = content; 30 | this.contentInputStream = new ByteArrayInputStream(content); 31 | } 32 | 33 | @Override 34 | public InputStream getContent() { 35 | return contentInputStream; 36 | } 37 | 38 | @Override 39 | public void writeTo(OutputStream out) throws IOException { 40 | if (out == null) { 41 | throw new IllegalArgumentException("Output stream may not be null"); 42 | } 43 | 44 | out.write(content); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/ParseCallback1.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | /** 12 | * A {@code ParseCallback} is used to do something after a background task completes. End users will 13 | * use a specific subclass of {@code ParseCallback}. 14 | */ 15 | interface ParseCallback1 { 16 | /** 17 | * {@code done(t)} must be overridden when you are doing a background operation. It is called 18 | * when the background operation completes. 19 | * 20 | *

If the operation is successful, {@code t} will be {@code null}. 21 | * 22 | *

If the operation was unsuccessful, {@code t} will contain information about the operation 23 | * failure. 24 | * 25 | * @param t Generally an {@link Throwable} that was thrown by the operation, if there was any. 26 | */ 27 | void done(T t); 28 | } 29 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/ParseCallback2.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | /** 12 | * A {@code ParseCallback} is used to do something after a background task completes. End users will 13 | * use a specific subclass of {@code ParseCallback}. 14 | */ 15 | interface ParseCallback2 { 16 | /** 17 | * {@code done(t1, t2)} must be overridden when you are doing a background operation. It is 18 | * called when the background operation completes. 19 | * 20 | *

If the operation is successful, {@code t1} will contain the results and {@code t2} will be 21 | * {@code null}. 22 | * 23 | *

If the operation was unsuccessful, {@code t1} will be {@code null} and {@code t2} will 24 | * contain information about the operation failure. 25 | * 26 | * @param t1 Generally the results of the operation. 27 | * @param t2 Generally an {@link Throwable} that was thrown by the operation, if there was any. 28 | */ 29 | void done(T1 t1, T2 t2); 30 | } 31 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/ParseClassName.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import java.lang.annotation.Documented; 12 | import java.lang.annotation.ElementType; 13 | import java.lang.annotation.Inherited; 14 | import java.lang.annotation.Retention; 15 | import java.lang.annotation.RetentionPolicy; 16 | import java.lang.annotation.Target; 17 | 18 | /** Associates a class name for a subclass of ParseObject. */ 19 | @Target({ElementType.TYPE}) 20 | @Retention(RetentionPolicy.RUNTIME) 21 | @Inherited 22 | @Documented 23 | public @interface ParseClassName { 24 | /** @return The Parse class name associated with the ParseObject subclass. */ 25 | String value(); 26 | } 27 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/ParseCloudCodeController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import com.parse.boltsinternal.Task; 12 | import java.util.Map; 13 | import org.json.JSONObject; 14 | 15 | class ParseCloudCodeController { 16 | 17 | /* package for test */ final ParseHttpClient restClient; 18 | 19 | public ParseCloudCodeController(ParseHttpClient restClient) { 20 | this.restClient = restClient; 21 | } 22 | 23 | public Task callFunctionInBackground( 24 | final String name, final Map params, String sessionToken) { 25 | ParseRESTCommand command = 26 | ParseRESTCloudCommand.callFunctionCommand(name, params, sessionToken); 27 | return command.executeAsync(restClient) 28 | .onSuccess( 29 | task -> { 30 | @SuppressWarnings("unchecked") 31 | T result = (T) convertCloudResponse(task.getResult()); 32 | return result; 33 | }); 34 | } 35 | 36 | /* 37 | * Decodes any Parse data types in the result of the cloud function call. 38 | */ 39 | /* package for test */ Object convertCloudResponse(Object result) { 40 | if (result instanceof JSONObject) { 41 | JSONObject jsonResult = (JSONObject) result; 42 | // We want to make sure we pass back a null result as null, and not a JSONObject 43 | if (jsonResult.isNull("result")) { 44 | return null; 45 | } 46 | result = jsonResult.opt("result"); 47 | } 48 | 49 | ParseDecoder decoder = ParseDecoder.get(); 50 | Object finalResult = decoder.decode(result); 51 | if (finalResult != null) { 52 | return finalResult; 53 | } 54 | 55 | return result; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/ParseConfigController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import com.parse.boltsinternal.Task; 12 | import org.json.JSONObject; 13 | 14 | class ParseConfigController { 15 | 16 | private final ParseHttpClient restClient; 17 | private final ParseCurrentConfigController currentConfigController; 18 | 19 | public ParseConfigController( 20 | ParseHttpClient restClient, ParseCurrentConfigController currentConfigController) { 21 | this.restClient = restClient; 22 | this.currentConfigController = currentConfigController; 23 | } 24 | 25 | /* package */ ParseCurrentConfigController getCurrentConfigController() { 26 | return currentConfigController; 27 | } 28 | 29 | public Task getAsync(String sessionToken) { 30 | final ParseRESTCommand command = ParseRESTConfigCommand.fetchConfigCommand(sessionToken); 31 | return command.executeAsync(restClient) 32 | .onSuccessTask( 33 | task -> { 34 | JSONObject result = task.getResult(); 35 | 36 | final ParseConfig config = 37 | ParseConfig.decode(result, ParseDecoder.get()); 38 | return currentConfigController 39 | .setCurrentConfigAsync(config) 40 | .continueWith(task1 -> config); 41 | }); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/ParseCountingByteArrayHttpBody.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import static java.lang.Math.min; 12 | 13 | import java.io.IOException; 14 | import java.io.OutputStream; 15 | 16 | class ParseCountingByteArrayHttpBody extends ParseByteArrayHttpBody { 17 | private static final int DEFAULT_CHUNK_SIZE = 4096; 18 | private final ProgressCallback progressCallback; 19 | 20 | public ParseCountingByteArrayHttpBody( 21 | byte[] content, String contentType, final ProgressCallback progressCallback) { 22 | super(content, contentType); 23 | this.progressCallback = progressCallback; 24 | } 25 | 26 | @Override 27 | public void writeTo(OutputStream out) throws IOException { 28 | if (out == null) { 29 | throw new IllegalArgumentException("Output stream may not be null"); 30 | } 31 | 32 | int position = 0; 33 | int totalLength = content.length; 34 | while (position < totalLength) { 35 | int length = min(totalLength - position, DEFAULT_CHUNK_SIZE); 36 | 37 | out.write(content, position, length); 38 | out.flush(); 39 | 40 | if (progressCallback != null) { 41 | position += length; 42 | 43 | int progress = 100 * position / totalLength; 44 | progressCallback.done(progress); 45 | } 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/ParseCountingFileHttpBody.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import java.io.File; 12 | import java.io.FileInputStream; 13 | import java.io.IOException; 14 | import java.io.OutputStream; 15 | 16 | class ParseCountingFileHttpBody extends ParseFileHttpBody { 17 | 18 | private static final int DEFAULT_CHUNK_SIZE = 4096; 19 | private static final int EOF = -1; 20 | 21 | private final ProgressCallback progressCallback; 22 | 23 | public ParseCountingFileHttpBody(File file, ProgressCallback progressCallback) { 24 | this(file, null, progressCallback); 25 | } 26 | 27 | public ParseCountingFileHttpBody( 28 | File file, String contentType, ProgressCallback progressCallback) { 29 | super(file, contentType); 30 | this.progressCallback = progressCallback; 31 | } 32 | 33 | @Override 34 | public void writeTo(OutputStream output) throws IOException { 35 | if (output == null) { 36 | throw new IllegalArgumentException("Output stream may not be null"); 37 | } 38 | 39 | final FileInputStream fileInput = new FileInputStream(file); 40 | try { 41 | byte[] buffer = new byte[DEFAULT_CHUNK_SIZE]; 42 | int n; 43 | long totalLength = file.length(); 44 | long position = 0; 45 | while (EOF != (n = fileInput.read(buffer))) { 46 | output.write(buffer, 0, n); 47 | position += n; 48 | 49 | if (progressCallback != null) { 50 | int progress = (int) (100 * position / totalLength); 51 | progressCallback.done(progress); 52 | } 53 | } 54 | } finally { 55 | ParseIOUtils.closeQuietly(fileInput); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/ParseCountingUriHttpBody.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import android.net.Uri; 12 | import java.io.IOException; 13 | import java.io.InputStream; 14 | import java.io.OutputStream; 15 | 16 | class ParseCountingUriHttpBody extends ParseUriHttpBody { 17 | 18 | private static final int DEFAULT_CHUNK_SIZE = 4096; 19 | private static final int EOF = -1; 20 | 21 | private final ProgressCallback progressCallback; 22 | 23 | public ParseCountingUriHttpBody(Uri uri, ProgressCallback progressCallback) { 24 | this(uri, null, progressCallback); 25 | } 26 | 27 | public ParseCountingUriHttpBody( 28 | Uri uri, String contentType, ProgressCallback progressCallback) { 29 | super(uri, contentType); 30 | this.progressCallback = progressCallback; 31 | } 32 | 33 | @Override 34 | public void writeTo(OutputStream output) throws IOException { 35 | if (output == null) { 36 | throw new IllegalArgumentException("Output stream may not be null"); 37 | } 38 | 39 | final InputStream fileInput = 40 | Parse.getApplicationContext().getContentResolver().openInputStream(uri); 41 | try { 42 | byte[] buffer = new byte[DEFAULT_CHUNK_SIZE]; 43 | int n; 44 | long totalLength = getContentLength(); 45 | long position = 0; 46 | while (EOF != (n = fileInput.read(buffer))) { 47 | output.write(buffer, 0, n); 48 | position += n; 49 | 50 | if (progressCallback != null) { 51 | int progress = (int) (100 * position / totalLength); 52 | progressCallback.done(progress); 53 | } 54 | } 55 | } finally { 56 | ParseIOUtils.closeQuietly(fileInput); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/ParseCurrentInstallationController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | interface ParseCurrentInstallationController 12 | extends ParseObjectCurrentController {} 13 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/ParseCurrentUserController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import com.parse.boltsinternal.Task; 12 | 13 | interface ParseCurrentUserController extends ParseObjectCurrentController { 14 | 15 | /** 16 | * Gets the persisted current ParseUser. 17 | * 18 | * @param shouldAutoCreateUser should auto create user 19 | * @return task 20 | */ 21 | Task getAsync(boolean shouldAutoCreateUser); 22 | 23 | /** 24 | * Sets the persisted current ParseUser only if it's current or we're not synced with disk. 25 | * 26 | * @param user user 27 | * @return task 28 | */ 29 | Task setIfNeededAsync(ParseUser user); 30 | 31 | /** 32 | * Gets the session token of the persisted current ParseUser. 33 | * 34 | * @return task 35 | */ 36 | Task getCurrentSessionTokenAsync(); 37 | 38 | /** 39 | * Logs out the current ParseUser. 40 | * 41 | * @return task 42 | */ 43 | Task logOutAsync(); 44 | } 45 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/ParseDateFormat.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import java.text.DateFormat; 12 | import java.text.SimpleDateFormat; 13 | import java.util.Date; 14 | import java.util.Locale; 15 | import java.util.SimpleTimeZone; 16 | 17 | /** This is the currently used date format. It is precise to the millisecond. */ 18 | /* package */ class ParseDateFormat { 19 | private static final String TAG = "ParseDateFormat"; 20 | 21 | private static final ParseDateFormat INSTANCE = new ParseDateFormat(); 22 | // SimpleDateFormat isn't inherently thread-safe 23 | private final Object lock = new Object(); 24 | private final DateFormat dateFormat; 25 | 26 | private ParseDateFormat() { 27 | DateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US); 28 | format.setTimeZone(new SimpleTimeZone(0, "GMT")); 29 | dateFormat = format; 30 | } 31 | 32 | public static ParseDateFormat getInstance() { 33 | return INSTANCE; 34 | } 35 | 36 | /* package */ Date parse(String dateString) { 37 | synchronized (lock) { 38 | try { 39 | return dateFormat.parse(dateString); 40 | } catch (java.text.ParseException e) { 41 | // Should never happen 42 | PLog.e(TAG, "could not parse date: " + dateString, e); 43 | return null; 44 | } 45 | } 46 | } 47 | 48 | /* package */ String format(Date date) { 49 | synchronized (lock) { 50 | return dateFormat.format(date); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/ParseDeleteOperation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import android.os.Parcel; 12 | import org.json.JSONException; 13 | import org.json.JSONObject; 14 | 15 | /** An operation where a field is deleted from the object. */ 16 | class ParseDeleteOperation implements ParseFieldOperation { 17 | /* package */ static final String OP_NAME = "Delete"; 18 | 19 | private static final ParseDeleteOperation defaultInstance = new ParseDeleteOperation(); 20 | 21 | private ParseDeleteOperation() {} 22 | 23 | public static ParseDeleteOperation getInstance() { 24 | return defaultInstance; 25 | } 26 | 27 | @Override 28 | public JSONObject encode(ParseEncoder objectEncoder) throws JSONException { 29 | JSONObject output = new JSONObject(); 30 | output.put("__op", OP_NAME); 31 | return output; 32 | } 33 | 34 | @Override 35 | public void encode(Parcel dest, ParseParcelEncoder parcelableEncoder) { 36 | dest.writeString(OP_NAME); 37 | } 38 | 39 | @Override 40 | public ParseFieldOperation mergeWithPrevious(ParseFieldOperation previous) { 41 | return this; 42 | } 43 | 44 | @Override 45 | public Object apply(Object oldValue, String key) { 46 | return null; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/ParseDigestUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import java.security.MessageDigest; 12 | import java.security.NoSuchAlgorithmException; 13 | 14 | /** Static utility helpers to compute {@link MessageDigest}s. */ 15 | /* package */ class ParseDigestUtils { 16 | 17 | private static final char[] hexArray = "0123456789abcdef".toCharArray(); 18 | 19 | private ParseDigestUtils() { 20 | // no instances allowed 21 | } 22 | 23 | public static String md5(String string) { 24 | MessageDigest digester; 25 | try { 26 | digester = MessageDigest.getInstance("MD5"); 27 | } catch (NoSuchAlgorithmException e) { 28 | throw new RuntimeException(e); 29 | } 30 | 31 | digester.update(string.getBytes()); 32 | byte[] digest = digester.digest(); 33 | return toHex(digest); 34 | } 35 | 36 | private static String toHex(byte[] bytes) { 37 | // The returned string will be double the length of the passed array, as it takes two 38 | // characters to represent any given byte. 39 | char[] hexChars = new char[bytes.length * 2]; 40 | for (int j = 0; j < bytes.length; j++) { 41 | int v = bytes[j] & 0xFF; 42 | hexChars[j * 2] = hexArray[v >>> 4]; 43 | hexChars[j * 2 + 1] = hexArray[v & 0x0F]; 44 | } 45 | return new String(hexChars); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/ParseExecutors.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import com.parse.boltsinternal.Task; 12 | import java.util.concurrent.Executor; 13 | import java.util.concurrent.ScheduledExecutorService; 14 | 15 | class ParseExecutors { 16 | 17 | private static final Object SCHEDULED_EXECUTOR_LOCK = new Object(); 18 | private static ScheduledExecutorService scheduledExecutor; 19 | 20 | /** Long running operations should NOT be put onto SCHEDULED_EXECUTOR. */ 21 | /* package */ 22 | static ScheduledExecutorService scheduled() { 23 | synchronized (SCHEDULED_EXECUTOR_LOCK) { 24 | if (scheduledExecutor == null) { 25 | scheduledExecutor = java.util.concurrent.Executors.newScheduledThreadPool(1); 26 | } 27 | } 28 | return scheduledExecutor; 29 | } 30 | 31 | /* package */ 32 | static Executor main() { 33 | return Task.UI_THREAD_EXECUTOR; 34 | } 35 | 36 | /* package */ 37 | static Executor io() { 38 | return Task.BACKGROUND_EXECUTOR; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/ParseFileHttpBody.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import com.parse.http.ParseHttpBody; 12 | import java.io.File; 13 | import java.io.FileInputStream; 14 | import java.io.IOException; 15 | import java.io.InputStream; 16 | import java.io.OutputStream; 17 | 18 | class ParseFileHttpBody extends ParseHttpBody { 19 | 20 | /* package */ final File file; 21 | 22 | public ParseFileHttpBody(File file) { 23 | this(file, null); 24 | } 25 | 26 | public ParseFileHttpBody(File file, String contentType) { 27 | super(contentType, file.length()); 28 | this.file = file; 29 | } 30 | 31 | @Override 32 | public InputStream getContent() throws IOException { 33 | return new FileInputStream(file); 34 | } 35 | 36 | @Override 37 | public void writeTo(OutputStream out) throws IOException { 38 | if (out == null) { 39 | throw new IllegalArgumentException("Output stream can not be null"); 40 | } 41 | 42 | final FileInputStream fileInput = new FileInputStream(file); 43 | try { 44 | ParseIOUtils.copy(fileInput, out); 45 | } finally { 46 | ParseIOUtils.closeQuietly(fileInput); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/ParseImpreciseDateFormat.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import java.text.DateFormat; 12 | import java.text.SimpleDateFormat; 13 | import java.util.Date; 14 | import java.util.Locale; 15 | import java.util.SimpleTimeZone; 16 | 17 | /** Used to parse legacy created_at and updated_at from disk. It is only precise to the second. */ 18 | class ParseImpreciseDateFormat { 19 | private static final String TAG = "ParseDateFormat"; 20 | 21 | private static final ParseImpreciseDateFormat INSTANCE = new ParseImpreciseDateFormat(); 22 | // SimpleDateFormat isn't inherently thread-safe 23 | private final Object lock = new Object(); 24 | private final DateFormat dateFormat; 25 | 26 | private ParseImpreciseDateFormat() { 27 | DateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US); 28 | format.setTimeZone(new SimpleTimeZone(0, "GMT")); 29 | dateFormat = format; 30 | } 31 | 32 | public static ParseImpreciseDateFormat getInstance() { 33 | return INSTANCE; 34 | } 35 | 36 | /* package */ Date parse(String dateString) { 37 | synchronized (lock) { 38 | try { 39 | return dateFormat.parse(dateString); 40 | } catch (java.text.ParseException e) { 41 | // Should never happen 42 | PLog.e(TAG, "could not parse date: " + dateString, e); 43 | return null; 44 | } 45 | } 46 | } 47 | 48 | /* package */ String format(Date date) { 49 | synchronized (lock) { 50 | return dateFormat.format(date); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/ParseJSONUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import java.util.Collection; 12 | import java.util.Iterator; 13 | import java.util.List; 14 | import org.json.JSONException; 15 | import org.json.JSONObject; 16 | 17 | /** Static utility methods pertaining to org.json classes. */ 18 | class ParseJSONUtils { 19 | 20 | /** Creates a copy of {@code copyFrom}, excluding the keys from {@code excludes}. */ 21 | public static JSONObject create(JSONObject copyFrom, Collection excludes) { 22 | JSONObject json = new JSONObject(); 23 | Iterator iterator = copyFrom.keys(); 24 | while (iterator.hasNext()) { 25 | String name = iterator.next(); 26 | if (excludes.contains(name)) { 27 | continue; 28 | } 29 | try { 30 | json.put(name, copyFrom.opt(name)); 31 | } catch (JSONException e) { 32 | // This shouldn't ever happen since it'll only throw if `name` is null 33 | throw new RuntimeException(e); 34 | } 35 | } 36 | return json; 37 | } 38 | 39 | /** A helper for nonugly iterating over JSONObject keys. */ 40 | public static Iterable keys(JSONObject object) { 41 | final JSONObject finalObject = object; 42 | return finalObject::keys; 43 | } 44 | 45 | /** A helper for returning the value mapped by a list of keys, ordered by priority. */ 46 | public static int getInt(JSONObject object, List keys) throws JSONException { 47 | for (String key : keys) { 48 | try { 49 | return object.getInt(key); 50 | } catch (JSONException e) { 51 | // do nothing 52 | } 53 | } 54 | throw new JSONException("No value for " + keys); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/ParseMulticastDelegate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import java.util.ArrayList; 12 | import java.util.LinkedList; 13 | import java.util.List; 14 | 15 | class ParseMulticastDelegate { 16 | private final List> callbacks; 17 | 18 | public ParseMulticastDelegate() { 19 | callbacks = new LinkedList<>(); 20 | } 21 | 22 | public void subscribe(ParseCallback2 callback) { 23 | callbacks.add(callback); 24 | } 25 | 26 | public void unsubscribe(ParseCallback2 callback) { 27 | callbacks.remove(callback); 28 | } 29 | 30 | public void invoke(T result, ParseException exception) { 31 | for (ParseCallback2 callback : new ArrayList<>(callbacks)) { 32 | callback.done(result, exception); 33 | } 34 | } 35 | 36 | public void clear() { 37 | callbacks.clear(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/ParseNotificationManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import android.app.Notification; 12 | import android.app.NotificationManager; 13 | import android.content.Context; 14 | import java.util.concurrent.atomic.AtomicInteger; 15 | 16 | /** A utility class for building and showing notifications. */ 17 | class ParseNotificationManager { 18 | private final AtomicInteger notificationCount = new AtomicInteger(0); 19 | 20 | public static ParseNotificationManager getInstance() { 21 | return Singleton.INSTANCE; 22 | } 23 | 24 | public void showNotification(Context context, Notification notification) { 25 | if (context != null && notification != null) { 26 | notificationCount.incrementAndGet(); 27 | 28 | // Fire off the notification 29 | NotificationManager nm = 30 | (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); 31 | 32 | // Pick an id that probably won't overlap anything 33 | int notificationId = (int) System.currentTimeMillis(); 34 | 35 | try { 36 | nm.notify(notificationId, notification); 37 | } catch (SecurityException e) { 38 | // Some phones throw an exception for unapproved vibration 39 | notification.defaults = Notification.DEFAULT_LIGHTS | Notification.DEFAULT_SOUND; 40 | nm.notify(notificationId, notification); 41 | } 42 | } 43 | } 44 | 45 | private static class Singleton { 46 | private static final ParseNotificationManager INSTANCE = new ParseNotificationManager(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/ParseObjectController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import com.parse.boltsinternal.Task; 12 | import java.util.List; 13 | 14 | interface ParseObjectController { 15 | 16 | Task fetchAsync( 17 | ParseObject.State state, String sessionToken, ParseDecoder decoder); 18 | 19 | Task saveAsync( 20 | ParseObject.State state, 21 | ParseOperationSet operations, 22 | String sessionToken, 23 | ParseDecoder decoder); 24 | 25 | List> saveAllAsync( 26 | List states, 27 | List operationsList, 28 | String sessionToken, 29 | List decoders); 30 | 31 | Task deleteAsync(ParseObject.State state, String sessionToken); 32 | 33 | List> deleteAllAsync(List states, String sessionToken); 34 | } 35 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/ParseObjectCurrentController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import com.parse.boltsinternal.Task; 12 | 13 | interface ParseObjectCurrentController { 14 | 15 | /** 16 | * Persist the currentParseObject 17 | * 18 | * @param object object 19 | * @return task 20 | */ 21 | Task setAsync(T object); 22 | 23 | /** 24 | * Get the persisted currentParseObject 25 | * 26 | * @return task 27 | */ 28 | Task getAsync(); 29 | 30 | /** 31 | * Check whether the currentParseObject exists or not 32 | * 33 | * @return task 34 | */ 35 | Task existsAsync(); 36 | 37 | /** 38 | * Judge whether the given ParseObject is the currentParseObject 39 | * 40 | * @param object object 41 | * @return {@code true} if the give {@link ParseObject} is the currentParseObject 42 | */ 43 | boolean isCurrent(T object); 44 | 45 | /** 46 | * A test helper to reset the current ParseObject. This method nullifies the in memory 47 | * currentParseObject 48 | */ 49 | void clearFromMemory(); 50 | 51 | /** 52 | * A test helper to reset the current ParseObject. This method nullifies the in memory and in 53 | * disk currentParseObject 54 | */ 55 | void clearFromDisk(); 56 | } 57 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/ParseObjectParcelDecoder.java: -------------------------------------------------------------------------------- 1 | package com.parse; 2 | 3 | import android.os.Parcel; 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | 7 | /** 8 | * This is a stateful implementation of {@link ParseParcelDecoder} that remembers which {@code 9 | * ParseObject}s have been decoded. When a pointer is found and we have already decoded an instance 10 | * for the same object id, we use the decoded instance. 11 | * 12 | *

This is very similar to what {@link KnownParseObjectDecoder} does for JSON. 13 | */ 14 | /* package */ class ParseObjectParcelDecoder extends ParseParcelDecoder { 15 | 16 | private final Map objects = new HashMap<>(); 17 | 18 | public ParseObjectParcelDecoder() {} 19 | 20 | public void addKnownObject(ParseObject object) { 21 | objects.put(getObjectOrLocalId(object), object); 22 | } 23 | 24 | @Override 25 | protected ParseObject decodePointer(Parcel source) { 26 | String className = source.readString(); 27 | String objectId = source.readString(); 28 | if (objects.containsKey(objectId)) { 29 | return objects.get(objectId); 30 | } 31 | // Should not happen if encoding was done through ParseObjectParcelEncoder. 32 | ParseObject object = ParseObject.createWithoutData(className, objectId); 33 | objects.put(objectId, object); 34 | return object; 35 | } 36 | 37 | private String getObjectOrLocalId(ParseObject object) { 38 | return object.getObjectId() != null ? object.getObjectId() : object.getOrCreateLocalId(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/ParseObjectParcelEncoder.java: -------------------------------------------------------------------------------- 1 | package com.parse; 2 | 3 | import android.os.Parcel; 4 | import java.util.HashSet; 5 | import java.util.Set; 6 | 7 | /** 8 | * This is a stateful implementation of {@link ParseParcelEncoder} that remembers which {@code 9 | * ParseObject}s have been encoded. If an object is found again in the object tree, it is encoded as 10 | * a pointer rather than a full object, to avoid {@code StackOverflowError}s due to circular 11 | * references. 12 | */ 13 | /* package */ class ParseObjectParcelEncoder extends ParseParcelEncoder { 14 | 15 | private final Set ids = new HashSet<>(); 16 | 17 | public ParseObjectParcelEncoder() {} 18 | 19 | public ParseObjectParcelEncoder(ParseObject root) { 20 | ids.add(getObjectOrLocalId(root)); 21 | } 22 | 23 | @Override 24 | protected void encodeParseObject(ParseObject object, Parcel dest) { 25 | String id = getObjectOrLocalId(object); 26 | if (ids.contains(id)) { 27 | encodePointer(object.getClassName(), id, dest); 28 | } else { 29 | ids.add(id); 30 | super.encodeParseObject(object, dest); 31 | } 32 | } 33 | 34 | private String getObjectOrLocalId(ParseObject object) { 35 | return object.getObjectId() != null ? object.getObjectId() : object.getOrCreateLocalId(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/ParseObjectStore.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import com.parse.boltsinternal.Task; 12 | 13 | interface ParseObjectStore { 14 | 15 | Task getAsync(); 16 | 17 | Task setAsync(T object); 18 | 19 | Task existsAsync(); 20 | 21 | Task deleteAsync(); 22 | } 23 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/ParsePin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import java.util.List; 12 | 13 | @ParseClassName("_Pin") 14 | class ParsePin extends ParseObject { 15 | 16 | /* package */ static final String KEY_NAME = "_name"; 17 | private static final String KEY_OBJECTS = "_objects"; 18 | 19 | public ParsePin() { 20 | // do nothing 21 | } 22 | 23 | @Override 24 | boolean needsDefaultACL() { 25 | return false; 26 | } 27 | 28 | public String getName() { 29 | return getString(KEY_NAME); 30 | } 31 | 32 | public void setName(String name) { 33 | put(KEY_NAME, name); 34 | } 35 | 36 | public List getObjects() { 37 | return getList(KEY_OBJECTS); 38 | } 39 | 40 | public void setObjects(List objects) { 41 | put(KEY_OBJECTS, objects); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/ParsePushController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import com.parse.boltsinternal.Task; 12 | 13 | class ParsePushController { 14 | 15 | private final ParseHttpClient restClient; 16 | 17 | public ParsePushController(ParseHttpClient restClient) { 18 | this.restClient = restClient; 19 | } 20 | 21 | public Task sendInBackground(ParsePush.State state, String sessionToken) { 22 | return buildRESTSendPushCommand(state, sessionToken).executeAsync(restClient).makeVoid(); 23 | } 24 | 25 | ParseRESTCommand buildRESTSendPushCommand(ParsePush.State state, String sessionToken) { 26 | return ParseRESTPushCommand.sendPushCommand( 27 | state.queryState(), 28 | state.channelSet(), 29 | state.expirationTime(), 30 | state.expirationTimeInterval(), 31 | state.pushTime(), 32 | state.data(), 33 | sessionToken); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/ParseQueryController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import com.parse.boltsinternal.Task; 12 | import java.util.List; 13 | 14 | /** A {@code ParseQueryController} defines how a {@link ParseQuery} is executed. */ 15 | interface ParseQueryController { 16 | 17 | /** 18 | * Executor for {@code find} queries. 19 | * 20 | * @param state Immutable query state to execute. 21 | * @param user The user executing the query that can be used to match ACLs. 22 | * @param cancellationToken Cancellation token. 23 | * @return A {@link Task} that resolves to the results of the find. 24 | */ 25 | Task> findAsync( 26 | ParseQuery.State state, ParseUser user, Task cancellationToken); 27 | 28 | /** 29 | * Executor for {@code count} queries. 30 | * 31 | * @param state Immutable query state to execute. 32 | * @param user The user executing the query that can be used to match ACLs. 33 | * @param cancellationToken Cancellation token. 34 | * @return A {@link Task} that resolves to the results of the count. 35 | */ 36 | Task countAsync( 37 | ParseQuery.State state, ParseUser user, Task cancellationToken); 38 | 39 | /** 40 | * Executor for {@code getFirst} queries. 41 | * 42 | * @param state Immutable query state to execute. 43 | * @param user The user executing the query that can be used to match ACLs. 44 | * @param cancellationToken Cancellation token. 45 | * @return A {@link Task} that resolves to the the first result of the query if successful and 46 | * there is at least one result or {@link ParseException#OBJECT_NOT_FOUND} if there are no 47 | * results. 48 | */ 49 | Task getFirstAsync( 50 | ParseQuery.State state, ParseUser user, Task cancellationToken); 51 | } 52 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/ParseRESTCloudCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import com.parse.http.ParseHttpRequest; 12 | import java.util.Map; 13 | 14 | class ParseRESTCloudCommand extends ParseRESTCommand { 15 | 16 | private ParseRESTCloudCommand( 17 | String httpPath, 18 | ParseHttpRequest.Method httpMethod, 19 | Map parameters, 20 | String sessionToken) { 21 | super(httpPath, httpMethod, parameters, sessionToken); 22 | } 23 | 24 | public static ParseRESTCloudCommand callFunctionCommand( 25 | String functionName, Map parameters, String sessionToken) { 26 | final String httpPath = String.format("functions/%s", functionName); 27 | return new ParseRESTCloudCommand( 28 | httpPath, ParseHttpRequest.Method.POST, parameters, sessionToken); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/ParseRESTConfigCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import com.parse.http.ParseHttpRequest; 12 | import java.util.HashMap; 13 | import java.util.Map; 14 | 15 | class ParseRESTConfigCommand extends ParseRESTCommand { 16 | 17 | public ParseRESTConfigCommand( 18 | String httpPath, 19 | ParseHttpRequest.Method httpMethod, 20 | Map parameters, 21 | String sessionToken) { 22 | super(httpPath, httpMethod, parameters, sessionToken); 23 | } 24 | 25 | public static ParseRESTConfigCommand fetchConfigCommand(String sessionToken) { 26 | return new ParseRESTConfigCommand( 27 | "config", ParseHttpRequest.Method.GET, null, sessionToken); 28 | } 29 | 30 | public static ParseRESTConfigCommand updateConfigCommand( 31 | final Map configParameters, String sessionToken) { 32 | Map> commandParameters = null; 33 | if (configParameters != null) { 34 | commandParameters = new HashMap<>(); 35 | commandParameters.put("params", configParameters); 36 | } 37 | return new ParseRESTConfigCommand( 38 | "config", ParseHttpRequest.Method.PUT, commandParameters, sessionToken); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/ParseRESTSessionCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import com.parse.http.ParseHttpRequest; 12 | import org.json.JSONObject; 13 | 14 | class ParseRESTSessionCommand extends ParseRESTCommand { 15 | 16 | private ParseRESTSessionCommand( 17 | String httpPath, 18 | ParseHttpRequest.Method httpMethod, 19 | JSONObject jsonParameters, 20 | String sessionToken) { 21 | super(httpPath, httpMethod, jsonParameters, sessionToken); 22 | } 23 | 24 | public static ParseRESTSessionCommand getCurrentSessionCommand(String sessionToken) { 25 | return new ParseRESTSessionCommand( 26 | "sessions/me", ParseHttpRequest.Method.GET, null, sessionToken); 27 | } 28 | 29 | public static ParseRESTSessionCommand revoke(String sessionToken) { 30 | return new ParseRESTSessionCommand( 31 | "logout", ParseHttpRequest.Method.POST, new JSONObject(), sessionToken); 32 | } 33 | 34 | public static ParseRESTSessionCommand upgradeToRevocableSessionCommand(String sessionToken) { 35 | return new ParseRESTSessionCommand( 36 | "upgradeToRevocableSession", 37 | ParseHttpRequest.Method.POST, 38 | new JSONObject(), 39 | sessionToken); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/ParseSQLiteOpenHelper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import android.content.Context; 12 | import android.database.sqlite.SQLiteDatabase; 13 | import android.database.sqlite.SQLiteOpenHelper; 14 | import com.parse.boltsinternal.Task; 15 | 16 | abstract class ParseSQLiteOpenHelper { 17 | 18 | private final SQLiteOpenHelper helper; 19 | 20 | public ParseSQLiteOpenHelper( 21 | Context context, String name, SQLiteDatabase.CursorFactory factory, int version) { 22 | helper = 23 | new SQLiteOpenHelper(context, name, factory, version) { 24 | @Override 25 | public void onOpen(SQLiteDatabase db) { 26 | super.onOpen(db); 27 | ParseSQLiteOpenHelper.this.onOpen(db); 28 | } 29 | 30 | @Override 31 | public void onCreate(SQLiteDatabase db) { 32 | ParseSQLiteOpenHelper.this.onCreate(db); 33 | } 34 | 35 | @Override 36 | public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 37 | ParseSQLiteOpenHelper.this.onUpgrade(db, oldVersion, newVersion); 38 | } 39 | }; 40 | } 41 | 42 | public Task getReadableDatabaseAsync() { 43 | return getDatabaseAsync(false); 44 | } 45 | 46 | public Task getWritableDatabaseAsync() { 47 | return getDatabaseAsync(true); 48 | } 49 | 50 | private Task getDatabaseAsync(final boolean writable) { 51 | return ParseSQLiteDatabase.openDatabaseAsync( 52 | helper, !writable ? SQLiteDatabase.OPEN_READONLY : SQLiteDatabase.OPEN_READWRITE); 53 | } 54 | 55 | public void onOpen(SQLiteDatabase db) { 56 | // do nothing 57 | } 58 | 59 | public abstract void onCreate(SQLiteDatabase db); 60 | 61 | public abstract void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion); 62 | } 63 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/ParseSessionController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import com.parse.boltsinternal.Task; 12 | 13 | interface ParseSessionController { 14 | 15 | Task getSessionAsync(String sessionToken); 16 | 17 | Task revokeAsync(String sessionToken); 18 | 19 | Task upgradeToRevocable(String sessionToken); 20 | } 21 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/ParseSetOperation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import android.os.Parcel; 12 | 13 | /** An operation where a field is set to a given value regardless of its previous value. */ 14 | class ParseSetOperation implements ParseFieldOperation { 15 | /* package */ static final String OP_NAME = "Set"; 16 | 17 | private final Object value; 18 | 19 | public ParseSetOperation(Object newValue) { 20 | value = newValue; 21 | } 22 | 23 | public Object getValue() { 24 | return value; 25 | } 26 | 27 | @Override 28 | public Object encode(ParseEncoder objectEncoder) { 29 | return objectEncoder.encode(value); 30 | } 31 | 32 | @Override 33 | public void encode(Parcel dest, ParseParcelEncoder parcelableEncoder) { 34 | dest.writeString(OP_NAME); 35 | parcelableEncoder.encode(value, dest); 36 | } 37 | 38 | @Override 39 | public ParseFieldOperation mergeWithPrevious(ParseFieldOperation previous) { 40 | return this; 41 | } 42 | 43 | @Override 44 | public Object apply(Object oldValue, String key) { 45 | return value; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/ParseUserController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import com.parse.boltsinternal.Task; 12 | import java.util.Map; 13 | 14 | interface ParseUserController { 15 | 16 | Task signUpAsync( 17 | ParseObject.State state, ParseOperationSet operations, String sessionToken); 18 | 19 | // region logInAsync 20 | 21 | Task logInAsync(String username, String password); 22 | 23 | Task logInAsync(ParseUser.State state, ParseOperationSet operations); 24 | 25 | Task logInAsync(String authType, Map authData); 26 | 27 | // endregion 28 | 29 | Task getUserAsync(String sessionToken); 30 | 31 | Task requestPasswordResetAsync(String email); 32 | } 33 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/PointerEncoder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import org.json.JSONObject; 12 | 13 | /** 14 | * Encodes {@link ParseObject}s as pointers. If the object does not have an objectId, throws an 15 | * exception. 16 | */ 17 | public class PointerEncoder extends PointerOrLocalIdEncoder { 18 | 19 | // This class isn't really a Singleton, but since it has no state, it's more efficient to get 20 | // the 21 | // default instance. 22 | private static final PointerEncoder INSTANCE = new PointerEncoder(); 23 | 24 | public static PointerEncoder get() { 25 | return INSTANCE; 26 | } 27 | 28 | @Override 29 | public JSONObject encodeRelatedObject(ParseObject object) { 30 | // Ensure the ParseObject has an id so it can be encoded as a pointer. 31 | if (object.getObjectId() == null) { 32 | // object that hasn't been saved. 33 | throw new IllegalStateException( 34 | "unable to encode an association with an unsaved ParseObject"); 35 | } 36 | return super.encodeRelatedObject(object); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/PointerOrLocalIdEncoder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import org.json.JSONException; 12 | import org.json.JSONObject; 13 | 14 | /** 15 | * Encodes {@link ParseObject}s as pointers. If the object does not have an objectId, uses a local 16 | * id. 17 | */ 18 | public class PointerOrLocalIdEncoder extends ParseEncoder { 19 | 20 | // This class isn't really a Singleton, but since it has no state, it's more efficient to get 21 | // the 22 | // default instance. 23 | private static final PointerOrLocalIdEncoder INSTANCE = new PointerOrLocalIdEncoder(); 24 | 25 | public static PointerOrLocalIdEncoder get() { 26 | return INSTANCE; 27 | } 28 | 29 | @Override 30 | public JSONObject encodeRelatedObject(ParseObject object) { 31 | JSONObject json = new JSONObject(); 32 | try { 33 | if (object.getObjectId() != null) { 34 | json.put("__type", "Pointer"); 35 | json.put("className", object.getClassName()); 36 | json.put("objectId", object.getObjectId()); 37 | } else { 38 | json.put("__type", "Pointer"); 39 | json.put("className", object.getClassName()); 40 | json.put("localId", object.getOrCreateLocalId()); 41 | } 42 | } catch (JSONException e) { 43 | // This should not happen 44 | throw new RuntimeException(e); 45 | } 46 | return json; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/ProgressCallback.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | /** 12 | * A {@code ProgressCallback} is used to get upload or download progress of a {@link ParseFile} 13 | * action. 14 | * 15 | *

The easiest way to use a {@code ProgressCallback} is through an anonymous inner class. 16 | */ 17 | // FYI, this does not extend ParseCallback2 since it does not match the usual signature 18 | // done(T, ParseException), but is done(T). 19 | public interface ProgressCallback { 20 | /** Override this function with your desired callback. */ 21 | void done(Integer percentDone); 22 | } 23 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/RequestPasswordResetCallback.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | /** 12 | * A {@code RequestPasswordResetCallback} is used to run code requesting a password reset for a 13 | * user. 14 | * 15 | *

The easiest way to use a {@code RequestPasswordResetCallback} is through an anonymous inner 16 | * class. Override the {@code done} function to specify what the callback should do after the 17 | * request is complete. The {@code done} function will be run in the UI thread, while the request 18 | * happens in a background thread. This ensures that the UI does not freeze while the request 19 | * happens. 20 | * 21 | *

For example, this sample code requests a password reset for a user and calls a different 22 | * function depending on whether the request succeeded or not. 23 | * 24 | *

25 | * 26 | *

27 |  * ParseUser.requestPasswordResetInBackground("forgetful@example.com",
28 |  *     new RequestPasswordResetCallback() {
29 |  *       public void done(ParseException e) {
30 |  *         if (e == null) {
31 |  *           requestedSuccessfully();
32 |  *         } else {
33 |  *           requestDidNotSucceed();
34 |  *         }
35 |  *       }
36 |  *     });
37 |  * 
38 | */ 39 | public interface RequestPasswordResetCallback extends ParseCallback1 { 40 | /** 41 | * Override this function with the code you want to run after the request is complete. 42 | * 43 | * @param e The exception raised by the save, or {@code null} if no account is associated with 44 | * the email address. 45 | */ 46 | @Override 47 | void done(ParseException e); 48 | } 49 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/SaveCallback.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | /** 12 | * A {@code SaveCallback} is used to run code after saving a {@link ParseObject} in a background 13 | * thread. 14 | * 15 | *

The easiest way to use a {@code SaveCallback} is through an anonymous inner class. Override 16 | * the {@code done} function to specify what the callback should do after the save is complete. The 17 | * {@code done} function will be run in the UI thread, while the save happens in a background 18 | * thread. This ensures that the UI does not freeze while the save happens. 19 | * 20 | *

For example, this sample code saves the object {@code myObject} and calls a different function 21 | * depending on whether the save succeeded or not. 22 | * 23 | *

24 | * 25 | *

26 |  * myObject.saveInBackground(new SaveCallback() {
27 |  *   public void done(ParseException e) {
28 |  *     if (e == null) {
29 |  *       myObjectSavedSuccessfully();
30 |  *     } else {
31 |  *       myObjectSaveDidNotSucceed();
32 |  *     }
33 |  *   }
34 |  * });
35 |  * 
36 | */ 37 | public interface SaveCallback extends ParseCallback1 { 38 | /** 39 | * Override this function with the code you want to run after the save is complete. 40 | * 41 | * @param e The exception raised by the save, or {@code null} if it succeeded. 42 | */ 43 | @Override 44 | void done(ParseException e); 45 | } 46 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/SendCallback.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | /** 12 | * A {@code SendCallback} is used to run code after sending a {@link ParsePush} in a background 13 | * thread. 14 | * 15 | *

The easiest way to use a {@code SendCallback} is through an anonymous inner class. Override 16 | * the {@code done} function to specify what the callback should do after the send is complete. The 17 | * {@code done} function will be run in the UI thread, while the send happens in a background 18 | * thread. This ensures that the UI does not freeze while the send happens. 19 | * 20 | *

For example, this sample code sends the message {@code "Hello world"} on the {@code "hello"} 21 | * channel and logs whether the send succeeded. 22 | * 23 | *

24 | * 25 | *

26 |  * ParsePush push = new ParsePush();
27 |  * push.setChannel("hello");
28 |  * push.setMessage("Hello world!");
29 |  * push.sendInBackground(new SendCallback() {
30 |  *   public void done(ParseException e) {
31 |  *     if (e == null) {
32 |  *       Log.d("push", "success!");
33 |  *     } else {
34 |  *       Log.d("push", "failure");
35 |  *     }
36 |  *   }
37 |  * });
38 |  * 
39 | */ 40 | public interface SendCallback extends ParseCallback1 { 41 | /** 42 | * Override this function with the code you want to run after the send is complete. 43 | * 44 | * @param e The exception raised by the send, or {@code null} if it succeeded. 45 | */ 46 | @Override 47 | void done(ParseException e); 48 | } 49 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/SignUpCallback.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | /** 12 | * A {@code SignUpCallback} is used to run code after signing up a {@link ParseUser} in a background 13 | * thread. 14 | * 15 | *

The easiest way to use a {@code SignUpCallback} is through an anonymous inner class. Override 16 | * the {@code done} function to specify what the callback should do after the save is complete. The 17 | * {@code done} function will be run in the UI thread, while the signup happens in a background 18 | * thread. This ensures that the UI does not freeze while the signup happens. 19 | * 20 | *

For example, this sample code signs up the object {@code myUser} and calls a different 21 | * function depending on whether the signup succeeded or not. 22 | * 23 | *

24 | * 25 | *

26 | * 27 | *

28 |  * myUser.signUpInBackground(new SignUpCallback() {
29 |  *   public void done(ParseException e) {
30 |  *     if (e == null) {
31 |  *       myUserSignedUpSuccessfully();
32 |  *     } else {
33 |  *       myUserSignUpDidNotSucceed();
34 |  *     }
35 |  *   }
36 |  * });
37 |  * 
38 | */ 39 | public interface SignUpCallback extends ParseCallback1 { 40 | /** 41 | * Override this function with the code you want to run after the signUp is complete. 42 | * 43 | * @param e The exception raised by the signUp, or {@code null} if it succeeded. 44 | */ 45 | @Override 46 | void done(ParseException e); 47 | } 48 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/TaskStackBuilderHelper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import android.annotation.TargetApi; 12 | import android.app.Activity; 13 | import android.app.TaskStackBuilder; 14 | import android.content.Context; 15 | import android.content.Intent; 16 | import android.os.Build; 17 | 18 | /** 19 | * This is here to avoid the dependency on the android support library. TaskStackBuilder was 20 | * introduced in API 11, so in order to eliminate warnings of the type 'Could not find class...' 21 | * this takes advantage of lazy class loading. TODO (pdjones): make more similar to support-v4 api 22 | */ 23 | @TargetApi(Build.VERSION_CODES.JELLY_BEAN) 24 | /* package */ class TaskStackBuilderHelper { 25 | public static void startActivities( 26 | Context context, Class cls, Intent activityIntent) { 27 | TaskStackBuilder stackBuilder = TaskStackBuilder.create(context); 28 | stackBuilder.addParentStack(cls); 29 | stackBuilder.addNextIntent(activityIntent); 30 | stackBuilder.startActivities(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /parse/src/main/java/com/parse/WeakValueHashMap.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import java.lang.ref.WeakReference; 12 | import java.util.HashMap; 13 | 14 | /** A HashMap where all the values are weak. */ 15 | class WeakValueHashMap { 16 | private final HashMap> map; 17 | 18 | public WeakValueHashMap() { 19 | map = new HashMap<>(); 20 | } 21 | 22 | public void put(K key, V value) { 23 | map.put(key, new WeakReference<>(value)); 24 | } 25 | 26 | /** 27 | * Returns null if the key isn't in the map, or if it is an expired reference. If it is, then 28 | * the reference is removed from the map. 29 | */ 30 | public V get(K key) { 31 | WeakReference reference = map.get(key); 32 | if (reference == null) { 33 | return null; 34 | } 35 | 36 | V value = reference.get(); 37 | if (value == null) { 38 | map.remove(key); 39 | } 40 | 41 | return value; 42 | } 43 | 44 | public void remove(K key) { 45 | map.remove(key); 46 | } 47 | 48 | public void clear() { 49 | map.clear(); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /parse/src/test/java/com/parse/EventuallyPinTest.java: -------------------------------------------------------------------------------- 1 | package com.parse; 2 | 3 | import static org.mockito.ArgumentMatchers.any; 4 | import static org.mockito.ArgumentMatchers.eq; 5 | import static org.mockito.ArgumentMatchers.nullable; 6 | import static org.mockito.Mockito.mock; 7 | import static org.mockito.Mockito.when; 8 | 9 | import android.database.sqlite.SQLiteException; 10 | import com.parse.boltsinternal.Task; 11 | import org.junit.After; 12 | import org.junit.Before; 13 | import org.junit.Rule; 14 | import org.junit.Test; 15 | import org.junit.rules.ExpectedException; 16 | import org.junit.runner.RunWith; 17 | import org.robolectric.RobolectricTestRunner; 18 | 19 | @RunWith(RobolectricTestRunner.class) 20 | public class EventuallyPinTest { 21 | 22 | @Rule public final ExpectedException thrown = ExpectedException.none(); 23 | 24 | @Before 25 | public void setUp() { 26 | ParseObject.registerSubclass(EventuallyPin.class); 27 | ParseObject.registerSubclass(ParsePin.class); 28 | } 29 | 30 | @After 31 | public void tearDown() { 32 | ParseObject.unregisterSubclass(EventuallyPin.class); 33 | ParseObject.unregisterSubclass(ParsePin.class); 34 | Parse.setLocalDatastore(null); 35 | ParsePlugins.reset(); 36 | } 37 | 38 | @Test 39 | public void testFailingFindAllPinned() throws Exception { 40 | OfflineStore offlineStore = mock(OfflineStore.class); 41 | Parse.setLocalDatastore(offlineStore); 42 | when(offlineStore.findFromPinAsync( 43 | eq(EventuallyPin.PIN_NAME), 44 | any(ParseQuery.State.class), 45 | nullable(ParseUser.class))) 46 | .thenReturn(Task.forError(new SQLiteException())); 47 | 48 | ParsePlugins plugins = mock(ParsePlugins.class); 49 | ParsePlugins.set(plugins); 50 | when(plugins.restClient()).thenReturn(ParseHttpClient.createClient(null)); 51 | 52 | thrown.expect(SQLiteException.class); 53 | 54 | ParseTaskUtils.wait(EventuallyPin.findAllPinned()); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /parse/src/test/java/com/parse/ListsTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import static org.junit.Assert.assertEquals; 12 | 13 | import java.util.ArrayList; 14 | import java.util.List; 15 | import org.junit.Test; 16 | 17 | public class ListsTest { 18 | 19 | @Test 20 | public void testPartition() { 21 | List list = new ArrayList<>(); 22 | for (int i = 0; i < 99; i++) { 23 | list.add(i); 24 | } 25 | List> partitions = Lists.partition(list, 5); 26 | assertEquals(20, partitions.size()); 27 | 28 | int count = 0; 29 | for (int i = 0; i < 19; i++) { 30 | List partition = partitions.get(i); 31 | assertEquals(5, partition.size()); 32 | for (int j : partition) { 33 | assertEquals(count, j); 34 | count += 1; 35 | } 36 | } 37 | assertEquals(4, partitions.get(19).size()); 38 | for (int i = 0; i < 4; i++) { 39 | assertEquals(95 + i, partitions.get(19).get(i).intValue()); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /parse/src/test/java/com/parse/ParseByteArrayHttpBodyTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import static org.junit.Assert.assertArrayEquals; 12 | import static org.junit.Assert.assertEquals; 13 | 14 | import java.io.ByteArrayOutputStream; 15 | import java.io.IOException; 16 | import org.junit.Test; 17 | 18 | public class ParseByteArrayHttpBodyTest { 19 | 20 | @Test 21 | public void testInitializeWithString() throws IOException { 22 | String content = "content"; 23 | String contentType = "application/json"; 24 | ParseByteArrayHttpBody body = new ParseByteArrayHttpBody(content, contentType); 25 | assertArrayEquals(content.getBytes(), ParseIOUtils.toByteArray(body.getContent())); 26 | assertEquals(contentType, body.getContentType()); 27 | assertEquals(7, body.getContentLength()); 28 | } 29 | 30 | @Test 31 | public void testInitializeWithByteArray() throws IOException { 32 | byte[] content = {1, 1, 1, 1, 1}; 33 | String contentType = "application/json"; 34 | ParseByteArrayHttpBody body = new ParseByteArrayHttpBody(content, contentType); 35 | assertArrayEquals(content, ParseIOUtils.toByteArray(body.getContent())); 36 | assertEquals(contentType, body.getContentType()); 37 | assertEquals(5, body.getContentLength()); 38 | } 39 | 40 | @Test 41 | public void testWriteTo() throws IOException { 42 | String content = "content"; 43 | String contentType = "application/json"; 44 | ParseByteArrayHttpBody body = new ParseByteArrayHttpBody(content, contentType); 45 | 46 | // Check content 47 | ByteArrayOutputStream output = new ByteArrayOutputStream(); 48 | body.writeTo(output); 49 | String contentAgain = output.toString(); 50 | assertEquals(content, contentAgain); 51 | 52 | // No need to check whether content input stream is closed since it is a 53 | // ByteArrayInputStream 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /parse/src/test/java/com/parse/ParseClientConfigurationTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import static org.junit.Assert.assertEquals; 12 | import static org.junit.Assert.assertNull; 13 | import static org.junit.Assert.assertTrue; 14 | 15 | import org.junit.Test; 16 | import org.junit.runner.RunWith; 17 | import org.robolectric.RobolectricTestRunner; 18 | 19 | @RunWith(RobolectricTestRunner.class) 20 | public class ParseClientConfigurationTest { 21 | 22 | @Test 23 | public void testBuilder() { 24 | Parse.Configuration.Builder builder = new Parse.Configuration.Builder(null); 25 | builder.applicationId("foo"); 26 | builder.clientKey("bar"); 27 | builder.enableLocalDataStore(); 28 | builder.allowCustomObjectId(); 29 | Parse.Configuration configuration = builder.build(); 30 | 31 | assertNull(configuration.context); 32 | assertEquals(configuration.applicationId, "foo"); 33 | assertEquals(configuration.clientKey, "bar"); 34 | assertTrue(configuration.localDataStoreEnabled); 35 | assertEquals(configuration.allowCustomObjectId, true); 36 | } 37 | 38 | @Test 39 | public void testBuilderServerURL() { 40 | Parse.Configuration.Builder builder = new Parse.Configuration.Builder(null); 41 | builder.server("http://myserver.com/parse/"); 42 | Parse.Configuration configuration = builder.build(); 43 | assertEquals(configuration.server, "http://myserver.com/parse/"); 44 | } 45 | 46 | @Test 47 | public void testBuilderServerMissingSlashURL() { 48 | Parse.Configuration.Builder builder = new Parse.Configuration.Builder(null); 49 | builder.server("http://myserver.com/missingslash"); 50 | Parse.Configuration configuration = builder.build(); 51 | assertEquals(configuration.server, "http://myserver.com/missingslash/"); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /parse/src/test/java/com/parse/ParseCoderTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import static org.junit.Assert.assertEquals; 12 | 13 | import org.json.JSONObject; 14 | import org.junit.Test; 15 | import org.junit.runner.RunWith; 16 | import org.robolectric.RobolectricTestRunner; 17 | 18 | // For android.util.Base64 19 | @RunWith(RobolectricTestRunner.class) 20 | public class ParseCoderTest { 21 | 22 | @Test 23 | public void testBytes() { 24 | // string of bytes, including some invalid UTF8 data 25 | byte[] bytes = {4, 8, 16, 32, -128, 0, 0, 0}; 26 | 27 | ParseEncoder encoder = PointerEncoder.get(); 28 | JSONObject json = (JSONObject) encoder.encode(bytes); 29 | 30 | ParseDecoder decoder = ParseDecoder.get(); 31 | byte[] bytesAgain = (byte[]) decoder.decode(json); 32 | 33 | assertEquals(8, bytesAgain.length); 34 | assertEquals(4, bytesAgain[0]); 35 | assertEquals(8, bytesAgain[1]); 36 | assertEquals(16, bytesAgain[2]); 37 | assertEquals(32, bytesAgain[3]); 38 | assertEquals(-128, bytesAgain[4]); 39 | assertEquals(0, bytesAgain[5]); 40 | assertEquals(0, bytesAgain[6]); 41 | assertEquals(0, bytesAgain[7]); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /parse/src/test/java/com/parse/ParseDateFormatTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import static org.junit.Assert.assertEquals; 12 | import static org.junit.Assert.assertNull; 13 | 14 | import java.util.Date; 15 | import org.junit.Test; 16 | 17 | public class ParseDateFormatTest { 18 | @Test 19 | public void testParse() { 20 | String string = "2015-05-13T11:08:01.123Z"; 21 | Date date = ParseDateFormat.getInstance().parse(string); 22 | assertEquals(1431515281123L, date.getTime()); 23 | } 24 | 25 | @Test 26 | public void testParseInvalid() { 27 | String string = "2015-05-13T11:08:01Z"; 28 | Date date = ParseDateFormat.getInstance().parse(string); 29 | assertNull(date); 30 | } 31 | 32 | @Test 33 | public void testFormat() { 34 | Date date = new Date(1431515281123L); 35 | String string = ParseDateFormat.getInstance().format(date); 36 | assertEquals("2015-05-13T11:08:01.123Z", string); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /parse/src/test/java/com/parse/ParseDigestUtilsTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import static org.junit.Assert.assertEquals; 12 | 13 | import java.util.HashMap; 14 | import java.util.Map; 15 | import org.junit.Test; 16 | 17 | public class ParseDigestUtilsTest { 18 | 19 | @Test 20 | public void testMD5() { 21 | Map stringToMD5 = new HashMap<>(); 22 | stringToMD5.put("grantland", "66ad19754cd2edcc20c3221a5488a599"); 23 | stringToMD5.put("nikita", "b00a50c448238a71ed479f81fa4d9066"); 24 | stringToMD5.put("1337", "e48e13207341b6bffb7fb1622282247b"); 25 | stringToMD5.put("I am a potato", "2e832e16f60587842c7e4080142dbeca"); 26 | 27 | for (Map.Entry entry : stringToMD5.entrySet()) { 28 | String md5 = ParseDigestUtils.md5(entry.getKey()); 29 | assertEquals(entry.getValue(), md5); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /parse/src/test/java/com/parse/ParseGeoPointTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import static org.junit.Assert.assertEquals; 12 | import static org.junit.Assert.assertNotEquals; 13 | 14 | import android.os.Parcel; 15 | import org.junit.Test; 16 | import org.junit.runner.RunWith; 17 | import org.robolectric.RobolectricTestRunner; 18 | 19 | @RunWith(RobolectricTestRunner.class) 20 | public class ParseGeoPointTest { 21 | 22 | @Test 23 | public void testConstructors() { 24 | ParseGeoPoint point = new ParseGeoPoint(); 25 | assertEquals(0, point.getLatitude(), 0); 26 | assertEquals(0, point.getLongitude(), 0); 27 | 28 | double lat = 1.0; 29 | double lng = 2.0; 30 | point = new ParseGeoPoint(lat, lng); 31 | assertEquals(lat, point.getLatitude(), 0); 32 | assertEquals(lng, point.getLongitude(), 0); 33 | 34 | ParseGeoPoint copy = new ParseGeoPoint(point); 35 | assertEquals(lat, copy.getLatitude(), 0); 36 | assertEquals(lng, copy.getLongitude(), 0); 37 | } 38 | 39 | @Test 40 | public void testEquals() { 41 | ParseGeoPoint pointA = new ParseGeoPoint(30d, 50d); 42 | ParseGeoPoint pointB = new ParseGeoPoint(30d, 50d); 43 | ParseGeoPoint pointC = new ParseGeoPoint(45d, 45d); 44 | 45 | assertEquals(pointA, pointB); 46 | assertEquals(pointA, pointA); 47 | assertEquals(pointB, pointA); 48 | 49 | assertNotEquals(null, pointA); 50 | assertNotEquals(true, pointA); 51 | assertNotEquals(pointA, pointC); 52 | } 53 | 54 | @Test 55 | public void testParcelable() { 56 | ParseGeoPoint point = new ParseGeoPoint(30d, 50d); 57 | Parcel parcel = Parcel.obtain(); 58 | point.writeToParcel(parcel, 0); 59 | parcel.setDataPosition(0); 60 | point = ParseGeoPoint.CREATOR.createFromParcel(parcel); 61 | assertEquals(point.getLatitude(), 30d, 0); 62 | assertEquals(point.getLongitude(), 50d, 0); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /parse/src/test/java/com/parse/ParseImpreciseDateFormatTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import static org.junit.Assert.assertEquals; 12 | import static org.junit.Assert.assertNull; 13 | 14 | import java.util.Date; 15 | import org.junit.Test; 16 | 17 | public class ParseImpreciseDateFormatTest { 18 | @Test 19 | public void testParse() { 20 | String string = "2015-05-13T11:08:01Z"; 21 | Date date = ParseImpreciseDateFormat.getInstance().parse(string); 22 | assertEquals(1431515281000L, date.getTime()); 23 | } 24 | 25 | @Test 26 | public void testParseInvalid() { 27 | String string = "2015-05-13T11:08:01.123Z"; 28 | Date date = ParseImpreciseDateFormat.getInstance().parse(string); 29 | assertNull(date); 30 | } 31 | 32 | @Test 33 | public void testFormat() { 34 | Date date = new Date(1431515281000L); 35 | String string = ParseImpreciseDateFormat.getInstance().format(date); 36 | assertEquals("2015-05-13T11:08:01Z", string); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /parse/src/test/java/com/parse/ParseMatchers.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import static org.hamcrest.CoreMatchers.equalTo; 12 | 13 | import org.hamcrest.Description; 14 | import org.hamcrest.Matcher; 15 | import org.junit.internal.matchers.TypeSafeMatcher; 16 | 17 | public class ParseMatchers { 18 | public static Matcher hasParseErrorCode(int code) { 19 | return hasParseErrorCode(equalTo(code)); 20 | } 21 | 22 | public static Matcher hasParseErrorCode(final Matcher matcher) { 23 | return new TypeSafeMatcher() { 24 | @Override 25 | public boolean matchesSafely(Throwable item) { 26 | return item instanceof ParseException 27 | && matcher.matches(((ParseException) item).getCode()); 28 | } 29 | 30 | @Override 31 | public void describeTo(Description description) { 32 | description.appendText("exception with message "); 33 | description.appendDescriptionOf(matcher); 34 | } 35 | }; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /parse/src/test/java/com/parse/ParseSessionTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import static org.junit.Assert.assertTrue; 12 | 13 | import java.util.Collections; 14 | import org.junit.After; 15 | import org.junit.Before; 16 | import org.junit.Test; 17 | 18 | public class ParseSessionTest { 19 | 20 | @Before 21 | public void setUp() { 22 | ParseObject.registerSubclass(ParseSession.class); 23 | } 24 | 25 | @After 26 | public void tearDown() { 27 | ParseObject.unregisterSubclass(ParseSession.class); 28 | } 29 | 30 | @Test 31 | public void testImmutableKeys() { 32 | String[] immutableKeys = { 33 | "sessionToken", "createdWith", "restricted", "user", "expiresAt", "installationId" 34 | }; 35 | 36 | ParseSession session = new ParseSession(); 37 | session.put("foo", "bar"); 38 | session.put("USER", "bar"); 39 | session.put("_user", "bar"); 40 | session.put("token", "bar"); 41 | 42 | for (String immutableKey : immutableKeys) { 43 | try { 44 | session.put(immutableKey, "blah"); 45 | } catch (IllegalArgumentException e) { 46 | assertTrue(e.getMessage().contains("Cannot modify")); 47 | } 48 | 49 | try { 50 | session.remove(immutableKey); 51 | } catch (IllegalArgumentException e) { 52 | assertTrue(e.getMessage().contains("Cannot modify")); 53 | } 54 | 55 | try { 56 | session.removeAll(immutableKey, Collections.emptyList()); 57 | } catch (IllegalArgumentException e) { 58 | assertTrue(e.getMessage().contains("Cannot modify")); 59 | } 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /parse/src/test/java/com/parse/ParseTaskUtilsTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import static org.junit.Assert.assertTrue; 12 | 13 | import com.parse.boltsinternal.AggregateException; 14 | import com.parse.boltsinternal.Task; 15 | import java.util.ArrayList; 16 | import org.junit.Test; 17 | 18 | public class ParseTaskUtilsTest { 19 | /** 20 | * Verifies {@link AggregateException} gets wrapped with {@link ParseException} when thrown from 21 | * {@link com.parse.ParseTaskUtils#wait(Task)}. 22 | */ 23 | @Test 24 | public void testWaitForTaskWrapsAggregateExceptionAsParseException() { 25 | final Exception error = new RuntimeException("This task failed."); 26 | 27 | final ArrayList> tasks = new ArrayList<>(); 28 | for (int i = 0; i < 20; i++) { 29 | final int number = i; 30 | Task task = 31 | Task.callInBackground( 32 | () -> { 33 | Thread.sleep((long) (Math.random() * 100)); 34 | if (number == 10 || number == 11) { 35 | throw error; 36 | } 37 | return null; 38 | }); 39 | tasks.add(task); 40 | } 41 | 42 | try { 43 | ParseTaskUtils.wait(Task.whenAll(tasks)); 44 | } catch (ParseException e) { 45 | assertTrue(e.getCause() instanceof AggregateException); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /parse/src/test/java/com/parse/ParseUriHttpBodyTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import static org.junit.Assert.assertArrayEquals; 12 | import static org.junit.Assert.assertEquals; 13 | 14 | import android.net.Uri; 15 | import java.io.ByteArrayOutputStream; 16 | import java.io.File; 17 | import java.io.IOException; 18 | import org.junit.Rule; 19 | import org.junit.Test; 20 | import org.junit.rules.TemporaryFolder; 21 | 22 | public class ParseUriHttpBodyTest { 23 | @Rule public final TemporaryFolder temporaryFolder = new TemporaryFolder(); 24 | 25 | @Test 26 | public void testInitializeWithUri() throws IOException { 27 | byte[] content = {1, 1, 1, 1, 1}; 28 | String contentType = "application/json"; 29 | File file = temporaryFolder.newFile("name"); 30 | ParseFileUtils.writeByteArrayToFile(file, content); 31 | Uri uri = Uri.fromFile(file); 32 | ParseUriHttpBody body = new ParseUriHttpBody(uri, contentType); 33 | assertArrayEquals(content, ParseIOUtils.toByteArray(body.getContent())); 34 | assertEquals(contentType, body.getContentType()); 35 | assertEquals(5, body.getContentLength()); 36 | } 37 | 38 | @Test 39 | public void testWriteTo() throws IOException { 40 | String content = "content"; 41 | String contentType = "application/json"; 42 | File file = temporaryFolder.newFile("name"); 43 | ParseFileUtils.writeStringToFile(file, content, "UTF-8"); 44 | Uri uri = Uri.fromFile(file); 45 | ParseUriHttpBody body = new ParseUriHttpBody(uri, contentType); 46 | 47 | // Check content 48 | ByteArrayOutputStream output = new ByteArrayOutputStream(); 49 | body.writeTo(output); 50 | String contentAgain = output.toString(); 51 | assertEquals(content, contentAgain); 52 | 53 | // No need to check whether content input stream is closed since it is a 54 | // ByteArrayInputStream 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /parse/src/test/java/com/parse/PointerEncoderTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import static org.junit.Assert.assertNotNull; 12 | 13 | import org.json.JSONObject; 14 | import org.junit.Rule; 15 | import org.junit.Test; 16 | import org.junit.rules.ExpectedException; 17 | 18 | public class PointerEncoderTest { 19 | 20 | @Rule public final ExpectedException thrown = ExpectedException.none(); 21 | 22 | @Test 23 | public void testEncodeRelatedObjectWithoutObjectId() { 24 | thrown.expect(IllegalStateException.class); 25 | thrown.expectMessage("unable to encode an association with an unsaved ParseObject"); 26 | 27 | ParseObject parseObject = new ParseObject("TestObject"); 28 | JSONObject jsonObject = (JSONObject) PointerEncoder.get().encode(parseObject); 29 | } 30 | 31 | @Test 32 | public void testEncodeRelatedObjectWithObjectId() { 33 | ParseObject parseObject = new ParseObject("TestObject"); 34 | parseObject.setObjectId("1234"); 35 | JSONObject jsonObject = (JSONObject) PointerEncoder.get().encode(parseObject); 36 | assertNotNull(jsonObject); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /parse/src/test/java/com/parse/ResetPluginsParseTest.java: -------------------------------------------------------------------------------- 1 | package com.parse; 2 | 3 | import org.junit.After; 4 | import org.junit.Before; 5 | 6 | /** 7 | * Automatically takes care of setup and teardown of plugins between tests. The order tests run in 8 | * can be different, so if you see a test failing randomly, the test before it may not be tearing 9 | * down properly, and you may need to have the test class subclass this class. 10 | */ 11 | class ResetPluginsParseTest { 12 | 13 | @Before 14 | public void setUp() throws Exception { 15 | ParseCorePlugins.getInstance().reset(); 16 | ParsePlugins.reset(); 17 | } 18 | 19 | @After 20 | public void tearDown() throws Exception { 21 | ParseCorePlugins.getInstance().reset(); 22 | ParsePlugins.reset(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /parse/src/test/java/com/parse/TaskQueueTestHelper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse; 10 | 11 | import com.parse.boltsinternal.Task; 12 | import com.parse.boltsinternal.TaskCompletionSource; 13 | import java.util.ArrayList; 14 | import java.util.List; 15 | 16 | /** 17 | * Helper class to step through a {@link TaskQueue}. 18 | * 19 | *

{@link #enqueue()} and {@link #dequeue()} works as FIFO list that enqueues an unresolved 20 | * {@link Task} to the end of the {@link TaskQueue} and resolves the first {@link Task}. 21 | */ 22 | public class TaskQueueTestHelper { 23 | 24 | private final Object lock = new Object(); 25 | private final TaskQueue taskQueue; 26 | private final List> pendingTasks = new ArrayList<>(); 27 | 28 | public TaskQueueTestHelper(TaskQueue taskQueue) { 29 | this.taskQueue = taskQueue; 30 | } 31 | 32 | /** Pauses the {@link TaskQueue} by enqueuing an unresolved {@link Task} to it. */ 33 | public void enqueue() { 34 | synchronized (lock) { 35 | final TaskCompletionSource tcs = new TaskCompletionSource(); 36 | taskQueue.enqueue(task -> tcs.getTask()); 37 | pendingTasks.add(tcs); 38 | } 39 | } 40 | 41 | /** Resumes the {@link TaskQueue} by resolving the first {@link Task}. */ 42 | public void dequeue() { 43 | synchronized (lock) { 44 | TaskCompletionSource tcs = pendingTasks.remove(0); 45 | tcs.setResult(null); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /parse/src/test/java/com/parse/TestHelper.java: -------------------------------------------------------------------------------- 1 | package com.parse; 2 | 3 | /** Helper class for testing */ 4 | public class TestHelper { 5 | 6 | public static final int ROBOLECTRIC_SDK_VERSION = 25; 7 | } 8 | -------------------------------------------------------------------------------- /rxjava/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /rxjava/README.md: -------------------------------------------------------------------------------- 1 | # Parse SDK Android RxJava 2 | RxJava 3 support for Parse Android 3 | 4 | ## Dependency 5 | 6 | After including JitPack: 7 | ```gradle 8 | dependencies { 9 | implementation "com.github.parse-community.Parse-SDK-Android:rxjava:latest.version.here" 10 | } 11 | ``` 12 | 13 | ## Usage 14 | RxJava support is provided as an extension method on any `Task`. For example: 15 | ```kotlin 16 | ParseTwitterUtils.logInInBackground(this) 17 | .toSingle() 18 | .subscribeOn(Schedulers.io()) 19 | .observeOn(AndroidSchedulers.mainThread()) 20 | .subscribe({ 21 | Timber.d("Logged in with user ${it.objectId}" 22 | }, { 23 | Timber.e(it) 24 | }) 25 | ``` 26 | Tasks with a Void results, ie. `Task` can be made into a `Completable`. 27 | For example: 28 | ```kotlin 29 | val user = ParseUser.getCurrentUser() 30 | user.put("lastLoggedIn", System.currentTimeMillis()) 31 | user.saveInBackground().toCompletable() 32 | .subscribeOn(Schedulers.io()) 33 | .observeOn(AndroidSchedulers.mainThread()) 34 | .subscribe({ 35 | // yay 36 | Timber.d("user saved") 37 | }, { 38 | Timber.e(it) 39 | }) 40 | ``` 41 | Note that these examples uses RxAndroid as well, which you need to add yourself as a dependency. 42 | 43 | ### From Java 44 | If you need to call this from Java: 45 | ```java 46 | ParseUser user = ParseUser.getCurrentUser(); 47 | Completable completable = ParseRxJavaUtils.toCompletable(user.saveInBackground()); 48 | ``` 49 | You would use similar calls to create a `Single`. 50 | 51 | ## License 52 | Copyright (c) 2015-present, Parse, LLC. 53 | All rights reserved. 54 | 55 | This source code is licensed under the BSD-style license found in the 56 | LICENSE file in the root directory of this source tree. An additional grant 57 | of patent rights can be found in the PATENTS file in the same directory. 58 | -------------------------------------------------------------------------------- /rxjava/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "com.android.library" 2 | apply plugin: "kotlin-android" 3 | apply plugin: "maven-publish" 4 | apply plugin: "io.freefair.android-javadoc-jar" 5 | apply plugin: "io.freefair.android-sources-jar" 6 | 7 | 8 | android { 9 | compileSdkVersion rootProject.ext.compileSdkVersion 10 | 11 | defaultConfig { 12 | minSdkVersion rootProject.ext.minSdkVersion 13 | targetSdkVersion rootProject.ext.targetSdkVersion 14 | } 15 | 16 | lintOptions { 17 | abortOnError false 18 | } 19 | 20 | buildTypes { 21 | debug { 22 | testCoverageEnabled = true 23 | buildConfigField("String","PARSE_VERSION","\"${version}\"") 24 | } 25 | release { 26 | minifyEnabled false 27 | testCoverageEnabled = false 28 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 29 | buildConfigField("String","PARSE_VERSION","\"${version}\"") 30 | } 31 | } 32 | 33 | compileOptions { 34 | sourceCompatibility JavaVersion.VERSION_1_8 35 | targetCompatibility JavaVersion.VERSION_1_8 36 | } 37 | 38 | kotlinOptions { 39 | jvmTarget = "1.8" 40 | } 41 | } 42 | 43 | dependencies { 44 | api "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" 45 | api 'io.reactivex.rxjava3:rxjava:3.1.4' 46 | implementation project(":parse") 47 | } 48 | 49 | afterEvaluate { 50 | publishing { 51 | publications { 52 | release(MavenPublication) { 53 | from components.release 54 | } 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /rxjava/proguard-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parse-community/Parse-SDK-Android/d6926f3dbffb2c2abfb8bb70895eda5601011b36/rxjava/proguard-rules.pro -------------------------------------------------------------------------------- /rxjava/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /rxjava/src/main/java/com/parse/rxjava/Extensions.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("ParseRxJavaUtils") 2 | @file:Suppress("unused") 3 | 4 | package com.parse.rxjava 5 | 6 | import com.parse.boltsinternal.Task 7 | import io.reactivex.rxjava3.core.Completable 8 | import io.reactivex.rxjava3.core.Single 9 | 10 | fun Task.toSingle(): Single { 11 | return Single.defer { 12 | this.waitForCompletion() 13 | if (isFaulted) { 14 | throw error 15 | } 16 | Single.just(result) 17 | } 18 | } 19 | 20 | fun Task.toCompletable(): Completable { 21 | return Completable.defer { 22 | this.waitForCompletion() 23 | if (isFaulted) { 24 | throw error 25 | } 26 | Completable.complete() 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':parse', ':fcm', ':ktx', ':coroutines', 'rxjava', ':google', ':facebook', ':twitter', ':bolts-tasks' 2 | -------------------------------------------------------------------------------- /twitter/README.md: -------------------------------------------------------------------------------- 1 | # Parse Twitter Utils for Android 2 | A utility library to authenticate `ParseUser`s with Twitter. 3 | 4 | ## Dependency 5 | 6 | After including JitPack: 7 | ```gradle 8 | dependencies { 9 | implementation "com.github.parse-community.Parse-SDK-Android:twitter:latest.version.here" 10 | } 11 | ``` 12 | 13 | ## Usage 14 | Extensive docs can be found in the [guide](https://docs.parseplatform.org/android/guide/#twitter-users). The basic steps are: 15 | ```java 16 | // in Application.onCreate(); or somewhere similar 17 | ParseTwitterUtils.initialize("YOUR CONSUMER KEY", "YOUR CONSUMER SECRET"); 18 | ``` 19 | Then later, when your user taps the login button: 20 | ```java 21 | ParseTwitterUtils.logIn(this, new LogInCallback() { 22 | @Override 23 | public void done(ParseUser user, ParseException err) { 24 | if (user == null) { 25 | Log.d("MyApp", "Uh oh. The user cancelled the Twitter login."); 26 | } else if (user.isNew()) { 27 | Log.d("MyApp", "User signed up and logged in through Twitter!"); 28 | } else { 29 | Log.d("MyApp", "User logged in through Twitter!"); 30 | } 31 | } 32 | }); 33 | ``` 34 | 35 | ## License 36 | Copyright (c) 2015-present, Parse, LLC. 37 | All rights reserved. 38 | 39 | This source code is licensed under the BSD-style license found in the 40 | LICENSE file in the root directory of this source tree. An additional grant 41 | of patent rights can be found in the PATENTS file in the same directory. 42 | -------------------------------------------------------------------------------- /twitter/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "com.android.library" 2 | apply plugin: "maven-publish" 3 | apply plugin: "io.freefair.android-javadoc-jar" 4 | apply plugin: "io.freefair.android-sources-jar" 5 | 6 | android { 7 | compileSdkVersion rootProject.ext.compileSdkVersion 8 | 9 | defaultConfig { 10 | minSdkVersion rootProject.ext.minSdkVersion 11 | targetSdkVersion rootProject.ext.targetSdkVersion 12 | } 13 | 14 | lintOptions { 15 | abortOnError false 16 | } 17 | 18 | buildTypes { 19 | debug { 20 | testCoverageEnabled = true 21 | buildConfigField("String","PARSE_VERSION","\"${version}\"") 22 | } 23 | release { 24 | minifyEnabled false 25 | testCoverageEnabled = false 26 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 27 | buildConfigField("String","PARSE_VERSION","\"${version}\"") 28 | } 29 | } 30 | 31 | compileOptions { 32 | sourceCompatibility JavaVersion.VERSION_1_8 33 | targetCompatibility JavaVersion.VERSION_1_8 34 | } 35 | } 36 | 37 | dependencies { 38 | api "androidx.appcompat:appcompat:1.5.0" 39 | api "oauth.signpost:signpost-core:2.1.1" 40 | api "se.akerfeldt:okhttp-signpost:1.1.0" 41 | implementation project(":parse") 42 | 43 | testImplementation "junit:junit:$rootProject.ext.junitVersion" 44 | testImplementation "org.mockito:mockito-core:$rootProject.ext.mockitoCoreVersion" 45 | } 46 | 47 | afterEvaluate { 48 | publishing { 49 | publications { 50 | release(MavenPublication) { 51 | from components.release 52 | } 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /twitter/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 9 | 10 | -------------------------------------------------------------------------------- /twitter/src/main/java/com/parse/twitter/AsyncCallback.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse.twitter; 10 | 11 | public interface AsyncCallback { 12 | void onSuccess(Object result); 13 | 14 | void onCancel(); 15 | 16 | void onFailure(Throwable error); 17 | } 18 | -------------------------------------------------------------------------------- /twitter/src/main/java/com/parse/twitter/OAuth1FlowException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-present, Parse, LLC. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | package com.parse.twitter; 10 | 11 | /** OAuth Flow exception */ 12 | public class OAuth1FlowException extends Exception { 13 | private static final long serialVersionUID = 4272662026279290823L; 14 | private final int errorCode; 15 | private final String description; 16 | private final String failingUrl; 17 | 18 | public OAuth1FlowException(int errorCode, String description, String failingUrl) { 19 | super( 20 | String.format( 21 | "OAuth Flow Error %d: Url: %s Description: %s", 22 | errorCode, failingUrl, description)); 23 | this.errorCode = errorCode; 24 | this.description = description; 25 | this.failingUrl = failingUrl; 26 | } 27 | 28 | public int getErrorCode() { 29 | return errorCode; 30 | } 31 | 32 | public String getDescription() { 33 | return description; 34 | } 35 | 36 | public String getFailingUrl() { 37 | return failingUrl; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /twitter/src/main/res/layout/parse_twitter_dialog_login.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 10 | 11 | 15 | 16 | 21 | 22 | 23 | --------------------------------------------------------------------------------