diff --git a/.codegen.json b/.codegen.json
new file mode 100644
index 000000000..fdb838280
--- /dev/null
+++ b/.codegen.json
@@ -0,0 +1 @@
+{ "engineHash": "7b5a612", "specHash": "86fcc6c", "version": "10.16.0" }
diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md
new file mode 100644
index 000000000..1c852d9ca
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug.md
@@ -0,0 +1,53 @@
+---
+name: Bug
+about: Report a bug found in the SDK
+title: ''
+labels: bug
+assignees: mwwoda, mhagmajer, arjankowski, lukaszsocha2, bartlomiejleszczynski, congminh1254
+---
+
+- [ ] I have checked that the [SDK documentation][sdk-docs] doesn't solve my issue.
+- [ ] I have checked that the [API documentation][api-docs] doesn't solve my issue.
+- [ ] I have searched the [Box Developer Forums][dev-forums] and my issue isn't already reported (or if it has been reported, I have attached a link to it, for reference).
+- [ ] I have searched [Issues in this repo][github-repo] and my issue isn't already reported.
+
+### Description of the Issue
+
+
+
+
+
+
+### Steps to Reproduce
+
+
+
+
+
+
+1. Go to '...'
+2. Click on '....'
+3. Scroll down to '....'
+4. See error
+
+### Expected Behavior
+
+
+
+### Error Message, Including Stack Trace
+
+
+
+
+### Screenshots
+
+
+
+### Versions Used
+
+
+
+[sdk-docs]: https://github.com/box/box-java-sdk-gen/tree/main/docs
+[api-docs]: https://developer.box.com/docs
+[dev-forums]: https://community.box.com/t5/Platform-and-Development-Forum/bd-p/DeveloperForum
+[github-repo]: https://github.com/box/box-java-sdk-gen/search?type=Issues
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644
index 000000000..c3b59c317
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1,14 @@
+blank_issues_enabled: false
+contact_links:
+ - name: SDK documentation
+ url: https://github.com/box/box-java-sdk/tree/main/docs
+ about: Before creating an issue, I have checked that the SDK documentation doesn't solve my issue.
+ - name: API documentation
+ url: https://developer.box.com/docs
+ about: Before creating an issue, I have checked that the API documentation doesn't solve my issue.
+ - name: Box Developer Forums
+ url: https://community.box.com/box-platform-5
+ about: Before creating an issue, I have searched the Box Developer Forums and my issue isn't already reported there.
+ - name: Issues in this repo
+ url: https://github.com/box/box-java-sdk/search?type=Issues
+ about: Before creating an issue, I have searched Issues in this repo and my issue isn't already reported.
diff --git a/.github/ISSUE_TEMPLATE/enhancement.md b/.github/ISSUE_TEMPLATE/enhancement.md
new file mode 100644
index 000000000..ea91c6e44
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/enhancement.md
@@ -0,0 +1,23 @@
+---
+name: Enhancement
+about: Suggest a new feature or change
+title: ''
+labels: enhancement
+assignees: mwwoda, mhagmajer, arjankowski, lukaszsocha2, bartlomiejleszczynski, congminh1254
+---
+
+### Is your feature request related to a problem? Please describe.
+
+
+
+### Describe the solution you'd like
+
+
+
+### Describe alternatives you've considered
+
+
+
+### Additional context
+
+
diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md
new file mode 100644
index 000000000..e8d6a28a2
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/question.md
@@ -0,0 +1,53 @@
+---
+name: Question
+about: Request for Assistance
+title: ''
+labels: question
+assignees: mwwoda, mhagmajer, arjankowski, lukaszsocha2, bartlomiejleszczynski, congminh1254
+---
+
+- [ ] I have checked that the [SDK documentation][sdk-docs] doesn't solve my issue.
+- [ ] I have checked that the [API documentation][api-docs] doesn't solve my issue.
+- [ ] I have searched the [Box Developer Forums][dev-forums] and my issue isn't already reported (or if it has been reported, I have attached a link to it, for reference).
+- [ ] I have searched [Issues in this repo][github-repo] and my issue isn't already reported.
+
+### Description of the Issue
+
+
+
+
+
+
+### Steps to Reproduce
+
+
+
+
+
+
+1. Go to '...'
+2. Click on '....'
+3. Scroll down to '....'
+4. See error
+
+### Expected Behavior
+
+
+
+### Error Message, Including Stack Trace
+
+
+
+
+### Screenshots
+
+
+
+### Versions Used
+
+
+
+[sdk-docs]: https://github.com/box/box-java-sdk-gen/tree/main/docs
+[api-docs]: https://developer.box.com/docs
+[dev-forums]: https://community.box.com/t5/Platform-and-Development-Forum/bd-p/DeveloperForum
+[github-repo]: https://github.com/box/box-java-sdk-gen/search?type=Issues
diff --git a/.github/stale.yml b/.github/stale.yml
new file mode 100644
index 000000000..70cf69f6b
--- /dev/null
+++ b/.github/stale.yml
@@ -0,0 +1,22 @@
+# Number of days of inactivity before an issue becomes stale
+daysUntilStale: 30
+
+# Number of days of inactivity before a stale issue is closed
+daysUntilClose: 7
+
+# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable
+exemptLabels:
+ - enhancement
+ - dontstale
+ - needs-triage
+
+# Label to use when marking an issue as stale
+staleLabel: stale
+
+# Comment to post when marking an issue as stale. Set to `false` to disable
+markComment: >
+ This issue has been automatically marked as stale because it has not been updated in the last 30 days. It will be closed if no further activity occurs within the next 7 days. Feel free to reach out or mention Box SDK team member for further help and resources if they are needed.
+
+# Comment to post when closing a stale issue. Set to `false` to disable
+closeComment: >
+ This issue has been automatically closed due to maximum period of being stale. Thank you for your contribution to Box SDK and feel free to open another PR/issue at any time.
diff --git a/.github/workflows/autoupdate-pr.yml b/.github/workflows/autoupdate-pr.yml
new file mode 100644
index 000000000..085213119
--- /dev/null
+++ b/.github/workflows/autoupdate-pr.yml
@@ -0,0 +1,42 @@
+name: Autoupdate PR
+on:
+ push:
+ branches:
+ - main
+ - sdk-gen
+
+permissions: {}
+
+jobs:
+ update_pull_requests:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+ with:
+ token: ${{ secrets.DISPATCH_ACCESS_TOKEN }}
+
+ - name: Set up Git
+ run: |
+ git config --global user.name 'box-sdk-build'
+ git config --global user.email 'box-sdk-build@box.com'
+
+ - name: Fetch all branches and tags
+ run: git fetch --prune --unshallow
+
+ - name: Auto update pull requests
+ run: |
+ PR_LIST=$(curl -s -H "Authorization: Bearer ${{ secrets.DISPATCH_ACCESS_TOKEN }}" "https://api.github.com/repos/$GITHUB_REPOSITORY/pulls?state=open&base=${{ github.ref_name }}" | jq -r '.[] | .head.ref')
+ for pr_branch in $PR_LIST; do
+ git checkout "$pr_branch"
+ if git merge origin/${{ github.ref_name }}; then
+ git push
+ else
+ # Conflict occurred, resolve by keeping our changes
+ git checkout --ours .
+ git add .
+ git commit -m "Auto resolve conflict by keeping our changes"
+ git push
+ fi
+ done
diff --git a/.github/workflows/build-and-test-daily.yml b/.github/workflows/build-and-test-daily.yml
new file mode 100644
index 000000000..30d2be5ca
--- /dev/null
+++ b/.github/workflows/build-and-test-daily.yml
@@ -0,0 +1,72 @@
+name: Build and Test daily
+on:
+ schedule:
+ - cron: '20 1 * * 1-5'
+
+permissions:
+ contents: read
+
+jobs:
+ build-and-test:
+ runs-on: ubuntu-latest
+ strategy:
+ max-parallel: 1
+ matrix:
+ distribution: ['zulu', 'temurin']
+ java: ['8', '17']
+ name: Java ${{ matrix.java }} (${{ matrix.distribution }})
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ with:
+ ref: main
+ - name: Setup Java
+ uses: actions/setup-java@v4
+ with:
+ distribution: ${{ matrix.distribution }}
+ java-version: ${{ matrix.java }}
+ cache: 'gradle'
+ - name: All Tests
+ env:
+ JWT_CONFIG_BASE_64: ${{ secrets.JWT_CONFIG_BASE_64 }}
+ ADMIN_USER_ID: ${{ secrets.ADMIN_USER_ID }}
+ CLIENT_ID: ${{ secrets.CLIENT_ID }}
+ CLIENT_SECRET: ${{ secrets.CLIENT_SECRET }}
+ USER_ID: ${{ secrets.USER_ID }}
+ ENTERPRISE_ID: ${{ secrets.ENTERPRISE_ID }}
+ BOX_FILE_REQUEST_ID: ${{ secrets.BOX_FILE_REQUEST_ID }}
+ BOX_EXTERNAL_USER_EMAIL: ${{ secrets.BOX_EXTERNAL_USER_EMAIL }}
+ BOX_EXTERNAL_USER_ID: ${{ secrets.BOX_EXTERNAL_USER_ID }}
+ APP_ITEM_ASSOCIATION_FILE_ID: ${{ secrets.APP_ITEM_ASSOCIATION_FILE_ID }}
+ APP_ITEM_ASSOCIATION_FOLDER_ID: ${{ secrets.APP_ITEM_ASSOCIATION_FOLDER_ID }}
+ WORKFLOW_FOLDER_ID: ${{ secrets.WORKFLOW_FOLDER_ID }}
+ APP_ITEM_SHARED_LINK: ${{ secrets.APP_ITEM_SHARED_LINK }}
+ SLACK_AUTOMATION_USER_ID: ${{ secrets.SLACK_AUTOMATION_USER_ID }}
+ SLACK_ORG_ID: ${{ secrets.SLACK_ORG_ID }}
+ SLACK_PARTNER_ITEM_ID: ${{ secrets.SLACK_PARTNER_ITEM_ID }}
+ AUTOMATE_WORKFLOW_FOLDER_ID: ${{ secrets.AUTOMATE_WORKFLOW_FOLDER_ID }}
+ run: ./gradlew check --stacktrace
+ - name: Coverage
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: ./gradlew jacocoTestReport coverallsJacoco
+ notify:
+ name: Send Slack Notification
+ runs-on: ubuntu-latest
+ needs: [build-and-test]
+ if: always()
+ steps:
+ - name: Send Slack Notification
+ env:
+ SLACK_WEBHOOK_TEST_NOTIFICATION_URL: ${{ secrets.SLACK_WEBHOOK_TEST_NOTIFICATION_URL }}
+ BUILD_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
+ run: |
+ if [ "${{ needs.build-and-test.result }}" != "success" ]; then
+ STATUS="Failure ❌"
+ else
+ STATUS="Success ✅"
+ fi
+
+ curl -X POST -H "Content-Type: application/json" \
+ --data "{\"text\":\"<${BUILD_URL}|Daily Tests Job> in *${GITHUB_REPOSITORY}* finished with status: ${STATUS}\"}" \
+ "$SLACK_WEBHOOK_TEST_NOTIFICATION_URL"
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 000000000..84a244e1c
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,60 @@
+name: build
+on:
+ pull_request:
+ branches:
+ - main
+
+permissions:
+ contents: read
+
+jobs:
+ build-and-test:
+ runs-on: ubuntu-latest
+ strategy:
+ max-parallel: 1
+ matrix:
+ distribution: ['zulu', 'temurin']
+ java: ['8', '17']
+ name: Java ${{ matrix.java }} (${{ matrix.distribution }})
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ - name: Setup Java
+ uses: actions/setup-java@v4
+ with:
+ distribution: ${{ matrix.distribution }}
+ java-version: ${{ matrix.java }}
+ cache: 'gradle'
+ - name: All Tests
+ if: ${{ startsWith(github.head_ref, 'codegen-release') && github.actor != 'dependabot[bot]' }}
+ env:
+ JWT_CONFIG_BASE_64: ${{ secrets.JWT_CONFIG_BASE_64 }}
+ ADMIN_USER_ID: ${{ secrets.ADMIN_USER_ID }}
+ CLIENT_ID: ${{ secrets.CLIENT_ID }}
+ CLIENT_SECRET: ${{ secrets.CLIENT_SECRET }}
+ USER_ID: ${{ secrets.USER_ID }}
+ ENTERPRISE_ID: ${{ secrets.ENTERPRISE_ID }}
+ BOX_FILE_REQUEST_ID: ${{ secrets.BOX_FILE_REQUEST_ID }}
+ BOX_EXTERNAL_USER_EMAIL: ${{ secrets.BOX_EXTERNAL_USER_EMAIL }}
+ BOX_EXTERNAL_USER_ID: ${{ secrets.BOX_EXTERNAL_USER_ID }}
+ APP_ITEM_ASSOCIATION_FILE_ID: ${{ secrets.APP_ITEM_ASSOCIATION_FILE_ID }}
+ APP_ITEM_ASSOCIATION_FOLDER_ID: ${{ secrets.APP_ITEM_ASSOCIATION_FOLDER_ID }}
+ WORKFLOW_FOLDER_ID: ${{ secrets.WORKFLOW_FOLDER_ID }}
+ APP_ITEM_SHARED_LINK: ${{ secrets.APP_ITEM_SHARED_LINK }}
+ SLACK_AUTOMATION_USER_ID: ${{ secrets.SLACK_AUTOMATION_USER_ID }}
+ SLACK_ORG_ID: ${{ secrets.SLACK_ORG_ID }}
+ SLACK_PARTNER_ITEM_ID: ${{ secrets.SLACK_PARTNER_ITEM_ID }}
+ AUTOMATE_WORKFLOW_FOLDER_ID: ${{ secrets.AUTOMATE_WORKFLOW_FOLDER_ID }}
+ run: ./gradlew check --stacktrace
+ - name: Smoke Tests
+ if: ${{ !startsWith(github.head_ref, 'codegen-release') && github.actor != 'dependabot[bot]' }}
+ env:
+ JWT_CONFIG_BASE_64: ${{ secrets.JWT_CONFIG_BASE_64 }}
+ CLIENT_ID: ${{ secrets.CLIENT_ID }}
+ CLIENT_SECRET: ${{ secrets.CLIENT_SECRET }}
+ USER_ID: ${{ secrets.USER_ID }}
+ ENTERPRISE_ID: ${{ secrets.ENTERPRISE_ID }}
+ run: ./gradlew test --tests com.box.sdkgen.auth.AuthITest --tests com.box.sdkgen.files.FilesITest --tests com.box.sdkgen.downloads.DownloadsITest --tests com.box.sdkgen.uploads.UploadsITest --stacktrace
+ - name: Build (Dependabot only, no tests)
+ if: github.actor == 'dependabot[bot]'
+ run: ./gradlew assemble --stacktrace
diff --git a/.github/workflows/notify-changelog.yml b/.github/workflows/notify-changelog.yml
new file mode 100644
index 000000000..464fd56b7
--- /dev/null
+++ b/.github/workflows/notify-changelog.yml
@@ -0,0 +1,29 @@
+# A GitHub action that notifies the developer
+# changelog repository of any new releases.
+
+name: Notify changelog
+
+on:
+ # Only trigger for a full release,
+ # ignoring pre-releases and drafts
+ release:
+ types:
+ - released
+
+permissions: {}
+
+jobs:
+ notify:
+ # This job can run on the latest Ubuntu
+ # and it should not take more than 3 minutes
+ runs-on: ubuntu-latest
+ timeout-minutes: 3
+
+ steps:
+ - name: Notify changelog of new release
+ uses: peter-evans/repository-dispatch@v1
+ with:
+ token: ${{ secrets.DISPATCH_ACCESS_TOKEN }}
+ repository: box/box-developer-changelog
+ event-type: new-release-note
+ client-payload: '{"ref": "${{ github.ref }}", "repository": "${{github.repository}}", "labels": "sdks,java", "repo_display_name": "Box Java SDK"}'
diff --git a/.github/workflows/semantic-pr.yml b/.github/workflows/semantic-pr.yml
new file mode 100644
index 000000000..1bf079c95
--- /dev/null
+++ b/.github/workflows/semantic-pr.yml
@@ -0,0 +1,22 @@
+name: Semantic PR
+
+on:
+ pull_request_target:
+ types:
+ - opened
+ - edited
+ - synchronize
+ branches:
+ - main
+
+permissions:
+ contents: read
+
+jobs:
+ main:
+ name: Validate semantic PR title
+ runs-on: ubuntu-latest
+ steps:
+ - uses: amannn/action-semantic-pull-request@v4
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/spell-check-lint.yml b/.github/workflows/spell-check-lint.yml
new file mode 100644
index 000000000..1adbdeb74
--- /dev/null
+++ b/.github/workflows/spell-check-lint.yml
@@ -0,0 +1,27 @@
+name: spell-check-lint
+on:
+ pull_request_target:
+ types: [opened, synchronize, edited]
+ branches:
+ - main
+
+permissions:
+ contents: read
+
+jobs:
+ spellcheck-request-title:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout current repository
+ uses: actions/checkout@v4
+ - name: Checkout spellchecker
+ uses: actions/checkout@v4
+ with:
+ ref: refs/heads/main
+ repository: box/box-sdk-spellchecker
+ token: ${{ secrets.DISPATCH_ACCESS_TOKEN }}
+ path: spellchecker
+ - name: Execute spellchecker
+ uses: ./spellchecker
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.gitignore b/.gitignore
index 21d476036..0df7a29b8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,16 @@
.gradle/
build/
.DS_Store
-src/test/config/config.properties
/target/
+.settings/
+.idea/
+*.iml
+# Eclipse Related
+.project
+.classpath
+.checkstyle
+bin/
+out/
+*.secret
+#Sdkman
+.sdkmanrc
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index dff5f3a5d..000000000
--- a/.travis.yml
+++ /dev/null
@@ -1 +0,0 @@
-language: java
diff --git a/.versionrc b/.versionrc
new file mode 100644
index 000000000..ca2ea3076
--- /dev/null
+++ b/.versionrc
@@ -0,0 +1,34 @@
+{
+ "types": [
+ {
+ "type": "feat",
+ "section": "New Features and Enhancements",
+ "hidden": false
+ },
+ {
+ "type": "fix",
+ "section": "Bug Fixes",
+ "hidden": false
+ },
+ {
+ "type": "chore",
+ "hidden": true
+ },
+ {
+ "type": "docs",
+ "hidden": true
+ },
+ {
+ "type": "style",
+ "hidden": true
+ },
+ {
+ "type": "refactor",
+ "hidden": true
+ },
+ {
+ "type": "test",
+ "hidden": true
+ }
+ ]
+}
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 000000000..9834014ac
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,1123 @@
+# Changelog
+
+All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
+
+## [10.16.0](https://github.com/box/box-java-sdk/compare/v10.15.2...v10.16.0) (2026-08-05)
+
+
+### New Features and Enhancements
+
+* add `is_collaborated_content_available_when_owner_inactive` property (box/box-openapi[#613](https://github.com/box/box-java-sdk/issues/613)) ([#1946](https://github.com/box/box-java-sdk/issues/1946)) ([3a67096](https://github.com/box/box-java-sdk/commit/3a67096b0ab31836ef597daf0f2d8a25ef94013d))
+* Added two missing event types (box/box-openapi[#611](https://github.com/box/box-java-sdk/issues/611)) ([#1940](https://github.com/box/box-java-sdk/issues/1940)) ([a37b296](https://github.com/box/box-java-sdk/commit/a37b2964ab71ab789c359680e6f09ad19a310cf9))
+* Support query APIs (box/box-openapi[#610](https://github.com/box/box-java-sdk/issues/610)) ([#1938](https://github.com/box/box-java-sdk/issues/1938)) ([bf8aaaa](https://github.com/box/box-java-sdk/commit/bf8aaaab213b85d704a2735e6ef65a91f5225386))
+
+### [10.15.2](https://github.com/box/box-java-sdk/compare/v10.15.1...v10.15.2) (2026-07-15)
+
+
+### Bug Fixes
+
+* Fix broken readme link (box/box-codegen[#974](https://github.com/box/box-java-sdk/issues/974)) ([#1929](https://github.com/box/box-java-sdk/issues/1929)) ([f216711](https://github.com/box/box-java-sdk/commit/f2167116cc3a84782b89984abbbd9d75fc7cfc91))
+
+### [10.15.1](https://github.com/box/box-java-sdk/compare/v10.15.0...v10.15.1) (2026-07-10)
+
+
+### Bug Fixes
+
+* Bump `Bouncy Castle` to fix CVE in Java (box/box-codegen[#972](https://github.com/box/box-java-sdk/issues/972)) ([#1918](https://github.com/box/box-java-sdk/issues/1918)) ([4441f03](https://github.com/box/box-java-sdk/commit/4441f037afaf148b300466a23818108a364457ab))
+
+## [10.15.0](https://github.com/box/box-java-sdk/compare/v10.14.0...v10.15.0) (2026-07-09)
+
+
+### New Features and Enhancements
+
+* Add new fields to Hubs(box/box-openapi[#606](https://github.com/box/box-java-sdk/issues/606)) ([#1901](https://github.com/box/box-java-sdk/issues/1901)) ([f590481](https://github.com/box/box-java-sdk/commit/f590481020c9d8670dd1f3a96583b1b7c909c303))
+* Setup common default timeout (box/box-codegen[#965](https://github.com/box/box-java-sdk/issues/965)) ([#1905](https://github.com/box/box-java-sdk/issues/1905)) ([a87b8d1](https://github.com/box/box-java-sdk/commit/a87b8d1e10e0f03f61e56b1a3328714bb78efd17))
+
+## [10.14.0](https://github.com/box/box-java-sdk/compare/v10.13.0...v10.14.0) (2026-06-11)
+
+
+### New Features and Enhancements
+
+* Add new event types (box/box-openapi[#1703](https://github.com/box/box-java-sdk/issues/1703)) (box/box-openapi[#605](https://github.com/box/box-java-sdk/issues/605)) ([#1889](https://github.com/box/box-java-sdk/issues/1889)) ([1747b14](https://github.com/box/box-java-sdk/commit/1747b14eac8ae1b4a96e1da2602d9e6894d6b4ee))
+* Add new parameters to ai extract structured method (box/box-openapi[#604](https://github.com/box/box-java-sdk/issues/604)) ([#1888](https://github.com/box/box-java-sdk/issues/1888)) ([09c342f](https://github.com/box/box-java-sdk/commit/09c342f5979f0bdb1a93c822273638aa0e60dbdf))
+* Expose `errorCode` in sign request schemas (box/box-openapi[#601](https://github.com/box/box-java-sdk/issues/601)) ([#1887](https://github.com/box/box-java-sdk/issues/1887)) ([70dc787](https://github.com/box/box-java-sdk/commit/70dc787c16f096070428af8e2caa02be3ba6fcc0))
+
+## [10.13.0](https://github.com/box/box-java-sdk/compare/v10.12.0...v10.13.0) (2026-06-03)
+
+
+### New Features and Enhancements
+
+* Convert Note Public API (box/box-openapi[#599](https://github.com/box/box-java-sdk/issues/599)) ([#1855](https://github.com/box/box-java-sdk/issues/1855)) ([e396190](https://github.com/box/box-java-sdk/commit/e396190406633a2071dacbbe0b67c4a92b03c7e0))
+
+## [10.12.0](https://github.com/box/box-java-sdk/compare/v10.11.0...v10.12.0) (2026-05-20)
+
+
+### New Features and Enhancements
+
+* add failure related fields to `DocGenJob` (box/box-openapi[#598](https://github.com/box/box-java-sdk/issues/598)) ([#1849](https://github.com/box/box-java-sdk/issues/1849)) ([8d72727](https://github.com/box/box-java-sdk/commit/8d72727367cb0b1643db9488d0659264ad7aa45e))
+* Add new event types (box/box-openapi[#597](https://github.com/box/box-java-sdk/issues/597)) ([#1840](https://github.com/box/box-java-sdk/issues/1840)) ([aa439b4](https://github.com/box/box-java-sdk/commit/aa439b475e26f761f7f3aca8e6b5eec55d472838))
+* Sanitize request body in `BoxAPIError` (box/box-codegen[#948](https://github.com/box/box-java-sdk/issues/948)) ([#1844](https://github.com/box/box-java-sdk/issues/1844)) ([39b6fcc](https://github.com/box/box-java-sdk/commit/39b6fccb3067364d9f4eaa3a0f9627eabd526b13))
+
+## [10.11.0](https://github.com/box/box-java-sdk/compare/v10.10.0...v10.11.0) (2026-05-06)
+
+
+### ⚠ BREAKING CHANGES
+
+* Mark `id` field of `AIAgentReference` required (box/box-openapi[#1629](https://github.com/box/box-java-sdk/issues/1629)) (box/box-openapi[#595](https://github.com/box/box-java-sdk/issues/595)) ([#1827](https://github.com/box/box-java-sdk/issues/1827)) ([1c59b46](https://github.com/box/box-java-sdk/commit/1c59b46e90ef5d33ff85eff45125cefe00e5e950))
+
+### Bug Fixes
+
+* Fix metadata template schema (box/box-openapi[#596](https://github.com/box/box-java-sdk/issues/596)) ([#1828](https://github.com/box/box-java-sdk/issues/1828)) ([193718a](https://github.com/box/box-java-sdk/commit/193718a5eb07e0816f7fc23daad3ebbe5cba993b))
+* Mark `id` field of `AIAgentReference` required (box/box-openapi[#1629](https://github.com/box/box-java-sdk/issues/1629)) (box/box-openapi[#595](https://github.com/box/box-java-sdk/issues/595)) ([#1827](https://github.com/box/box-java-sdk/issues/1827)) ([1c59b46](https://github.com/box/box-java-sdk/commit/1c59b46e90ef5d33ff85eff45125cefe00e5e950))
+
+## [10.10.0](https://github.com/box/box-java-sdk/compare/v10.9.0...v10.10.0) (2026-04-30)
+
+
+### Bug Fixes
+
+* Fix java `oneOf` serialization (box/box-codegen[#942](https://github.com/box/box-java-sdk/issues/942)) ([#1806](https://github.com/box/box-java-sdk/issues/1806)) ([dcd5df6](https://github.com/box/box-java-sdk/commit/dcd5df60f3545983209e58c50ab1648a6d5fb167))
+
+
+### New Features and Enhancements
+
+* Automate Public API (box/box-openapi[#594](https://github.com/box/box-java-sdk/issues/594)) ([#1820](https://github.com/box/box-java-sdk/issues/1820)) ([41e859a](https://github.com/box/box-java-sdk/commit/41e859acf78844b0a2e28d3d14ca721b88e2a108))
+
+## [10.9.0](https://github.com/box/box-java-sdk/compare/v10.8.0...v10.9.0) (2026-04-22)
+
+
+### New Features and Enhancements
+
+* Add `max_extension_length` field to Retention Policies (box/box-openapi[#593](https://github.com/box/box-java-sdk/issues/593)) ([#1799](https://github.com/box/box-java-sdk/issues/1799)) ([fc91872](https://github.com/box/box-java-sdk/commit/fc91872b19e16d919fd641e1a6b461639ebbdc54))
+
+## [10.8.0](https://github.com/box/box-java-sdk/compare/v10.7.0...v10.8.0) (2026-04-16)
+
+
+### New Features and Enhancements
+
+* **boxsdkgen:** Update `retentionLength` field to accept both string and integer (box/box-codegen#932) (#1776)
+
+### Bug Fixes
+
+* **boxsdkgen:** Update `retentionLength` field to accept both string and integer (box/box-codegen[#932](https://github.com/box/box-java-sdk/issues/932)) ([#1776](https://github.com/box/box-java-sdk/issues/1776)) ([31f4b04](https://github.com/box/box-java-sdk/commit/31f4b043116fb6ffde0834593fb876a636678346))
+* Fix error propagation in Java (box/box-codegen[#936](https://github.com/box/box-java-sdk/issues/936)) ([#1780](https://github.com/box/box-java-sdk/issues/1780)) ([257fdb2](https://github.com/box/box-java-sdk/commit/257fdb2b6b15ffe6b0d9b48613d5fcea481c42bd))
+* Fix serialization of `OffsetDateTime` (box/box-codegen[#935](https://github.com/box/box-java-sdk/issues/935)) ([#1778](https://github.com/box/box-java-sdk/issues/1778)) ([d9ff755](https://github.com/box/box-java-sdk/commit/d9ff7553fb958811b3344c7b98828a57a8134531))
+
+## [10.7.0](https://github.com/box/box-java-sdk/compare/v10.6.0...v10.7.0) (2026-04-01)
+
+
+### ⚠ BREAKING CHANGES
+
+* Correct search content type 'tags' to match API (box/box-openapi#591) (#1766)
+* Align `LegalHoldPolicyAssignedItem` with API (box/box-openapi#1554) (box/box-openapi#590) (#1762)
+
+### Bug Fixes
+
+* Align `LegalHoldPolicyAssignedItem` with API (box/box-openapi[#1554](https://github.com/box/box-java-sdk/issues/1554)) (box/box-openapi[#590](https://github.com/box/box-java-sdk/issues/590)) ([#1762](https://github.com/box/box-java-sdk/issues/1762)) ([8f82b46](https://github.com/box/box-java-sdk/commit/8f82b46afe978342fb93af6ad31006342a1f5b5a))
+* Correct search content type 'tags' to match API (box/box-openapi[#591](https://github.com/box/box-java-sdk/issues/591)) ([#1766](https://github.com/box/box-java-sdk/issues/1766)) ([52b408e](https://github.com/box/box-java-sdk/commit/52b408ec649dd7d36d3ecc6f2506f34afde644bd))
+
+
+### New Features and Enhancements
+
+* Add `reference` to `AI` and `parent_id` to `HubsItems` (box/box-openapi[#588](https://github.com/box/box-java-sdk/issues/588)) ([#1741](https://github.com/box/box-java-sdk/issues/1741)) ([fccccb7](https://github.com/box/box-java-sdk/commit/fccccb766d961e9badd1cde274595e07ba88b7a2))
+* Support Hub Document API (box/box-codegen[#930](https://github.com/box/box-java-sdk/issues/930)) ([#1767](https://github.com/box/box-java-sdk/issues/1767)) ([8b2ef9f](https://github.com/box/box-java-sdk/commit/8b2ef9f003b76f88ea0481a0539efad38ae63a3b))
+
+## [10.6.0](https://github.com/box/box-java-sdk/compare/v10.5.0...v10.6.0) (2026-03-18)
+
+
+### New Features and Enhancements
+
+* add `canPublicSharedLinkBeCreated` to `Hubs` (box/box-codegen[#928](https://github.com/box/box-java-sdk/issues/928)) ([#1737](https://github.com/box/box-java-sdk/issues/1737)) ([50c2bc9](https://github.com/box/box-java-sdk/commit/50c2bc9dcaaac2445876d2d305c5547e434105b1))
+* Add configurable timeouts for SDKs (box/box-codegen[#924](https://github.com/box/box-java-sdk/issues/924)) ([#1730](https://github.com/box/box-java-sdk/issues/1730)) ([1fa2c9a](https://github.com/box/box-java-sdk/commit/1fa2c9ad954ed01ec387b7a1d1018c62d5de3867))
+
+## [10.5.0](https://github.com/box/box-java-sdk/compare/v10.4.0...v10.5.0) (2026-02-11)
+
+
+### Bug Fixes
+
+* Correct enum value for legal hold policy changes (box/box-openapi[#581](https://github.com/box/box-java-sdk/issues/581)) ([#1695](https://github.com/box/box-java-sdk/issues/1695)) ([f9e3d5e](https://github.com/box/box-java-sdk/commit/f9e3d5ee3c54d074d5b5aef1c5c01599c0b8c9e9))
+* Move assigning default values from builder constructor to `build()` method (box/box-codegen[#922](https://github.com/box/box-java-sdk/issues/922)) ([#1716](https://github.com/box/box-java-sdk/issues/1716)) ([0a9dbe3](https://github.com/box/box-java-sdk/commit/0a9dbe3bebb618a0a33c53cd1e9a90582c0504e2))
+
+
+### New Features and Enhancements
+
+* add confidence scores for structured extract (box/box-openapi[#582](https://github.com/box/box-java-sdk/issues/582)) ([#1697](https://github.com/box/box-java-sdk/issues/1697)) ([112b954](https://github.com/box/box-java-sdk/commit/112b9545d0ef1839d007bf215356b31e658daad8))
+* add signer language, cancel sign request reason (box/box-openapi[#584](https://github.com/box/box-java-sdk/issues/584)) ([#1721](https://github.com/box/box-java-sdk/issues/1721)) ([3c94cfc](https://github.com/box/box-java-sdk/commit/3c94cfc69d6be2db40b72bf2902ee095824e0796))
+* Add watermarking permissions and sources information (box/box-openapi[#579](https://github.com/box/box-java-sdk/issues/579)) ([#1688](https://github.com/box/box-java-sdk/issues/1688)) ([215c0f3](https://github.com/box/box-java-sdk/commit/215c0f3cce4042332373eec66b1695ed958f1f3b))
+
+## [10.4.0](https://github.com/box/box-java-sdk/compare/v10.3.0...v10.4.0) (2025-12-19)
+
+
+### Bug Fixes
+
+* add taxonomy to Metadata Field (read) definition (box/box-openapi[#572](https://github.com/box/box-java-sdk/issues/572)) ([#1644](https://github.com/box/box-java-sdk/issues/1644)) ([61235da](https://github.com/box/box-java-sdk/commit/61235da7d51a64845d344a8286821e59b217a848))
+* fix `RetryAfter` function when there's no `Retry-After` header (box/box-codegen[#903](https://github.com/box/box-java-sdk/issues/903)) ([#1622](https://github.com/box/box-java-sdk/issues/1622)) ([f135e2b](https://github.com/box/box-java-sdk/commit/f135e2b62d4b2d2d266ab40b3b366c8c7968d2db))
+
+
+### New Features and Enhancements
+
+* add Metadata Taxonomies api (box/box-openapi[#569](https://github.com/box/box-java-sdk/issues/569)) ([#1630](https://github.com/box/box-java-sdk/issues/1630)) ([d1e8924](https://github.com/box/box-java-sdk/commit/d1e8924ad123e5fcbf014be50fbbf52ea45d546b))
+* text input validation for Box Sign (box/box-openapi[#568](https://github.com/box/box-java-sdk/issues/568)) ([#1624](https://github.com/box/box-java-sdk/issues/1624)) ([8c5b5c1](https://github.com/box/box-java-sdk/commit/8c5b5c17285c1c0d4a644eb8187dac92f1f96f28))
+* Treat `nullable` fields as Optional (box/box-codegen[#906](https://github.com/box/box-java-sdk/issues/906)) ([#1634](https://github.com/box/box-java-sdk/issues/1634)) ([cacc729](https://github.com/box/box-java-sdk/commit/cacc729dc246c914eb1a6d8281f4261c96711dc1))
+
+## [10.3.0](https://github.com/box/box-java-sdk/compare/v10.2.0...v10.3.0) (2025-12-10)
+
+
+### New Features and Enhancements
+
+* Remove `confidence_score` and `include_confidence_score` from AI extract (box/box-openapi[#567](https://github.com/box/box-java-sdk/issues/567)) ([#1615](https://github.com/box/box-java-sdk/issues/1615)) ([0a069cd](https://github.com/box/box-java-sdk/commit/0a069cdecc4837d8bdb6f1e91401d88c58af5a92))
+* Support new sign request metadata (box/box-openapi[#565](https://github.com/box/box-java-sdk/issues/565)) ([#1599](https://github.com/box/box-java-sdk/issues/1599)) ([b3c46bb](https://github.com/box/box-java-sdk/commit/b3c46bbf2f2f7b9b25befcd6442a4e5c9a92e790))
+
+## [10.2.0](https://github.com/box/box-java-sdk/compare/v10.1.0...v10.2.0) (2025-11-19)
+
+
+### Bug Fixes
+
+* Fix parsing `OffsetDateTime` from String (box/box-codegen[#887](https://github.com/box/box-java-sdk/issues/887)) ([#1582](https://github.com/box/box-java-sdk/issues/1582)) ([d1288c4](https://github.com/box/box-java-sdk/commit/d1288c4804b032d5211d664c396e212a08a5775b))
+
+
+### New Features and Enhancements
+
+* Support GET enterprise configuration API (box/box-openapi[#559](https://github.com/box/box-java-sdk/issues/559)) ([#1519](https://github.com/box/box-java-sdk/issues/1519)) ([88dd8d2](https://github.com/box/box-java-sdk/commit/88dd8d2867d85ca8fc3b48d2aee61060ef328821))
+* Disable OkHttp auto retries on connection failure (box/box-codegen[#874](https://github.com/box/box-java-sdk/issues/874)) ([#1541](https://github.com/box/box-java-sdk/issues/1541)) ([c2bd137](https://github.com/box/box-java-sdk/commit/c2bd137e469b9e67a14a33bb073107ff5db44175))
+* Support Archive API (box/box-openapi[#563](https://github.com/box/box-java-sdk/issues/563)) ([#1553](https://github.com/box/box-java-sdk/issues/1553)) ([609e8bb](https://github.com/box/box-java-sdk/commit/609e8bb5eb7143281543dcfaada23f2649acae9d))
+
+## [10.1.0](https://github.com/box/box-java-sdk/compare/v10.0.0...v10.1.0) (2025-10-06)
+
+
+### Bug Fixes
+
+* Allow flexible key-value data in `AiExtractResponse.answer` and `Event.additionalDetails` (box/box-openapi[#556](https://github.com/box/box-java-sdk/issues/556)) ([#1470](https://github.com/box/box-java-sdk/issues/1470)) ([e215a5f](https://github.com/box/box-java-sdk/commit/e215a5f2502e694421a05d8da550d2b305c09460))
+* Make `role` parameter of update collaboration optional (box/box-openapi[#557](https://github.com/box/box-java-sdk/issues/557)) ([#1479](https://github.com/box/box-java-sdk/issues/1479)) ([6896386](https://github.com/box/box-java-sdk/commit/6896386c6086996399066b09b5afc998a5a95ca4))
+
+
+### New Features and Enhancements
+
+* Add `Javadoc` comments (box/box-codegen[#839](https://github.com/box/box-java-sdk/issues/839)) ([#1465](https://github.com/box/box-java-sdk/issues/1465)) ([c72407d](https://github.com/box/box-java-sdk/commit/c72407dc77cc67f3a178d607a2b1bd4e90e832a8))
+
+## [10.0.0](https://github.com/box/box-java-sdk/compare/v4.16.3...v10.0.0) (2025-09-17)
+
+Introducing **`Box SDK v10`**, a major release designed to elevate your developer experience and streamline integration with Box Content Cloud. Currently available as a separate [`sdk-gen`](https://github.com/box/box-java-sdk/tree/sdk-gen) branch, `v10` will ultimately become the main branch.
+
+### Breaking Changes
+
+- This SDK version is auto-generated and introduces a new interface for all methods. Extensive documentation is available [here](https://github.com/box/box-java-sdk/tree/sdk-gen/docs).
+
+### What's New in `v10`
+
+- **Full API Support** — Complete coverage of the Box API ecosystem, giving you access to all the latest features and functionalities to build feature-rich applications.
+
+- **Rapid API Updates** — Our new auto-generation approach enables Box API additions within days, ensuring you can leverage the most up-to-date features without delay.
+
+- **Embedded Documentation** — All objects and parameters are documented directly in the SDK source code, keeping essential information in one place.
+
+- **Enhanced Convenience Methods** — New methods for authentication, chunk uploads, automatic retries, retry strategy, and more.
+
+### Important Notes
+
+This version includes the Box Next Generation SDK artifact, previously developed in parallel to core Box SDKs. To facilitate migration and provide access to the newest features, we'll soon release an additional major version combining both artifacts. Migration to `v10` includes breaking changes, please review the [migration guide](https://github.com/box/box-java-sdk/blob/sdk-gen/migration-guides/from-v4-to-v10.md) for details. For more information, see the [SDK versioning strategy document](https://developer.box.com/guides/tooling/sdks/sdk-versioning). Follow developer changelog for future updates.
+
+---
+
+### What’s New Compared to [Java SDK Gen](https://github.com/box/box-java-sdk-gen) `v0.8.1`
+
+#### ⚠ BREAKING CHANGES
+
+* Change names of unions (box/box-codegen[#787](https://github.com/box/box-java-sdk/issues/787)) ([#1359](https://github.com/box/box-java-sdk/issues/1359)) ([114e778](https://github.com/box/box-java-sdk/commit/114e7785031e19fb58933f231e656a991b5effb7))
+* Remove unused models from schemas (box/box-openapi[#547](https://github.com/box/box-java-sdk/issues/547)) ([#1354](https://github.com/box/box-java-sdk/issues/1354)) ([e031308](https://github.com/box/box-java-sdk/commit/e031308f102137351238bf3823372150d3927442)), closes [box/box-openapi#542](https://github.com/box/box-openapi/issues/542) [box/box-openapi#544](https://github.com/box/box-openapi/issues/544) [box/box-codegen#781](https://github.com/box/box-codegen/issues/781) [box/box-openapi#545](https://github.com/box/box-openapi/issues/545) [box/box-codegen#782](https://github.com/box/box-codegen/issues/782)
+* Replace `Date` with `OffsetDateTime` (box/box-codegen[#826](https://github.com/box/box-java-sdk/issues/826)) ([#1419](https://github.com/box/box-java-sdk/issues/1419)) ([ed04407](https://github.com/box/box-java-sdk/commit/ed04407e8effa8811bc85023783097f8a95e5223))
+
+#### New Features and Enhancements
+
+* Add proxy support (box/box-codegen[#830](https://github.com/box/box-java-sdk/issues/830)) ([#1424](https://github.com/box/box-java-sdk/issues/1424)) ([cc53247](https://github.com/box/box-java-sdk/commit/cc532475cdaf5ec3fd710149b41a6e7b04dcd32f))
+
+For more details check [migration guide](https://github.com/box/box-java-sdk/blob/sdk-gen/migration-guides/from-box-java-sdk-gen-v0-to-box-java-sdk-v10.md) from `box-java-sdk-gen` `v0` to `box-java-sdk` `v10`.
+
+### [4.16.3](https://github.com/box/box-java-sdk/compare/v4.16.2...v4.16.3) (2025-07-23)
+
+
+### Bug Fixes:
+
+* Fix compare message webhook message signature ([#1315](https://github.com/box/box-java-sdk/issues/1315)) ([e2d407d](https://github.com/box/box-java-sdk/commit/e2d407ded3370ffee6eb074044fd562629a904be))
+* Fix File Request Copy method to return valid data ([#1320](https://github.com/box/box-java-sdk/issues/1320)) ([8392a43](https://github.com/box/box-java-sdk/commit/8392a437c1a738bebb4e7d0f84d6bf833c76bdf3))
+
+### [4.16.2](https://github.com/box/box-java-sdk/compare/v4.16.1...v4.16.2) (2025-06-02)
+
+
+### Bug Fixes:
+
+* Fix parsing `downloadFileCount` property for `BoxZipDownloadStatus` ([50c2249](https://github.com/box/box-java-sdk/commit/50c2249ff5e0f0d1fdc99c9ff8786e9c134e58eb))
+
+### [4.16.1](https://github.com/box/box-java-sdk/compare/v4.16.0...v4.16.1) (2025-04-29)
+
+
+### Bug Fixes:
+
+* use `Locale.ROOT` to prevent issues with non-US locales ([#1306](https://github.com/box/box-java-sdk/issues/1306)) ([f083092](https://github.com/box/box-java-sdk/commit/f083092d5fdac37c93493945ab0c05ecdcdbc838))
+
+## [4.16.0](https://github.com/box/box-java-sdk/compare/v4.15.3...v4.16.0) (2025-04-15)
+
+
+### New Features and Enhancements:
+
+* Bump version of `zstd-jni` ([#1302](https://github.com/box/box-java-sdk/issues/1302)) ([9ebf8b5](https://github.com/box/box-java-sdk/commit/9ebf8b5d16c0ab8f4aa19849fdaa86935d38b294))
+
+### [4.15.3](https://github.com/box/box-java-sdk/compare/v4.15.2...v4.15.3) (2025-03-12)
+
+
+### Bug Fixes:
+
+* trim `content-length` header value ([#1297](https://github.com/box/box-java-sdk/issues/1297)) ([fa11d14](https://github.com/box/box-java-sdk/commit/fa11d141edf511eabc5f2398e55dc411d0cdcd31))
+
+### [4.15.2](https://github.com/box/box-java-sdk/compare/v4.15.1...v4.15.2) (2025-02-26)
+
+
+### Bug Fixes:
+
+* Improve logging for API Request and API Response ([#1295](https://github.com/box/box-java-sdk/issues/1295)) ([6eb1f57](https://github.com/box/box-java-sdk/commit/6eb1f57a584571b46daa14d045a36bca382493fa))
+
+### [4.15.1](https://github.com/box/box-java-sdk/compare/v4.15.0...v4.15.1) (2025-02-24)
+
+
+### Bug Fixes:
+
+* Fix parsing content length header ([#1292](https://github.com/box/box-java-sdk/issues/1292)) ([3bcf788](https://github.com/box/box-java-sdk/commit/3bcf788dd9849305aa2cc85b8e5f88b35803ecb2))
+
+## [4.15.0](https://github.com/box/box-java-sdk/compare/v4.14.0...v4.15.0) (2025-02-19)
+
+
+### New Features and Enhancements:
+
+* Add `canNonOwnersViewCollaborators` flag to `Folder` ([#1288](https://github.com/box/box-java-sdk/issues/1288)) ([9119adc](https://github.com/box/box-java-sdk/commit/9119adceae35e892e73ed61ed30cf82ad912960d))
+* Support `zstd` encoding for downloads ([#1287](https://github.com/box/box-java-sdk/issues/1287)) ([0e3c4c0](https://github.com/box/box-java-sdk/commit/0e3c4c07e65ef1887cd5c393e3daf98aeb50ee47))
+
+### Bug Fixes:
+
+* Fix AI dialogue history ([#1289](https://github.com/box/box-java-sdk/issues/1289)) ([29b6519](https://github.com/box/box-java-sdk/commit/29b651987a5cbeead4b129cab20970f983cb6889))
+
+## [4.14.0](https://github.com/box/box-java-sdk/compare/v4.13.1...v4.14.0) (2025-01-22)
+
+
+### New Features and Enhancements:
+
+* Support downloading file from shared link ([#1282](https://github.com/box/box-java-sdk/issues/1282)) ([9b7f28b](https://github.com/box/box-java-sdk/commit/9b7f28b0288977513b0db3ed4f800647545e1f2c))
+
+### Bug Fixes:
+
+* Remove sensitive data when `BoxAPIException` logs request ([#1284](https://github.com/box/box-java-sdk/issues/1284)) ([f1e226f](https://github.com/box/box-java-sdk/commit/f1e226f710c301202acff067ef34687ddbb57b7b))
+* Support creating ongoing Legal Hold policy with start date ([#1281](https://github.com/box/box-java-sdk/issues/1281)) ([d9564e2](https://github.com/box/box-java-sdk/commit/d9564e2e86ea110af933ca3dd0f728111d7140ae))
+
+### [4.13.1](https://github.com/box/box-java-sdk/compare/v4.13.0...v4.13.1) (2024-11-29)
+
+
+### Bug Fixes:
+
+* Correctly calculate `Content-Length` when reading from a stream ([#1277](https://github.com/box/box-java-sdk/issues/1277)) ([b1d5371](https://github.com/box/box-java-sdk/commit/b1d5371491abe1729a95eb9dc39d375135c8681d))
+
+## [4.13.0](https://github.com/box/box-java-sdk/compare/v4.12.0...v4.13.0) (2024-11-21)
+
+
+### New Features and Enhancements:
+
+* Enforce exact byte reading from `Content-Length` header for `BoxFile` representation ([#1274](https://github.com/box/box-java-sdk/issues/1274)) ([0b45cdb](https://github.com/box/box-java-sdk/commit/0b45cdb74c21996d1dfea505d25430a1fa9ee730))
+* Expose `getVersionByID` method on `BoxFile` ([#1268](https://github.com/box/box-java-sdk/issues/1268)) ([6ea70f7](https://github.com/box/box-java-sdk/commit/6ea70f79ad39dd9a427ee574b5536d0ab1e3a9a4))
+* make `tryRestoreUsingAccessTokenCache` in Box API connection public ([#1272](https://github.com/box/box-java-sdk/issues/1272)) ([50f5a61](https://github.com/box/box-java-sdk/commit/50f5a61184bd1a17a17e811536166f9f8e081a13))
+
+### Bug Fixes:
+
+* Fix `accessToken` locking mechanism ([#1270](https://github.com/box/box-java-sdk/issues/1270)) ([5eb4c93](https://github.com/box/box-java-sdk/commit/5eb4c93bd3653b28dc7def747779d008369f486a))
+
+## [4.12.0](https://github.com/box/box-java-sdk/compare/v4.11.1...v4.12.0) (2024-10-17)
+
+
+### New Features and Enhancements:
+
+* Support AI Agent ([#1265](https://github.com/box/box-java-sdk/issues/1265)) ([3cb2c7c](https://github.com/box/box-java-sdk/commit/3cb2c7c275761a24be9403a6a2b41d0725ba8d9b))
+* Support AI extract and AI extract structured ([#1266](https://github.com/box/box-java-sdk/issues/1266)) ([7ba90b9](https://github.com/box/box-java-sdk/commit/7ba90b96070a32b3e2ac60e5c55bd04d0a5973c0))
+
+### [4.11.1](https://github.com/box/box-java-sdk/compare/v4.11.0...v4.11.1) (2024-07-16)
+
+
+### Bug Fixes:
+
+* Fix order of file upload multipart request ([#1261](https://github.com/box/box-java-sdk/issues/1261)) ([7200ac7](https://github.com/box/box-java-sdk/commit/7200ac77888b3639f2c294486be278e316efcfb0))
+
+## [4.11.0](https://github.com/box/box-java-sdk/compare/v4.10.0...v4.11.0) (2024-07-15)
+
+
+### New Features and Enhancements:
+
+* Allow overriding creation of OkHttp Call ([#1257](https://github.com/box/box-java-sdk/issues/1257)) ([bd6fde6](https://github.com/box/box-java-sdk/commit/bd6fde6689bebe6cb5889c91214db68e08a4ec8b))
+
+### Bug Fixes:
+
+* Add missing fields when update classification template ([#1255](https://github.com/box/box-java-sdk/issues/1255)) ([f17f817](https://github.com/box/box-java-sdk/commit/f17f817bde5a412358bf3de8e489ed080715ec4b))
+* Fix deserializing permissions for `BoxFile` and `BoxFolder` ([#1256](https://github.com/box/box-java-sdk/issues/1256)) ([f088448](https://github.com/box/box-java-sdk/commit/f08844889800a01f7c78941036f6228502fca8b0))
+
+## [4.10.0](https://github.com/box/box-java-sdk/compare/v4.9.1...v4.10.0) (2024-06-06)
+
+
+### New Features and Enhancements:
+
+* Overload the `getRepresentationContent` method with a `maxRetries` parameter ([#1251](https://github.com/box/box-java-sdk/issues/1251)) ([d26bd4f](https://github.com/box/box-java-sdk/commit/d26bd4f5a141150a372159bc3867abbbbdda1406))
+* Support `login_required`, `password`, `suppress_nofitications`, `verification_phone_number` and `additional_info` fields in sign request ([#1250](https://github.com/box/box-java-sdk/issues/1250)) ([3ee55b3](https://github.com/box/box-java-sdk/commit/3ee55b3613c5f5fa92cdd4a17c0cb3e2cc86a9a4))
+
+### [4.9.1](https://github.com/box/box-java-sdk/compare/v4.9.0...v4.9.1) (2024-05-20)
+
+
+### Bug Fixes:
+
+* Bumped `org.bouncycastle:bcprov-jdk18on:1.78.1` and `org.bouncycastle:bcpkix-jdk18on:1.78.1` ([#1246](https://github.com/box/box-java-sdk/issues/1246)) ([0557bed](https://github.com/box/box-java-sdk/commit/0557bed2b65d1be717b64a612d74fca73ba21096))
+
+## [4.9.0](https://github.com/box/box-java-sdk/compare/v4.8.0...v4.9.0) (2024-05-06)
+
+
+### New Features and Enhancements:
+
+* Support AI API ([#1243](https://github.com/box/box-java-sdk/issues/1243)) ([4e64f27](https://github.com/box/box-java-sdk/commit/4e64f27874fabf36f7fbf385ca4a60683f4a7670))
+* Support pagination of file versions ([#1240](https://github.com/box/box-java-sdk/issues/1240)) ([7e7af3f](https://github.com/box/box-java-sdk/commit/7e7af3f6e40a44522a7649817547846e3f633fc8))
+
+### Bug Fixes:
+
+* Support create empty shared link ([#1241](https://github.com/box/box-java-sdk/issues/1241)) ([0c86487](https://github.com/box/box-java-sdk/commit/0c86487848e5004a713873baffa2d9dcc63b1502))
+* Update exception message for get representation content ([#1239](https://github.com/box/box-java-sdk/issues/1239)) ([a608f9a](https://github.com/box/box-java-sdk/commit/a608f9a4350b723e9f07eaf00af45243737a17c9))
+
+## [4.8.0](https://github.com/box/box-java-sdk/compare/v4.7.0...v4.8.0) (2024-02-27)
+
+
+### New Features and Enhancements:
+
+* allow modifying `BoxAPIRequest` URL ([#1236](https://github.com/box/box-java-sdk/issues/1236)) ([eaea019](https://github.com/box/box-java-sdk/commit/eaea0193ab7e72b73746ea85806e62468825bbce))
+* Bumped `org.bouncycastle:bcprov-jdk18on:1.77` and `org.bouncycastle:bcpkix-jdk18on:1.77` ([#1237](https://github.com/box/box-java-sdk/issues/1237)) ([6c7fe7b](https://github.com/box/box-java-sdk/commit/6c7fe7b74dbfb34e729fcecf8a29a1d3a1ba596f)), closes [#1235](https://github.com/box/box-java-sdk/issues/1235)
+
+### Bug Fixes:
+
+* fix download for empty files ([#1231](https://github.com/box/box-java-sdk/issues/1231)) ([0e2230b](https://github.com/box/box-java-sdk/commit/0e2230b0be36f6bfb35f1d6b9dd4ba58e4d125ec))
+* stop using `SharedLinkAPIConnection` in `getSharedItem()` ([#1234](https://github.com/box/box-java-sdk/issues/1234)) ([9f9af8e](https://github.com/box/box-java-sdk/commit/9f9af8e22b4a38dc9a31a611ff1b962966bbd6b5))
+
+## [4.7.0](https://github.com/box/box-java-sdk/compare/v4.6.1...v4.7.0) (2024-01-16)
+
+
+### New Features and Enhancements:
+
+* Add `signer_group_id` for signer in sign request ([#1220](https://github.com/box/box-java-sdk/issues/1220)) ([f560db8](https://github.com/box/box-java-sdk/commit/f560db8d5587406099066803789d16374ec7dbb9))
+* Introduce `IPrivateKeyDecryptor` to allow using custom cryptography provider ([#1226](https://github.com/box/box-java-sdk/issues/1226)) ([727e6d7](https://github.com/box/box-java-sdk/commit/727e6d71ee375a48b4241a26a093becfe0965898))
+
+### Bug Fixes:
+
+* Remove delete classification ([#1222](https://github.com/box/box-java-sdk/issues/1222)) ([9814038](https://github.com/box/box-java-sdk/commit/981403896b4cd16a42c9feeecf30e75e1e8fa072))
+
+### [4.6.1](https://github.com/box/box-java-sdk/compare/v4.6.0...v4.6.1) (2023-11-02)
+
+
+### Dependency Upgrades:
+
+* Bumped `org.bitbucket.b_c:jose4j:0.9.3` ([#1212](https://github.com/box/box-java-sdk/issues/1212)) ([f522a56](https://github.com/box/box-java-sdk/commit/f522a5660f3522b11a0516774ba0cca69db3ec31))
+
+## [4.6.0](https://github.com/box/box-java-sdk/compare/v4.5.0...v4.6.0) (2023-09-28)
+
+
+### New Features and Enhancements:
+
+* Support search deleted filters ([#1207](https://github.com/box/box-java-sdk/issues/1207)) ([5e0e9ed](https://github.com/box/box-java-sdk/commit/5e0e9ed9aea2818da6fba0d562b56987c4948aaa))
+
+### Bug Fixes:
+
+* Added protected accessors for trust manager and hostname verifier. ([#1206](https://github.com/box/box-java-sdk/issues/1206)) ([0c79d17](https://github.com/box/box-java-sdk/commit/0c79d1754bffeb3f0487e10d55d716ba1cbed1aa))
+* fix not closing response body ([#1208](https://github.com/box/box-java-sdk/issues/1208)) ([ab5e170](https://github.com/box/box-java-sdk/commit/ab5e1702934607b258802b33f3663af3e9c56027))
+
+## [4.5.0](https://github.com/box/box-java-sdk/compare/v4.4.0...v4.5.0) (2023-09-13)
+
+
+### New Features and Enhancements:
+
+* Add `iframeable_embed_url` field to `BoxSignRequestSigner` class ([#1202](https://github.com/box/box-java-sdk/issues/1202)) ([2e931d8](https://github.com/box/box-java-sdk/commit/2e931d8c36694a665d1c6315d3bf2d226929b713))
+
+### Bug Fixes:
+
+* `SharedLinkAPIConnection` uses request interceptor ([#1203](https://github.com/box/box-java-sdk/issues/1203)) ([b2b6a1d](https://github.com/box/box-java-sdk/commit/b2b6a1dba316ba50a1e011250c320fca156c6708)), closes [#1200](https://github.com/box/box-java-sdk/issues/1200)
+* Update sign template missing enum ([#1201](https://github.com/box/box-java-sdk/issues/1201)) ([fcb6657](https://github.com/box/box-java-sdk/commit/fcb6657bb2375e32c3fb0f861e7ecaeb84503f2c))
+
+## [4.4.0](https://github.com/box/box-java-sdk/compare/v4.3.0...v4.4.0) (2023-08-29)
+
+
+### New Features and Enhancements:
+
+* Support sign template and new sign status ([#1197](https://github.com/box/box-java-sdk/issues/1197)) ([e37c0dc](https://github.com/box/box-java-sdk/commit/e37c0dce86a422de5e8e6ed26fd93f1324f4b3e3))
+
+## [4.3.0](https://github.com/box/box-java-sdk/compare/v4.2.1...v4.3.0) (2023-08-11)
+
+
+### New Features and Enhancements:
+
+* Support access only collaboration ([#1193](https://github.com/box/box-java-sdk/issues/1193)) ([664c01f](https://github.com/box/box-java-sdk/commit/664c01f80ca0647645c60920eb0ef1f9353a619f))
+
+### [4.2.1](https://github.com/box/box-java-sdk/compare/v4.2.0...v4.2.1) (2023-08-03)
+
+
+### Bug Fixes:
+
+* Fixed upload when data are coming from a dynamic source ([#1189](https://github.com/box/box-java-sdk/issues/1189)) ([77b39f2](https://github.com/box/box-java-sdk/commit/77b39f2645d53bdab0ade23b637c211ea070fcf5)), closes [#1183](https://github.com/box/box-java-sdk/issues/1183) [#1190](https://github.com/box/box-java-sdk/issues/1190)
+
+## [4.2.0](https://github.com/box/box-java-sdk/compare/v4.1.2...v4.2.0) (2023-06-21)
+
+
+### New Features and Enhancements:
+
+* Getting collaborators allows to specify fields ([#1178](https://github.com/box/box-java-sdk/issues/1178)) ([1694d75](https://github.com/box/box-java-sdk/commit/1694d75fff0fbddb938426ef03ba24f360a344aa))
+
+### [4.1.2](https://github.com/box/box-java-sdk/compare/v4.1.1...v4.1.2) (2023-06-14)
+
+
+### Bug Fixes:
+
+* Class cast exception when uploading large file ([#1174](https://github.com/box/box-java-sdk/issues/1174)) ([e7d28bd](https://github.com/box/box-java-sdk/commit/e7d28bddb706c8b4fd1328f0eebc50db19a8c656)), closes [#1173](https://github.com/box/box-java-sdk/issues/1173)
+* Make `SharedLinkAPIConnection` constructors public ([#1172](https://github.com/box/box-java-sdk/issues/1172)) ([4d1616d](https://github.com/box/box-java-sdk/commit/4d1616ddd2c39d1cb0d03af998d2c47efe607853))
+* Remove invalid Group membership role ([#1171](https://github.com/box/box-java-sdk/issues/1171)) ([a5915f9](https://github.com/box/box-java-sdk/commit/a5915f94114a8269287831280a57949ed203e4e8))
+
+### [4.1.1](https://github.com/box/box-java-sdk/compare/v4.1.0...v4.1.1) (2023-05-16)
+
+
+### Bug Fixes:
+
+* Allow users to disable adding authentication header. ([#1167](https://github.com/box/box-java-sdk/issues/1167)) ([3433e5a](https://github.com/box/box-java-sdk/commit/3433e5a405ceb9bc32791642518b1fd65c4b4032))
+* Logging headers when retrying request ([#1164](https://github.com/box/box-java-sdk/issues/1164)) ([e0c3d8e](https://github.com/box/box-java-sdk/commit/e0c3d8e730962ba5c97105ce506ee931a3bba362))
+
+## [4.1.0](https://github.com/box/box-java-sdk/compare/v4.0.1...v4.1.0) (2023-04-24)
+
+
+### New Features and Enhancements:
+
+* Add missing `fields` parameter to create and update `BoxUser` methods ([#1155](https://github.com/box/box-java-sdk/issues/1155)) ([be3820d](https://github.com/box/box-java-sdk/commit/be3820dc4df15e99dfc13602d4f7269841bd15b3)), closes [#1154](https://github.com/box/box-java-sdk/issues/1154)
+
+### Bug Fixes:
+
+* Allow registering custom logger handlers ([#1156](https://github.com/box/box-java-sdk/issues/1156)) ([7373d5c](https://github.com/box/box-java-sdk/commit/7373d5cc2bf49bc198cbca70d056e43f0dffdb3a))
+* Fallback to default value of `maxRetryAttempts` when restoring `BoxAPIConnection` ([#1161](https://github.com/box/box-java-sdk/issues/1161)) ([2a10e5d](https://github.com/box/box-java-sdk/commit/2a10e5d07497611e077a9207fe98c1d8146cfd22)), closes [#1160](https://github.com/box/box-java-sdk/issues/1160)
+
+### [4.0.1](https://github.com/box/box-java-sdk/compare/v4.0.0...v4.0.1) (2023-03-06)
+
+
+### Bug Fixes:
+
+* `OAUTH_SUFFIX` gets appended twice to `baseAuthorizationURL` ([#1148](https://github.com/box/box-java-sdk/issues/1148)) ([3164770](https://github.com/box/box-java-sdk/commit/3164770498e5115a43318640735317a896950f54)), closes [#1147](https://github.com/box/box-java-sdk/issues/1147)
+* Wrong progress reported to `ProgressListener` by `AbstractBoxMultipartRequest` ([#1151](https://github.com/box/box-java-sdk/issues/1151)) ([947ded3](https://github.com/box/box-java-sdk/commit/947ded394490fc840b8191bc7ad69ae0ea5f5c7d)), closes [#1149](https://github.com/box/box-java-sdk/issues/1149)
+
+## [4.0.0](https://github.com/box/box-java-sdk/compare/v3.8.2...v4.0.0) (2023-01-17)
+
+
+The most important change this release includes is the replacement of the HTTP library from a native one to
+[OkHttp](https://square.github.io/okhttp/) which allows SDK to
+- Support the HTTP2 version of the HTTP protocol.
+- Support proxies that do not use only basic authentication method. For details on creating custom proxy authenticators and an example of
+ [NTLM proxy authentication](https://github.com/box/box-java-sdk/blob/kb/ok-http/doc/configuration.md#custom-proxy-authenticator).
+
+### Breaking Changes
+* `BatchAPIRequest` – is no longer supported by the SDK
+* `BoxAPIConnection#DEFAULT_MAX_ATTEMPTS` is replaced with `BoxAPIConnection#DEFAULT_MAX_RETRIES`
+* `BoxRedirectResponse` – was removed and will not be replaced
+* `BoxEvent.Type` is replaced with `EventType`
+* Removing deprecated methods from `BoxFile`, `BoxFileVersionRetention`, `BoxFolder`, `BoxGroup`, `BoxGroupMembership`,`BoxItem`, `BoxRetentionPolicy`, `BoxTask`, `BoxUser`, `BoxWebLink`, `EventLog`, `Metadata` and `MetadataTemplate`.
+
+Migration details can be found [here](doc/upgrades/3.x.x%20to%204.x.x.md).
+
+### New Features and Enhancements:
+
+* Using `OkHttp` in Java SDK ([#1083](https://github.com/box/box-java-sdk/issues/1083)) ([2656698](https://github.com/box/box-java-sdk/commit/265669897100dd8f1757fc2c5f25665da42c2889))
+
+### [3.8.2](https://github.com/box/box-java-sdk/compare/v3.8.1...v3.8.2) (2023-01-04)
+
+
+### Bug Fixes:
+
+* Fixed restoring state without refresh token. ([#1139](https://github.com/box/box-java-sdk/issues/1139)) ([3544709](https://github.com/box/box-java-sdk/commit/3544709480eb03e5bd50f5dc99be7409569304c4))
+
+### [3.8.1](https://github.com/box/box-java-sdk/compare/v3.8.0...v3.8.1) (2022-12-19)
+
+
+### Bug Fixes:
+
+* Restoring state from previous `SDK` version works. ([#1134](https://github.com/box/box-java-sdk/issues/1134)) ([b6d97dd](https://github.com/box/box-java-sdk/commit/b6d97dd5b0cc91eb2e4c922ff217e0878e0f63ec))
+
+## [3.8.0](https://github.com/box/box-java-sdk/compare/v3.7.1...v3.8.0) (2022-11-15)
+
+
+### New Features and Enhancements:
+
+* Added Box Sign webhooks ([#1109](https://github.com/box/box-java-sdk/issues/1109)) ([99051a5](https://github.com/box/box-java-sdk/commit/99051a575f120a8c0939359c1f4875b16b98b7f0))
+
+### Bug Fixes:
+
+* `NullPointerException` when using `BoxSignRequestPrefillTag` ([#1121](https://github.com/box/box-java-sdk/issues/1121)) ([73fd5b6](https://github.com/box/box-java-sdk/commit/73fd5b6e6e40f7e79b385edf46b8eee5ff612ace)), closes [#1120](https://github.com/box/box-java-sdk/issues/1120)
+* Regenerate JWT ID and retry auth request when JTI claim is rejected ([#1110](https://github.com/box/box-java-sdk/issues/1110)) ([420da0f](https://github.com/box/box-java-sdk/commit/420da0f2c80bfe8cfbaba4fa8dec4826c4cb6337))
+
+### Dependency Upgrades:
+
+* Bumped org.bitbucket.b_c:jose4j:0.9.0 ([#1111](https://github.com/box/box-java-sdk/issues/1111)) ([349694d](https://github.com/box/box-java-sdk/commit/349694ddcfeb701a9ecdfd5ae555d49bea4d1030))
+
+### [3.7.1](https://github.com/box/box-java-sdk/compare/v3.7.0...v3.7.1) (2022-09-29)
+
+
+### Bug Fixes:
+
+* Better logging when JSON cannot be parsed ([#1106](https://github.com/box/box-java-sdk/issues/1106)) ([5e66ef8](https://github.com/box/box-java-sdk/commit/5e66ef8cc983a6cff34995efc75e9effd3195d48))
+
+## [3.7.0](https://github.com/box/box-java-sdk/compare/v3.6.0...v3.7.0) (2022-09-20)
+
+
+### New Features and Enhancements:
+
+* Add `is_accessible_via_shared_link` field to File and Folder ([#1103](https://github.com/box/box-java-sdk/issues/1103)) ([45e9906](https://github.com/box/box-java-sdk/commit/45e9906efca6a7f2d4d738914dc804de12d3646e))
+
+### Bug Fixes:
+
+* `BoxCollaboration.getItem()` returns `BoxItem.Info` not `BoxFolder.Info` ([#1102](https://github.com/box/box-java-sdk/issues/1102)) ([135850d](https://github.com/box/box-java-sdk/commit/135850d97164ee5f6d74708d74c531f7fa8bee26)), closes [#1101](https://github.com/box/box-java-sdk/issues/1101) [#1100](https://github.com/box/box-java-sdk/issues/1100). `BoxCollaboration.getItem()` used to return `BoxFolder.Info`. However, if collaboration was added on a file it would still return `BoxFolder.Info` which will end with throwing `BoxAPIException` when doing any API call. If you are getting collaboration item it is best to store it as `BoxItem.Info` or check its type and store it as `BoxFile.Info` or `BoxFolder.Info`.
+* Add missing constructor to `BoxNotificationEmail` class ([#1098](https://github.com/box/box-java-sdk/issues/1098)) ([2534f34](https://github.com/box/box-java-sdk/commit/2534f34133f9554abd1e80fc1555659a2c52b23f))
+
+## [3.6.0](https://github.com/box/box-java-sdk/compare/v3.5.0...v3.6.0) (2022-09-07)
+
+
+### New Features and Enhancements:
+
+* Add support for modifiable retention policies & enable deleting retention policy assignment ([#1093](https://github.com/box/box-java-sdk/issues/1093)) ([30e2fcb](https://github.com/box/box-java-sdk/commit/30e2fcb74c12867fd3859c3490539557b47ab006))
+
+### Bug Fixes:
+
+* Stop sending not specified optional fields when creating a user ([#1095](https://github.com/box/box-java-sdk/issues/1095)) ([b7d894d](https://github.com/box/box-java-sdk/commit/b7d894d3f134137f3a5925f09accfd4334837f81))
+
+## [3.5.0](https://github.com/box/box-java-sdk/compare/v3.4.0...v3.5.0) (2022-08-26)
+
+
+### New Features and Enhancements:
+
+* Add `content-type` sign request and response ([#1087](https://github.com/box/box-java-sdk/issues/1087)) ([49411aa](https://github.com/box/box-java-sdk/commit/49411aaeea6d3ff8de10e3fbc3c60bba1bc54748))
+* Add `notification_email` to `BoxUser` ([#1088](https://github.com/box/box-java-sdk/issues/1088)) ([5477223](https://github.com/box/box-java-sdk/commit/547722347a920ba11e5fff7a8df5201720af815a))
+* Add `redirect_url` and `declined_redirect_url` to sign request response ([#1089](https://github.com/box/box-java-sdk/issues/1089)) ([3921fe1](https://github.com/box/box-java-sdk/commit/3921fe1a4a6249146a8dd2f22e15801846bc073b))
+
+### Bug Fixes:
+
+* Fixed canceling sign request fails because of empty body ([#1085](https://github.com/box/box-java-sdk/issues/1085)) ([32b8e79](https://github.com/box/box-java-sdk/commit/32b8e79ebc8995ab933c32d28c3e2f17d9627a70))
+
+## [3.4.0](https://github.com/box/box-java-sdk/compare/v3.3.0...v3.4.0) (2022-08-10)
+
+
+### New Features and Enhancements:
+
+* Added pagination for getting items in trash with new `BoxTrash#items` API ([#1072](https://github.com/box/box-java-sdk/issues/1072)) ([9cd411d](https://github.com/box/box-java-sdk/commit/9cd411d20af1bc76ae815905396d72008af62539))
+
+### Bug Fixes:
+
+* buffered body write and fixed SDK logging ([#1079](https://github.com/box/box-java-sdk/issues/1079)) ([bc35ef3](https://github.com/box/box-java-sdk/commit/bc35ef3279e68a3d794de454f506ba41d14c3b16))
+
+## [3.3.0](https://github.com/box/box-java-sdk/compare/v3.2.1...v3.3.0) (2022-07-01)
+
+
+### New Features and Enhancements:
+
+* Added support of Editable Shared Links ([#1064](https://github.com/box/box-java-sdk/issues/1064)) ([9b7d60c](https://github.com/box/box-java-sdk/commit/9b7d60c41fbd481465bf3f2a5877746f10849712))
+
+### Bug Fixes:
+
+* Fix closed stream exception in `canUpload` method ([#1067](https://github.com/box/box-java-sdk/issues/1067)) ([543f91c](https://github.com/box/box-java-sdk/commit/543f91c46dfcc9de7e61ce11cd93d472916533ac))
+
+### [3.2.1](https://github.com/box/box-java-sdk/compare/v3.2.0...v3.2.1) (2022-06-10)
+
+
+### Bug Fixes:
+
+* Fix getting proper URL to authenticate with OAuth ([#1059](https://github.com/box/box-java-sdk/issues/1059)) ([42876b4](https://github.com/box/box-java-sdk/commit/42876b45ccdb7fa6f357186cecaba051abf1c269)), closes [#1057](https://github.com/box/box-java-sdk/issues/1057)
+
+## [3.2.0](https://github.com/box/box-java-sdk/compare/v3.1.2...v3.2.0) (2022-05-23)
+
+
+### New Features and Enhancements:
+
+* Revamped setting base URLs ([#1042](https://github.com/box/box-java-sdk/issues/1042)) ([129baf7](https://github.com/box/box-java-sdk/commit/129baf704ced127788bb0f62ef9f4fb6a50fdc63))
+* support for Avatar V2 API ([#1044](https://github.com/box/box-java-sdk/issues/1044)) ([18651d7](https://github.com/box/box-java-sdk/commit/18651d7a5b419796e3733c7582ae471d7af7ed5c))
+
+### [3.1.2](https://github.com/box/box-java-sdk/compare/v3.1.1...v3.1.2) (2022-03-22)
+
+
+### Bug Fixes:
+
+* Allow using `As-User` header with CCG Authentication ([#1031](https://github.com/box/box-java-sdk/issues/1031)) ([b0c2389](https://github.com/box/box-java-sdk/commit/b0c238913cc1dbcecfd546a5eae68277c3c76d42))
+* Fix retry logic when `Retry-After` header is present ([#1033](https://github.com/box/box-java-sdk/issues/1033)) ([05224c4](https://github.com/box/box-java-sdk/commit/05224c433d2a101a01959644674153df9542b711))
+
+### [3.1.1](https://github.com/box/box-java-sdk/compare/v3.1.0...v3.1.1) (2022-02-28)
+
+
+### Bug Fixes:
+
+* retry `jwt` auth when error code is in error field ([#1020](https://github.com/box/box-java-sdk/issues/1020)) ([8c9d11d](https://github.com/box/box-java-sdk/commit/8c9d11d1b3556552751c9f4ac99a0f7180af97f3)), closes [#1019](https://github.com/box/box-java-sdk/issues/1019)
+
+## [3.1.0](https://github.com/box/box-java-sdk/compare/v3.0.0...v3.1.0) (2022-02-17)
+
+
+### New Features and Enhancements:
+
+* Added support for Client Credentials Grant authentication method ([#1002](https://github.com/box/box-java-sdk/issues/1002)) ([9cfcaff](https://github.com/box/box-java-sdk/commit/9cfcaff243dbf0541409f91f9f863a207345dc47))
+* API to extend disposition date on a file ([#1001](https://github.com/box/box-java-sdk/issues/1001)) ([f3f6b60](https://github.com/box/box-java-sdk/commit/f3f6b6043eec362c5a8ad9a01d6588538ca34e71))
+* Deprecating `indexName` when executing metadata query ([#1000](https://github.com/box/box-java-sdk/issues/1000)) ([c20dbbf](https://github.com/box/box-java-sdk/commit/c20dbbf6a927e31cfdd7ffa71069c0897f7a0536))
+
+### Dependency Upgrades:
+
+* Upgrade Gradle to 7.3.3 ([#985](https://github.com/box/box-java-sdk/issues/985)) ([e4acbb1](https://github.com/box/box-java-sdk/commit/e4acbb1f0c10ccdeeee139e2566b344052680010))
+
+## [3.0.0](https://github.com/box/box-java-sdk/compare/v2.58.0...v3.0.0) (2022-01-17)
+
+
+### ⚠ BREAKING CHANGES
+
+* Changed `BoxFileVersion` class and removed `fileVersion` field (#978)
+* Removed deprecated API `BoxCollaborationWhitelist` replaced with `BoxCollaborationAllowlist`, `BoxCollaborationWhitelistExemptTarget` replaced with `BoxCollaborationAllowlistExemptTarget` (#969)
+* Dropping Java 7 support (#962)
+* Downgrading `bouncycastle` libraries to 1.57 (#942)
+
+### New Features and Enhancements:
+
+* Add `typeName` to `BoxEvent` that contains name of the event, even if it is not mapped to `BoxEvent.EventType` ([#979](https://github.com/box/box-java-sdk/issues/979)) ([b30f61f](https://github.com/box/box-java-sdk/commit/b30f61f8cc9c02a1fc4cd5eb35469749e1a16558)), closes [#968](https://github.com/box/box-java-sdk/issues/968)
+* Add new optional `description` parameter to the `retention_policies` endpoint and `start_date_field` to the `retention_policy_assignments endpoint`. ([#967](https://github.com/box/box-java-sdk/issues/967)) ([0aa4ff4](https://github.com/box/box-java-sdk/commit/0aa4ff48a1e035efc9ac6aaa42f18f4c92955b7b))
+* Adding `BoxFile#getVersions(String... fields)` to allow users to specify what information they want to extract. Fixes [#946](https://github.com/box/box-java-sdk/issues/946). ([#947](https://github.com/box/box-java-sdk/issues/947)) ([a2eb638](https://github.com/box/box-java-sdk/commit/a2eb63896606a6c00ccee6bd9745f4c51f8d89a2))
+* Missing `eventTypes` from `BoxAPI` Documents. Fixes [#974](https://github.com/box/box-java-sdk/issues/974) ([#975](https://github.com/box/box-java-sdk/issues/975)) ([2c69360](https://github.com/box/box-java-sdk/commit/2c69360e80b1bdd6213933cf2f4da195d52c92d4))
+* Removed deprecated API `BoxCollaborationWhitelist` replaced with `BoxCollaborationAllowlist`, `BoxCollaborationWhitelistExemptTarget` replaced with `BoxCollaborationAllowlistExemptTarget` ([#969](https://github.com/box/box-java-sdk/issues/969)) ([2fd4d6f](https://github.com/box/box-java-sdk/commit/2fd4d6f884410c8884c4c038687bfc8f32837b55))
+
+### Bug Fixes:
+
+* Changed `BoxFileVersion` class and removed `fileVersion` field ([#978](https://github.com/box/box-java-sdk/issues/978)) ([8c39451](https://github.com/box/box-java-sdk/commit/8c3945167581400043a070c2f6906ef05d3d7b85))
+* Changed SDK loggers name to `"com.box.sdk"`, fixes [#638](https://github.com/box/box-java-sdk/issues/638) ([#950](https://github.com/box/box-java-sdk/issues/950)) ([443c230](https://github.com/box/box-java-sdk/commit/443c23085e55bbcaa1524c5b9e1bf852a1e2a1ce))
+* Date parsing error when `BoxSignRequestPrefillTag` created with date value. ([#970](https://github.com/box/box-java-sdk/issues/970)) ([cc2c8da](https://github.com/box/box-java-sdk/commit/cc2c8da9ea7d066ae2c247c2de5ac8b8bbba9b99))
+* Fix sending limit param in `EventLog` ([#977](https://github.com/box/box-java-sdk/issues/977)) ([96bdccc](https://github.com/box/box-java-sdk/commit/96bdccc9ca40ed43a6028a2b0d055d9d9a8de525))
+* Fixed `NullPointerException` when empty metadata used on BoxFile or `BoxFolder` ([#918](https://github.com/box/box-java-sdk/issues/918)) ([#945](https://github.com/box/box-java-sdk/issues/945)) ([68bc3c5](https://github.com/box/box-java-sdk/commit/68bc3c578d760b7239f6d704fed9bb5a834bf52a))
+* Fixes issue ([#951](https://github.com/box/box-java-sdk/issues/951)) error when deserialising sign request ([#952](https://github.com/box/box-java-sdk/issues/952)) ([070bdc5](https://github.com/box/box-java-sdk/commit/070bdc56074a1533c41f9085943d09502c79a7f4))
+
+### Dependency Upgrades:
+
+* Dropping Java 7 support ([#962](https://github.com/box/box-java-sdk/issues/962)) ([953ad78](https://github.com/box/box-java-sdk/commit/953ad78ac84833082439d0def1dcc63dc11ac04a))
+* Downgrading `bouncycastle` libraries to 1.57 ([#942](https://github.com/box/box-java-sdk/issues/942)) ([26aaed5](https://github.com/box/box-java-sdk/commit/26aaed51fd914eaf2061da735f11830524e4cfe4))
+
+
+## [2.58.0] (2021-11-23)
+
+### ⚠ BREAKING CHANGES
+
+### New Features and Enhancements:
+ - SDK support for new GET /events stream_type: admin_logs_streaming ([#938](https://github.com/box/box-java-sdk/pull/938))
+ - Adding BoxDeveloperEditionAPIConnection#getUserConnection to indicate that we can use this connection for managed users or app users ([#940](https://github.com/box/box-java-sdk/pull/940))
+
+### Bug Fixes:
+ - Fix for deprecated enums still being used ([#931](https://github.com/box/box-java-sdk/issues/931))
+
+## [2.57.0] (2021-10-18)
+
+### ⚠ BREAKING CHANGES
+
+### New Features and Enhancements:
+- Add support for marker-based paging in BoxFolder.getChildren ([#927](https://github.com/box/box-java-sdk/pull/927))
+- Upgraded minimal-json to v0.9.5
+- Upgraded jose4j to v0.7.9
+- Adding Gradle wrapper in version 4.0.1 ([#928](https://github.com/box/box-java-sdk/pull/928))
+
+### Bug Fixes:
+- Fix for infinite recursion ([#924](https://github.com/box/box-java-sdk/pull/924))
+- Fix unable to set Vanity URL on `BoxSharedLink` for BoxFile and BoxFolder ([#925](https://github.com/box/box-java-sdk/issues/925))
+
+## [2.56.0] (2021-08-31)
+
+### New Features and Enhancements:
+- Replace `submaster` GroupMembershipRole with `coadmin`. Replace `MASTER_INVITE_ACCEPT` and `MASTER_INVITE_REJECT` with `ADMIN_INVITE_ACCEPT` and `ADMIN_INVITE_REJECT`. ([#907](https://github.com/box/box-java-sdk/pull/907))
+- Add `tracking_codes` to create User API call ([#910](https://github.com/box/box-java-sdk/pull/910))
+
+### Bug Fixes:
+- Fix `url` for `BoxFileRequest.Info` object ([#906](https://github.com/box/box-java-sdk/pull/906))
+- Attempt to fix thread locking issue on refresh of access token ([#912](https://github.com/box/box-java-sdk/pull/912))
+
+## [2.55.1] (2021-07-30)
+
+### Bug Fixes:
+- Restore methods for Execute Metadata Query, which were removed in ([#890](https://github.com/box/box-java-sdk/pull/890)), and mark them as deprecated ([#905](https://github.com/box/box-java-sdk/pull/905))
+
+## [2.55.0] (2021-07-26)
+
+NOTE: Due to the benign nature of the "breaking change" below, we decided NOT to increment the major version for this release. There should be no customer impact due to this change.
+
+### ⚠ BREAKING CHANGES
+- Update execute metadata query to match API response ([#890](https://github.com/box/box-java-sdk/pull/890))
+ - NOTE: This change removes a method without deprecating it. It was not possible to use the method correctly at all, because the underlying service no longer supported it.
+
+### New Features and Enhancements:
+- Remove or deprecate insensitive language ([#889])(https://github.com/box/box-java-sdk/pull/889)
+- Add support for `is_external_collab_restricted` parameter for User ([#896](https://github.com/box/box-java-sdk/pull/896))
+- Add configurable permissions support for `GroupMembership` ([#897](https://github.com/box/box-java-sdk/pull/897))
+- Add `SHIELD_JUSTIFICATION_APPROVAL` event type ([#898](https://github.com/box/box-java-sdk/pull/898))
+- Add ability to get files under retention for assignment and file versions under retention for assignment ([#899](https://github.com/box/box-java-sdk/pull/899))
+- Add `TASK_UPDATE`, `FILE_VERSION_RESTORE` and `ADVANCED_FOLDER_SETTINGS_UPDATE` event types ([#902](https://github.com/box/box-java-sdk/pull/902))
+- Add SignAPI support ([#904](https://github.com/box/box-java-sdk/pull/904))
+
+### Bug Fixes:
+- Add setters for `BoxLegalHoldPolicy` ([#885](https://github.com/box/box-java-sdk/pull/885))
+- Add setters for `BoxTaskAssignment` ([#886](https://github.com/box/box-java-sdk/pull/886))
+- Add setters for Group Membership and Web Links ([#887](https://github.com/box/box-java-sdk/pull/887))
+- Add setters for Webhooks ([#888](https://github.com/box/box-java-sdk/pull/888))
+- Deprecate `BoxFile.getThumbnail` in favor of `BoxFile.getRepresentationContent` ([#891](https://github.com/box/box-java-sdk/pull/891))
+
+## [2.54.0] (2021-04-01)
+
+### New Features and Enhancements:
+
+- Add file request support ([#869](https://github.com/box/box-java-sdk/pull/869))
+
+### Bug Fixes:
+
+- Fix `BoxWeblink` deserialization ([#881](https://github.com/box/box-java-sdk/pull/881))
+
+## [2.53.0] (2021-01-08)
+
+### New Features and Enhancements:
+
+- Add offset and limit parameters to `BoxFolder.getChildren` ([#861](https://github.com/box/box-java-sdk/pull/861))
+
+## [2.52.0] (2020-11-24)
+
+### New Features and Enhancements:
+
+- Add folder lock functionality ([#856](https://github.com/box/box-java-sdk/pull/856))
+- Add support for search param to get shared link items ([#855](https://github.com/box/box-java-sdk/pull/855))
+
+### Bug Fixes:
+
+- Fix bug with updating tracking codes ([#857](https://github.com/box/box-java-sdk/pull/857))
+
+## [2.51.1] (2020-11-12)
+
+### Bug Fixes:
+
+- Fix for cross-enterprise collaborator calls to updateMetadata on files
+
+## [2.51.0] (2020-10-29)
+
+### New Features and Enhancements:
+
+- Add support for `copyInstanceOnItemCopy` field for metadata templates ([#850](https://github.com/box/box-java-sdk/pull/850))
+- Add support for more fields in `BoxCollaborator.Info` ([#843](https://github.com/box/box-java-sdk/pull/843))
+
+### Bug Fixes:
+
+- Update `getAllGroupsByName()` to use documented parameter ([#851](https://github.com/box/box-java-sdk/pull/851))
+
+## [2.50.1] (2020-08-20)
+- Fix bug that occurred when downscoping a token for a Box folder ([#832](https://github.com/box/box-java-sdk/pull/832))
+
+## [2.50.0] (2020-07-21)
+- API request creation errors are now retried with the same automatic retry logic as 429 and 5XX response errors ([#828](https://github.com/box/box-java-sdk/pull/828))
+
+## [2.49.0] (2020-07-17)
+- Fix bug with setting the unshared at date for a shared link ([#819](https://github.com/box/box-java-sdk/pull/819))
+- Add zip functionality ([#825](https://github.com/box/box-java-sdk/pull/825))
+- Add `fields` parameter for metadata query ([#826](https://github.com/box/box-java-sdk/pull/826))
+
+## [2.48.0] (2020-06-23)
+- Add ability to get groups by name with fields option ([#789](https://github.com/box/box-java-sdk/pull/789))
+- Add shared link downscoping ([#785](https://github.com/box/box-java-sdk/pull/785))
+- Deprecate the use of float for Metadata values, in preference of the underlying value (double) ([#811](https://github.com/box/box-java-sdk/pull/811))
+- Add iterator support for group collaborations ([#813](https://github.com/box/box-java-sdk/pull/813))
+- Add ability to set the filename when uploading a new version of a file ([#810](https://github.com/box/box-java-sdk/pull/810))
+- Add support for the classification field for Files and Folders ([#809](https://github.com/box/box-java-sdk/pull/809))
+- Add support for setting Tracking Codes ([#766](https://github.com/box/box-java-sdk/pull/766))
+- Fix issue for `getIsExternallyOwned()` for Files and Folders ([#808](https://github.com/box/box-java-sdk/pull/808))
+
+## [2.47.0] (2020-04-23)
+- Add support for the uploader display name field for Files and File Versions ([#791](https://github.com/box/box-java-sdk/pull/791))
+- Fix path parameter sanitization ([#797](https://github.com/box/box-java-sdk/pull/797))
+
+## [2.46.0] (2020-04-09)
+- Fix retry logic ([#787](https://github.com/box/box-java-sdk/pull/787))
+ - Retry for 400 `invalid_grant` error in authentication requests (Clock Skew)
+ - Honor Retry-After header, if present, by waiting for the time specified in the header before retrying
+ - The concept of setting / getting "Maximum API Requests" has been deprecated in favor of "Maximum API Retries" to more clearly show the number of times a request will be retried after an error response is received.
+- Add ability to set expiration date for a collaboration ([#788](https://github.com/box/box-java-sdk/pull/788))
+- Add path parameter sanitization ([#790](https://github.com/box/box-java-sdk/pull/790))
+
+## [2.45.0] (2020-04-02)
+- Add preflight check before chunked uploads ([#782](https://github.com/box/box-java-sdk/pull/782))
+- Check that part was successfully uploaded for large file uploads before retrying for 500 errors ([#781](https://github.com/box/box-java-sdk/pull/781))
+- Fix bug with premature disconnect when renaming files and weblinks ([#779](https://github.com/box/box-java-sdk/pull/779))
+- Add metadata to each item returned by a metadata query ([#778](https://github.com/box/box-java-sdk/pull/778))
+
+## [2.44.1] (2020-02-13)
+- Fix formatting bug for Java Logger
+- Improve date / time parsing for responses
+
+## [2.44.0] (2020-01-21)
+- Fix Authentication Request Retries
+
+## [2.43.0] (2019-12-20)
+- Throw exceptions for setMetadata on Files and Folders for non-409 errors
+
+## [2.42.0] (2019-12-17)
+- Added Metadata Query support
+- Added marker based pagination for get users methods
+
+## [2.41.0] (2019-10-24)
+- Added enum action option for completed in Box Task class.
+
+## [2.40.0] (2019-10-24)
+- General doc changes.
+
+## [2.39.0] (2019-10-17)
+- Deprecated Batch API functionality.
+- Added support for [Task completion_rule](https://github.com/box/box-java-sdk/blob/main/src/main/java/com/box/sdk/BoxFile.java#L249)
+
+## [2.38.0] (2019-09-19)
+- Added missing fields for File Version: trashed_by, restored_at, purged_at, purged_by.
+- Added support for [chunked uploads with file attributes](https://github.com/box/box-java-sdk/blob/main/doc/files.md#upload-a-large-file-in-chunks-including-attributes).
+
+## [2.37.0] (2019-08-22)
+- Added support for replace in multi-select metadata for [files](https://github.com/box/box-java-sdk/blob/main/doc/files.md#update-metadata) and
+ for [folders](https://github.com/box/box-java-sdk/blob/main/doc/folders.md#update-metadata)
+- Improved getting started with JWT authentication docs that can be found [here](https://github.com/box/box-java-sdk/blob/main/doc/authentication.md#server-authentication-with-jwt)
+
+## [2.36.0] (2019-08-01)
+- Added support for [removing shared link](https://github.com/box/box-java-sdk/blob/main/src/main/java/com/box/sdk/BoxItem.java#L413) and fixed an issue with setting null for shared link field on BoxItem.
+- Added support for additional fields for Box files, folders, and web links.
+
+## [2.35.0] (2019-07-18)
+- Added support for retrieving [is_external_only field](https://github.com/box/box-java-sdk/blob/main/src/main/java/com/box/sdk/BoxFile.java#L1668) for Box Files and Folders.
+
+## [2.34.0] (2019-06-06)
+- Added support for retrieving a [string type action for tasks](https://github.com/box/box-java-sdk/blob/main/src/main/java/com/box/sdk/BoxTask.java#L281).
+ Please use getActionType() going forward instead of the deprecated getAction().
+
+## [2.33.0] (2019-05-23)
+
+- Added support for [setting can_owners_invite field](https://github.com/box/box-java-sdk/blob/1ed10d7a457e44b863ec1c9b1d0d1408fb55e1e5/src/main/java/com/box/sdk/BoxFolder.java#L1272) Thank you @Band-Aid for you pull request! Greatly Appreciated.
+- Fixed a bug where chunked upload was not populating the correct part size for upload part.
+
+## [2.32.0] (2019-04-25)
+- Added support [setting metadata](https://github.com/box/box-java-sdk/blob/main/doc/folders.md#set-metadata).
+
+## [2.31.0] (2019-04-11)
+
+- Added support for [sorting folder items](https://github.com/box/box-java-sdk/blob/main/doc/folders.md#get-a-folders-items) retrieved from a folder by ascending or descending order.
+
+## [2.30.1] (2019-04-08)
+
+- Fixed a bug where the SDK could throw when parsing JSON containing dates using the Zulu timezone format
+
+## [2.30.0] (2019-04-04)
+- Added `action_by` field to enterprise events stream.
+
+## [2.29.0] (2019-04-01)
+- Added support for [sorting results returned from Box Search](https://github.com/box/box-java-sdk/blob/main/doc/search.md#search-1)
+- Added ability to [attach a file description upon file upload](https://github.com/box/box-java-sdk/blob/main/doc/files.md#upload-a-file)
+
+## [2.28.1] (2019-03-07)
+- Fixed a bug where BoxMetadataCascadePolicy.forceApply() would not return correctly.
+
+## [2.28.0] (2019-02-21)
+- Added ability for user to [retrieve an avatar](http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxUser.html#getAvatar--)) for a specified user.
+
+## [2.27.0] (2019-01-31)
+- Added support for Metadata Classification for [File](http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxFile.html#setClassification-java.lang.String...-) and [Folder](http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxFolder.html#setClassification-java.lang.String...-)
+
+## [2.26.0] (2019-01-17)
+- Added [invite_email](https://github.com/box/box-java-sdk/blob/main/src/main/java/com/box/sdk/BoxCollaboration.java#L277) field to collaboration object.
+- Added [is_collaboration_restricted_to_enterprise](https://github.com/box/box-java-sdk/blob/main/src/main/java/com/box/sdk/BoxFolder.java#L1104) field to folder object.
+- Added [status](https://github.com/box/box-java-sdk/blob/main/src/main/java/com/box/sdk/BoxTaskAssignment.java#L196) field to task assignment object.
+- Added ability to retrieve fields for [`BoxFile#getTasks()`](http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxFile.html#getTasks-java.lang.String...-)
+- Fixed bug where offset based paging would not return correctly.
+
+## [2.25.1] (2019-01-03)
+- Upgraded dependencies: jose4j to v0.5.5, and bouncycastle to v1.60
+
+## [2.25.0] (2018-12-13)
+- Added functionality to allow [content streaming to Box through outputstream](http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxFolder.html#uploadFile-com.box.UploadFileCallback-java.lang.String-). Thank you @gajarajkalburgi for the pr!
+
+## [2.24.0] (2018-11-16)
+- Added `getOptionsObjects()` on `MetadataTemplate.Field` which returns both key and type.
+- Added functionality for [`BoxItem#getType()`](http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxItem.html#getType--) for BoxItem.
+- Added functionality for [`BoxAPIConnection#BoxGlobalSettings()`](http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxAPIConnection.html#setConnectTimeout-java.lang.String-)
+and [`BoxAPIConnection#BoxGlobalSettings()`](http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxAPIConnection.html#getConnectTimeout--) as well as getting and reading the timeout for the connection.
+- Added functionality for [`BoxGlobalSettings#getMaxRequestAttempts()`](http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxGlobalSettings.html#getMaxRequestAttempts--)
+and [`BoxGlobalSettings#setMaxRquestAttempts()`](http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxGlobalSettings.html#setMaxRequestAttempts-java.lang.Integer-)
+- Fixed a bug where [`BoxLegalHoldPolicy#create()`](http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxLegalHoldPolicy.html#create-com.box.BoxAPIConnection-java.lang.String-) was not setting the correct legal hold policy duration.
+
+## [2.23.2] (2018-09-27)
+- Fixed a bug where the specified headers for batch requests were not being sent.
+
+## [2.23.1] (2018-09-13)
+- Fixed a bug where too many TCP connections were being opened. Thank you @pmatte1 for implementing this fix!
+
+## [2.23.0] (2018-08-23)
+- Added support for [Metadata Cascade Policy](https://github.com/box/box-java-sdk/blob/main/doc/folders.md#create-cascade-policy-on-folder)
+
+## [2.22.0] (2018-08-09)
+- Deprecated the [moveFolderToUser()](https://github.com/box/box-java-sdk/blob/main/src/main/java/com/box/sdk/BoxUser.java#L455) for Box Users. We encourage users to
+use [transferContent](https://github.com/box/box-java-sdk/blob/main/src/main/java/com/box/sdk/BoxUser.java#L482) going forward because idiomatically it is more correct.
+
+## [2.21.0] (2018-07-05)
+- Added functionality to allow users to [set passwords on shared links](https://github.com/box/box-java-sdk/pull/623) for Box files, folders, and web links.
+- Fixed wrong redirect for two links in the `Getting Started` and `Quick Test` section of the README.
+
+## [2.20.2] (2018-06-28)
+- Fixed a bug where customers had issues with large file uploads because they fail to parse the Retry-After header from the
+commit response. Reason being headers storage/lookup was case sensitive.
+
+## [2.20.1] (2018-06-04)
+- Added better exception handling for JSON parse in response exception.
+- Fixed a bug where uploadNewVersion() was returning an empty object.
+
+## [2.20.0] (2018-05-24)
+- Fixed a bug where multiple As-User headers could be set.
+- Added support to [test update](http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/Metadata.html#test-java.lang.String-java.util.List-) for multiselect field on metadata
+
+## [2.19.0] (2018-05-10)
+- Added support for enterprise admins with Box Zones purchased to have support for [Box Storage Policies and Box Storage Policy Assignments](./doc/storage_policy)
+- Added support to allow users to work with [multiselect metadata](./doc/files.md#get-metadata)
+- Added `getLogin()` method for the "login" field on the "accessible by" for BoxCollaboration.Info class.
+
+
+## [2.18.0] (2018-04-30)
+- Fixed a bug where the the private key password should be passed into `setPrivateKetPassword()` instead of the private key. A big thank you to [breach10ck](https://github.com/breach10ck)
+for their pull request!
+- Added an additional check to ensure that the [request properties on the request object is not null in the `toString()` method](https://github.com/box/box-java-sdk/pull/595)
+- Added support to [fetch the content of the generated representation](./doc/files.md#get-representation-content) after it has been generated
+- Improved error messages for API response errors to allow for better debugging.
+
+## [2.17.0] (2018-04-10)
+- Added support for assigning [Retention Policies to Metadata Templates](./doc/retention_policies.md#create-retention-policy-assignment)
+
+## [2.16.1] (2018-03-29)
+
+- Added `CONTENT_ACCESS` to event type enum
+
+## [2.16.0] (2018-03-22)
+- Added support for [user tracking codes](http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxUser.Info.html#getTrackingCodes--) on the user object.
+- Fixed a bug where JWT authentication would fail due to improper date parsing.
+- Added support for setting custom headers on API connection. This allow for setting [As-User support](./doc/overview.md#as-user)
+and [suppressing notifications](./doc/overview.md/suppressing-notifications) support.
+- Changed default JWT expiration window to reduce chances of error.
+
+## [2.15.0] (2018-03-12)
+- Added support for retrieving a [metadata template by ID](./doc/metadata_template.md#get-by-id)
+- Added support for allowing the user to [retrieve specific Collaboration fields on a Collaboration object](./doc/collaborations.md#get-a-collaborations-information)
+
+## [2.14.1] (2018-03-01)
+
+- Reduced the number of API calls that the `EventStream` makes to fetch new events, which should
+help users who are running into rate limit issues.
+- Force support for TLSv1.1 or higher when available to improve the security of connections to the Box API
+- Add randomized jitter to the exponential backoff algorithm used by the SDK to improve the success rate
+of retried requests.
+
+## [2.14.0] (2018-02-15)
+
+- Added support for getting and setting the `can_view_path` field on a collaboration object.
+- Added support for getting and setting the `tags` field on files and folders.
+
+## [2.13.0] (2018-02-07)
+
+- Fixed an issue where all types of metadata values were being coerced to Strings. This change deprecates
+`Metadata#get()` in favor of type-specific methods like `Metadata#getFloat()` or a generic `Metadata#getValue()`,
+which returns a `JsonValue` object that represents any JSON type. See the [file metadata](./doc/files.md#get-metadata)
+or [folder metadata](./doc/folders.md#get-metadata) documentation for more information.
+
+## [2.12.0] (2018-02-01)
+
+- Fixed ability to notify users or groups regarding [file collaboration](https://github.com/box/box-java-sdk/blob/main/doc/files.md#share-a-file) or [folder collaboration](https://github.com/box/box-java-sdk/blob/main/doc/folders.md#share-a-folder)
+- Added [OAuth2 token creation event types](https://github.com/box/box-java-sdk/blob/main/src/main/java/com/box/sdk/BoxEvent.java#L747)
+- Added support for [inviting a user to another Box Enterprise](http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxInvite.html)
+- Fixed an [OutOfMemory error in large file upload by capping the maximum number of parts that are uploaded concurrently](https://github.com/box/box-java-sdk/pull/543)
+
+
+## [2.11.0] (2018-01-25)
+
+- [uploadLargeFile now returns a BoxFile object](https://github.com/box/box-java-sdk/pull/524)
+- [Fixed chunked upload for Box Files greater than 2GB](https://github.com/box/box-java-sdk/pull/531)
+- [Perform modified retry on JWT auth for when the local clock and the Box Server clock are not aligned as well as if the JWT ID has already been consumed](https://github.com/box/box-java-sdk/pull/523)
+- BoxFolder.search has been deprecated in favor of [BoxSearch.searchRange](https://github.com/box/box-java-sdk/blob/86b82f2be3c57e3b89ae150b5f237d410e2d4900/doc/search.md)
+
+## [2.10.0] (2018-01-11)
+
+- [Add optional is_confirmed paramater for adding user email alias](https://github.com/box/box-java-sdk/pull/499)
+- Added support for [Metadata Template Delete](./doc/metadata_template#delete-a-metadata-template)
+
+## [2.9.0] (2018-01-04)
+
+- Added option to pass file [SHA-1 hash for upload integrity](https://github.com/box/box-java-sdk/blob/main/doc/files.md#upload-a-file)
+- Added support for [Terms of Service](./doc/terms_of_service) endpoint
+- Fixed missing [webhook triggers](https://github.com/box/box-java-sdk/pull/497)
+- Fixed missing [event types for events enum](https://github.com/box/box-java-sdk/pull/500)
+- Added [modified_at timestamp to BoxComment.Info](https://github.com/box/box-java-sdk/pull/499)
+- Added support for [Collaboration Whitelists](./doc/collaboration_whitelists) endpoint
+
+## [2.8.2] (2017-10-05)
+
+- Added additional check for `PrivateKeyInfo` in `BoxDeveloperEditionApiConnection`
+
+## [2.8.1] (2017-10-05)
+
+- Added ability to [set connect and read timeout globally](https://github.com/box/box-java-sdk/pull/459)
+
+## [2.8.0] (2017-09-07)
+
+- Added method for getting file representations
+- Changes to Representation object
+
+## [2.7.0] (2017-08-30)
+
+- Added support for [Representations](https://github.com/box/box-java-sdk/blob/main/src/main/java/com/box/sdk/BoxFile.java#L445) endpoint
+
+## [2.6.0] (2017-08-28)
+
+- Added support for [Batch](https://github.com/box/box-java-sdk/blob/575861fad0b3e67d432b5d5955d1e760b3f6444e/README.md#batchrequestexample)
+- Added support for [Unified Metadata](./doc/folders#get-metadata-using-unified-metadata-api)
+
+## [2.5.0] (2017-07-28)
+
+- Added support for [Recent Items](https://github.com/box/box-java-sdk/blob/main/src/main/java/com/box/sdk/BoxRecents.java#L1) endpoint
+- Added support [Get All Groups By Name](https://github.com/box/box-java-sdk/blob/a1833950c18139fd9cbb4d8ee61d310c7bbedadf/src/main/java/com/box/sdk/BoxGroup.java#L143) endpoint
+- Added support for [Token Exchange](https://github.com/box/box-java-sdk/blob/main/src/main/java/com/box/sdk/BoxAPIConnection.java#L634)
+
+## [2.4.0] (2017-05-02)
+
+- Support for multiput upload. New methods in BoxFolder and BoxFile support multiput upload for better performance and reliability for large files.
+- Single file collaborations. The BoxFile class now supports sharing individual files.
+- Automatic configuration for JWT auth. The Box Developer console now lets you download a JSON file of your JWT app configuration settings. You can import this file into the Java SDK to easily configure your app.
+
+## [2.3.0] (2017-01-12)
+
+New API Endpoints:
+
+[Legal Holds](https://github.com/box/box-java-sdk/blob/main/doc/legal_holds.md)
+[Retention Policies](https://github.com/box/box-java-sdk/blob/main/doc/retention_policies.md)
+[Create Metadata Template](https://github.com/box/box-java-sdk/blob/main/doc/metadata_template.md#create-metadata-template)
+[Get All Metadata on File](https://github.com/box/box-java-sdk/blob/main/doc/files.md#get-all-metadata-on-file)
+[Get All Metadata on Folder](https://github.com/box/box-java-sdk/blob/main/doc/folders.md#get-all-metadata-on-folder)
+[Get Enterprise Metadata Templates](https://github.com/box/box-java-sdk/blob/main/doc/metadata_template.md#get-enterprise-metadata-templates)
+[Update Group](https://github.com/box/box-java-sdk/blob/main/doc/groups.md#update-a-group)
+[Watermarking](https://github.com/box/box-java-sdk/blob/main/doc/watermarking.md)
+[Webhooks V2](https://github.com/box/box-java-sdk/blob/main/doc/webhooks.md)
+[WebLinks](https://github.com/box/box-java-sdk/blob/main/doc/weblinks.md)
+[Collections](https://github.com/box/box-java-sdk/blob/main/doc/collections.md)
+[BoxGroupMembership with for Paging](https://github.com/box/box-java-sdk/blob/main/doc/groups.md)
+[Enterprise Device Pins](https://github.com/box/box-java-sdk/blob/86b82f2be3c57e3b89ae150b5f237d410e2d4900/doc/devices.md)
+
+New Features:
+
+Transactional Authentication. Support for Box's new Transactional Auth APIs.
+Upload file versions with SHA1. A file's SHA1 can be passed in to BoxFile.uploadVersion(...) when uploading new versions.
+Get effective_access for shared links. The effective_access field is accessible through BoxSharedLink. getEffectiveAccess().
+Added additional Event Types. The TASK_ASSIGNMENT_COMPLETE, TASK_ASSIGNMENT_UPDATE, TASK_CREATE, COMMENT_DELETE types are now included in the BoxEvent class.
+
+## [2.1.0] (2016-02-22)
+
+This release includes improvements to token caching for App Users and support for additional API endpoints.
+
+New Features:
+
+ - App Users token caching. A token cache can now be specified in BoxDeveloperEditionAPIConnection. This allows for improved performance when using App Users authentication.
+ - Support for retrieving download URLs. The BoxFile.getDownloadURL() method allows for retrieving a direct download URL to a file.
+ - File thumbnails. The BoxFile.getThumbnail() method allows for downloading the [Thumbnail](https://github.com/box/box-java-sdk/blob/main/doc/files.md#get-thumbnail) for a file.
+
+Bug Fixes:
+
+ - Getting info for a file could crash when there's no preview. Previously, an exception would be thrown if BoxFile.getInfo (BoxFile.ALL_FIELDS) was called and the file didn't have a preview available.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index fc1d7822f..e12872653 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,108 +1,20 @@
-Contributing
-============
+# Contributing
All contributions are welcome to this project.
-Contributor License Agreement
------------------------------
+## Contributor License Agreement
-Before a contribution can be merged into this project, please fill out the
-Contributor License Agreement (CLA) located at:
+Before a contribution can be merged into this project, please fill out the Contributor License Agreement (CLA) located at:
http://opensource.box.com/cla
-To learn more about CLAs and why they are important to open source projects,
-please see the [Wikipedia entry][1].
+To learn more about CLAs and why they are important to open source projects, please see the [Wikipedia entry](http://en.wikipedia.org/wiki/Contributor_License_Agreement).
-How to contribute
------------------
+## Code of Conduct
-* **File an issue** - if you found a bug, want to request an enhancement, or
- want to implement something (bug fix or feature).
-* **Send a pull request** - if you want to contribute code. Please be sure to
- file an issue first.
+This project adheres to the [Box Open Code of Conduct](http://opensource.box.com/code-of-conduct/). By participating, you are expected to uphold this code.
-Pull request best practices
----------------------------
+## How to contribute
-Following these steps will help ensure that your pull request gets reviewed and
-accepted as quickly as possible.
-
-### Step 1: File an issue
-
-Before writing any code, please file an issue stating the problem you want to
-solve or the feature you want to implement. This allows us to give you feedback
-before you spend any time writing code. There may be a known limitation that
-can't be addressed, or a bug that has already been fixed in a different way. The
-issue allows us to communicate and figure out if it's worth your time to write a
-bunch of code for the project.
-
-### Step 2: Fork this repository in GitHub
-
-This will create your own copy of our repository.
-
-### Step 3: Add the upstream source
-
-The upstream source is the project under the Box organization on GitHub. To add
-an upstream source for this project, type:
-
-```
-git remote add upstream git@github.com:box/box-java-sdk.git
-```
-
-This will come in useful later.
-
-### Step 4: Create a feature branch
-
-Create a branch with a descriptive name, such as `add-search`.
-
-### Step 5: Push your feature branch to your fork
-
-As you develop code, continue to push code to your remote feature branch. Please
-make sure to include the issue number you're addressing in the body of your
-commit message and adhere to [standard git commit message guidelines][2]. For
-example:
-
-```
-Add search
-
-Introduced a new BoxSearch class that uses the /search API endpoint.
-
-Closes #123.
-```
-
-This helps us out by allowing us to track which issue your commit relates to.
-
-Keep a separate feature branch for each issue you want to address.
-
-### Step 6: Rebase
-
-Before sending a pull request, rebase against upstream, such as:
-
-```
-git fetch upstream
-git rebase upstream/master
-```
-
-This will add your changes on top of what's already in upstream, minimizing
-merge issues.
-
-### Step 7: Build and test your changes
-
-Make sure that the code builds and passes all unit tests by running:
-
-```bash
-$ gradle clean build
-```
-
-### Step 8: Send the pull request
-
-Send the pull request from your feature branch to us. Be sure to include a
-description in your commit message (not the pull request description) that lets
-us know what work you did.
-
-Keep in mind that we like to see one issue addressed per pull request, as this
-helps keep our git history clean and we can more easily track down issues.
-
-[1]: http://en.wikipedia.org/wiki/Contributor_License_Agreement
-[2]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
+- **File an issue** - if you found a bug, want to request an enhancement, or want to implement something (bug fix or feature).
+- **Send a pull request** - this project is generated using [Box Codegen](https://github.com/box/box-codegen) based on[Box OpenAPI 3.0 Specification](https://github.com/box/box-openapi), so if you want found something you want to change in the generated code, you'll need to modify the codegen project and submit a pull request there.
diff --git a/README.md b/README.md
index 29523a2b0..123549c76 100644
--- a/README.md
+++ b/README.md
@@ -1,113 +1,307 @@
+
This class handles storing authentication information, automatic token refresh, and rate-limiting. It can also be
- * used to configure the Box API endpoint URL in order to hit a different version of the API. Multiple instances of
- * BoxAPIConnection may be created to support multi-user login.
- */
-public class BoxAPIConnection {
- /**
- * The default maximum number of times an API request will be tried when an error occurs.
- */
- public static final int DEFAULT_MAX_ATTEMPTS = 3;
-
- private static final String TOKEN_URL_STRING = "https://www.box.com/api/oauth2/token";
- private static final String DEFAULT_BASE_URL = "https://api.box.com/2.0/";
- private static final String DEFAULT_BASE_UPLOAD_URL = "https://upload.box.com/api/2.0/";
-
- /**
- * The amount of buffer time, in milliseconds, to use when determining if an access token should be refreshed. For
- * example, if REFRESH_EPSILON = 60000 and the access token expires in less than one minute, it will be refreshed.
- */
- private static final long REFRESH_EPSILON = 60000;
-
- private final String clientID;
- private final String clientSecret;
- private final ReadWriteLock refreshLock;
-
- // These volatile fields are used when determining if the access token needs to be refreshed. Since they are used in
- // the double-checked lock in getAccessToken(), they must be atomic.
- private volatile long lastRefresh;
- private volatile long expires;
-
- private String userAgent;
- private String accessToken;
- private String refreshToken;
- private String tokenURL;
- private String baseURL;
- private String baseUploadURL;
- private boolean autoRefresh;
- private int maxRequestAttempts;
- private List listeners;
- private RequestInterceptor interceptor;
-
- /**
- * Constructs a new BoxAPIConnection that authenticates with a developer or access token.
- * @param accessToken a developer or access token to use for authenticating with the API.
- */
- public BoxAPIConnection(String accessToken) {
- this(null, null, accessToken, null);
- }
-
- /**
- * Constructs a new BoxAPIConnection with an access token that can be refreshed.
- * @param clientID the client ID to use when refreshing the access token.
- * @param clientSecret the client secret to use when refreshing the access token.
- * @param accessToken an initial access token to use for authenticating with the API.
- * @param refreshToken an initial refresh token to use when refreshing the access token.
- */
- public BoxAPIConnection(String clientID, String clientSecret, String accessToken, String refreshToken) {
- this.clientID = clientID;
- this.clientSecret = clientSecret;
- this.accessToken = accessToken;
- this.refreshToken = refreshToken;
- this.tokenURL = TOKEN_URL_STRING;
- this.baseURL = DEFAULT_BASE_URL;
- this.baseUploadURL = DEFAULT_BASE_UPLOAD_URL;
- this.autoRefresh = true;
- this.maxRequestAttempts = DEFAULT_MAX_ATTEMPTS;
- this.refreshLock = new ReentrantReadWriteLock();
- this.userAgent = "Box Java SDK v0.7.0";
- this.listeners = new ArrayList();
- }
-
- /**
- * Constructs a new BoxAPIConnection with an auth code that was obtained from the first half of OAuth.
- * @param clientID the client ID to use when exchanging the auth code for an access token.
- * @param clientSecret the client secret to use when exchanging the auth code for an access token.
- * @param authCode an auth code obtained from the first half of the OAuth process.
- */
- public BoxAPIConnection(String clientID, String clientSecret, String authCode) {
- this(clientID, clientSecret, null, null);
- this.authenticate(authCode);
- }
-
- /**
- * Constructs a new BoxAPIConnection.
- * @param clientID the client ID to use when exchanging the auth code for an access token.
- * @param clientSecret the client secret to use when exchanging the auth code for an access token.
- */
- public BoxAPIConnection(String clientID, String clientSecret) {
- this(clientID, clientSecret, null, null);
- }
-
- /**
- * Authenticates the API connection by obtaining access and refresh tokens using the auth code that was obtained
- * from the first half of OAuth.
- * @param authCode the auth code obtained from the first half of the OAuth process.
- */
- public void authenticate(String authCode) {
- URL url = null;
- try {
- url = new URL(this.tokenURL);
- } catch (MalformedURLException e) {
- assert false : "An invalid token URL indicates a bug in the SDK.";
- throw new RuntimeException("An invalid token URL indicates a bug in the SDK.", e);
- }
-
- String urlParameters = String.format("grant_type=authorization_code&code=%s&client_id=%s&client_secret=%s",
- authCode, this.clientID, this.clientSecret);
-
- BoxAPIRequest request = new BoxAPIRequest(url, "POST");
- request.addHeader("Content-Type", "application/x-www-form-urlencoded");
- request.setBody(urlParameters);
-
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- String json = response.getJSON();
-
- JsonObject jsonObject = JsonObject.readFrom(json);
- this.accessToken = jsonObject.get("access_token").asString();
- this.refreshToken = jsonObject.get("refresh_token").asString();
- this.lastRefresh = System.currentTimeMillis();
- this.expires = jsonObject.get("expires_in").asLong() * 1000;
- }
-
- /**
- * Sets the amount of time for which this connection's access token is valid before it must be refreshed.
- * @param milliseconds the number of milliseconds for which the access token is valid.
- */
- public void setExpires(long milliseconds) {
- this.expires = milliseconds;
- }
-
- /**
- * Gets the amount of time for which this connection's access token is valid.
- * @return the amount of time in milliseconds.
- */
- public long getExpires() {
- return this.expires;
- }
-
- /**
- * Gets the token URL that's used to request access tokens. The default value is
- * "https://www.box.com/api/oauth2/token".
- * @return the token URL.
- */
- public String getTokenURL() {
- return this.tokenURL;
- }
-
- /**
- * Sets the token URL that's used to request access tokens. For example, the default token URL is
- * "https://www.box.com/api/oauth2/token".
- * @param tokenURL the token URL.
- */
- public void setTokenURL(String tokenURL) {
- this.tokenURL = tokenURL;
- }
-
- /**
- * Gets the base URL that's used when sending requests to the Box API. The default value is
- * "https://api.box.com/2.0/".
- * @return the base URL.
- */
- public String getBaseURL() {
- return this.baseURL;
- }
-
- /**
- * Sets the base URL to be used when sending requests to the Box API. For example, the default base URL is
- * "https://api.box.com/2.0/".
- * @param baseURL a base URL
- */
- public void setBaseURL(String baseURL) {
- this.baseURL = baseURL;
- }
-
- /**
- * Gets the base upload URL that's used when performing file uploads to Box.
- * @return the base upload URL.
- */
- public String getBaseUploadURL() {
- return this.baseUploadURL;
- }
-
- /**
- * Sets the base upload URL to be used when performing file uploads to Box.
- * @param baseUploadURL a base upload URL.
- */
- public void setBaseUploadURL(String baseUploadURL) {
- this.baseUploadURL = baseUploadURL;
- }
-
- /**
- * Gets the user agent that's used when sending requests to the Box API.
- * @return the user agent.
- */
- public String getUserAgent() {
- return this.userAgent;
- }
-
- /**
- * Sets the user agent to be used when sending requests to the Box API.
- * @param userAgent the user agent.
- */
- public void setUserAgent(String userAgent) {
- this.userAgent = userAgent;
- }
-
- /**
- * Gets an access token that can be used to authenticate an API request. This method will automatically refresh the
- * access token if it has expired since the last call to getAccessToken().
- * @return a valid access token that can be used to authenticate an API request.
- */
- public String getAccessToken() {
- if (this.autoRefresh && this.canRefresh() && this.needsRefresh()) {
- this.refreshLock.writeLock().lock();
- try {
- if (this.needsRefresh()) {
- this.refresh();
- }
- } finally {
- this.refreshLock.writeLock().unlock();
- }
- }
-
- return this.accessToken;
- }
-
- /**
- * Sets the access token to use when authenticating API requests.
- * @param accessToken a valid access token to use when authenticating API requests.
- */
- public void setAccessToken(String accessToken) {
- this.accessToken = accessToken;
- }
-
- /**
- * Gets a refresh token that can be used to refresh an access token.
- * @return a valid refresh token.
- */
- public String getRefreshToken() {
- return this.refreshToken;
- }
-
- /**
- * Sets the refresh token to use when refreshing an access token.
- * @param refreshToken a valid refresh token.
- */
- public void setRefreshToken(String refreshToken) {
- this.refreshToken = refreshToken;
- }
-
- /**
- * Enables or disables automatic refreshing of this connection's access token. Defaults to true.
- * @param autoRefresh true to enable auto token refresh; otherwise false.
- */
- public void setAutoRefresh(boolean autoRefresh) {
- this.autoRefresh = autoRefresh;
- }
-
- /**
- * Gets whether or not automatic refreshing of this connection's access token is enabled. Defaults to true.
- * @return true if auto token refresh is enabled; otherwise false.
- */
- public boolean getAutoRefresh() {
- return this.autoRefresh;
- }
-
- /**
- * Gets the maximum number of times an API request will be tried when an error occurs.
- * @return the maximum number of request attempts.
- */
- public int getMaxRequestAttempts() {
- return this.maxRequestAttempts;
- }
-
- /**
- * Sets the maximum number of times an API request will be tried when an error occurs.
- * @param attempts the maximum number of request attempts.
- */
- public void setMaxRequestAttempts(int attempts) {
- this.maxRequestAttempts = attempts;
- }
-
- /**
- * Determines if this connection's access token can be refreshed. An access token cannot be refreshed if a refresh
- * token was never set.
- * @return true if the access token can be refreshed; otherwise false.
- */
- public boolean canRefresh() {
- return this.refreshToken != null;
- }
-
- /**
- * Determines if this connection's access token has expired and needs to be refreshed.
- * @return true if the access token needs to be refreshed; otherwise false.
- */
- public boolean needsRefresh() {
- boolean needsRefresh;
-
- this.refreshLock.readLock().lock();
- if (this.expires == 0) {
- needsRefresh = false;
- } else {
- long now = System.currentTimeMillis();
- long tokenDuration = (now - this.lastRefresh);
- needsRefresh = (tokenDuration >= this.expires - REFRESH_EPSILON);
- }
- this.refreshLock.readLock().unlock();
-
- return needsRefresh;
- }
-
- /**
- * Refresh's this connection's access token using its refresh token.
- * @throws IllegalStateException if this connection's access token cannot be refreshed.
- */
- public void refresh() {
- this.refreshLock.writeLock().lock();
-
- if (!this.canRefresh()) {
- this.refreshLock.writeLock().unlock();
- throw new IllegalStateException("The BoxAPIConnection cannot be refreshed because it doesn't have a "
- + "refresh token.");
- }
-
- URL url = null;
- try {
- url = new URL(this.tokenURL);
- } catch (MalformedURLException e) {
- this.refreshLock.writeLock().unlock();
- assert false : "An invalid refresh URL indicates a bug in the SDK.";
- throw new RuntimeException("An invalid refresh URL indicates a bug in the SDK.", e);
- }
-
- String urlParameters = String.format("grant_type=refresh_token&refresh_token=%s&client_id=%s&client_secret=%s",
- this.refreshToken, this.clientID, this.clientSecret);
-
- BoxAPIRequest request = new BoxAPIRequest(url, "POST");
- request.addHeader("Content-Type", "application/x-www-form-urlencoded");
- request.setBody(urlParameters);
-
- String json;
- try {
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- json = response.getJSON();
- } catch (BoxAPIException e) {
- this.refreshLock.writeLock().unlock();
- throw e;
- }
-
- JsonObject jsonObject = JsonObject.readFrom(json);
- this.accessToken = jsonObject.get("access_token").asString();
- this.refreshToken = jsonObject.get("refresh_token").asString();
- this.lastRefresh = System.currentTimeMillis();
- this.expires = jsonObject.get("expires_in").asLong() * 1000;
-
- this.notifyRefresh();
-
- this.refreshLock.writeLock().unlock();
- }
-
- /**
- * Notifies refresh event to all the listeners.
- */
- private void notifyRefresh() {
- for (BoxAPIConnectionListener listener : this.listeners) {
- listener.onRefresh();
- }
- }
-
- /**
- * Add a listener to listen to Box API connection events.
- * @param listener a listener to listen to Box API connection.
- */
- public void addListener(BoxAPIConnectionListener listener) {
- this.listeners.add(listener);
- }
-
- /**
- * Remove a listener listening to Box API connection events.
- * @param listener the listener to remove.
- */
- public void removeListener(BoxAPIConnectionListener listener) {
- this.listeners.remove(listener);
- }
-
- /**
- * Gets the RequestInterceptor associated with this API connection.
- * @return the RequestInterceptor associated with this API connection.
- */
- public RequestInterceptor getRequestInterceptor() {
- return this.interceptor;
- }
-
- /**
- * Sets a RequestInterceptor that can intercept requests and manipulate them before they're sent to the Box API.
- * @param interceptor the RequestInterceptor.
- */
- public void setRequestInterceptor(RequestInterceptor interceptor) {
- this.interceptor = interceptor;
- }
-}
diff --git a/src/main/java/com/box/sdk/BoxAPIConnectionListener.java b/src/main/java/com/box/sdk/BoxAPIConnectionListener.java
deleted file mode 100644
index c2f2996db..000000000
--- a/src/main/java/com/box/sdk/BoxAPIConnectionListener.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package com.box.sdk;
-
-/**
- * Listener to listen to Box API connection events.
- */
-public interface BoxAPIConnectionListener {
-
- /**
- * Called when the Box API connection refreshes its tokens.
- */
- void onRefresh();
-}
diff --git a/src/main/java/com/box/sdk/BoxAPIException.java b/src/main/java/com/box/sdk/BoxAPIException.java
deleted file mode 100644
index 4d30d6c97..000000000
--- a/src/main/java/com/box/sdk/BoxAPIException.java
+++ /dev/null
@@ -1,77 +0,0 @@
-package com.box.sdk;
-
-/**
- * Thrown to indicate that an error occurred while communicating with the Box API.
- */
-public class BoxAPIException extends RuntimeException {
- private static final long serialVersionUID = 1L;
-
- private final int responseCode;
- private final String response;
-
- /**
- * Constructs a BoxAPIException with a specified message.
- * @param message a message explaining why the exception occurred.
- */
- public BoxAPIException(String message) {
- super(message);
-
- this.responseCode = 0;
- this.response = null;
- }
-
- /**
- * Constructs a BoxAPIException with details about the server's response.
- * @param message a message explaining why the exception occurred.
- * @param responseCode the response code returned by the Box server.
- * @param response the response body returned by the Box server.
- */
- public BoxAPIException(String message, int responseCode, String response) {
- super(message);
-
- this.responseCode = responseCode;
- this.response = response;
- }
-
- /**
- * Constructs a BoxAPIException that wraps another underlying exception.
- * @param message a message explaining why the exception occurred.
- * @param cause an underlying exception.
- */
- public BoxAPIException(String message, Throwable cause) {
- super(message, cause);
-
- this.responseCode = 0;
- this.response = null;
- }
-
- /**
- * Constructs a BoxAPIException that wraps another underlying exception with details about the server's response.
- * @param message a message explaining why the exception occurred.
- * @param responseCode the response code returned by the Box server.
- * @param response the response body returned by the Box server.
- * @param cause an underlying exception.
- */
- public BoxAPIException(String message, int responseCode, String response, Throwable cause) {
- super(message, cause);
-
- this.responseCode = responseCode;
- this.response = response;
- }
-
- /**
- * Gets the response code returned by the server when this exception was thrown.
- * @return the response code returned by the server.
- */
- public int getResponseCode() {
- return this.responseCode;
- }
-
- /**
- * Gets the body of the response returned by the server when this exception was thrown.
- * @return the body of the response returned by the server.
- */
- public String getResponse() {
- return this.response;
- }
-}
diff --git a/src/main/java/com/box/sdk/BoxAPIRequest.java b/src/main/java/com/box/sdk/BoxAPIRequest.java
deleted file mode 100644
index ba1210ca8..000000000
--- a/src/main/java/com/box/sdk/BoxAPIRequest.java
+++ /dev/null
@@ -1,471 +0,0 @@
-package com.box.sdk;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
-import java.net.ProtocolException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Used to make HTTP requests to the Box API.
- *
- *
All requests to the REST API are sent using this class or one of its subclasses. This class wraps {@link
- * HttpURLConnection} in order to provide a simpler interface that can automatically handle various conditions specific
- * to Box's API. Requests will be authenticated using a {@link BoxAPIConnection} (if one is provided), so it isn't
- * necessary to add authorization headers. Requests can also be sent more than once, unlike with HttpURLConnection. If
- * an error occurs while sending a request, it will be automatically retried (with a back off delay) up to the maximum
- * number of times set in the BoxAPIConnection.
- *
- *
Specifying a body for a BoxAPIRequest is done differently than it is with HttpURLConnection. Instead of writing to
- * an OutputStream, the request is provided an {@link InputStream} which will be read when the {@link #send} method is
- * called. This makes it easy to retry requests since the stream can automatically reset and reread with each attempt.
- * If the stream cannot be reset, then a new stream will need to be provided before each call to send. There is also a
- * convenience method for specifying the body as a String, which simply wraps the String with an InputStream.
- */
-public class BoxAPIRequest {
- private static final Logger LOGGER = Logger.getLogger(BoxAPIRequest.class.getName());
- private static final int BUFFER_SIZE = 8192;
- private static final int MAX_REDIRECTS = 3;
-
- private final BoxAPIConnection api;
- private final List headers;
- private final String method;
-
- private URL url;
- private BackoffCounter backoffCounter;
- private int timeout;
- private InputStream body;
- private long bodyLength;
- private Map> requestProperties;
- private int numRedirects;
-
- /**
- * Constructs an unauthenticated BoxAPIRequest.
- * @param url the URL of the request.
- * @param method the HTTP method of the request.
- */
- public BoxAPIRequest(URL url, String method) {
- this(null, url, method);
- }
-
- /**
- * Constructs an authenticated BoxAPIRequest using a provided BoxAPIConnection.
- * @param api an API connection for authenticating the request.
- * @param url the URL of the request.
- * @param method the HTTP method of the request.
- */
- public BoxAPIRequest(BoxAPIConnection api, URL url, String method) {
- this.api = api;
- this.url = url;
- this.method = method;
- this.headers = new ArrayList();
- this.backoffCounter = new BackoffCounter(new Time());
-
- this.addHeader("Accept-Encoding", "gzip");
- this.addHeader("Accept-Charset", "utf-8");
- }
-
- /**
- * Adds an HTTP header to this request.
- * @param key the header key.
- * @param value the header value.
- */
- public void addHeader(String key, String value) {
- this.headers.add(new RequestHeader(key, value));
- }
-
- /**
- * Sets a timeout for this request in milliseconds.
- * @param timeout the timeout in milliseconds.
- */
- public void setTimeout(int timeout) {
- this.timeout = timeout;
- }
-
- /**
- * Sets the request body to the contents of an InputStream.
- *
- *
The stream must support the {@link InputStream#reset} method if auto-retry is used or if the request needs to
- * be resent. Otherwise, the body must be manually set before each call to {@link #send}.
- *
- * @param stream an InputStream containing the contents of the body.
- */
- public void setBody(InputStream stream) {
- this.body = stream;
- }
-
- /**
- * Sets the request body to the contents of an InputStream.
- *
- *
Providing the length of the InputStream allows for the progress of the request to be monitored when calling
- * {@link #send(ProgressListener)}.
- *
- *
See {@link #setBody(InputStream)} for more information on setting the body of the request.
- *
- * @param stream an InputStream containing the contents of the body.
- * @param length the expected length of the stream.
- */
- public void setBody(InputStream stream, long length) {
- this.bodyLength = length;
- this.body = stream;
- }
-
- /**
- * Sets the request body to the contents of a String.
- *
- *
If the contents of the body are large, then it may be more efficient to use an {@link InputStream} instead of
- * a String. Using a String requires that the entire body be in memory before sending the request.
- *
- * @param body a String containing the contents of the body.
- */
- public void setBody(String body) {
- byte[] bytes = body.getBytes(StandardCharsets.UTF_8);
- this.bodyLength = bytes.length;
- this.body = new ByteArrayInputStream(bytes);
- }
-
- /**
- * Sends this request and returns a BoxAPIResponse containing the server's response.
- *
- *
The type of the returned BoxAPIResponse will be based on the content type returned by the server, allowing it
- * to be cast to a more specific type. For example, if it's known that the API call will return a JSON response,
- * then it can be cast to a {@link BoxJSONResponse} like so:
If the server returns an error code or if a network error occurs, then the request will be automatically
- * retried. If the maximum number of retries is reached and an error still occurs, then a {@link BoxAPIException}
- * will be thrown.
- *
- * @throws BoxAPIException if the server returns an error code or if a network error occurs.
- * @return a {@link BoxAPIResponse} containing the server's response.
- */
- public BoxAPIResponse send() {
- return this.send(null);
- }
-
- /**
- * Sends this request while monitoring its progress and returns a BoxAPIResponse containing the server's response.
- *
- *
A ProgressListener is generally only useful when the size of the request is known beforehand. If the size is
- * unknown, then the ProgressListener will be updated for each byte sent, but the total number of bytes will be
- * reported as 0.
- *
- *
See {@link #send} for more information on sending requests.
- *
- * @param listener a listener for monitoring the progress of the request.
- * @throws BoxAPIException if the server returns an error code or if a network error occurs.
- * @return a {@link BoxAPIResponse} containing the server's response.
- */
- public BoxAPIResponse send(ProgressListener listener) {
- if (this.api == null) {
- this.backoffCounter.reset(BoxAPIConnection.DEFAULT_MAX_ATTEMPTS);
- } else {
- this.backoffCounter.reset(this.api.getMaxRequestAttempts());
- }
-
- while (this.backoffCounter.getAttemptsRemaining() > 0) {
- try {
- return this.trySend(listener);
- } catch (BoxAPIException apiException) {
- if (!this.backoffCounter.decrement() || !isResponseRetryable(apiException.getResponseCode())) {
- throw apiException;
- }
-
- try {
- this.resetBody();
- } catch (IOException ioException) {
- throw apiException;
- }
-
- try {
- this.backoffCounter.waitBackoff();
- } catch (InterruptedException interruptedException) {
- Thread.currentThread().interrupt();
- throw apiException;
- }
- }
- }
-
- throw new RuntimeException();
- }
-
- /**
- * Returns a String containing the URL, HTTP method, headers and body of this request.
- * @return a String containing information about this request.
- */
- @Override
- public String toString() {
- String lineSeparator = System.getProperty("line.separator");
- StringBuilder builder = new StringBuilder();
- builder.append("Request");
- builder.append(lineSeparator);
- builder.append(this.method);
- builder.append(' ');
- builder.append(this.url.toString());
- builder.append(lineSeparator);
-
- for (Map.Entry> entry : this.requestProperties.entrySet()) {
- List nonEmptyValues = new ArrayList();
- for (String value : entry.getValue()) {
- if (value != null && value.trim().length() != 0) {
- nonEmptyValues.add(value);
- }
- }
-
- if (nonEmptyValues.size() == 0) {
- continue;
- }
-
- builder.append(entry.getKey());
- builder.append(": ");
- for (String value : nonEmptyValues) {
- builder.append(value);
- builder.append(", ");
- }
-
- builder.delete(builder.length() - 2, builder.length());
- builder.append(lineSeparator);
- }
-
- String bodyString = this.bodyToString();
- if (bodyString != null) {
- builder.append(lineSeparator);
- builder.append(bodyString);
- }
-
- return builder.toString().trim();
- }
-
- /**
- * Returns a String representation of this request's body used in {@link #toString}. This method returns
- * null by default.
- *
- *
A subclass may want override this method if the body can be converted to a String for logging or debugging
- * purposes.
- *
- * @return a String representation of this request's body.
- */
- protected String bodyToString() {
- return null;
- }
-
- /**
- * Writes the body of this request to an HttpURLConnection.
- *
- *
Subclasses overriding this method must remember to close the connection's OutputStream after writing.
- *
- * @param connection the connection to which the body should be written.
- * @param listener an optional listener for monitoring the write progress.
- * @throws BoxAPIException if an error occurs while writing to the connection.
- */
- protected void writeBody(HttpURLConnection connection, ProgressListener listener) {
- if (this.body == null) {
- return;
- }
-
- connection.setDoOutput(true);
- try {
- OutputStream output = connection.getOutputStream();
- if (listener != null) {
- output = new ProgressOutputStream(output, listener, this.bodyLength);
- }
- int b = this.body.read();
- while (b != -1) {
- output.write(b);
- b = this.body.read();
- }
- output.close();
- } catch (IOException e) {
- throw new BoxAPIException("Couldn't connect to the Box API due to a network error.", e);
- }
- }
-
- /**
- * Resets the InputStream containing this request's body.
- *
- *
This method will be called before each attempt to resend the request, giving subclasses an opportunity to
- * reset any streams that need to be read when sending the body.
- *
- * @throws IOException if the stream cannot be reset.
- */
- protected void resetBody() throws IOException {
- if (this.body != null) {
- this.body.reset();
- }
- }
-
- void setBackoffCounter(BackoffCounter counter) {
- this.backoffCounter = counter;
- }
-
- private BoxAPIResponse trySend(ProgressListener listener) {
- if (this.api != null) {
- RequestInterceptor interceptor = this.api.getRequestInterceptor();
- if (interceptor != null) {
- BoxAPIResponse response = interceptor.onRequest(this);
- if (response != null) {
- return response;
- }
- }
- }
-
- HttpURLConnection connection = this.createConnection();
-
- if (this.bodyLength > 0) {
- connection.setFixedLengthStreamingMode((int) this.bodyLength);
- connection.setDoOutput(true);
- }
-
- if (this.api != null) {
- connection.addRequestProperty("Authorization", "Bearer " + this.api.getAccessToken());
- connection.setRequestProperty("User-Agent", this.api.getUserAgent());
-
- if (this.api instanceof SharedLinkAPIConnection) {
- SharedLinkAPIConnection sharedItemAPI = (SharedLinkAPIConnection) this.api;
- String sharedLink = sharedItemAPI.getSharedLink();
- String boxAPIValue = "shared_link=" + sharedLink;
- String sharedLinkPassword = sharedItemAPI.getSharedLinkPassword();
- if (sharedLinkPassword != null) {
- boxAPIValue += "&shared_link_password=" + sharedLinkPassword;
- }
- connection.addRequestProperty("BoxApi", boxAPIValue);
- }
- }
-
- this.requestProperties = connection.getRequestProperties();
- this.writeBody(connection, listener);
-
- // Ensure that we're connected in case writeBody() didn't write anything.
- try {
- connection.connect();
- } catch (IOException e) {
- throw new BoxAPIException("Couldn't connect to the Box API due to a network error.", e);
- }
-
- this.logRequest(connection);
-
- // We need to manually handle redirects by creating a new HttpURLConnection so that connection pooling happens
- // correctly. There seems to be a bug in Oracle's Java implementation where automatically handled redirects will
- // not keep the connection alive.
- int responseCode;
- try {
- responseCode = connection.getResponseCode();
- } catch (IOException e) {
- throw new BoxAPIException("Couldn't connect to the Box API due to a network error.", e);
- }
- if (isResponseRedirect(responseCode)) {
- return this.handleRedirect(connection, listener);
- }
-
- String contentType = connection.getContentType();
- BoxAPIResponse response;
- if (contentType == null) {
- response = new BoxAPIResponse(connection);
- } else if (contentType.contains("application/json")) {
- response = new BoxJSONResponse(connection);
- } else {
- response = new BoxAPIResponse(connection);
- }
-
- return response;
- }
-
- private BoxAPIResponse handleRedirect(HttpURLConnection connection, ProgressListener listener) {
- if (this.numRedirects >= MAX_REDIRECTS) {
- throw new BoxAPIException("The Box API responded with too many redirects.");
- }
- this.numRedirects++;
-
- // Even though the redirect response won't have a body, we need to read the InputStream so that Java will put
- // the connection back in the connection pool.
- try {
- InputStream stream = connection.getInputStream();
- byte[] buffer = new byte[8192];
- int n = stream.read(buffer);
- while (n != -1) {
- n = stream.read(buffer);
- }
- stream.close();
- } catch (IOException e) {
- throw new BoxAPIException("Couldn't connect to the Box API due to a network error.", e);
- }
-
- String redirect = connection.getHeaderField("Location");
- try {
- this.url = new URL(redirect);
- } catch (MalformedURLException e) {
- throw new BoxAPIException("The Box API responded with an invalid redirect.", e);
- }
- return this.trySend(listener);
- }
-
- private void logRequest(HttpURLConnection connection) {
- if (LOGGER.isLoggable(Level.FINE)) {
- LOGGER.log(Level.FINE, this.toString());
- }
- }
-
- private HttpURLConnection createConnection() {
- HttpURLConnection connection = null;
-
- try {
- connection = (HttpURLConnection) this.url.openConnection();
- } catch (IOException e) {
- throw new BoxAPIException("Couldn't connect to the Box API due to a network error.", e);
- }
-
- try {
- connection.setRequestMethod(this.method);
- } catch (ProtocolException e) {
- throw new BoxAPIException("Couldn't connect to the Box API because the request's method was invalid.", e);
- }
-
- connection.setConnectTimeout(this.timeout);
- connection.setReadTimeout(this.timeout);
-
- // Don't allow HttpURLConnection to automatically redirect because it messes up the connection pool. See the
- // trySend(ProgressListener) method for how we handle redirects.
- connection.setInstanceFollowRedirects(false);
-
- for (RequestHeader header : this.headers) {
- connection.addRequestProperty(header.getKey(), header.getValue());
- }
-
- return connection;
- }
-
- private static boolean isResponseRetryable(int responseCode) {
- return (responseCode >= 500 || responseCode == 429);
- }
-
- private static boolean isResponseRedirect(int responseCode) {
- return (responseCode == 301 || responseCode == 302);
- }
-
- private final class RequestHeader {
- private final String key;
- private final String value;
-
- public RequestHeader(String key, String value) {
- this.key = key;
- this.value = value;
- }
-
- public String getKey() {
- return this.key;
- }
-
- public String getValue() {
- return this.value;
- }
- }
-}
diff --git a/src/main/java/com/box/sdk/BoxAPIResponse.java b/src/main/java/com/box/sdk/BoxAPIResponse.java
deleted file mode 100644
index 0b1204481..000000000
--- a/src/main/java/com/box/sdk/BoxAPIResponse.java
+++ /dev/null
@@ -1,258 +0,0 @@
-package com.box.sdk;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.net.HttpURLConnection;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import java.util.zip.GZIPInputStream;
-
-/**
- * Used to read HTTP responses from the Box API.
- *
- *
All responses from the REST API are read using this class or one of its subclasses. This class wraps {@link
- * HttpURLConnection} in order to provide a simpler interface that can automatically handle various conditions specific
- * to Box's API. When a response is contructed, it will throw a {@link BoxAPIException} if the response from the API
- * was an error. Therefore every BoxAPIResponse instance is guaranteed to represent a successful response.
- *
- *
This class usually isn't instantiated directly, but is instead returned after calling {@link BoxAPIRequest#send}.
- *
- */
-public class BoxAPIResponse {
- private static final Logger LOGGER = Logger.getLogger(BoxAPIResponse.class.getName());
- private static final int BUFFER_SIZE = 8192;
-
- private final HttpURLConnection connection;
-
- private int responseCode;
- private String bodyString;
-
- /**
- * The raw InputStream is the stream returned directly from HttpURLConnection.getInputStream(). We need to keep
- * track of this stream in case we need to access it after wrapping it inside another stream.
- */
- private InputStream rawInputStream;
-
- /**
- * The regular InputStream is the stream that will be returned by getBody(). This stream might be a GZIPInputStream
- * or a ProgressInputStream (or both) that wrap the raw InputStream.
- */
- private InputStream inputStream;
-
- /**
- * Constructs an empty BoxAPIResponse without an associated HttpURLConnection.
- */
- public BoxAPIResponse() {
- this.connection = null;
- }
-
- /**
- * Constructs a BoxAPIResponse using an HttpURLConnection.
- * @param connection a connection that has already sent a request to the API.
- */
- public BoxAPIResponse(HttpURLConnection connection) {
- this.connection = connection;
- this.inputStream = null;
-
- try {
- this.responseCode = this.connection.getResponseCode();
- } catch (IOException e) {
- throw new BoxAPIException("Couldn't connect to the Box API due to a network error.", e);
- }
-
- if (!isSuccess(this.responseCode)) {
- this.logResponse();
- throw new BoxAPIException("The API returned an error code: " + this.responseCode, this.responseCode,
- this.bodyToString());
- }
-
- this.logResponse();
- }
-
- /**
- * Gets the response code returned by the API.
- * @return the response code returned by the API.
- */
- public int getResponseCode() {
- return this.responseCode;
- }
-
- /**
- * Gets the length of this response's body as indicated by the "Content-Length" header.
- * @return the length of the response's body.
- */
- public long getContentLength() {
- return this.connection.getContentLength();
- }
-
- /**
- * Gets an InputStream for reading this response's body.
- * @return an InputStream for reading the response's body.
- */
- public InputStream getBody() {
- return this.getBody(null);
- }
-
- /**
- * Gets an InputStream for reading this response's body which will report its read progress to a ProgressListener.
- * @param listener a listener for monitoring the read progress of the body.
- * @return an InputStream for reading the response's body.
- */
- public InputStream getBody(ProgressListener listener) {
- if (this.inputStream == null) {
- String contentEncoding = this.connection.getContentEncoding();
- try {
- if (this.rawInputStream == null) {
- this.rawInputStream = this.connection.getInputStream();
- }
-
- if (listener == null) {
- this.inputStream = this.rawInputStream;
- } else {
- this.inputStream = new ProgressInputStream(this.rawInputStream, listener,
- this.getContentLength());
- }
-
- if (contentEncoding != null && contentEncoding.equalsIgnoreCase("gzip")) {
- this.inputStream = new GZIPInputStream(this.inputStream);
- }
- } catch (IOException e) {
- throw new BoxAPIException("Couldn't connect to the Box API due to a network error.", e);
- }
- }
-
- return this.inputStream;
- }
-
- /**
- * Disconnects this response from the server and frees up any network resources. The body of this response can no
- * longer be read after it has been disconnected.
- */
- public void disconnect() {
- try {
- if (this.rawInputStream == null) {
- this.rawInputStream = this.connection.getInputStream();
- }
-
- // We need to manually read from the raw input stream in case there are any remaining bytes. There's a bug
- // where a wrapping GZIPInputStream may not read to the end of a chunked response, causing Java to not
- // return the connection to the connection pool.
- byte[] buffer = new byte[BUFFER_SIZE];
- int n = this.rawInputStream.read(buffer);
- while (n != -1) {
- n = this.rawInputStream.read(buffer);
- }
- this.rawInputStream.close();
-
- if (this.inputStream != null) {
- this.inputStream.close();
- }
- } catch (IOException e) {
- throw new BoxAPIException("Couldn't finish closing the connection to the Box API due to a network error or "
- + "because the stream was already closed.", e);
- }
- }
-
- @Override
- public String toString() {
- String lineSeparator = System.getProperty("line.separator");
- Map> headers = this.connection.getHeaderFields();
- StringBuilder builder = new StringBuilder();
- builder.append("Response");
- builder.append(lineSeparator);
- builder.append(this.connection.getRequestMethod());
- builder.append(' ');
- builder.append(this.connection.getURL().toString());
- builder.append(lineSeparator);
- builder.append(headers.get(null).get(0));
- builder.append(lineSeparator);
-
- for (Map.Entry> entry : headers.entrySet()) {
- String key = entry.getKey();
- if (key == null) {
- continue;
- }
-
- List nonEmptyValues = new ArrayList();
- for (String value : entry.getValue()) {
- if (value != null && value.trim().length() != 0) {
- nonEmptyValues.add(value);
- }
- }
-
- if (nonEmptyValues.size() == 0) {
- continue;
- }
-
- builder.append(key);
- builder.append(": ");
- for (String value : nonEmptyValues) {
- builder.append(value);
- builder.append(", ");
- }
-
- builder.delete(builder.length() - 2, builder.length());
- builder.append(lineSeparator);
- }
-
- String bodyString = this.bodyToString();
- if (bodyString != null && bodyString != "") {
- builder.append(lineSeparator);
- builder.append(bodyString);
- }
-
- return builder.toString().trim();
- }
-
- /**
- * Returns a string representation of this response's body. This method is used when logging this response's body.
- * By default, it returns an empty string (to avoid accidentally logging binary data) unless the response contained
- * an error message.
- * @return a string representation of this response's body.
- */
- protected String bodyToString() {
- if (this.bodyString == null && !isSuccess(this.responseCode)) {
- this.bodyString = readErrorStream(this.connection.getErrorStream());
- }
-
- return this.bodyString;
- }
-
- private void logResponse() {
- if (LOGGER.isLoggable(Level.FINE)) {
- LOGGER.log(Level.FINE, this.toString());
- }
- }
-
- private static boolean isSuccess(int responseCode) {
- return responseCode >= 200 && responseCode < 300;
- }
-
- private static String readErrorStream(InputStream stream) {
- if (stream == null) {
- return null;
- }
-
- InputStreamReader reader = new InputStreamReader(stream, StandardCharsets.UTF_8);
- StringBuilder builder = new StringBuilder();
- char[] buffer = new char[BUFFER_SIZE];
-
- try {
- int read = reader.read(buffer, 0, BUFFER_SIZE);
- while (read != -1) {
- builder.append(buffer, 0, read);
- read = reader.read(buffer, 0, BUFFER_SIZE);
- }
-
- reader.close();
- } catch (IOException e) {
- return null;
- }
-
- return builder.toString();
- }
-}
diff --git a/src/main/java/com/box/sdk/BoxCollaboration.java b/src/main/java/com/box/sdk/BoxCollaboration.java
deleted file mode 100644
index a80f39220..000000000
--- a/src/main/java/com/box/sdk/BoxCollaboration.java
+++ /dev/null
@@ -1,408 +0,0 @@
-package com.box.sdk;
-
-import java.net.URL;
-import java.text.ParseException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Date;
-
-import com.eclipsesource.json.JsonArray;
-import com.eclipsesource.json.JsonObject;
-import com.eclipsesource.json.JsonValue;
-
-/**
- * Represents a collaboration between a user and another user or group. Collaborations are Box's equivalent of access
- * control lists. They can be used to set and apply permissions for users or groups to folders.
- *
- *
Unless otherwise noted, the methods in this class can throw an unchecked {@link BoxAPIException} (unchecked
- * meaning that the compiler won't force you to handle it) if an error occurs. If you wish to implement custom error
- * handling for errors related to the Box REST API, you should capture this exception explicitly.
- */
-public class BoxCollaboration extends BoxResource {
- private static final URLTemplate COLLABORATIONS_URL_TEMPLATE = new URLTemplate("collaborations");
- private static final URLTemplate PENDING_COLLABORATIONS_URL = new URLTemplate("collaborations?status=pending");
- private static final URLTemplate COLLABORATION_URL_TEMPLATE = new URLTemplate("collaborations/%s");
-
- /**
- * Constructs a BoxCollaboration for a collaboration with a given ID.
- * @param api the API connection to be used by the collaboration.
- * @param id the ID of the collaboration.
- */
- public BoxCollaboration(BoxAPIConnection api, String id) {
- super(api, id);
- }
-
- /**
- * Gets all pending collaboration invites for the current user.
- * @param api the API connection to use.
- * @return a collection of pending collaboration infos.
- */
- public static Collection getPendingCollaborations(BoxAPIConnection api) {
- URL url = PENDING_COLLABORATIONS_URL.build(api.getBaseURL());
-
- BoxAPIRequest request = new BoxAPIRequest(api, url, "GET");
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- JsonObject responseJSON = JsonObject.readFrom(response.getJSON());
-
- int entriesCount = responseJSON.get("total_count").asInt();
- Collection collaborations = new ArrayList(entriesCount);
- JsonArray entries = responseJSON.get("entries").asArray();
- for (JsonValue entry : entries) {
- JsonObject entryObject = entry.asObject();
- BoxCollaboration collaboration = new BoxCollaboration(api, entryObject.get("id").asString());
- BoxCollaboration.Info info = collaboration.new Info(entryObject);
- collaborations.add(info);
- }
-
- return collaborations;
- }
-
- /**
- * Gets information about this collaboration.
- * @return info about this collaboration.
- */
- public Info getInfo() {
- BoxAPIConnection api = this.getAPI();
- URL url = COLLABORATIONS_URL_TEMPLATE.build(api.getBaseURL());
-
- BoxAPIRequest request = new BoxAPIRequest(api, url, "GET");
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
- return new Info(jsonObject);
- }
-
- /**
- * Updates the information about this collaboration with any info fields that have been modified locally.
- * @param info the updated info.
- */
- public void updateInfo(Info info) {
- BoxAPIConnection api = this.getAPI();
- URL url = COLLABORATION_URL_TEMPLATE.build(api.getBaseURL(), this.getID());
-
- BoxJSONRequest request = new BoxJSONRequest(api, url, "PUT");
- request.setBody(info.getPendingChanges());
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
- info.update(jsonObject);
- }
-
- /**
- * Deletes this collaboration.
- */
- public void delete() {
- BoxAPIConnection api = this.getAPI();
- URL url = COLLABORATION_URL_TEMPLATE.build(api.getBaseURL(), this.getID());
-
- BoxAPIRequest request = new BoxAPIRequest(api, url, "DELETE");
- BoxAPIResponse response = request.send();
- response.disconnect();
- }
-
- /**
- * Contains information about a BoxCollaboration.
- */
- public class Info extends BoxResource.Info {
- private BoxUser.Info createdBy;
- private Date createdAt;
- private Date modifiedAt;
- private Date expiresAt;
- private Status status;
- private BoxCollaborator.Info accessibleBy;
- private Role role;
- private Date acknowledgedAt;
- private BoxFolder.Info item;
-
- /**
- * Constructs an empty Info object.
- */
- public Info() {
- super();
- }
-
- /**
- * Constructs an Info object by parsing information from a JSON string.
- * @param json the JSON string to parse.
- */
- public Info(String json) {
- super(json);
- }
-
- Info(JsonObject jsonObject) {
- super(jsonObject);
- }
-
- /**
- * Gets the user who created the collaboration.
- * @return the user who created the collaboration.
- */
- public BoxUser.Info getCreatedBy() {
- return this.createdBy;
- }
-
- /**
- * Gets the time the collaboration was created.
- * @return the time the collaboration was created.
- */
- public Date getCreatedAt() {
- return this.createdAt;
- }
-
- /**
- * Gets the time the collaboration was last modified.
- * @return the time the collaboration was last modified.
- */
- public Date getModifiedAt() {
- return this.modifiedAt;
- }
-
- /**
- * Gets the time the collaboration will expire.
- * @return the time the collaboration will expire.
- */
- public Date getExpiresAt() {
- return this.expiresAt;
- }
-
- /**
- * Gets the status of the collaboration.
- * @return the status of the collaboration.
- */
- public Status getStatus() {
- return this.status;
- }
-
- /**
- * Sets the status of the collaboration in order to accept or reject the collaboration if it's pending.
- * @param status the new status of the collaboration.
- */
- public void setStatus(Status status) {
- this.status = status;
- this.addPendingChange("status", status.name().toLowerCase());
- }
-
- /**
- * Gets the collaborator who this collaboration applies to.
- * @return the collaborator who this collaboration applies to.
- */
- public BoxCollaborator.Info getAccessibleBy() {
- return this.accessibleBy;
- }
-
- /**
- * Gets the level of access the collaborator has.
- * @return the level of access the collaborator has.
- */
- public Role getRole() {
- return this.role;
- }
-
- /**
- * Sets the level of access the collaborator has.
- * @param role the new level of access to give the collaborator.
- */
- public void setRole(Role role) {
- this.role = role;
- this.addPendingChange("role", role.toJSONString());
- }
-
- /**
- * Gets the time the collaboration's status was changed.
- * @return the time the collaboration's status was changed.
- */
- public Date getAcknowledgedAt() {
- return this.acknowledgedAt;
- }
-
- /**
- * Gets the folder the collaboration is related to.
- * @return the folder the collaboration is related to.
- */
- public BoxFolder.Info getItem() {
- return this.item;
- }
-
- @Override
- public BoxCollaboration getResource() {
- return BoxCollaboration.this;
- }
-
- @Override
- protected void parseJSONMember(JsonObject.Member member) {
- super.parseJSONMember(member);
-
- String memberName = member.getName();
- JsonValue value = member.getValue();
- try {
- if (memberName.equals("created_by")) {
- JsonObject userJSON = value.asObject();
- if (this.createdBy == null) {
- String userID = userJSON.get("id").asString();
- BoxUser user = new BoxUser(getAPI(), userID);
- this.createdBy = user.new Info(userJSON);
- } else {
- this.createdBy.update(userJSON);
- }
-
- } else if (memberName.equals("created_at")) {
- this.createdAt = BoxDateFormat.parse(value.asString());
-
- } else if (memberName.equals("modified_at")) {
- this.modifiedAt = BoxDateFormat.parse(value.asString());
-
- } else if (memberName.equals("expires_at")) {
- this.expiresAt = BoxDateFormat.parse(value.asString());
-
- } else if (memberName.equals("status")) {
- String statusString = value.asString().toUpperCase();
- this.status = Status.valueOf(statusString);
-
- } else if (memberName.equals("accessible_by")) {
- JsonObject userJSON = value.asObject();
- if (this.accessibleBy == null) {
- String userID = userJSON.get("id").asString();
- BoxUser user = new BoxUser(getAPI(), userID);
- BoxUser.Info userInfo = user.new Info(userJSON);
- this.accessibleBy = userInfo;
- } else {
- this.accessibleBy.update(userJSON);
- }
-
- } else if (memberName.equals("role")) {
- this.role = Role.fromJSONString(value.asString());
-
- } else if (memberName.equals("acknowledged_at")) {
- this.acknowledgedAt = BoxDateFormat.parse(value.asString());
-
- } else if (memberName.equals("item")) {
- JsonObject folderJSON = value.asObject();
- if (this.item == null) {
- String folderID = folderJSON.get("id").asString();
- BoxFolder folder = new BoxFolder(getAPI(), folderID);
- this.item = folder.new Info(folderJSON);
- } else {
- this.item.update(folderJSON);
- }
- }
- } catch (ParseException e) {
- assert false : "A ParseException indicates a bug in the SDK.";
- }
- }
- }
-
- /**
- * Enumerates the possible statuses that a collaboration can have.
- */
- public enum Status {
- /**
- * The collaboration has been accepted.
- */
- ACCEPTED,
-
- /**
- * The collaboration is waiting to be accepted or rejected.
- */
- PENDING,
-
- /**
- * The collaboration has been rejected.
- */
- REJECTED;
- }
-
- /**
- * Enumerates the possible access levels that a collaborator can have.
- */
- public enum Role {
- /**
- * An Editor has full read/write access to a folder. Once invited to a folder, they will be able to view,
- * download, upload, edit, delete, copy, move, rename, generate shared links, make comments, assign tasks,
- * create tags, and invite/remove collaborators. They will not be able to delete or move root level folders.
- */
- EDITOR ("editor"),
-
- /**
- * The viewer role has full read access to a folder. Once invited to a folder, they will be able to preview,
- * download, make comments, and generate shared links. They will not be able to add tags, invite new
- * collaborators, upload, edit, or delete items in the folder.
- */
- VIEWER ("viewer"),
-
- /**
- * The previewer role has limited read access to a folder. They will only be able to preview the items in the
- * folder using the integrated content viewer. They will not be able to share, upload, edit, or delete any
- * content. This role is only available to enterprise accounts.
- */
- PREVIEWER ("previewer"),
-
- /**
- * The uploader has limited write access to a folder. They will only be able to upload and see the names of the
- * items in a folder. They will not able to download or view any content. This role is only available to
- * enterprise accounts.
- */
- UPLOADER ("uploader"),
-
- /**
- * The previewer-uploader role is a combination of previewer and uploader. A user with this access level will be
- * able to preview files using the integrated content viewer as well as upload items into the folder. They will
- * not be able to download, edit, or share, items in the folder. This role is only available to enterprise
- * accounts.
- */
- PREVIEWER_UPLOADER ("previewer uploader"),
-
- /**
- * The viewer-uploader role is a combination of viewer and uploader. A viewer-uploader has full read access to a
- * folder and limited write access. They are able to preview, download, add comments, generate shared links, and
- * upload content to the folder. They will not be able to add tags, invite new collaborators, edit, or delete
- * items in the folder. This role is only available to enterprise accounts.
- */
- VIEWER_UPLOADER ("viewer uploader"),
-
- /**
- * The co-owner role has all of the functional read/write access that an editor does. This permission level has
- * the added ability of being able to manage users in the folder. A co-owner can add new collaborators, change
- * access levels of existing collaborators, and remove collaborators. However, they will not be able to
- * manipulate the owner of the folder or transfer ownership to another user. This role is only available to
- * enterprise accounts.
- */
- CO_OWNER ("co-owner"),
-
- /**
- * The owner role has all of the functional capabilities of a co-owner. However, they will be able to manipulate
- * the owner of the folder or transfer ownership to another user. This role is only available to enterprise
- * accounts.
- */
- OWNER ("owner");
-
- private final String jsonValue;
-
- private Role(String jsonValue) {
- this.jsonValue = jsonValue;
- }
-
- static Role fromJSONString(String jsonValue) {
- if (jsonValue.equals("editor")) {
- return EDITOR;
- } else if (jsonValue.equals("viewer")) {
- return VIEWER;
- } else if (jsonValue.equals("previewer")) {
- return PREVIEWER;
- } else if (jsonValue.equals("uploader")) {
- return UPLOADER;
- } else if (jsonValue.equals("previewer uploader")) {
- return PREVIEWER_UPLOADER;
- } else if (jsonValue.equals("viewer uploader")) {
- return VIEWER_UPLOADER;
- } else if (jsonValue.equals("co-owner")) {
- return CO_OWNER;
- } else if (jsonValue.equals("owner")) {
- return OWNER;
- } else {
- throw new IllegalArgumentException("The provided JSON value isn't a valid Role.");
- }
- }
-
- String toJSONString() {
- return this.jsonValue;
- }
- }
-}
diff --git a/src/main/java/com/box/sdk/BoxCollaborator.java b/src/main/java/com/box/sdk/BoxCollaborator.java
deleted file mode 100644
index f9ee21fc2..000000000
--- a/src/main/java/com/box/sdk/BoxCollaborator.java
+++ /dev/null
@@ -1,106 +0,0 @@
-package com.box.sdk;
-
-import java.text.ParseException;
-import java.util.Date;
-
-import com.eclipsesource.json.JsonObject;
-import com.eclipsesource.json.JsonValue;
-
-/**
- * The abstract base class for types that can be added to collaborations.
- */
-public abstract class BoxCollaborator extends BoxResource {
-
- /**
- * Constructs a BoxCollaborator for a collaborator with a given ID.
- * @param api the API connection to be used by the collaborator.
- * @param id the ID of the collaborator.
- */
- public BoxCollaborator(BoxAPIConnection api, String id) {
- super(api, id);
- }
-
- /**
- * Contains information about a BoxCollaborator.
- */
- public abstract class Info extends BoxResource.Info {
- private String name;
- private Date createdAt;
- private Date modifiedAt;
-
- /**
- * Constructs an empty Info object.
- */
- public Info() {
- super();
- }
-
- /**
- * Constructs an Info object by parsing information from a JSON string.
- * @param json the JSON string to parse.
- */
- public Info(String json) {
- super(json);
- }
-
- /**
- * Constructs an Info object using an already parsed JSON object.
- * @param jsonObject the parsed JSON object.
- */
- Info(JsonObject jsonObject) {
- super(jsonObject);
- }
-
- /**
- * Gets the name of the collaborator.
- * @return the name of the collaborator.
- */
- public String getName() {
- return this.name;
- }
-
- /**
- * Sets the name of the collaborator.
- * @param name the new name of the collaborator.
- */
- public void setName(String name) {
- this.name = name;
- this.addPendingChange("name", name);
- }
-
- /**
- * Gets the date that the collaborator was created.
- * @return the date that the collaborator was created.
- */
- public Date getCreatedAt() {
- return this.createdAt;
- }
-
- /**
- * Gets the date that the collaborator was modified.
- * @return the date that the collaborator was modified.
- */
- public Date getModifiedAt() {
- return this.modifiedAt;
- }
-
- @Override
- protected void parseJSONMember(JsonObject.Member member) {
- super.parseJSONMember(member);
-
- try {
- JsonValue value = member.getValue();
- String name = member.getName();
- if (name.equals("name")) {
- this.name = value.asString();
- } else if (name.equals("created_at")) {
- this.createdAt = BoxDateFormat.parse(value.asString());
- } else if (name.equals("modified_at")) {
- this.modifiedAt = BoxDateFormat.parse(value.asString());
- }
- } catch (ParseException e) {
- assert false : "A ParseException indicates a bug in the SDK.";
- }
- }
- }
-}
diff --git a/src/main/java/com/box/sdk/BoxComment.java b/src/main/java/com/box/sdk/BoxComment.java
deleted file mode 100644
index 5b7e5a239..000000000
--- a/src/main/java/com/box/sdk/BoxComment.java
+++ /dev/null
@@ -1,299 +0,0 @@
-package com.box.sdk;
-
-import java.net.URL;
-import java.text.ParseException;
-import java.util.Date;
-import java.util.regex.Pattern;
-
-import com.eclipsesource.json.JsonObject;
-import com.eclipsesource.json.JsonValue;
-
-/**
- * Represents a comment on a file. Comments can be added directly to a file or they can be created as replies to other
- * comments.
- *
- *
Unless otherwise noted, the methods in this class can throw an unchecked {@link BoxAPIException} (unchecked
- * meaning that the compiler won't force you to handle it) if an error occurs. If you wish to implement custom error
- * handling for errors related to the Box REST API, you should capture this exception explicitly.
- */
-public class BoxComment extends BoxResource {
- private static final Pattern MENTION_REGEX = Pattern.compile("@\\[.+:.+\\]");
- private static final URLTemplate ADD_COMMENT_URL_TEMPLATE = new URLTemplate("comments");
- private static final URLTemplate COMMENT_URL_TEMPLATE = new URLTemplate("comments/%s");
-
- /**
- * Constructs a BoxComment for a comment with a given ID.
- * @param api the API connection to be used with the comment.
- * @param id the ID of the comment.
- */
- public BoxComment(BoxAPIConnection api, String id) {
- super(api, id);
- }
-
- /**
- * Determines if a comment message contains an @mention.
- * @param message the comment message.
- * @return true if the message contains an @mention; otherwise false.
- */
- static boolean messageContainsMention(String message) {
- return MENTION_REGEX.matcher(message).find();
- }
-
- /**
- * Gets information about this comment.
- * @return info about this comment.
- */
- public Info getInfo() {
- URL url = COMMENT_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
- BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET");
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- JsonObject jsonResponse = JsonObject.readFrom(response.getJSON());
-
- return new Info(jsonResponse);
- }
-
- /**
- * Changes the message of this comment.
- * @param newMessage the new message for this comment.
- * @return updated info about this comment.
- */
- public Info changeMessage(String newMessage) {
- Info newInfo = new Info();
- newInfo.setMessage(newMessage);
-
- URL url = COMMENT_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
- BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "PUT");
- request.setBody(newInfo.getPendingChanges());
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- JsonObject jsonResponse = JsonObject.readFrom(response.getJSON());
-
- return new Info(jsonResponse);
- }
-
- /**
- * Replies to this comment with another message.
- * @param message the message for the reply.
- * @return info about the newly created reply comment.
- */
- public BoxComment.Info reply(String message) {
- JsonObject itemJSON = new JsonObject();
- itemJSON.add("type", "comment");
- itemJSON.add("id", this.getID());
-
- JsonObject requestJSON = new JsonObject();
- requestJSON.add("item", itemJSON);
- if (BoxComment.messageContainsMention(message)) {
- requestJSON.add("tagged_message", message);
- } else {
- requestJSON.add("message", message);
- }
-
- URL url = ADD_COMMENT_URL_TEMPLATE.build(this.getAPI().getBaseURL());
- BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "POST");
- request.setBody(requestJSON.toString());
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- JsonObject responseJSON = JsonObject.readFrom(response.getJSON());
-
- BoxComment addedComment = new BoxComment(this.getAPI(), responseJSON.get("id").asString());
- return addedComment.new Info(responseJSON);
- }
-
- /**
- * Deletes this comment.
- */
- public void delete() {
- URL url = COMMENT_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
- BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "DELETE");
- BoxAPIResponse response = request.send();
- response.disconnect();
- }
-
- /**
- * Contains information about a BoxComment.
- */
- public class Info extends BoxResource.Info {
- private boolean isReplyComment;
- private String message;
- private String taggedMessage;
- private BoxUser.Info createdBy;
- private Date createdAt;
- private BoxResource.Info item;
- private BoxUser.Info modifiedBy;
-
- /**
- * Constructs an empty Info object.
- */
- public Info() {
- super();
- }
-
- /**
- * Constructs an Info object by parsing information from a JSON string.
- * @param json the JSON string to parse.
- */
- public Info(String json) {
- super(json);
- }
-
- /**
- * Constructs an Info object using an already parsed JSON object.
- * @param jsonObject the parsed JSON object.
- */
- Info(JsonObject jsonObject) {
- super(jsonObject);
- }
-
- /**
- * Gets whether or not the comment is a reply to another comment.
- * @return true if this comment is a reply to another comment; otherwise false.
- */
- public boolean getIsReplyComment() {
- return this.isReplyComment;
- }
-
- /**
- * Gets the comment's message.
- * @return the comment's message.
- */
- public String getMessage() {
- if (this.taggedMessage != null) {
- return this.taggedMessage;
- }
-
- return this.message;
- }
-
- /**
- * Sets the comment's message. The message can contain @mentions by using the string @[userid:username] anywhere
- * within the message, where userid and username are the ID and username of the person being mentioned.
- * @param message the comment's new message.
- */
- public void setMessage(String message) {
- if (messageContainsMention(message)) {
- this.taggedMessage = message;
- this.addPendingChange("tagged_message", message);
- this.removePendingChange("message");
- } else {
- this.message = message;
- this.addPendingChange("message", message);
- this.removePendingChange("tagged_message");
- }
- }
-
- /**
- * Gets info about the user who created the comment.
- * @return info about the user who created the comment.
- */
- public BoxUser.Info getCreatedBy() {
- return this.createdBy;
- }
-
- /**
- * Gets the time the comment was created.
- * @return the time the comment was created.
- */
- public Date getCreatedAt() {
- return this.createdAt;
- }
-
- /**
- * Gets info about the item this comment is attached to. If the comment is a reply, then the item will be
- * another BoxComment. Otherwise, the item will be a {@link BoxFile}.
- * @return the item this comment is attached to.
- */
- public BoxResource.Info getItem() {
- return this.item;
- }
-
- /**
- * Gets info about the user who last modified the comment.
- * @return info about the user who last modified the comment.
- */
- public BoxUser.Info getModifiedBy() {
- return this.modifiedBy;
- }
-
- @Override
- public BoxComment getResource() {
- return BoxComment.this;
- }
-
- @Override
- protected void parseJSONMember(JsonObject.Member member) {
- super.parseJSONMember(member);
-
- try {
- String memberName = member.getName();
- JsonValue value = member.getValue();
- if (memberName.equals("is_reply_comment")) {
- this.isReplyComment = value.asBoolean();
-
- } else if (memberName.equals("message")) {
- this.message = value.asString();
-
- } else if (memberName.equals("tagged_message")) {
- this.taggedMessage = value.asString();
-
- } else if (memberName.equals("created_by")) {
- JsonObject userJSON = value.asObject();
- if (this.createdBy == null) {
- String userID = userJSON.get("id").asString();
- BoxUser user = new BoxUser(getAPI(), userID);
- this.createdBy = user.new Info(userJSON);
- } else {
- this.createdBy.update(userJSON);
- }
-
- } else if (memberName.equals("created_at")) {
- this.createdAt = BoxDateFormat.parse(value.asString());
-
- } else if (memberName.equals("item")) {
- this.parseItem(value);
-
- } else if (memberName.equals("modified_by")) {
- JsonObject userJSON = value.asObject();
- if (this.modifiedBy == null) {
- String userID = userJSON.get("id").asString();
- BoxUser user = new BoxUser(getAPI(), userID);
- this.modifiedBy = user.new Info(userJSON);
- } else {
- this.modifiedBy.update(userJSON);
- }
- }
- } catch (ParseException e) {
- assert false : "A ParseException indicates a bug in the SDK.";
- }
- }
-
- private void parseItem(JsonValue value) {
- JsonObject itemJSON = value.asObject();
- String itemType = itemJSON.get("type").asString();
- if (itemType.equals("file")) {
- this.updateItemAsFile(itemJSON);
- } else if (itemType.equals("comment")) {
- this.updateItemAsComment(itemJSON);
- }
- }
-
- private void updateItemAsFile(JsonObject itemJSON) {
- String itemID = itemJSON.get("id").asString();
- if (this.item != null && this.item instanceof BoxFile.Info && this.item.getID().equals(itemID)) {
- this.item.update(itemJSON);
- } else {
- BoxFile file = new BoxFile(getAPI(), itemID);
- this.item = file.new Info(itemJSON);
- }
- }
-
- private void updateItemAsComment(JsonObject itemJSON) {
- String itemType = itemJSON.get("type").asString();
- String itemID = itemJSON.get("id").asString();
- if (this.item != null && this.item instanceof BoxComment.Info && this.item.getID().equals(itemID)) {
- this.item.update(itemJSON);
- } else {
- BoxComment comment = new BoxComment(getAPI(), itemID);
- this.item = comment.new Info(itemJSON);
- }
- }
- }
-}
diff --git a/src/main/java/com/box/sdk/BoxDateFormat.java b/src/main/java/com/box/sdk/BoxDateFormat.java
deleted file mode 100644
index 5d3571c09..000000000
--- a/src/main/java/com/box/sdk/BoxDateFormat.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package com.box.sdk;
-
-import java.text.DateFormat;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-/**
- * Contains methods for parsing and formatting dates for use with the Box API.
- */
-public final class BoxDateFormat {
- private static final ThreadLocal THREAD_LOCAL_DATE_FORMAT = new ThreadLocal() {
- @Override
- protected DateFormat initialValue() {
- return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
- }
- };
-
- private BoxDateFormat() { }
-
- /**
- * Parses a date string returned by the Box API into a {@link Date} object.
- * @param dateString a string containing the date.
- * @return the parsed date.
- * @throws ParseException if the string cannot be parsed into a valid date.
- */
- public static Date parse(String dateString) throws ParseException {
- return THREAD_LOCAL_DATE_FORMAT.get().parse(fixIso8601TimeZone(dateString));
- }
-
- /**
- * Formats a date as a string that can be sent to the Box API.
- * @param date the date to format.
- * @return a string containing the formatted date.
- */
- public static String format(Date date) {
- return THREAD_LOCAL_DATE_FORMAT.get().format(date);
- }
-
- /**
- * Helper function to handle ISO 8601 strings of the following format:
- * "2008-03-01T13:00:00+01:00". Note that the final colon (":") in the
- * time zone is not supported by SimpleDateFormat's "Z" token.
- *
- * @param dateString a string containing the date.
- * @return a date string that matches the date format.
- */
- private static String fixIso8601TimeZone(String dateString) {
- if (dateString.length() >= 24 && dateString.charAt(22) == ':') {
- return dateString.substring(0, 22) + dateString.substring(23);
- }
- return dateString;
- }
-}
diff --git a/src/main/java/com/box/sdk/BoxEvent.java b/src/main/java/com/box/sdk/BoxEvent.java
deleted file mode 100644
index 58357f16c..000000000
--- a/src/main/java/com/box/sdk/BoxEvent.java
+++ /dev/null
@@ -1,214 +0,0 @@
-package com.box.sdk;
-
-import com.eclipsesource.json.JsonObject;
-import com.eclipsesource.json.JsonValue;
-
-/**
- * Represents an event that was fired off by the Box events API.
- */
-public class BoxEvent extends BoxResource {
- private BoxResource.Info sourceInfo;
- private BoxEvent.Type type;
-
- /**
- * Constructs a BoxEvent from a JSON string.
- * @param api the API connection to be used by the file.
- * @param json the JSON encoded event.
- */
- public BoxEvent(BoxAPIConnection api, String json) {
- this(api, JsonObject.readFrom(json));
- }
-
- BoxEvent(BoxAPIConnection api, JsonObject jsonObject) {
- super(api, jsonObject.get("event_id").asString());
-
- for (JsonObject.Member member : jsonObject) {
- if (member.getValue().isNull()) {
- continue;
- }
-
- this.parseJsonMember(member);
- }
- }
-
- /**
- * Gets info about the source of this event.
- * @return info about the source of this event.
- */
- public BoxResource.Info getSourceInfo() {
- return this.sourceInfo;
- }
-
- /**
- * Gets the type of this event.
- * @return the type of this event.
- */
- public BoxEvent.Type getType() {
- return this.type;
- }
-
- void parseJsonMember(JsonObject.Member member) {
- JsonValue value = member.getValue();
- if (value.isNull()) {
- return;
- }
-
- String memberName = member.getName();
- if (memberName.equals("source")) {
- this.sourceInfo = BoxResource.parseInfo(this.getAPI(), value.asObject());
-
- } else if (memberName.equals("event_type")) {
- String stringValue = value.asString();
- for (Type t : Type.values()) {
- if (t.name().equals(stringValue)) {
- this.type = t;
- break;
- }
- }
-
- if (this.type == null) {
- this.type = Type.UNKNOWN;
- }
- }
- }
-
- /**
- * Enumerates the possible types for an event.
- */
- public enum Type {
- /**
- * The type of the event is unknown.
- */
- UNKNOWN,
-
- /**
- * An file or folder was created.
- */
- ITEM_CREATE,
-
- /**
- * An file or folder was uploaded.
- */
- ITEM_UPLOAD,
-
- /**
- * A comment was created on a folder, file, or other comment.
- */
- COMMENT_CREATE,
-
- /**
- * An file or folder was downloaded.
- */
- ITEM_DOWNLOAD,
-
- /**
- * A file was previewed.
- */
- ITEM_PREVIEW,
-
- /**
- * A file or folder was moved.
- */
- ITEM_MOVE,
-
- /**
- * A file or folder was copied.
- */
- ITEM_COPY,
-
- /**
- * A task was assigned.
- */
- TASK_ASSIGNMENT_CREATE,
-
- /**
- * A file was locked.
- */
- LOCK_CREATE,
-
- /**
- * A file was unlocked.
- */
- LOCK_DESTROY,
-
- /**
- * A file or folder was deleted.
- */
- ITEM_TRASH,
-
- /**
- * A file or folder was recovered from the trash.
- */
- ITEM_UNDELETE_VIA_TRASH,
-
- /**
- * A collaborator was added to a folder.
- */
- COLLAB_ADD_COLLABORATOR,
-
- /**
- * A collaborator was removed from a folder.
- */
- COLLAB_REMOVE_COLLABORATOR,
-
- /**
- * A collaborator was invited to a folder.
- */
- COLLAB_INVITE_COLLABORATOR,
-
- /**
- * A collaborator's role was change in a folder.
- */
- COLLAB_ROLE_CHANGE,
-
- /**
- * A folder was marked for sync.
- */
- ITEM_SYNC,
-
- /**
- * A folder was un-marked for sync.
- */
- ITEM_UNSYNC,
-
- /**
- * A file or folder was renamed.
- */
- ITEM_RENAME,
-
- /**
- * A file or folder was enabled for sharing.
- */
- ITEM_SHARED_CREATE,
-
- /**
- * A file or folder was disabled for sharing.
- */
- ITEM_SHARED_UNSHARE,
-
- /**
- * A folder was shared.
- */
- ITEM_SHARED,
-
- /**
- * A tag was added to a file or folder.
- */
- TAG_ITEM_CREATE,
-
- /**
- * A user logged in from a new device.
- */
- ADD_LOGIN_ACTIVITY_DEVICE,
-
- /**
- * A user session associated with an app was invalidated.
- */
- REMOVE_LOGIN_ACTIVITY_DEVICE,
-
- /**
- * An admin role changed for a user.
- */
- CHANGE_ADMIN_ROLE;
- }
-}
diff --git a/src/main/java/com/box/sdk/BoxFile.java b/src/main/java/com/box/sdk/BoxFile.java
deleted file mode 100644
index b08eacb18..000000000
--- a/src/main/java/com/box/sdk/BoxFile.java
+++ /dev/null
@@ -1,667 +0,0 @@
-package com.box.sdk;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Date;
-import java.util.EnumSet;
-import java.util.List;
-
-import com.eclipsesource.json.JsonArray;
-import com.eclipsesource.json.JsonObject;
-import com.eclipsesource.json.JsonValue;
-
-/**
- * Represents an individual file on Box. This class can be used to download a file's contents, upload new versions, and
- * perform other common file operations (move, copy, delete, etc.).
- *
- *
Unless otherwise noted, the methods in this class can throw an unchecked {@link BoxAPIException} (unchecked
- * meaning that the compiler won't force you to handle it) if an error occurs. If you wish to implement custom error
- * handling for errors related to the Box REST API, you should capture this exception explicitly.
- */
-public class BoxFile extends BoxItem {
- /**
- * An array of all possible file fields that can be requested when calling {@link #getInfo()}.
- */
- public static final String[] ALL_FIELDS = {"type", "id", "sequence_id", "etag", "sha1", "name", "description",
- "size", "path_collection", "created_at", "modified_at", "trashed_at", "purged_at", "content_created_at",
- "content_modified_at", "created_by", "modified_by", "owned_by", "shared_link", "parent", "item_status",
- "version_number", "comment_count", "permissions", "tags", "lock", "extension", "is_package"};
-
- private static final URLTemplate FILE_URL_TEMPLATE = new URLTemplate("files/%s");
- private static final URLTemplate CONTENT_URL_TEMPLATE = new URLTemplate("files/%s/content");
- private static final URLTemplate VERSIONS_URL_TEMPLATE = new URLTemplate("files/%s/versions");
- private static final URLTemplate COPY_URL_TEMPLATE = new URLTemplate("files/%s/copy");
- private static final URLTemplate ADD_COMMENT_URL_TEMPLATE = new URLTemplate("comments");
- private static final URLTemplate GET_COMMENTS_URL_TEMPLATE = new URLTemplate("files/%s/comments");
- private static final URLTemplate METADATA_URL_TEMPLATE = new URLTemplate("files/%s/metadata/%s");
- private static final String DEFAULT_METADATA_TYPE = "properties";
- private static final int BUFFER_SIZE = 8192;
-
- /**
- * Constructs a BoxFile for a file with a given ID.
- * @param api the API connection to be used by the file.
- * @param id the ID of the file.
- */
- public BoxFile(BoxAPIConnection api, String id) {
- super(api, id);
- }
-
- @Override
- public BoxSharedLink createSharedLink(BoxSharedLink.Access access, Date unshareDate,
- BoxSharedLink.Permissions permissions) {
-
- BoxSharedLink sharedLink = new BoxSharedLink(access, unshareDate, permissions);
- Info info = new Info();
- info.setSharedLink(sharedLink);
-
- this.updateInfo(info);
- return info.getSharedLink();
- }
-
- /**
- * Adds a comment to this file. The message can contain @mentions by using the string @[userid:username] anywhere
- * within the message, where userid and username are the ID and username of the person being mentioned.
- * @see the tagged_message field
- * for including @mentions.
- * @param message the comment's message.
- * @return information about the newly added comment.
- */
- public BoxComment.Info addComment(String message) {
- JsonObject itemJSON = new JsonObject();
- itemJSON.add("type", "file");
- itemJSON.add("id", this.getID());
-
- JsonObject requestJSON = new JsonObject();
- requestJSON.add("item", itemJSON);
- if (BoxComment.messageContainsMention(message)) {
- requestJSON.add("tagged_message", message);
- } else {
- requestJSON.add("message", message);
- }
-
- URL url = ADD_COMMENT_URL_TEMPLATE.build(this.getAPI().getBaseURL());
- BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "POST");
- request.setBody(requestJSON.toString());
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- JsonObject responseJSON = JsonObject.readFrom(response.getJSON());
-
- BoxComment addedComment = new BoxComment(this.getAPI(), responseJSON.get("id").asString());
- return addedComment.new Info(responseJSON);
- }
-
- /**
- * Downloads the contents of this file to a given OutputStream.
- * @param output the stream to where the file will be written.
- */
- public void download(OutputStream output) {
- this.download(output, null);
- }
-
- /**
- * Downloads the contents of this file to a given OutputStream while reporting the progress to a ProgressListener.
- * @param output the stream to where the file will be written.
- * @param listener a listener for monitoring the download's progress.
- */
- public void download(OutputStream output, ProgressListener listener) {
- URL url = CONTENT_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
- BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET");
- BoxAPIResponse response = request.send();
- InputStream input = response.getBody(listener);
-
- byte[] buffer = new byte[BUFFER_SIZE];
- try {
- int n = input.read(buffer);
- while (n != -1) {
- output.write(buffer, 0, n);
- n = input.read(buffer);
- }
- } catch (IOException e) {
- throw new BoxAPIException("Couldn't connect to the Box API due to a network error.", e);
- }
-
- response.disconnect();
- }
-
- /**
- * Downloads a part of this file's contents, starting at specified byte offset.
- * @param output the stream to where the file will be written.
- * @param offset the byte offset at which to start the download.
- */
- public void downloadRange(OutputStream output, long offset) {
- this.downloadRange(output, offset, -1);
- }
-
- /**
- * Downloads a part of this file's contents, starting at rangeStart and stopping at rangeEnd.
- * @param output the stream to where the file will be written.
- * @param rangeStart the byte offset at which to start the download.
- * @param rangeEnd the byte offset at which to stop the download.
- */
- public void downloadRange(OutputStream output, long rangeStart, long rangeEnd) {
- this.downloadRange(output, rangeStart, rangeEnd, null);
- }
-
- /**
- * Downloads a part of this file's contents, starting at rangeStart and stopping at rangeEnd, while reporting the
- * progress to a ProgressListener.
- * @param output the stream to where the file will be written.
- * @param rangeStart the byte offset at which to start the download.
- * @param rangeEnd the byte offset at which to stop the download.
- * @param listener a listener for monitoring the download's progress.
- */
- public void downloadRange(OutputStream output, long rangeStart, long rangeEnd, ProgressListener listener) {
- URL url = CONTENT_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
- BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET");
- if (rangeEnd > 0) {
- request.addHeader("Range", String.format("bytes=%s-%s", Long.toString(rangeStart),
- Long.toString(rangeEnd)));
- } else {
- request.addHeader("Range", String.format("bytes=%s-", Long.toString(rangeStart)));
- }
-
- BoxAPIResponse response = request.send();
- InputStream input = response.getBody(listener);
-
- byte[] buffer = new byte[BUFFER_SIZE];
- try {
- int n = input.read(buffer);
- while (n != -1) {
- output.write(buffer, 0, n);
- n = input.read(buffer);
- }
- } catch (IOException e) {
- throw new BoxAPIException("Couldn't connect to the Box API due to a network error.", e);
- }
-
- response.disconnect();
- }
-
- @Override
- public BoxFile.Info copy(BoxFolder destination) {
- return this.copy(destination, null);
- }
-
- @Override
- public BoxFile.Info copy(BoxFolder destination, String newName) {
- URL url = COPY_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
-
- JsonObject parent = new JsonObject();
- parent.add("id", destination.getID());
-
- JsonObject copyInfo = new JsonObject();
- copyInfo.add("parent", parent);
- if (newName != null) {
- copyInfo.add("name", newName);
- }
-
- BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "POST");
- request.setBody(copyInfo.toString());
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- JsonObject responseJSON = JsonObject.readFrom(response.getJSON());
- BoxFile copiedFile = new BoxFile(this.getAPI(), responseJSON.get("id").asString());
- return copiedFile.new Info(responseJSON);
- }
-
- /**
- * Deletes this file by moving it to the trash.
- */
- public void delete() {
- URL url = FILE_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
- BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "DELETE");
- BoxAPIResponse response = request.send();
- response.disconnect();
- }
-
- @Override
- public BoxItem.Info move(BoxFolder destination) {
- return this.move(destination, null);
- }
-
- @Override
- public BoxItem.Info move(BoxFolder destination, String newName) {
- URL url = FILE_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
- BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "PUT");
-
- JsonObject parent = new JsonObject();
- parent.add("id", destination.getID());
-
- JsonObject updateInfo = new JsonObject();
- updateInfo.add("parent", parent);
- if (newName != null) {
- updateInfo.add("name", newName);
- }
-
- request.setBody(updateInfo.toString());
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- JsonObject responseJSON = JsonObject.readFrom(response.getJSON());
- BoxFile movedFile = new BoxFile(this.getAPI(), responseJSON.get("id").asString());
- return movedFile.new Info(responseJSON);
- }
-
- /**
- * Renames this file.
- * @param newName the new name of the file.
- */
- public void rename(String newName) {
- URL url = FILE_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
- BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "PUT");
-
- JsonObject updateInfo = new JsonObject();
- updateInfo.add("name", newName);
-
- request.setBody(updateInfo.toString());
- BoxAPIResponse response = request.send();
- response.disconnect();
- }
-
- @Override
- public BoxFile.Info getInfo() {
- URL url = FILE_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
- BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET");
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- return new Info(response.getJSON());
- }
-
- @Override
- public BoxFile.Info getInfo(String... fields) {
- String queryString = new QueryStringBuilder().appendParam("fields", fields).toString();
- URL url = FILE_URL_TEMPLATE.buildWithQuery(this.getAPI().getBaseURL(), queryString, this.getID());
-
- BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET");
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- return new Info(response.getJSON());
- }
-
- /**
- * Updates the information about this file with any info fields that have been modified locally.
- *
- *
The only fields that will be updated are the ones that have been modified locally. For example, the following
- * code won't update any information (or even send a network request) since none of the info's fields were
- * changed:
- *
- *
BoxFile file = new File(api, id);
- *BoxFile.Info info = file.getInfo();
- *file.updateInfo(info);
- *
- * @param info the updated info.
- */
- public void updateInfo(BoxFile.Info info) {
- URL url = FILE_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
- BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "PUT");
- request.setBody(info.getPendingChanges());
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
- info.update(jsonObject);
- }
-
- /**
- * Gets any previous versions of this file. Note that only users with premium accounts will be able to retrieve
- * previous versions of their files.
- * @return a list of previous file versions.
- */
- public Collection getVersions() {
- URL url = VERSIONS_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
- BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET");
- BoxJSONResponse response = (BoxJSONResponse) request.send();
-
- JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
- JsonArray entries = jsonObject.get("entries").asArray();
- Collection versions = new ArrayList();
- for (JsonValue entry : entries) {
- versions.add(new BoxFileVersion(this.getAPI(), entry.asObject(), this.getID()));
- }
-
- return versions;
- }
-
- /**
- * Uploads a new version of this file, replacing the current version. Note that only users with premium accounts
- * will be able to view and recover previous versions of the file.
- * @param fileContent a stream containing the new file contents.
- */
- public void uploadVersion(InputStream fileContent) {
- this.uploadVersion(fileContent, null);
- }
-
- /**
- * Uploads a new version of this file, replacing the current version. Note that only users with premium accounts
- * will be able to view and recover previous versions of the file.
- * @param fileContent a stream containing the new file contents.
- * @param modified the date that the new version was modified.
- */
- public void uploadVersion(InputStream fileContent, Date modified) {
- this.uploadVersion(fileContent, modified, 0, null);
- }
-
- /**
- * Uploads a new version of this file, replacing the current version, while reporting the progress to a
- * ProgressListener. Note that only users with premium accounts will be able to view and recover previous versions
- * of the file.
- * @param fileContent a stream containing the new file contents.
- * @param modified the date that the new version was modified.
- * @param fileSize the size of the file used for determining the progress of the upload.
- * @param listener a listener for monitoring the upload's progress.
- */
- public void uploadVersion(InputStream fileContent, Date modified, long fileSize, ProgressListener listener) {
- URL uploadURL = CONTENT_URL_TEMPLATE.build(this.getAPI().getBaseUploadURL(), this.getID());
- BoxMultipartRequest request = new BoxMultipartRequest(getAPI(), uploadURL);
- if (fileSize > 0) {
- request.setFile(fileContent, "", fileSize);
- } else {
- request.setFile(fileContent, "");
- }
-
- if (modified != null) {
- request.putField("content_modified_at", modified);
- }
-
- BoxAPIResponse response;
- if (listener == null) {
- response = request.send();
- } else {
- response = request.send(listener);
- }
- response.disconnect();
- }
-
- /**
- * Gets a list of any comments on this file.
- * @return a list of comments on this file.
- */
- public List getComments() {
- URL url = GET_COMMENTS_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
- BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET");
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- JsonObject responseJSON = JsonObject.readFrom(response.getJSON());
-
- int totalCount = responseJSON.get("total_count").asInt();
- List comments = new ArrayList(totalCount);
- JsonArray entries = responseJSON.get("entries").asArray();
- for (JsonValue value : entries) {
- JsonObject commentJSON = value.asObject();
- BoxComment comment = new BoxComment(this.getAPI(), commentJSON.get("id").asString());
- BoxComment.Info info = comment.new Info(commentJSON);
- comments.add(info);
- }
-
- return comments;
- }
-
- /**
- * Creates metadata on this file.
- * @param metadata The new metadata values.
- * @return the metadata returned from the server.
- */
- public Metadata createMetadata(Metadata metadata) {
- return this.createMetadata(DEFAULT_METADATA_TYPE, metadata);
- }
-
- /**
- * Creates the metadata of specified type.
- * @param typeName the metadata type name.
- * @param metadata the new metadata values.
- * @return the metadata returned from the server.
- */
- public Metadata createMetadata(String typeName, Metadata metadata) {
- URL url = METADATA_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID(), typeName);
- BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "POST");
- request.addHeader("Content-Type", "application/json");
- request.setBody(metadata.toString());
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- return new Metadata(JsonObject.readFrom(response.getJSON()));
- }
-
- /**
- * Gets the file properties metadata.
- * @return the metadata returned from the server.
- */
- public Metadata getMetadata() {
- return this.getMetadata(DEFAULT_METADATA_TYPE);
- }
-
- /**
- * Gets the file metadata of specified type.
- * @param typeName the metadata type name.
- * @return the metadata returned from the server.
- */
- public Metadata getMetadata(String typeName) {
- URL url = METADATA_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID(), typeName);
- BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET");
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- return new Metadata(JsonObject.readFrom(response.getJSON()));
- }
-
- /**
- * Updates the file metadata.
- * @param metadata the new metadata values.
- * @return the metadata returned from the server.
- */
- public Metadata updateMetadata(Metadata metadata) {
- URL url = METADATA_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID(), metadata.getTypeName());
- BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "PUT");
- request.addHeader("Content-Type", "application/json-patch+json");
- request.setBody(metadata.getPatch());
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- return new Metadata(JsonObject.readFrom(response.getJSON()));
- }
-
- /**
- * Deletes the file properties metadata.
- */
- public void deleteMetadata() {
- this.deleteMetadata(DEFAULT_METADATA_TYPE);
- }
-
- /**
- * Deletes the file metadata of specified type.
- * @param typeName the metadata type name.
- */
- public void deleteMetadata(String typeName) {
- URL url = METADATA_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID(), typeName);
- BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "DELETE");
- request.send();
- }
-
- /**
- * Contains information about a BoxFile.
- */
- public class Info extends BoxItem.Info {
- private String sha1;
- private String versionNumber;
- private long commentCount;
- private EnumSet permissions;
- private String extension;
- private boolean isPackage;
-
- /**
- * Constructs an empty Info object.
- */
- public Info() {
- super();
- }
-
- /**
- * Constructs an Info object by parsing information from a JSON string.
- * @param json the JSON string to parse.
- */
- public Info(String json) {
- super(json);
- }
-
- /**
- * Constructs an Info object using an already parsed JSON object.
- * @param jsonObject the parsed JSON object.
- */
- Info(JsonObject jsonObject) {
- super(jsonObject);
- }
-
- @Override
- public BoxFile getResource() {
- return BoxFile.this;
- }
-
- /**
- * Gets the SHA1 hash of the file.
- * @return the SHA1 hash of the file.
- */
- public String getSha1() {
- return this.sha1;
- }
-
- /**
- * Gets the current version number of the file.
- * @return the current version number of the file.
- */
- public String getVersionNumber() {
- return this.versionNumber;
- }
-
- /**
- * Gets the number of comments on the file.
- * @return the number of comments on the file.
- */
- public long getCommentCount() {
- return this.commentCount;
- }
-
- /**
- * Gets the permissions that the current user has on the file.
- * @return the permissions that the current user has on the file.
- */
- public EnumSet getPermissions() {
- return this.permissions;
- }
-
- /**
- * Gets the extension suffix of the file, excluding the dot.
- * @return the extension of the file.
- */
- public String getExtension() {
- return this.extension;
- }
-
- /**
- * Gets whether or not the file is an OSX package.
- * @return true if the file is an OSX package; otherwise false.
- */
- public boolean getIsPackage() {
- return this.isPackage;
- }
-
- @Override
- protected void parseJSONMember(JsonObject.Member member) {
- super.parseJSONMember(member);
-
- String memberName = member.getName();
- JsonValue value = member.getValue();
- if (memberName.equals("sha1")) {
- this.sha1 = value.asString();
- } else if (memberName.equals("version_number")) {
- this.versionNumber = value.asString();
- } else if (memberName.equals("comment_count")) {
- this.commentCount = value.asLong();
- } else if (memberName.equals("permissions")) {
- this.permissions = this.parsePermissions(value.asObject());
- } else if (memberName.equals("extension")) {
- this.extension = value.asString();
- } else if (memberName.equals("is_package")) {
- this.isPackage = value.asBoolean();
- }
- }
-
- private EnumSet parsePermissions(JsonObject jsonObject) {
- EnumSet permissions = EnumSet.noneOf(Permission.class);
- for (JsonObject.Member member : jsonObject) {
- JsonValue value = member.getValue();
- if (value.isNull() || !value.asBoolean()) {
- continue;
- }
-
- String memberName = member.getName();
- if (memberName.equals("can_download")) {
- permissions.add(Permission.CAN_DOWNLOAD);
- } else if (memberName.equals("can_upload")) {
- permissions.add(Permission.CAN_UPLOAD);
- } else if (memberName.equals("can_rename")) {
- permissions.add(Permission.CAN_RENAME);
- } else if (memberName.equals("can_delete")) {
- permissions.add(Permission.CAN_DELETE);
- } else if (memberName.equals("can_share")) {
- permissions.add(Permission.CAN_SHARE);
- } else if (memberName.equals("can_set_share_access")) {
- permissions.add(Permission.CAN_SET_SHARE_ACCESS);
- } else if (memberName.equals("can_preview")) {
- permissions.add(Permission.CAN_PREVIEW);
- } else if (memberName.equals("can_comment")) {
- permissions.add(Permission.CAN_COMMENT);
- }
- }
-
- return permissions;
- }
- }
-
- /**
- * Enumerates the possible permissions that a user can have on a file.
- */
- public enum Permission {
- /**
- * The user can download the file.
- */
- CAN_DOWNLOAD ("can_download"),
-
- /**
- * The user can upload new versions of the file.
- */
- CAN_UPLOAD ("can_upload"),
-
- /**
- * The user can rename the file.
- */
- CAN_RENAME ("can_rename"),
-
- /**
- * The user can delete the file.
- */
- CAN_DELETE ("can_delete"),
-
- /**
- * The user can share the file.
- */
- CAN_SHARE ("can_share"),
-
- /**
- * The user can set the access level for shared links to the file.
- */
- CAN_SET_SHARE_ACCESS ("can_set_share_access"),
-
- /**
- * The user can preview the file.
- */
- CAN_PREVIEW ("can_preview"),
-
- /**
- * The user can comment on the file.
- */
- CAN_COMMENT ("can_comment");
-
- private final String jsonValue;
-
- private Permission(String jsonValue) {
- this.jsonValue = jsonValue;
- }
-
- static Permission fromJSONValue(String jsonValue) {
- return Permission.valueOf(jsonValue.toUpperCase());
- }
-
- String toJSONValue() {
- return this.jsonValue;
- }
- }
-}
diff --git a/src/main/java/com/box/sdk/BoxFileVersion.java b/src/main/java/com/box/sdk/BoxFileVersion.java
deleted file mode 100644
index 0d68521dd..000000000
--- a/src/main/java/com/box/sdk/BoxFileVersion.java
+++ /dev/null
@@ -1,183 +0,0 @@
-package com.box.sdk;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.URL;
-import java.text.ParseException;
-import java.util.Date;
-
-import com.eclipsesource.json.JsonObject;
-import com.eclipsesource.json.JsonValue;
-
-/**
- * Represents a particular version of a file on Box.
- */
-public class BoxFileVersion extends BoxResource {
- private static final URLTemplate CONTENT_URL_TEMPLATE = new URLTemplate("files/%s/content?version=%s");
- private static final URLTemplate VERSION_URL_TEMPLATE = new URLTemplate("files/%s/versions/%s");
- private static final int BUFFER_SIZE = 8192;
-
- private final String fileID;
-
- private String sha1;
- private String name;
- private long size;
- private Date createdAt;
- private Date modifiedAt;
- private BoxUser.Info modifiedBy;
-
- /**
- * Constructs a BoxFileVersion from a JSON string.
- * @param api the API connection to be used by the file.
- * @param json the JSON encoded file version.
- * @param fileID the ID of the file.
- */
- public BoxFileVersion(BoxAPIConnection api, String json, String fileID) {
- this(api, JsonObject.readFrom(json), fileID);
- }
-
- BoxFileVersion(BoxAPIConnection api, JsonObject jsonObject, String fileID) {
- super(api, jsonObject.get("id").asString());
-
- this.fileID = fileID;
- for (JsonObject.Member member : jsonObject) {
- JsonValue value = member.getValue();
- if (value.isNull()) {
- continue;
- }
-
- try {
- String memberName = member.getName();
- if (memberName.equals("sha1")) {
- this.sha1 = value.asString();
- } else if (memberName.equals("name")) {
- this.name = value.asString();
- } else if (memberName.equals("size")) {
- this.size = Double.valueOf(value.toString()).longValue();
- } else if (memberName.equals("created_at")) {
- this.createdAt = BoxDateFormat.parse(value.asString());
- } else if (memberName.equals("modified_at")) {
- this.modifiedAt = BoxDateFormat.parse(value.asString());
- } else if (memberName.equals("modified_by")) {
- JsonObject userJSON = value.asObject();
- String userID = userJSON.get("id").asString();
- BoxUser user = new BoxUser(getAPI(), userID);
- this.modifiedBy = user.new Info(userJSON);
- }
- } catch (ParseException e) {
- assert false : "A ParseException indicates a bug in the SDK.";
- }
- }
- }
-
- /**
- * Gets the SHA1 hash of this version of the file.
- * @return the SHA1 hash of this version of the file.
- */
- public String getSha1() {
- return this.sha1;
- }
-
- /**
- * Gets the name of this version of the file.
- * @return the name of this version of the file.
- */
- public String getName() {
- return this.name;
- }
-
- /**
- * Gets the size of this version of the file.
- * @return the size of this version of the file.
- */
- public long getSize() {
- return this.size;
- }
-
- /**
- * Gets the time that this version of the file was created.
- * @return the time that this version of the file was created.
- */
- public Date getCreatedAt() {
- return this.createdAt;
- }
-
- /**
- * Gets the time that this version of the file was modified.
- * @return the time that this version of the file was modified.
- */
- public Date getModifiedAt() {
- return this.modifiedAt;
- }
-
- /**
- * Gets information about the user who last modified this version of the file.
- * @return info about the user who last modified this version of the file.
- */
- public BoxUser.Info getModifiedBy() {
- return this.modifiedBy;
- }
-
- /**
- * Deletes this version of the file.
- */
- public void delete() {
- URL url = VERSION_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.fileID, this.getID());
- BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "DELETE");
- BoxAPIResponse response = request.send();
- response.disconnect();
- }
-
- /**
- * Downloads this version of the file to a given OutputStream.
- * @param output the stream to where the file will be written.
- */
- public void download(OutputStream output) {
- this.download(output, null);
- }
-
- /**
- * Downloads this version of the file to a given OutputStream while reporting the progress to a ProgressListener.
- * @param output the stream to where the file will be written.
- * @param listener a listener for monitoring the download's progress.
- */
- public void download(OutputStream output, ProgressListener listener) {
- URL url = CONTENT_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.fileID, this.getID());
- BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET");
- BoxAPIResponse response = request.send();
- InputStream input = response.getBody(listener);
-
- long totalRead = 0;
- byte[] buffer = new byte[BUFFER_SIZE];
- try {
- int n = input.read(buffer);
- totalRead += n;
- while (n != -1) {
- output.write(buffer, 0, n);
- n = input.read(buffer);
- totalRead += n;
- }
- } catch (IOException e) {
- throw new BoxAPIException("Couldn't connect to the Box API due to a network error.", e);
- }
-
- response.disconnect();
- }
-
- /**
- * Promotes this version of the file to be the latest version.
- */
- public void promote() {
- URL url = VERSION_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.fileID, "current");
-
- JsonObject jsonObject = new JsonObject();
- jsonObject.add("type", "file_version");
- jsonObject.add("id", this.getID());
-
- BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "POST");
- request.setBody(jsonObject.toString());
- BoxAPIResponse response = request.send();
- response.disconnect();
- }
-}
diff --git a/src/main/java/com/box/sdk/BoxFolder.java b/src/main/java/com/box/sdk/BoxFolder.java
deleted file mode 100644
index a87b75598..000000000
--- a/src/main/java/com/box/sdk/BoxFolder.java
+++ /dev/null
@@ -1,697 +0,0 @@
-package com.box.sdk;
-
-import java.io.InputStream;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Date;
-import java.util.EnumSet;
-import java.util.Iterator;
-
-import com.eclipsesource.json.JsonArray;
-import com.eclipsesource.json.JsonObject;
-import com.eclipsesource.json.JsonValue;
-
-/**
- * Represents a folder on Box. This class can be used to iterate through a folder's contents, collaborate a folder with
- * another user or group, and perform other common folder operations (move, copy, delete, etc.).
- *
- *
Unless otherwise noted, the methods in this class can throw an unchecked {@link BoxAPIException} (unchecked
- * meaning that the compiler won't force you to handle it) if an error occurs. If you wish to implement custom error
- * handling for errors related to the Box REST API, you should capture this exception explicitly.
- */
-public class BoxFolder extends BoxItem implements Iterable {
- /**
- * An array of all possible folder fields that can be requested when calling {@link #getInfo()}.
- */
- public static final String[] ALL_FIELDS = {"type", "id", "sequence_id", "etag", "name", "created_at", "modified_at",
- "description", "size", "path_collection", "created_by", "modified_by", "trashed_at", "purged_at",
- "content_created_at", "content_modified_at", "owned_by", "shared_link", "folder_upload_email", "parent",
- "item_status", "item_collection", "sync_state", "has_collaborations", "permissions", "tags",
- "can_non_owners_invite"};
-
- private static final URLTemplate CREATE_FOLDER_URL = new URLTemplate("folders");
- private static final URLTemplate COPY_FOLDER_URL = new URLTemplate("folders/%s/copy");
- private static final URLTemplate DELETE_FOLDER_URL = new URLTemplate("folders/%s?recursive=%b");
- private static final URLTemplate FOLDER_INFO_URL_TEMPLATE = new URLTemplate("folders/%s");
- private static final URLTemplate UPLOAD_FILE_URL = new URLTemplate("files/content");
- private static final URLTemplate ADD_COLLABORATION_URL = new URLTemplate("collaborations");
- private static final URLTemplate GET_COLLABORATIONS_URL = new URLTemplate("folders/%s/collaborations");
- private static final URLTemplate GET_ITEMS_URL = new URLTemplate("folders/%s/items/");
- private static final URLTemplate SEARCH_URL_TEMPLATE = new URLTemplate("search");
-
- /**
- * Constructs a BoxFolder for a folder with a given ID.
- * @param api the API connection to be used by the folder.
- * @param id the ID of the folder.
- */
- public BoxFolder(BoxAPIConnection api, String id) {
- super(api, id);
- }
-
- /**
- * Gets the current user's root folder.
- * @param api the API connection to be used by the folder.
- * @return the user's root folder.
- */
- public static BoxFolder getRootFolder(BoxAPIConnection api) {
- return new BoxFolder(api, "0");
- }
-
- /**
- * Adds a collaborator to this folder.
- * @param collaborator the collaborator to add.
- * @param role the role of the collaborator.
- * @return info about the new collaboration.
- */
- public BoxCollaboration.Info collaborate(BoxCollaborator collaborator, BoxCollaboration.Role role) {
- JsonObject accessibleByField = new JsonObject();
- accessibleByField.add("id", collaborator.getID());
-
- if (collaborator instanceof BoxUser) {
- accessibleByField.add("type", "user");
- } else {
- throw new IllegalArgumentException("The given collaborator is of an unknown type.");
- }
-
- return this.collaborate(accessibleByField, role);
- }
-
- /**
- * Adds a collaborator to this folder. An email will be sent to the collaborator if they don't already have a Box
- * account.
- * @param email the email address of the collaborator to add.
- * @param role the role of the collaborator.
- * @return info about the new collaboration.
- */
- public BoxCollaboration.Info collaborate(String email, BoxCollaboration.Role role) {
- JsonObject accessibleByField = new JsonObject();
- accessibleByField.add("login", email);
- accessibleByField.add("type", "user");
-
- return this.collaborate(accessibleByField, role);
- }
-
- private BoxCollaboration.Info collaborate(JsonObject accessibleByField, BoxCollaboration.Role role) {
- BoxAPIConnection api = this.getAPI();
- URL url = ADD_COLLABORATION_URL.build(api.getBaseURL());
-
- JsonObject itemField = new JsonObject();
- itemField.add("id", this.getID());
- itemField.add("type", "folder");
-
- JsonObject requestJSON = new JsonObject();
- requestJSON.add("item", itemField);
- requestJSON.add("accessible_by", accessibleByField);
- requestJSON.add("role", role.toJSONString());
-
- BoxJSONRequest request = new BoxJSONRequest(api, url, "POST");
- request.setBody(requestJSON.toString());
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- JsonObject responseJSON = JsonObject.readFrom(response.getJSON());
-
- BoxCollaboration newCollaboration = new BoxCollaboration(api, responseJSON.get("id").asString());
- BoxCollaboration.Info info = newCollaboration.new Info(responseJSON);
- return info;
- }
-
- @Override
- public BoxSharedLink createSharedLink(BoxSharedLink.Access access, Date unshareDate,
- BoxSharedLink.Permissions permissions) {
-
- BoxSharedLink sharedLink = new BoxSharedLink(access, unshareDate, permissions);
- Info info = new Info();
- info.setSharedLink(sharedLink);
-
- this.updateInfo(info);
- return info.getSharedLink();
- }
-
- /**
- * Gets information about all of the collaborations for this folder.
- * @return a collection of information about the collaborations for this folder.
- */
- public Collection getCollaborations() {
- BoxAPIConnection api = this.getAPI();
- URL url = GET_COLLABORATIONS_URL.build(api.getBaseURL(), this.getID());
-
- BoxAPIRequest request = new BoxAPIRequest(api, url, "GET");
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- JsonObject responseJSON = JsonObject.readFrom(response.getJSON());
-
- int entriesCount = responseJSON.get("total_count").asInt();
- Collection collaborations = new ArrayList(entriesCount);
- JsonArray entries = responseJSON.get("entries").asArray();
- for (JsonValue entry : entries) {
- JsonObject entryObject = entry.asObject();
- BoxCollaboration collaboration = new BoxCollaboration(api, entryObject.get("id").asString());
- BoxCollaboration.Info info = collaboration.new Info(entryObject);
- collaborations.add(info);
- }
-
- return collaborations;
- }
-
- @Override
- public BoxFolder.Info getInfo() {
- URL url = FOLDER_INFO_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
- BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET");
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- return new Info(response.getJSON());
- }
-
- @Override
- public BoxFolder.Info getInfo(String... fields) {
- String queryString = new QueryStringBuilder().appendParam("fields", fields).toString();
- URL url = FOLDER_INFO_URL_TEMPLATE.buildWithQuery(this.getAPI().getBaseURL(), queryString, this.getID());
-
- BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET");
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- return new Info(response.getJSON());
- }
-
- /**
- * Updates the information about this folder with any info fields that have been modified locally.
- * @param info the updated info.
- */
- public void updateInfo(BoxFolder.Info info) {
- URL url = FOLDER_INFO_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
- BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "PUT");
- request.setBody(info.getPendingChanges());
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
- info.update(jsonObject);
- }
-
- @Override
- public BoxFolder.Info copy(BoxFolder destination) {
- return this.copy(destination, null);
- }
-
- @Override
- public BoxFolder.Info copy(BoxFolder destination, String newName) {
- URL url = COPY_FOLDER_URL.build(this.getAPI().getBaseURL(), this.getID());
- BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "POST");
-
- JsonObject parent = new JsonObject();
- parent.add("id", destination.getID());
-
- JsonObject copyInfo = new JsonObject();
- copyInfo.add("parent", parent);
- if (newName != null) {
- copyInfo.add("name", newName);
- }
-
- request.setBody(copyInfo.toString());
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- JsonObject responseJSON = JsonObject.readFrom(response.getJSON());
- BoxFolder copiedFolder = new BoxFolder(this.getAPI(), responseJSON.get("id").asString());
- return copiedFolder.new Info(responseJSON);
- }
-
- /**
- * Creates a new child folder inside this folder.
- * @param name the new folder's name.
- * @return the created folder's info.
- */
- public BoxFolder.Info createFolder(String name) {
- JsonObject parent = new JsonObject();
- parent.add("id", this.getID());
-
- JsonObject newFolder = new JsonObject();
- newFolder.add("name", name);
- newFolder.add("parent", parent);
-
- BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), CREATE_FOLDER_URL.build(this.getAPI().getBaseURL()),
- "POST");
- request.setBody(newFolder.toString());
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- JsonObject responseJSON = JsonObject.readFrom(response.getJSON());
-
- BoxFolder createdFolder = new BoxFolder(this.getAPI(), responseJSON.get("id").asString());
- return createdFolder.new Info(responseJSON);
- }
-
- /**
- * Deletes this folder, optionally recursively deleting all of its contents.
- * @param recursive true to recursively delete this folder's contents; otherwise false.
- */
- public void delete(boolean recursive) {
- URL url = DELETE_FOLDER_URL.build(this.getAPI().getBaseURL(), this.getID(), recursive);
- BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "DELETE");
- BoxAPIResponse response = request.send();
- response.disconnect();
- }
-
- @Override
- public BoxItem.Info move(BoxFolder destination) {
- return this.move(destination, null);
- }
-
- @Override
- public BoxItem.Info move(BoxFolder destination, String newName) {
- URL url = FOLDER_INFO_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
- BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "PUT");
-
- JsonObject parent = new JsonObject();
- parent.add("id", destination.getID());
-
- JsonObject updateInfo = new JsonObject();
- updateInfo.add("parent", parent);
- if (newName != null) {
- updateInfo.add("name", newName);
- }
-
- request.setBody(updateInfo.toString());
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- JsonObject responseJSON = JsonObject.readFrom(response.getJSON());
- BoxFolder movedFolder = new BoxFolder(this.getAPI(), responseJSON.get("id").asString());
- return movedFolder.new Info(responseJSON);
- }
-
- /**
- * Renames this folder.
- * @param newName the new name of the folder.
- */
- public void rename(String newName) {
- URL url = FOLDER_INFO_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
- BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "PUT");
-
- JsonObject updateInfo = new JsonObject();
- updateInfo.add("name", newName);
-
- request.setBody(updateInfo.toString());
- BoxAPIResponse response = request.send();
- response.disconnect();
- }
-
- /**
- * Uploads a new file to this folder.
- * @param fileContent a stream containing the contents of the file to upload.
- * @param name the name to give the uploaded file.
- * @return the uploaded file's info.
- */
- public BoxFile.Info uploadFile(InputStream fileContent, String name) {
- FileUploadParams uploadInfo = new FileUploadParams()
- .setContent(fileContent)
- .setName(name);
- return this.uploadFile(uploadInfo);
- }
-
- /**
- * Uploads a new file to this folder while reporting the progress to a ProgressListener.
- * @param fileContent a stream containing the contents of the file to upload.
- * @param name the name to give the uploaded file.
- * @param fileSize the size of the file used for determining the progress of the upload.
- * @param listener a listener for monitoring the upload's progress.
- * @return the uploaded file's info.
- */
- public BoxFile.Info uploadFile(InputStream fileContent, String name, long fileSize, ProgressListener listener) {
- FileUploadParams uploadInfo = new FileUploadParams()
- .setContent(fileContent)
- .setName(name)
- .setSize(fileSize)
- .setProgressListener(listener);
- return this.uploadFile(uploadInfo);
- }
-
- /**
- * Uploads a new file to this folder with custom upload parameters.
- * @param uploadParams the custom upload parameters.
- * @return the uploaded file's info.
- */
- public BoxFile.Info uploadFile(FileUploadParams uploadParams) {
- URL uploadURL = UPLOAD_FILE_URL.build(this.getAPI().getBaseUploadURL());
- BoxMultipartRequest request = new BoxMultipartRequest(getAPI(), uploadURL);
- request.putField("parent_id", getID());
-
- if (uploadParams.getSize() > 0) {
- request.setFile(uploadParams.getContent(), uploadParams.getName(), uploadParams.getSize());
- } else {
- request.setFile(uploadParams.getContent(), uploadParams.getName());
- }
-
- if (uploadParams.getCreated() != null) {
- request.putField("content_created_at", uploadParams.getCreated());
- }
-
- if (uploadParams.getModified() != null) {
- request.putField("content_modified_at", uploadParams.getModified());
- }
-
- BoxJSONResponse response;
- if (uploadParams.getProgressListener() == null) {
- response = (BoxJSONResponse) request.send();
- } else {
- response = (BoxJSONResponse) request.send(uploadParams.getProgressListener());
- }
- JsonObject collection = JsonObject.readFrom(response.getJSON());
- JsonArray entries = collection.get("entries").asArray();
- JsonObject fileInfoJSON = entries.get(0).asObject();
- String uploadedFileID = fileInfoJSON.get("id").asString();
-
- BoxFile uploadedFile = new BoxFile(getAPI(), uploadedFileID);
- return uploadedFile.new Info(fileInfoJSON);
- }
-
- /**
- * Returns an iterable containing the items in this folder. Iterating over the iterable returned by this method is
- * equivalent to iterating over this BoxFolder directly.
- * @return an iterable containing the items in this folder.
- */
- public Iterable getChildren() {
- return this;
- }
-
- /**
- * Returns an iterable containing the items in this folder and specifies which child fields to retrieve from the
- * API.
- * @param fields the fields to retrieve.
- * @return an iterable containing the items in this folder.
- */
- public Iterable getChildren(final String... fields) {
- return new Iterable() {
- @Override
- public Iterator iterator() {
- String queryString = new QueryStringBuilder().appendParam("fields", fields).toString();
- URL url = GET_ITEMS_URL.buildWithQuery(getAPI().getBaseURL(), queryString, getID());
- return new BoxItemIterator(getAPI(), url);
- }
- };
- }
-
- /**
- * Retrieves a specific range of child items in this folder.
- * @param offset the index of the first child item to retrieve.
- * @param limit the maximum number of children to retrieve after the offset.
- * @param fields the fields to retrieve.
- * @return a partial collection containing the specified range of child items.
- */
- public PartialCollection getChildrenRange(long offset, long limit, String... fields) {
- QueryStringBuilder builder = new QueryStringBuilder()
- .appendParam("limit", limit)
- .appendParam("offset", offset);
-
- if (fields.length > 0) {
- builder.appendParam("fields", fields).toString();
- }
-
- URL url = GET_ITEMS_URL.buildWithQuery(getAPI().getBaseURL(), builder.toString(), getID());
- BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET");
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- JsonObject responseJSON = JsonObject.readFrom(response.getJSON());
-
- String totalCountString = responseJSON.get("total_count").toString();
- long fullSize = Double.valueOf(totalCountString).longValue();
- PartialCollection children = new PartialCollection(offset, limit, fullSize);
- JsonArray jsonArray = responseJSON.get("entries").asArray();
- for (JsonValue value : jsonArray) {
- JsonObject jsonObject = value.asObject();
- BoxItem.Info parsedItemInfo = (BoxItem.Info) BoxResource.parseInfo(this.getAPI(), jsonObject);
- if (parsedItemInfo != null) {
- children.add(parsedItemInfo);
- }
- }
- return children;
- }
-
- /**
- * Returns an iterator over the items in this folder.
- * @return an iterator over the items in this folder.
- */
- @Override
- public Iterator iterator() {
- URL url = GET_ITEMS_URL.build(this.getAPI().getBaseURL(), BoxFolder.this.getID());
- return new BoxItemIterator(BoxFolder.this.getAPI(), url);
- }
-
- /**
- * Searches this folder and all descendant folders using a given query.
- * @param query the search query.
- * @return an Iterable containing the search results.
- */
- public Iterable search(final String query) {
- return new Iterable() {
- @Override
- public Iterator iterator() {
- QueryStringBuilder builder = new QueryStringBuilder();
- builder.appendParam("query", query);
- builder.appendParam("ancestor_folder_ids", getID());
-
- URL url = SEARCH_URL_TEMPLATE.buildWithQuery(getAPI().getBaseURL(), builder.toString());
- return new BoxItemIterator(getAPI(), url);
- }
- };
- }
-
- /**
- * Contains information about a BoxFolder.
- */
- public class Info extends BoxItem.Info {
- private BoxUploadEmail uploadEmail;
- private boolean hasCollaborations;
- private SyncState syncState;
- private EnumSet permissions;
- private boolean canNonOwnersInvite;
-
- /**
- * Constructs an empty Info object.
- */
- public Info() {
- super();
- }
-
- /**
- * Constructs an Info object by parsing information from a JSON string.
- * @param json the JSON string to parse.
- */
- public Info(String json) {
- super(json);
- }
-
- /**
- * Constructs an Info object using an already parsed JSON object.
- * @param jsonObject the parsed JSON object.
- */
- Info(JsonObject jsonObject) {
- super(jsonObject);
- }
-
- /**
- * Gets the upload email for the folder.
- * @return the upload email for the folder.
- */
- public BoxUploadEmail getUploadEmail() {
- return this.uploadEmail;
- }
-
- /**
- * Sets the upload email for the folder.
- * @param uploadEmail the upload email for the folder.
- */
- public void setUploadEmail(BoxUploadEmail uploadEmail) {
- if (this.uploadEmail == uploadEmail) {
- return;
- }
-
- this.removeChildObject("folder_upload_email");
- this.uploadEmail = uploadEmail;
-
- if (uploadEmail == null) {
- this.addPendingChange("folder_upload_email", null);
- } else {
- this.addChildObject("folder_upload_email", uploadEmail);
- }
- }
-
- /**
- * Gets whether or not the folder has any collaborations.
- * @return true if the folder has collaborations; otherwise false.
- */
- public boolean getHasCollaborations() {
- return this.hasCollaborations;
- }
-
- /**
- * Gets the sync state of the folder.
- * @return the sync state of the folder.
- */
- public SyncState getSyncState() {
- return this.syncState;
- }
-
- /**
- * Sets the sync state of the folder.
- * @param syncState the sync state of the folder.
- */
- public void setSyncState(SyncState syncState) {
- this.syncState = syncState;
- this.addPendingChange("sync_state", syncState.toJSONValue());
- }
-
- /**
- * Gets the permissions that the current user has on the folder.
- * @return the permissions that the current user has on the folder.
- */
- public EnumSet getPermissions() {
- return this.permissions;
- }
-
- /**
- * Gets whether or not the non-owners can invite collaborators to the folder.
- * @return [description]
- */
- public boolean getCanNonOwnersInvite() {
- return this.canNonOwnersInvite;
- }
-
- @Override
- public BoxFolder getResource() {
- return BoxFolder.this;
- }
-
- @Override
- protected void parseJSONMember(JsonObject.Member member) {
- super.parseJSONMember(member);
-
- String memberName = member.getName();
- JsonValue value = member.getValue();
- if (memberName.equals("folder_upload_email")) {
- if (this.uploadEmail == null) {
- this.uploadEmail = new BoxUploadEmail(value.asObject());
- } else {
- this.uploadEmail.update(value.asObject());
- }
-
- } else if (memberName.equals("has_collaborations")) {
- this.hasCollaborations = value.asBoolean();
-
- } else if (memberName.equals("sync_state")) {
- this.syncState = SyncState.fromJSONValue(value.asString());
-
- } else if (memberName.equals("permissions")) {
- this.permissions = this.parsePermissions(value.asObject());
-
- } else if (memberName.equals("can_non_owners_invite")) {
- this.canNonOwnersInvite = value.asBoolean();
- }
- }
-
- private EnumSet parsePermissions(JsonObject jsonObject) {
- EnumSet permissions = EnumSet.noneOf(Permission.class);
- for (JsonObject.Member member : jsonObject) {
- JsonValue value = member.getValue();
- if (value.isNull() || !value.asBoolean()) {
- continue;
- }
-
- String memberName = member.getName();
- if (memberName.equals("can_download")) {
- permissions.add(Permission.CAN_DOWNLOAD);
- } else if (memberName.equals("can_upload")) {
- permissions.add(Permission.CAN_UPLOAD);
- } else if (memberName.equals("can_rename")) {
- permissions.add(Permission.CAN_RENAME);
- } else if (memberName.equals("can_delete")) {
- permissions.add(Permission.CAN_DELETE);
- } else if (memberName.equals("can_share")) {
- permissions.add(Permission.CAN_SHARE);
- } else if (memberName.equals("can_invite_collaborator")) {
- permissions.add(Permission.CAN_INVITE_COLLABORATOR);
- } else if (memberName.equals("can_set_share_access")) {
- permissions.add(Permission.CAN_SET_SHARE_ACCESS);
- }
- }
-
- return permissions;
- }
- }
-
- /**
- * Enumerates the possible sync states that a folder can have.
- */
- public enum SyncState {
- /**
- * The folder is synced.
- */
- SYNCED ("synced"),
-
- /**
- * The folder is not synced.
- */
- NOT_SYNCED ("not_synced"),
-
- /**
- * The folder is partially synced.
- */
- PARTIALLY_SYNCED ("partially_synced");
-
- private final String jsonValue;
-
- private SyncState(String jsonValue) {
- this.jsonValue = jsonValue;
- }
-
- static SyncState fromJSONValue(String jsonValue) {
- return SyncState.valueOf(jsonValue.toUpperCase());
- }
-
- String toJSONValue() {
- return this.jsonValue;
- }
- }
-
- /**
- * Enumerates the possible permissions that a user can have on a folder.
- */
- public enum Permission {
- /**
- * The user can download the folder.
- */
- CAN_DOWNLOAD ("can_download"),
-
- /**
- * The user can upload to the folder.
- */
- CAN_UPLOAD ("can_upload"),
-
- /**
- * The user can rename the folder.
- */
- CAN_RENAME ("can_rename"),
-
- /**
- * The user can delete the folder.
- */
- CAN_DELETE ("can_delete"),
-
- /**
- * The user can share the folder.
- */
- CAN_SHARE ("can_share"),
-
- /**
- * The user can invite collaborators to the folder.
- */
- CAN_INVITE_COLLABORATOR ("can_invite_collaborator"),
-
- /**
- * The user can set the access level for shared links to the folder.
- */
- CAN_SET_SHARE_ACCESS ("can_set_share_access");
-
- private final String jsonValue;
-
- private Permission(String jsonValue) {
- this.jsonValue = jsonValue;
- }
-
- static Permission fromJSONValue(String jsonValue) {
- return Permission.valueOf(jsonValue.toUpperCase());
- }
-
- String toJSONValue() {
- return this.jsonValue;
- }
- }
-}
diff --git a/src/main/java/com/box/sdk/BoxGroup.java b/src/main/java/com/box/sdk/BoxGroup.java
deleted file mode 100644
index fd3a8eb04..000000000
--- a/src/main/java/com/box/sdk/BoxGroup.java
+++ /dev/null
@@ -1,116 +0,0 @@
-package com.box.sdk;
-
-import java.net.URL;
-import java.util.Iterator;
-
-import com.eclipsesource.json.JsonObject;
-
-/**
- * Represents a set of Box users.
- *
- *
Unless otherwise noted, the methods in this class can throw an unchecked {@link BoxAPIException} (unchecked
- * meaning that the compiler won't force you to handle it) if an error occurs. If you wish to implement custom error
- * handling for errors related to the Box REST API, you should capture this exception explicitly.
- */
-public class BoxGroup extends BoxCollaborator {
- private static final URLTemplate GROUPS_URL_TEMPLATE = new URLTemplate("groups");
- private static final URLTemplate GROUP_URL_TEMPLATE = new URLTemplate("groups/%s");
-
- /**
- * Constructs a BoxGroup for a group with a given ID.
- * @param api the API connection to be used by the group.
- * @param id the ID of the group.
- */
- public BoxGroup(BoxAPIConnection api, String id) {
- super(api, id);
- }
-
- /**
- * Creates a new group with a specified name.
- * @param api the API connection to be used by the group.
- * @param name the name of the new group.
- * @return info about the created group.
- */
- public static BoxGroup.Info createGroup(BoxAPIConnection api, String name) {
- JsonObject requestJSON = new JsonObject();
- requestJSON.add("name", name);
-
- URL url = GROUPS_URL_TEMPLATE.build(api.getBaseURL());
- BoxJSONRequest request = new BoxJSONRequest(api, url, "POST");
- request.setBody(requestJSON.toString());
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- JsonObject responseJSON = JsonObject.readFrom(response.getJSON());
-
- BoxGroup group = new BoxGroup(api, responseJSON.get("id").asString());
- return group.new Info(responseJSON);
- }
-
- /**
- * Gets an iterable of all the groups that the current user is a member of.
- * @param api the API connection to be used when retrieving the groups.
- * @return an iterable containing info about all the groups.
- */
- public static Iterable getAllGroups(final BoxAPIConnection api) {
- return new Iterable() {
- public Iterator iterator() {
- URL url = GROUPS_URL_TEMPLATE.build(api.getBaseURL());
- return new BoxGroupIterator(api, url);
- }
- };
- }
-
- /**
- * Gets information about this group.
- * @return info about this group.
- */
- public Info getInfo() {
- URL url = GROUP_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
- BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET");
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- JsonObject responseJSON = JsonObject.readFrom(response.getJSON());
- return new Info(responseJSON);
- }
-
- /**
- * Deletes this group.
- */
- public void delete() {
- URL url = GROUP_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
- BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "DELETE");
- BoxAPIResponse response = request.send();
- response.disconnect();
- }
-
- /**
- * Contains information about a BoxGroup.
- */
- public class Info extends BoxCollaborator.Info {
- /**
- * Constructs an empty Info object.
- */
- public Info() {
- super();
- }
-
- /**
- * Constructs an Info object by parsing information from a JSON string.
- * @param json the JSON string to parse.
- */
- public Info(String json) {
- super(json);
- }
-
- /**
- * Constructs an Info object using an already parsed JSON object.
- * @param jsonObject the parsed JSON object.
- */
- Info(JsonObject jsonObject) {
- super(jsonObject);
- }
-
- @Override
- public BoxGroup getResource() {
- return BoxGroup.this;
- }
- }
-}
diff --git a/src/main/java/com/box/sdk/BoxGroupIterator.java b/src/main/java/com/box/sdk/BoxGroupIterator.java
deleted file mode 100644
index 19af1e0bf..000000000
--- a/src/main/java/com/box/sdk/BoxGroupIterator.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package com.box.sdk;
-
-import java.net.URL;
-import java.util.Iterator;
-
-import com.eclipsesource.json.JsonObject;
-
-class BoxGroupIterator implements Iterator {
- private static final long LIMIT = 1000;
-
- private final BoxAPIConnection api;
- private final JSONIterator jsonIterator;
-
- BoxGroupIterator(BoxAPIConnection api, URL url) {
- this.api = api;
- this.jsonIterator = new JSONIterator(api, url, LIMIT);
- }
-
- public boolean hasNext() {
- return this.jsonIterator.hasNext();
- }
-
- public BoxGroup.Info next() {
- JsonObject nextJSONObject = this.jsonIterator.next();
- String id = nextJSONObject.get("id").asString();
-
- BoxGroup group = new BoxGroup(this.api, id);
- return group.new Info(nextJSONObject);
- }
-
- public void remove() {
- throw new UnsupportedOperationException();
- }
-}
diff --git a/src/main/java/com/box/sdk/BoxItem.java b/src/main/java/com/box/sdk/BoxItem.java
deleted file mode 100644
index d5fa5dfc1..000000000
--- a/src/main/java/com/box/sdk/BoxItem.java
+++ /dev/null
@@ -1,447 +0,0 @@
-package com.box.sdk;
-
-import java.net.URL;
-import java.text.ParseException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-
-import com.eclipsesource.json.JsonArray;
-import com.eclipsesource.json.JsonObject;
-import com.eclipsesource.json.JsonValue;
-
-/**
- * The abstract base class for items in a user's file tree (files, folders, etc.).
- */
-public abstract class BoxItem extends BoxResource {
- /**
- * An array of all possible file fields that can be requested when calling {@link #getInfo()}.
- */
- public static final String[] ALL_FIELDS = {"type", "id", "sequence_id", "etag", "sha1", "name", "description",
- "size", "path_collection", "created_at", "modified_at", "trashed_at", "purged_at", "content_created_at",
- "content_modified_at", "created_by", "modified_by", "owned_by", "shared_link", "parent", "item_status",
- "version_number", "comment_count", "permissions", "tags", "lock", "extension", "is_package",
- "folder_upload_email", "item_collection", "sync_state", "has_collaborations", "can_non_owners_invite"};
-
- private static final URLTemplate SHARED_ITEM_URL_TEMPLATE = new URLTemplate("shared_items");
-
- /**
- * Constructs a BoxItem for an item with a given ID.
- * @param api the API connection to be used by the item.
- * @param id the ID of the item.
- */
- public BoxItem(BoxAPIConnection api, String id) {
- super(api, id);
- }
-
- /**
- * Gets an item that was shared with a shared link.
- * @param api the API connection to be used by the shared item.
- * @param sharedLink the shared link to the item.
- * @return info about the shared item.
- */
- public static BoxItem.Info getSharedItem(BoxAPIConnection api, String sharedLink) {
- return getSharedItem(api, sharedLink, null);
- }
-
- /**
- * Gets an item that was shared with a password-protected shared link.
- * @param api the API connection to be used by the shared item.
- * @param sharedLink the shared link to the item.
- * @param password the password for the shared link.
- * @return info about the shared item.
- */
- public static BoxItem.Info getSharedItem(BoxAPIConnection api, String sharedLink, String password) {
- BoxAPIConnection newAPI = new SharedLinkAPIConnection(api, sharedLink, password);
- URL url = SHARED_ITEM_URL_TEMPLATE.build(newAPI.getBaseURL());
- BoxAPIRequest request = new BoxAPIRequest(newAPI, url, "GET");
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- JsonObject json = JsonObject.readFrom(response.getJSON());
- return (BoxItem.Info) BoxResource.parseInfo(newAPI, json);
- }
-
- /**
- * Copies this item to another folder.
- * @param destination the destination folder.
- * @return info about the copied item.
- */
- public abstract BoxItem.Info copy(BoxFolder destination);
-
- /**
- * Copies this item to another folder and gives it a new name. If the destination is the same folder as the item's
- * current parent, then newName must be a new, unique name.
- * @param destination the destination folder.
- * @param newName a new name for the copied item.
- * @return info about the copied item.
- */
- public abstract BoxItem.Info copy(BoxFolder destination, String newName);
-
- /**
- * Moves this item to another folder.
- * @param destination the destination folder.
- * @return info about the moved item.
- */
- public abstract BoxItem.Info move(BoxFolder destination);
-
- /**
- * Moves this item to another folder and gives it a new name.
- * @param destination the destination folder.
- * @param newName a new name for the moved item.
- * @return info about the moved item.
- */
- public abstract BoxItem.Info move(BoxFolder destination, String newName);
-
- /**
- * Creates a new shared link for this item.
- *
- *
This method is a convenience method for manually creating a new shared link and applying it to this item with
- * {@link Info#setSharedLink}. You may want to create the shared link manually so that it can be updated along with
- * other changes to the item's info in a single network request, giving a boost to performance.
- *
- * @param access the access level of the shared link.
- * @param unshareDate the date and time at which the link will expire. Can be null to create a non-expiring link.
- * @param permissions the permissions of the shared link. Can be null to use the default permissions.
- * @return the created shared link.
- */
- public abstract BoxSharedLink createSharedLink(BoxSharedLink.Access access, Date unshareDate,
- BoxSharedLink.Permissions permissions);
-
- /**
- * Gets information about this item.
- * @return info about this item.
- */
- public abstract BoxItem.Info getInfo();
-
- /**
- * Gets information about this item that's limited to a list of specified fields.
- * @param fields the fields to retrieve.
- * @return info about this item containing only the specified fields.
- */
- public abstract BoxItem.Info getInfo(String... fields);
-
- /**
- * Contains information about a BoxItem.
- */
- public abstract class Info extends BoxResource.Info {
- private String sequenceID;
- private String etag;
- private String name;
- private Date createdAt;
- private Date modifiedAt;
- private String description;
- private long size;
- private List pathCollection;
- private BoxUser.Info createdBy;
- private BoxUser.Info modifiedBy;
- private Date trashedAt;
- private Date purgedAt;
- private Date contentCreatedAt;
- private Date contentModifiedAt;
- private BoxUser.Info ownedBy;
- private BoxSharedLink sharedLink;
- private List tags;
- private BoxFolder.Info parent;
- private String itemStatus;
-
- /**
- * Constructs an empty Info object.
- */
- public Info() {
- super();
- }
-
- /**
- * Constructs an Info object by parsing information from a JSON string.
- * @param json the JSON string to parse.
- */
- public Info(String json) {
- super(json);
- }
-
- /**
- * Constructs an Info object using an already parsed JSON object.
- * @param jsonObject the parsed JSON object.
- */
- Info(JsonObject jsonObject) {
- super(jsonObject);
- }
-
- /**
- * Gets a unique string identifying the version of the item.
- * @return a unique string identifying the version of the item.
- */
- public String getEtag() {
- return this.etag;
- }
-
- /**
- * Gets the name of the item.
- * @return the name of the item.
- */
- public String getName() {
- return this.name;
- }
-
- /**
- * Sets the name of the item.
- * @param name the new name of the item.
- */
- public void setName(String name) {
- this.name = name;
- this.addPendingChange("name", name);
- }
-
- /**
- * Gets the time the item was created.
- * @return the time the item was created.
- */
- public Date getCreatedAt() {
- return this.createdAt;
- }
-
- /**
- * Gets the time the item was last modified.
- * @return the time the item was last modified.
- */
- public Date getModifiedAt() {
- return this.modifiedAt;
- }
-
- /**
- * Gets the description of the item.
- * @return the description of the item.
- */
- public String getDescription() {
- return this.description;
- }
-
- /**
- * Sets the description of the item.
- * @param description the new description of the item.
- */
- public void setDescription(String description) {
- this.description = description;
- this.addPendingChange("description", description);
- }
-
- /**
- * Gets the size of the item in bytes.
- * @return the size of the item in bytes.
- */
- public long getSize() {
- return this.size;
- }
-
- /**
- * Gets the path of folders to the item, starting at the root.
- * @return the path of folders to the item.
- */
- public List getPathCollection() {
- return this.pathCollection;
- }
-
- /**
- * Gets info about the user who created the item.
- * @return info about the user who created the item.
- */
- public BoxUser.Info getCreatedBy() {
- return this.createdBy;
- }
-
- /**
- * Gets info about the user who last modified the item.
- * @return info about the user who last modified the item.
- */
- public BoxUser.Info getModifiedBy() {
- return this.modifiedBy;
- }
-
- /**
- * Gets the time that the item was trashed.
- * @return the time that the item was trashed.
- */
- public Date getTrashedAt() {
- return this.trashedAt;
- }
-
- /**
- * Gets the time that the item was purged from the trash.
- * @return the time that the item was purged from the trash.
- */
- public Date getPurgedAt() {
- return this.purgedAt;
- }
-
- /**
- * Gets the time that the item was created according to the uploader.
- * @return the time that the item was created according to the uploader.
- */
- public Date getContentCreatedAt() {
- return this.contentCreatedAt;
- }
-
- /**
- * Gets the time that the item was last modified according to the uploader.
- * @return the time that the item was last modified according to the uploader.
- */
- public Date getContentModifiedAt() {
- return this.contentModifiedAt;
- }
-
- /**
- * Gets info about the user who owns the item.
- * @return info about the user who owns the item.
- */
- public BoxUser.Info getOwnedBy() {
- return this.ownedBy;
- }
-
- /**
- * Gets the shared link for the item.
- * @return the shared link for the item.
- */
- public BoxSharedLink getSharedLink() {
- return this.sharedLink;
- }
-
- /**
- * Sets a shared link for the item.
- * @param sharedLink the shared link for the item.
- */
- public void setSharedLink(BoxSharedLink sharedLink) {
- if (this.sharedLink == sharedLink) {
- return;
- }
-
- this.removeChildObject("shared_link");
- this.sharedLink = sharedLink;
- this.addChildObject("shared_link", sharedLink);
- }
-
- /**
- * Gets a unique ID for use with the {@link EventStream}.
- * @return a unique ID for use with the EventStream.
- */
- public String getSequenceID() {
- return this.sequenceID;
- }
-
- /**
- * Gets a list of all the tags applied to the item.
- *
- *
Note that this field isn't populated by default and must be specified as a field parameter when getting
- * Info about the item.
- *
- * @return a list of all the tags applied to the item.
- */
- public List getTags() {
- return this.tags;
- }
-
- /**
- * Gets info about the parent folder of the item.
- * @return info abou thte parent folder of the item.
- */
- public BoxFolder.Info getParent() {
- return this.parent;
- }
-
- /**
- * Gets the status of the item.
- * @return the status of the item.
- */
- public String getItemStatus() {
- return this.itemStatus;
- }
-
- @Override
- protected void parseJSONMember(JsonObject.Member member) {
- super.parseJSONMember(member);
-
- try {
- JsonValue value = member.getValue();
- String memberName = member.getName();
- if (memberName.equals("sequence_id")) {
- this.sequenceID = value.asString();
- } else if (memberName.equals("etag")) {
- this.etag = value.asString();
- } else if (memberName.equals("name")) {
- this.name = value.asString();
- } else if (memberName.equals("created_at")) {
- this.createdAt = BoxDateFormat.parse(value.asString());
- } else if (memberName.equals("modified_at")) {
- this.modifiedAt = BoxDateFormat.parse(value.asString());
- } else if (memberName.equals("description")) {
- this.description = value.asString();
- } else if (memberName.equals("size")) {
- this.size = Double.valueOf(value.toString()).longValue();
- } else if (memberName.equals("trashed_at")) {
- this.trashedAt = BoxDateFormat.parse(value.asString());
- } else if (memberName.equals("purged_at")) {
- this.purgedAt = BoxDateFormat.parse(value.asString());
- } else if (memberName.equals("content_created_at")) {
- this.contentCreatedAt = BoxDateFormat.parse(value.asString());
- } else if (memberName.equals("content_modified_at")) {
- this.contentModifiedAt = BoxDateFormat.parse(value.asString());
- } else if (memberName.equals("path_collection")) {
- this.pathCollection = this.parsePathCollection(value.asObject());
- } else if (memberName.equals("created_by")) {
- this.createdBy = this.parseUserInfo(value.asObject());
- } else if (memberName.equals("modified_by")) {
- this.modifiedBy = this.parseUserInfo(value.asObject());
- } else if (memberName.equals("owned_by")) {
- this.ownedBy = this.parseUserInfo(value.asObject());
- } else if (memberName.equals("shared_link")) {
- if (this.sharedLink == null) {
- this.setSharedLink(new BoxSharedLink(value.asObject()));
- } else {
- this.sharedLink.update(value.asObject());
- }
- } else if (memberName.equals("tags")) {
- this.tags = this.parseTags(value.asArray());
- } else if (memberName.equals("parent")) {
- JsonObject jsonObject = value.asObject();
- if (this.parent == null) {
- String id = jsonObject.get("id").asString();
- BoxFolder parentFolder = new BoxFolder(getAPI(), id);
- this.parent = parentFolder.new Info(jsonObject);
- } else {
- this.parent.update(jsonObject);
- }
- } else if (memberName.equals("item_status")) {
- this.itemStatus = value.asString();
- }
- } catch (ParseException e) {
- assert false : "A ParseException indicates a bug in the SDK.";
- }
- }
-
- private List parsePathCollection(JsonObject jsonObject) {
- int count = jsonObject.get("total_count").asInt();
- List pathCollection = new ArrayList(count);
- JsonArray entries = jsonObject.get("entries").asArray();
- for (JsonValue value : entries) {
- JsonObject entry = value.asObject();
- String id = entry.get("id").asString();
- pathCollection.add(new BoxFolder(getAPI(), id));
- }
-
- return pathCollection;
- }
-
- private BoxUser.Info parseUserInfo(JsonObject jsonObject) {
- String userID = jsonObject.get("id").asString();
- BoxUser user = new BoxUser(getAPI(), userID);
- return user.new Info(jsonObject);
- }
-
- private List parseTags(JsonArray jsonArray) {
- List tags = new ArrayList(jsonArray.size());
- for (JsonValue value : jsonArray) {
- tags.add(value.asString());
- }
-
- return tags;
- }
- }
-}
diff --git a/src/main/java/com/box/sdk/BoxItemIterator.java b/src/main/java/com/box/sdk/BoxItemIterator.java
deleted file mode 100644
index e6d0e8792..000000000
--- a/src/main/java/com/box/sdk/BoxItemIterator.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package com.box.sdk;
-
-import java.net.URL;
-import java.util.Iterator;
-
-import com.eclipsesource.json.JsonObject;
-
-class BoxItemIterator implements Iterator {
- private static final long LIMIT = 1000;
-
- private final BoxAPIConnection api;
- private final JSONIterator jsonIterator;
-
- BoxItemIterator(BoxAPIConnection api, URL url) {
- this.api = api;
-
- this.jsonIterator = new JSONIterator(api, url, LIMIT);
- this.jsonIterator.setFilter(new Filter() {
- @Override
- public boolean shouldInclude(JsonObject jsonObject) {
- String type = jsonObject.get("type").asString();
- return (type.equals("file") || type.equals("folder"));
- }
- });
- }
-
- public boolean hasNext() {
- return this.jsonIterator.hasNext();
- }
-
- public BoxItem.Info next() {
- JsonObject nextJSONObject = this.jsonIterator.next();
- String type = nextJSONObject.get("type").asString();
- String id = nextJSONObject.get("id").asString();
-
- BoxItem.Info nextItemInfo;
- if (type.equals("folder")) {
- BoxFolder folder = new BoxFolder(this.api, id);
- nextItemInfo = folder.new Info(nextJSONObject);
- } else if (type.equals("file")) {
- BoxFile file = new BoxFile(this.api, id);
- nextItemInfo = file.new Info(nextJSONObject);
- } else {
- assert false : "Unsupported item type: " + type;
- throw new BoxAPIException("Unsupported item type: " + type);
- }
-
- return nextItemInfo;
- }
-
- public void remove() {
- throw new UnsupportedOperationException();
- }
-}
diff --git a/src/main/java/com/box/sdk/BoxJSONObject.java b/src/main/java/com/box/sdk/BoxJSONObject.java
deleted file mode 100644
index 0b25372f8..000000000
--- a/src/main/java/com/box/sdk/BoxJSONObject.java
+++ /dev/null
@@ -1,174 +0,0 @@
-package com.box.sdk;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import com.eclipsesource.json.JsonObject;
-import com.eclipsesource.json.JsonValue;
-
-/**
- * The abstract base class for all types that contain JSON data returned by the Box API. The most common implementation
- * of BoxJSONObject is {@link BoxResource.Info} and its subclasses. Changes made to a BoxJSONObject will be tracked
- * locally until the pending changes are sent back to Box in order to avoid unnecessary network requests.
- *
- */
-public abstract class BoxJSONObject {
- /**
- * The JsonObject that contains any local pending changes. When getPendingChanges is called, this object will be
- * encoded to a JSON string.
- */
- private JsonObject pendingChanges;
-
- /**
- * A map of other BoxJSONObjects which will be lazily converted to a JsonObject once getPendingChanges is called.
- * This allows changes to be made to a child BoxJSONObject and still have those changes reflected in the JSON
- * string.
- */
- private final Map children;
-
- /**
- * Constructs an empty BoxJSONObject.
- */
- public BoxJSONObject() {
- this.children = new HashMap();
- }
-
- /**
- * Constructs a BoxJSONObject by decoding it from a JSON string.
- * @param json the JSON string to decode.
- */
- public BoxJSONObject(String json) {
- this(JsonObject.readFrom(json));
- }
-
- /**
- * Constructs a BoxJSONObject using an already parsed JSON object.
- * @param jsonObject the parsed JSON object.
- */
- BoxJSONObject(JsonObject jsonObject) {
- this();
-
- this.update(jsonObject);
- }
-
- /**
- * Clears any pending changes from this JSON object.
- */
- public void clearPendingChanges() {
- this.pendingChanges = null;
- }
-
- /**
- * Gets a JSON string containing any pending changes to this object that can be sent back to the Box API.
- * @return a JSON string containing the pending changes.
- */
- public String getPendingChanges() {
- JsonObject jsonObject = this.getPendingJSONObject();
- if (jsonObject == null) {
- return null;
- }
-
- return jsonObject.toString();
- }
-
- /**
- * Invoked with a JSON member whenever this object is updated or created from a JSON object.
- *
- *
Subclasses should override this method in order to parse any JSON members it knows about. This method is a
- * no-op by default.
- *
- * @param member the JSON member to be parsed.
- */
- void parseJSONMember(JsonObject.Member member) { }
-
- /**
- * Adds a pending field change that needs to be sent to the API. It will be included in the JSON string the next
- * time {@link #getPendingChanges} is called.
- * @param key the name of the field.
- * @param value the new boolean value of the field.
- */
- void addPendingChange(String key, boolean value) {
- if (this.pendingChanges == null) {
- this.pendingChanges = new JsonObject();
- }
-
- this.pendingChanges.set(key, value);
- }
-
- /**
- * Adds a pending field change that needs to be sent to the API. It will be included in the JSON string the next
- * time {@link #getPendingChanges} is called.
- * @param key the name of the field.
- * @param value the new String value of the field.
- */
- void addPendingChange(String key, String value) {
- this.addPendingChange(key, JsonValue.valueOf(value));
- }
-
- void addChildObject(String fieldName, BoxJSONObject child) {
- if (child == null) {
- this.addPendingChange(fieldName, JsonValue.NULL);
- } else {
- this.children.put(fieldName, child);
- }
- }
-
- void removeChildObject(String fieldName) {
- this.children.remove(fieldName);
- }
-
- /**
- * Adds a pending field change that needs to be sent to the API. It will be included in the JSON string the next
- * time {@link #getPendingChanges} is called.
- * @param key the name of the field.
- * @param value the JsonValue of the field.
- */
- private void addPendingChange(String key, JsonValue value) {
- if (this.pendingChanges == null) {
- this.pendingChanges = new JsonObject();
- }
-
- this.pendingChanges.set(key, value);
- }
-
- void removePendingChange(String key) {
- if (this.pendingChanges != null) {
- this.pendingChanges.remove(key);
- }
- }
-
- /**
- * Updates this BoxJSONObject using the information in a JSON object.
- * @param jsonObject the JSON object containing updated information.
- */
- void update(JsonObject jsonObject) {
- for (JsonObject.Member member : jsonObject) {
- if (member.getValue().isNull()) {
- continue;
- }
-
- this.parseJSONMember(member);
- }
-
- this.clearPendingChanges();
- }
-
- /**
- * Gets a JsonObject containing any pending changes to this object that can be sent back to the Box API.
- * @return a JsonObject containing the pending changes.
- */
- private JsonObject getPendingJSONObject() {
- for (Map.Entry entry : this.children.entrySet()) {
- BoxJSONObject child = entry.getValue();
- JsonObject jsonObject = child.getPendingJSONObject();
- if (jsonObject != null) {
- if (this.pendingChanges == null) {
- this.pendingChanges = new JsonObject();
- }
-
- this.pendingChanges.set(entry.getKey(), jsonObject);
- }
- }
- return this.pendingChanges;
- }
-}
diff --git a/src/main/java/com/box/sdk/BoxJSONRequest.java b/src/main/java/com/box/sdk/BoxJSONRequest.java
deleted file mode 100644
index c67e51a40..000000000
--- a/src/main/java/com/box/sdk/BoxJSONRequest.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.box.sdk;
-
-import java.net.URL;
-
-/**
- * Used to make HTTP requests containing JSON to the Box API.
- *
- *
This request type extends BoxAPIRequest to provide additional functionality for handling JSON strings. It
- * automatically sets the appropriate "Content-Type" HTTP headers and allows the JSON in the request to be logged.
- */
-public class BoxJSONRequest extends BoxAPIRequest {
- private String json;
-
- /**
- * Constructs an authenticated BoxJSONRequest using a provided BoxAPIConnection.
- * @param api an API connection for authenticating the request.
- * @param url the URL of the request.
- * @param method the HTTP method of the request.
- */
- public BoxJSONRequest(BoxAPIConnection api, URL url, String method) {
- super(api, url, method);
-
- this.addHeader("Content-Type", "application/json");
- }
-
- /**
- * Sets the body of this request to a given JSON string.
- * @param body the JSON string to use as the body.
- */
- @Override
- public void setBody(String body) {
- super.setBody(body);
- this.json = body;
- }
-
- @Override
- protected String bodyToString() {
- return this.json;
- }
-}
diff --git a/src/main/java/com/box/sdk/BoxJSONResponse.java b/src/main/java/com/box/sdk/BoxJSONResponse.java
deleted file mode 100644
index eb7746f18..000000000
--- a/src/main/java/com/box/sdk/BoxJSONResponse.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package com.box.sdk;
-
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.net.HttpURLConnection;
-
-/**
- * Used to read HTTP responses containing JSON from the Box API.
- *
- *
This request type extends BoxAPIResponse to provide additional functionality for handling JSON strings. It reads
- * the response body into a string and allows the JSON in the response to be logged.
- */
-public class BoxJSONResponse extends BoxAPIResponse {
- private static final int BUFFER_SIZE = 8192;
-
- private String json;
-
- /**
- * Constructs a BoxJSONResponse using an HttpURLConnection.
- * @param connection a connection that has already sent a request to the API.
- */
- public BoxJSONResponse(HttpURLConnection connection) {
- super(connection);
- }
-
- /**
- * Gets the body of the response as a JSON string. When this method is called, the response's body will be read and
- * the response will be disconnected, meaning that the stream returned by {@link #getBody} can no longer be used.
- * @return the body of the response as a JSON string.
- */
- public String getJSON() {
- if (this.json != null) {
- return this.json;
- }
-
- InputStreamReader reader = new InputStreamReader(this.getBody(), StandardCharsets.UTF_8);
- StringBuilder builder = new StringBuilder();
- char[] buffer = new char[BUFFER_SIZE];
-
- try {
- int read = reader.read(buffer, 0, BUFFER_SIZE);
- while (read != -1) {
- builder.append(buffer, 0, read);
- read = reader.read(buffer, 0, BUFFER_SIZE);
- }
-
- this.disconnect();
- reader.close();
- } catch (IOException e) {
- throw new BoxAPIException("Couldn't connect to the Box API due to a network error.", e);
- }
- this.json = builder.toString();
- return this.json;
- }
-
- @Override
- protected String bodyToString() {
- String bodyString = super.bodyToString();
- if (bodyString == null) {
- return this.getJSON();
- } else {
- return bodyString;
- }
- }
-}
diff --git a/src/main/java/com/box/sdk/BoxMultipartRequest.java b/src/main/java/com/box/sdk/BoxMultipartRequest.java
deleted file mode 100644
index c4fb01482..000000000
--- a/src/main/java/com/box/sdk/BoxMultipartRequest.java
+++ /dev/null
@@ -1,203 +0,0 @@
-package com.box.sdk;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Used to make HTTP multipart requests to the Box API.
- *
- *
This class partially implements the HTTP multipart standard in order to upload files to Box. The body of this
- * request type cannot be set directly. Instead, it can be modified by adding multipart fields and setting file
- * contents. The body of multipart requests will not be logged since they are likely to contain binary data.
- *
- */
-public class BoxMultipartRequest extends BoxAPIRequest {
- private static final Logger LOGGER = Logger.getLogger(BoxMultipartRequest.class.getName());
- private static final String BOUNDARY = "da39a3ee5e6b4b0d3255bfef95601890afd80709";
- private static final int BUFFER_SIZE = 8192;
-
- private final StringBuilder loggedRequest = new StringBuilder();
-
- private OutputStream outputStream;
- private InputStream inputStream;
- private String filename;
- private long fileSize;
- private Map fields;
- private boolean firstBoundary;
-
- /**
- * Constructs an authenticated BoxMultipartRequest using a provided BoxAPIConnection.
- * @param api an API connection for authenticating the request.
- * @param url the URL of the request.
- */
- public BoxMultipartRequest(BoxAPIConnection api, URL url) {
- super(api, url, "POST");
-
- this.fields = new HashMap();
- this.firstBoundary = true;
-
- this.addHeader("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
- }
-
- /**
- * Adds or updates a multipart field in this request.
- * @param key the field's key.
- * @param value the field's value.
- */
- public void putField(String key, String value) {
- this.fields.put(key, value);
- }
-
- /**
- * Adds or updates a multipart field in this request.
- * @param key the field's key.
- * @param value the field's value.
- */
- public void putField(String key, Date value) {
- this.fields.put(key, BoxDateFormat.format(value));
- }
-
- /**
- * Sets the file contents of this request.
- * @param inputStream a stream containing the file contents.
- * @param filename the name of the file.
- */
- public void setFile(InputStream inputStream, String filename) {
- this.inputStream = inputStream;
- this.filename = filename;
- }
-
- /**
- * Sets the file contents of this request.
- * @param inputStream a stream containing the file contents.
- * @param filename the name of the file.
- * @param fileSize the size of the file.
- */
- public void setFile(InputStream inputStream, String filename, long fileSize) {
- this.setFile(inputStream, filename);
- this.fileSize = fileSize;
- }
-
- /**
- * This method is unsupported in BoxMultipartRequest. Instead, the body should be modified via the {@code putField}
- * and {@code setFile} methods.
- * @param stream N/A
- * @throws UnsupportedOperationException this method is unsupported.
- */
- @Override
- public void setBody(InputStream stream) {
- throw new UnsupportedOperationException();
- }
-
- /**
- * This method is unsupported in BoxMultipartRequest. Instead, the body should be modified via the {@code putField}
- * and {@code setFile} methods.
- * @param body N/A
- * @throws UnsupportedOperationException this method is unsupported.
- */
- @Override
- public void setBody(String body) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- protected void writeBody(HttpURLConnection connection, ProgressListener listener) {
- try {
- connection.setChunkedStreamingMode(0);
- connection.setDoOutput(true);
- this.outputStream = connection.getOutputStream();
-
- this.writePartHeader(new String[][] {{"name", "filename"}, {"filename", this.filename}},
- "application/octet-stream");
-
- OutputStream fileContentsOutputStream = this.outputStream;
- if (listener != null) {
- fileContentsOutputStream = new ProgressOutputStream(this.outputStream, listener, this.fileSize);
- }
- byte[] buffer = new byte[BUFFER_SIZE];
- int n = this.inputStream.read(buffer);
- while (n != -1) {
- fileContentsOutputStream.write(buffer, 0, n);
- n = this.inputStream.read(buffer);
- }
-
- if (LOGGER.isLoggable(Level.FINE)) {
- this.loggedRequest.append("");
- }
-
- for (Map.Entry entry : this.fields.entrySet()) {
- this.writePartHeader(new String[][] {{"name", entry.getKey()}});
- this.writeOutput(entry.getValue());
- }
-
- this.writeBoundary();
- } catch (IOException e) {
- throw new BoxAPIException("Couldn't connect to the Box API due to a network error.", e);
- }
- }
-
- @Override
- protected void resetBody() throws IOException {
- this.firstBoundary = true;
- this.inputStream.reset();
- this.loggedRequest.setLength(0);
- }
-
- @Override
- protected String bodyToString() {
- return this.loggedRequest.toString();
- }
-
- private void writeBoundary() throws IOException {
- if (!this.firstBoundary) {
- this.writeOutput("\r\n");
- }
-
- this.firstBoundary = false;
- this.writeOutput("--");
- this.writeOutput(BOUNDARY);
- }
-
- private void writePartHeader(String[][] formData) throws IOException {
- this.writePartHeader(formData, null);
- }
-
- private void writePartHeader(String[][] formData, String contentType) throws IOException {
- this.writeBoundary();
- this.writeOutput("\r\n");
- this.writeOutput("Content-Disposition: form-data");
- for (int i = 0; i < formData.length; i++) {
- this.writeOutput("; ");
- this.writeOutput(formData[i][0]);
- this.writeOutput("=\"");
- this.writeOutput(formData[i][1]);
- this.writeOutput("\"");
- }
-
- if (contentType != null) {
- this.writeOutput("\r\nContent-Type: ");
- this.writeOutput(contentType);
- }
-
- this.writeOutput("\r\n\r\n");
- }
-
- private void writeOutput(String s) throws IOException {
- this.outputStream.write(s.getBytes(StandardCharsets.UTF_8));
- if (LOGGER.isLoggable(Level.FINE)) {
- this.loggedRequest.append(s);
- }
- }
-
- private void writeOutput(int b) throws IOException {
- this.outputStream.write(b);
- }
-}
diff --git a/src/main/java/com/box/sdk/BoxResource.java b/src/main/java/com/box/sdk/BoxResource.java
deleted file mode 100644
index c73bb0acc..000000000
--- a/src/main/java/com/box/sdk/BoxResource.java
+++ /dev/null
@@ -1,138 +0,0 @@
-package com.box.sdk;
-
-import com.eclipsesource.json.JsonObject;
-
-/**
- * The abstract base class for all resource types (files, folders, comments, collaborations, etc.) used by the API.
- *
- *
Every API resource has an ID and a {@link BoxAPIConnection} that it uses to communicate with the API. Some
- * resources also have an associated {@link Info} class that contains information about the resource.
- */
-public abstract class BoxResource {
- private final BoxAPIConnection api;
- private final String id;
-
- /**
- * Constructs a BoxResource for a resource with a given ID.
- * @param api the API connection to be used by the resource.
- * @param id the ID of the resource.
- */
- public BoxResource(BoxAPIConnection api, String id) {
- this.api = api;
- this.id = id;
- }
-
- static BoxResource.Info parseInfo(BoxAPIConnection api, JsonObject jsonObject) {
- String type = jsonObject.get("type").asString();
- String id = jsonObject.get("id").asString();
-
- if (type.equals("folder")) {
- BoxFolder folder = new BoxFolder(api, id);
- return folder.new Info(jsonObject);
- } else if (type.equals("file")) {
- BoxFile file = new BoxFile(api, id);
- return file.new Info(jsonObject);
- } else if (type.equals("comment")) {
- BoxComment comment = new BoxComment(api, id);
- return comment.new Info(jsonObject);
- } else if (type.equals("collaboration")) {
- BoxCollaboration collaboration = new BoxCollaboration(api, id);
- return collaboration.new Info(jsonObject);
- } else if (type.equals("user")) {
- BoxUser user = new BoxUser(api, id);
- return user.new Info(jsonObject);
- } else if (type.equals("group")) {
- BoxGroup group = new BoxGroup(api, id);
- return group.new Info(jsonObject);
- } else {
- return null;
- }
- }
-
- /**
- * Gets the API connection used by this resource.
- * @return the API connection used by this resource.
- */
- public BoxAPIConnection getAPI() {
- return this.api;
- }
-
- /**
- * Gets the ID of this resource.
- * @return the ID of this resource.
- */
- public String getID() {
- return this.id;
- }
-
- /**
- * Indicates whether this BoxResource is equal to another BoxResource. Two BoxResources are equal if they have the
- * same type and ID.
- * @param other the other BoxResource to compare.
- * @return true if the type and IDs of the two resources are equal; otherwise false.
- */
- @Override
- public boolean equals(Object other) {
- if (other == null) {
- return false;
- }
-
- if (this.getClass().equals(other.getClass())) {
- BoxResource otherResource = (BoxResource) other;
- return this.getID().equals(otherResource.getID());
- }
-
- return false;
- }
-
- /**
- * Returns a hash code value for this BoxResource.
- * @return a hash code value for this BoxResource.
- */
- @Override
- public int hashCode() {
- return this.getID().hashCode();
- }
-
- /**
- * Contains information about a BoxResource.
- */
- public abstract class Info extends BoxJSONObject {
- /**
- * Constructs an empty Info object.
- */
- public Info() {
- super();
- }
-
- /**
- * Constructs an Info object by parsing information from a JSON string.
- * @param json the JSON string to parse.
- */
- public Info(String json) {
- super(json);
- }
-
- /**
- * Constructs an Info object using an already parsed JSON object.
- * @param jsonObject the parsed JSON object.
- */
- Info(JsonObject jsonObject) {
- super(jsonObject);
- }
-
- /**
- * Gets the ID of the resource associated with this Info.
- * @return the ID of the associated resource.
- */
- public String getID() {
- return BoxResource.this.getID();
- }
-
- /**
- * Gets the resource associated with this Info.
- * @return the associated resource.
- */
- public abstract BoxResource getResource();
- }
-}
diff --git a/src/main/java/com/box/sdk/BoxSharedLink.java b/src/main/java/com/box/sdk/BoxSharedLink.java
deleted file mode 100644
index c031eca53..000000000
--- a/src/main/java/com/box/sdk/BoxSharedLink.java
+++ /dev/null
@@ -1,291 +0,0 @@
-package com.box.sdk;
-
-import java.text.ParseException;
-import java.util.Date;
-
-import com.eclipsesource.json.JsonObject;
-import com.eclipsesource.json.JsonValue;
-
-/**
- * Represents a link to a file or folder on Box.
- */
-public class BoxSharedLink extends BoxJSONObject {
- private String url;
- private String downloadUrl;
- private String vanityUrl;
- private boolean isPasswordEnabled;
- private Date unsharedAt;
- private long downloadCount;
- private long previewCount;
- private Access access;
- private Permissions permissions;
-
- /**
- * Constructs a BoxSharedLink with default settings.
- */
- public BoxSharedLink() { }
-
- /**
- * Constructs a BoxSharedLink from a JSON string.
- * @param json the JSON encoded shared link.
- */
- public BoxSharedLink(String json) {
- super(json);
- }
-
- BoxSharedLink(JsonObject jsonObject) {
- super(jsonObject);
- }
-
- BoxSharedLink(BoxSharedLink.Access access, Date unshareDate, BoxSharedLink.Permissions permissions) {
- this.setAccess(access);
- this.setPermissions(permissions);
-
- if (unshareDate != null) {
- this.setUnsharedDate(unshareDate);
- }
- }
-
- /**
- * Get the URL of this shared link.
- * @return the URL of this shared link.
- */
- public String getURL() {
- return this.url;
- }
-
- /**
- * Gets the direct download URL of this shared link.
- * @return the direct download URL of this shared link.
- */
- public String getDownloadURL() {
- return this.downloadUrl;
- }
-
- /**
- * Gets the vanity URL of this shared link.
- * @return the vanity URL of this shared link.
- */
- public String getVanityURL() {
- return this.vanityUrl;
- }
-
- /**
- * Gets whether or not a password is enabled on this shared link.
- * @return true if there's a password enabled on this shared link; otherwise false.
- */
- public boolean getIsPasswordEnabled() {
- return this.isPasswordEnabled;
- }
-
- /**
- * Gets the time that this shared link will be deactivated.
- * @return the time that this shared link will be deactivated.
- */
- public Date getUnsharedDate() {
- return this.unsharedAt;
- }
-
- /**
- * Sets the time that this shared link will be deactivated.
- * @param unsharedDate the time that this shared link will be deactivated.
- */
- public void setUnsharedDate(Date unsharedDate) {
- this.unsharedAt = unsharedDate;
- this.addPendingChange("unshared_at", unsharedDate.toString());
- }
-
- /**
- * Gets the number of times that this shared link has been downloaded.
- * @return the number of times that this link has been downloaded.
- */
- public long getDownloadCount() {
- return this.downloadCount;
- }
-
- /**
- * Gets the number of times that this shared link has been previewed.
- * @return the number of times that this link has been previewed.
- */
- public long getPreviewCount() {
- return this.previewCount;
- }
-
- /**
- * Gets the access level of this shared link.
- * @return the access level of this shared link.
- */
- public Access getAccess() {
- return this.access;
- }
-
- /**
- * Sets the access level of this shared link.
- * @param access the new acccess level of this shared link.
- */
- public void setAccess(Access access) {
- this.access = access;
- this.addPendingChange("access", access.toJSONValue());
- }
-
- /**
- * Gets the permissions associated with this shared link.
- * @return the permissions associated with this shared link.
- */
- public Permissions getPermissions() {
- return this.permissions;
- }
-
- /**
- * Sets the permissions associated with this shared link.
- * @param permissions the new permissions for this shared link.
- */
- public void setPermissions(Permissions permissions) {
- if (this.permissions == permissions) {
- return;
- }
-
- this.removeChildObject("permissions");
- this.permissions = permissions;
- this.addChildObject("permissions", permissions);
- }
-
- @Override
- void parseJSONMember(JsonObject.Member member) {
- JsonValue value = member.getValue();
- try {
- String memberName = member.getName();
- if (memberName.equals("url")) {
- this.url = value.asString();
- } else if (memberName.equals("download_url")) {
- this.downloadUrl = value.asString();
- } else if (memberName.equals("vanity_url")) {
- this.vanityUrl = value.asString();
- } else if (memberName.equals("is_password_enabled")) {
- this.isPasswordEnabled = value.asBoolean();
- } else if (memberName.equals("unshared_at")) {
- this.unsharedAt = BoxDateFormat.parse(value.asString());
- } else if (memberName.equals("download_count")) {
- this.downloadCount = Double.valueOf(value.toString()).longValue();
- } else if (memberName.equals("preview_count")) {
- this.previewCount = Double.valueOf(value.toString()).longValue();
- } else if (memberName.equals("access")) {
- String accessString = value.asString().toUpperCase();
- this.access = Access.valueOf(accessString);
- } else if (memberName.equals("permissions")) {
- if (this.permissions == null) {
- this.setPermissions(new Permissions(value.asObject()));
- } else {
- this.permissions.update(value.asObject());
- }
- }
- } catch (ParseException e) {
- assert false : "A ParseException indicates a bug in the SDK.";
- }
- }
-
- /**
- * Contains permissions fields that can be set on a shared link.
- */
- public static class Permissions extends BoxJSONObject {
- private boolean canDownload;
- private boolean canPreview;
-
- /**
- * Constructs a Permissions object with all permissions disabled.
- */
- public Permissions() { }
-
- /**
- * Constructs a Permissions object from a JSON string.
- * @param json the JSON encoded shared link permissions.
- */
- public Permissions(String json) {
- super(json);
- }
-
- Permissions(JsonObject jsonObject) {
- super(jsonObject);
- }
-
- /**
- * Gets whether or not the shared link can be downloaded.
- * @return true if the shared link can be downloaded; otherwise false.
- */
- public boolean getCanDownload() {
- return this.canDownload;
- }
-
- /**
- * Sets whether or not the shared link can be downloaded.
- * @param enabled true if the shared link can be downloaded; otherwise false.
- */
- public void setCanDownload(boolean enabled) {
- this.canDownload = enabled;
- this.addPendingChange("can_download", enabled);
- }
-
- /**
- * Gets whether or not the shared link can be previewed.
- * @return true if the shared link can be previewed; otherwise false.
- */
- public boolean getCanPreview() {
- return this.canPreview;
- }
-
- /**
- * Sets whether or not the shared link can be previewed.
- * @param enabled true if the shared link can be previewed; otherwise false.
- */
- public void setCanPreview(boolean enabled) {
- this.canPreview = enabled;
- this.addPendingChange("can_preview", enabled);
- }
-
- @Override
- void parseJSONMember(JsonObject.Member member) {
- JsonValue value = member.getValue();
- String memberName = member.getName();
- if (memberName.equals("can_download")) {
- this.canDownload = value.asBoolean();
- } else if (memberName.equals("can_preview")) {
- this.canPreview = value.asBoolean();
- }
- }
- }
-
- /**
- * Enumerates the possible access levels that can be set on a shared link.
- */
- public enum Access {
- /**
- * The default access level for the user or enterprise.
- */
- DEFAULT (null),
-
- /**
- * The link can be accessed by anyone.
- */
- OPEN ("open"),
-
- /**
- * The link can be accessed by other users within the company.
- */
- COMPANY ("company"),
-
- /**
- * The link can be accessed by other collaborators.
- */
- COLLABORATORS ("collaborators");
-
- private final String jsonValue;
-
- private Access(String jsonValue) {
- this.jsonValue = jsonValue;
- }
-
- String toJSONValue() {
- return this.jsonValue;
- }
- }
-}
diff --git a/src/main/java/com/box/sdk/BoxTrash.java b/src/main/java/com/box/sdk/BoxTrash.java
deleted file mode 100644
index a7814c898..000000000
--- a/src/main/java/com/box/sdk/BoxTrash.java
+++ /dev/null
@@ -1,219 +0,0 @@
-package com.box.sdk;
-
-import java.net.URL;
-import java.util.Iterator;
-
-import com.eclipsesource.json.JsonObject;
-
-/**
- * Provides methods for deleting, recovering, and viewing a user's trashed files and folders.
- *
- *
Unless otherwise noted, the methods in this class can throw an unchecked {@link BoxAPIException} (unchecked
- * meaning that the compiler won't force you to handle it) if an error occurs. If you wish to implement custom error
- * handling for errors related to the Box REST API, you should capture this exception explicitly.
- */
-public class BoxTrash implements Iterable {
- private static final long LIMIT = 1000;
- private static final URLTemplate GET_ITEMS_URL = new URLTemplate("folders/trash/items/");
- private static final URLTemplate FOLDER_INFO_URL_TEMPLATE = new URLTemplate("folders/%s/trash");
- private static final URLTemplate FILE_INFO_URL_TEMPLATE = new URLTemplate("files/%s/trash");
- private static final URLTemplate RESTORE_FILE_URL_TEMPLATE = new URLTemplate("files/%s");
- private static final URLTemplate RESTORE_FOLDER_URL_TEMPLATE = new URLTemplate("folders/%s");
-
- private final BoxAPIConnection api;
-
- /**
- * Constructs a BoxTrash using a given API connection.
- * @param api the API connection to be used by the trash.
- */
- public BoxTrash(BoxAPIConnection api) {
- this.api = api;
- }
-
- /**
- * Permanently deletes a trashed folder.
- * @param folderID the ID of the trashed folder to permanently delete.
- */
- public void deleteFolder(String folderID) {
- URL url = FOLDER_INFO_URL_TEMPLATE.build(this.api.getBaseURL(), folderID);
- BoxAPIRequest request = new BoxAPIRequest(this.api, url, "DELETE");
- BoxAPIResponse response = request.send();
- response.disconnect();
- }
-
- /**
- * Gets information about a trashed folder.
- * @param folderID the ID of the trashed folder.
- * @return info about the trashed folder.
- */
- public BoxFolder.Info getFolderInfo(String folderID) {
- URL url = FOLDER_INFO_URL_TEMPLATE.build(this.api.getBaseURL(), folderID);
- BoxAPIRequest request = new BoxAPIRequest(this.api, url, "GET");
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
-
- BoxFolder folder = new BoxFolder(this.api, jsonObject.get("id").asString());
- return folder.new Info(response.getJSON());
- }
-
- /**
- * Gets information about a trashed folder that's limited to a list of specified fields.
- * @param folderID the ID of the trashed folder.
- * @param fields the fields to retrieve.
- * @return info about the trashed folder containing only the specified fields.
- */
- public BoxFolder.Info getFolderInfo(String folderID, String... fields) {
- String queryString = new QueryStringBuilder().appendParam("fields", fields).toString();
- URL url = FOLDER_INFO_URL_TEMPLATE.buildWithQuery(this.api.getBaseURL(), queryString, folderID);
- BoxAPIRequest request = new BoxAPIRequest(this.api, url, "GET");
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
-
- BoxFolder folder = new BoxFolder(this.api, jsonObject.get("id").asString());
- return folder.new Info(response.getJSON());
- }
-
- /**
- * Restores a trashed folder back to its original location.
- * @param folderID the ID of the trashed folder.
- * @return info about the restored folder.
- */
- public BoxFolder.Info restoreFolder(String folderID) {
- URL url = RESTORE_FOLDER_URL_TEMPLATE.build(this.api.getBaseURL(), folderID);
- BoxAPIRequest request = new BoxAPIRequest(this.api, url, "POST");
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- JsonObject responseJSON = JsonObject.readFrom(response.getJSON());
-
- BoxFolder restoredFolder = new BoxFolder(this.api, responseJSON.get("id").asString());
- return restoredFolder.new Info(responseJSON);
- }
-
- /**
- * Restores a trashed folder to a new location with a new name.
- * @param folderID the ID of the trashed folder.
- * @param newName an optional new name to give the folder. This can be null to use the folder's original name.
- * @param newParentID an optional new parent ID for the folder. This can be null to use the folder's original
- * parent.
- * @return info about the restored folder.
- */
- public BoxFolder.Info restoreFolder(String folderID, String newName, String newParentID) {
- JsonObject requestJSON = new JsonObject();
-
- if (newName != null) {
- requestJSON.add("name", newName);
- }
-
- if (newParentID != null) {
- JsonObject parent = new JsonObject();
- parent.add("id", newParentID);
- requestJSON.add("parent", parent);
- }
-
- URL url = RESTORE_FOLDER_URL_TEMPLATE.build(this.api.getBaseURL(), folderID);
- BoxJSONRequest request = new BoxJSONRequest(this.api, url, "POST");
- request.setBody(requestJSON.toString());
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- JsonObject responseJSON = JsonObject.readFrom(response.getJSON());
-
- BoxFolder restoredFolder = new BoxFolder(this.api, responseJSON.get("id").asString());
- return restoredFolder.new Info(responseJSON);
- }
-
- /**
- * Permanently deletes a trashed file.
- * @param fileID the ID of the trashed folder to permanently delete.
- */
- public void deleteFile(String fileID) {
- URL url = FILE_INFO_URL_TEMPLATE.build(this.api.getBaseURL(), fileID);
- BoxAPIRequest request = new BoxAPIRequest(this.api, url, "DELETE");
- BoxAPIResponse response = request.send();
- response.disconnect();
- }
-
- /**
- * Gets information about a trashed file.
- * @param fileID the ID of the trashed file.
- * @return info about the trashed file.
- */
- public BoxFile.Info getFileInfo(String fileID) {
- URL url = FILE_INFO_URL_TEMPLATE.build(this.api.getBaseURL(), fileID);
- BoxAPIRequest request = new BoxAPIRequest(this.api, url, "GET");
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
-
- BoxFile file = new BoxFile(this.api, jsonObject.get("id").asString());
- return file.new Info(response.getJSON());
- }
-
- /**
- * Gets information about a trashed file that's limited to a list of specified fields.
- * @param fileID the ID of the trashed file.
- * @param fields the fields to retrieve.
- * @return info about the trashed file containing only the specified fields.
- */
- public BoxFile.Info getFileInfo(String fileID, String... fields) {
- String queryString = new QueryStringBuilder().appendParam("fields", fields).toString();
- URL url = FILE_INFO_URL_TEMPLATE.buildWithQuery(this.api.getBaseURL(), queryString, fileID);
- BoxAPIRequest request = new BoxAPIRequest(this.api, url, "GET");
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
-
- BoxFile file = new BoxFile(this.api, jsonObject.get("id").asString());
- return file.new Info(response.getJSON());
- }
-
- /**
- * Restores a trashed file back to its original location.
- * @param fileID the ID of the trashed file.
- * @return info about the restored file.
- */
- public BoxFile.Info restoreFile(String fileID) {
- URL url = RESTORE_FILE_URL_TEMPLATE.build(this.api.getBaseURL(), fileID);
- BoxAPIRequest request = new BoxAPIRequest(this.api, url, "POST");
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- JsonObject responseJSON = JsonObject.readFrom(response.getJSON());
-
- BoxFile restoredFile = new BoxFile(this.api, responseJSON.get("id").asString());
- return restoredFile.new Info(responseJSON);
- }
-
- /**
- * Restores a trashed file to a new location with a new name.
- * @param fileID the ID of the trashed file.
- * @param newName an optional new name to give the file. This can be null to use the file's original name.
- * @param newParentID an optional new parent ID for the file. This can be null to use the file's original
- * parent.
- * @return info about the restored file.
- */
- public BoxFile.Info restoreFile(String fileID, String newName, String newParentID) {
- JsonObject requestJSON = new JsonObject();
-
- if (newName != null) {
- requestJSON.add("name", newName);
- }
-
- if (newParentID != null) {
- JsonObject parent = new JsonObject();
- parent.add("id", newParentID);
- requestJSON.add("parent", parent);
- }
-
- URL url = RESTORE_FILE_URL_TEMPLATE.build(this.api.getBaseURL(), fileID);
- BoxJSONRequest request = new BoxJSONRequest(this.api, url, "POST");
- request.setBody(requestJSON.toString());
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- JsonObject responseJSON = JsonObject.readFrom(response.getJSON());
-
- BoxFile restoredFile = new BoxFile(this.api, responseJSON.get("id").asString());
- return restoredFile.new Info(responseJSON);
- }
-
- /**
- * Returns an iterator over the items in the trash.
- * @return an iterator over the items in the trash.
- */
- public Iterator iterator() {
- URL url = GET_ITEMS_URL.build(this.api.getBaseURL());
- return new BoxItemIterator(this.api, url);
- }
-}
diff --git a/src/main/java/com/box/sdk/BoxUploadEmail.java b/src/main/java/com/box/sdk/BoxUploadEmail.java
deleted file mode 100644
index f7551a0ca..000000000
--- a/src/main/java/com/box/sdk/BoxUploadEmail.java
+++ /dev/null
@@ -1,94 +0,0 @@
-package com.box.sdk;
-
-import com.eclipsesource.json.JsonObject;
-import com.eclipsesource.json.JsonValue;
-
-/**
- * Represents an email address that can be used to upload files to a folder on Box.
- */
-public class BoxUploadEmail extends BoxJSONObject {
- private Access access;
- private String email;
-
- /**
- * Constructs a BoxUploadEmail with default settings.
- */
- public BoxUploadEmail() { }
-
- /**
- * Constructs a BoxUploadEmail from a JSON string.
- * @param json the JSON encoded upload email.
- */
- public BoxUploadEmail(String json) {
- super(json);
- }
-
- BoxUploadEmail(JsonObject jsonObject) {
- super(jsonObject);
- }
-
- /**
- * Gets the access level of this upload email.
- * @return the access level of this upload email.
- */
- public Access getAccess() {
- return this.access;
- }
-
- /**
- * Sets the access level of this upload email.
- * @param access the new access level of this upload email.
- */
- public void setAccess(Access access) {
- this.access = access;
- this.addPendingChange("access", access.toJSONValue());
- }
-
- /**
- * Gets the email address of this upload email.
- * @return the email address of this upload email.
- */
- public String getEmail() {
- return this.email;
- }
-
- @Override
- void parseJSONMember(JsonObject.Member member) {
- JsonValue value = member.getValue();
- String memberName = member.getName();
- if (memberName.equals("access")) {
- this.access = Access.fromJSONValue(value.asString());
- } else if (memberName.equals("email")) {
- this.email = value.asString();
- }
- }
-
- /**
- * Enumerates the possible access levels that can be set on an upload email.
- */
- public enum Access {
- /**
- * Anyone can send an upload to this email address.
- */
- OPEN("open"),
-
- /**
- * Only collaborators can send an upload to this email address.
- */
- COLLABORATORS("collaborators");
-
- private final String jsonValue;
-
- private Access(String jsonValue) {
- this.jsonValue = jsonValue;
- }
-
- static Access fromJSONValue(String jsonValue) {
- return Access.valueOf(jsonValue.toUpperCase());
- }
-
- String toJSONValue() {
- return this.jsonValue;
- }
- }
-}
diff --git a/src/main/java/com/box/sdk/BoxUser.java b/src/main/java/com/box/sdk/BoxUser.java
deleted file mode 100644
index c00b8d53e..000000000
--- a/src/main/java/com/box/sdk/BoxUser.java
+++ /dev/null
@@ -1,263 +0,0 @@
-package com.box.sdk;
-
-import java.net.URL;
-
-import com.eclipsesource.json.JsonObject;
-import com.eclipsesource.json.JsonValue;
-
-/**
- * Represents a Box user account.
- *
- *
Unless otherwise noted, the methods in this class can throw an unchecked {@link BoxAPIException} (unchecked
- * meaning that the compiler won't force you to handle it) if an error occurs. If you wish to implement custom error
- * handling for errors related to the Box REST API, you should capture this exception explicitly.
- */
-public class BoxUser extends BoxCollaborator {
- private static final URLTemplate GET_USER_URL = new URLTemplate("users/%s");
- private static final URLTemplate GET_ME_URL = new URLTemplate("users/me");
-
- /**
- * Constructs a BoxUser for a user with a given ID.
- * @param api the API connection to be used by the user.
- * @param id the ID of the user.
- */
- public BoxUser(BoxAPIConnection api, String id) {
- super(api, id);
- }
-
- /**
- * Gets the current user.
- * @param api the API connection of the current user.
- * @return the current user.
- */
- public static BoxUser getCurrentUser(BoxAPIConnection api) {
- URL url = GET_ME_URL.build(api.getBaseURL());
- BoxAPIRequest request = new BoxAPIRequest(api, url, "GET");
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
- return new BoxUser(api, jsonObject.get("id").asString());
- }
-
- /**
- * Gets information about this user.
- * @return info about this user.
- */
- public BoxUser.Info getInfo() {
- URL url = GET_USER_URL.build(this.getAPI().getBaseURL(), this.getID());
- BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET");
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
- return new Info(jsonObject);
- }
-
- /**
- * Enumerates the possible roles that a user can have within an enterprise.
- */
- public enum Role {
- /**
- * The user is an administrator of their enterprise.
- */
- ADMIN,
-
- /**
- * The user is a co-administrator of their enterprise.
- */
- COADMIN,
-
- /**
- * The user is a regular user within their enterprise.
- */
- USER
- }
-
- /**
- * Enumerates the possible statuses that a user's account can have.
- */
- public enum Status {
- /**
- * The user's account is active.
- */
- ACTIVE,
-
- /**
- * The user's account is inactive.
- */
- INACTIVE,
-
- /**
- * The user's account cannot delete or edit content.
- */
- CANNOT_DELETE_EDIT,
-
- /**
- * The user's account cannot delete, edit, or upload content.
- */
- CANNOT_DELETE_EDIT_UPLOAD
- }
-
- /**
- * Contains information about a BoxUser.
- */
- public class Info extends BoxCollaborator.Info {
- private String login;
- private Role role;
- private String language;
- private String timezone;
- private long spaceAmount;
- private long spaceUsed;
- private long maxUploadSize;
- private Status status;
- private String jobTitle;
- private String phone;
- private String address;
- private String avatarURL;
-
- Info(JsonObject jsonObject) {
- super(jsonObject);
- }
-
- @Override
- public BoxUser getResource() {
- return BoxUser.this;
- }
-
- /**
- * Gets the email address the user uses to login.
- * @return the email address the user uses to login.
- */
- public String getLogin() {
- return this.login;
- }
-
- /**
- * Gets the user's enterprise role.
- * @return the user's enterprise role.
- */
- public Role getRole() {
- return this.role;
- }
-
- /**
- * Gets the language of the user.
- * @return the language of the user.
- */
- public String getLanguage() {
- return this.language;
- }
-
- /**
- * Gets the timezone of the user.
- * @return the timezone of the user.
- */
- public String getTimezone() {
- return this.timezone;
- }
-
- /**
- * Gets the user's total available space in bytes.
- * @return the user's total available space in bytes.
- */
- public long getSpaceAmount() {
- return this.spaceAmount;
- }
-
- /**
- * Gets the amount of space the user has used in bytes.
- * @return the amount of space the user has used in bytes.
- */
- public long getSpaceUsed() {
- return this.spaceUsed;
- }
-
- /**
- * Gets the maximum individual file size in bytes the user can have.
- * @return the maximum individual file size in bytes the user can have.
- */
- public long getMaxUploadSize() {
- return this.maxUploadSize;
- }
-
- /**
- * Gets the user's current account status.
- * @return the user's current account status.
- */
- public Status getStatus() {
- return this.status;
- }
-
- /**
- * Gets the job title of the user.
- * @return the job title of the user.
- */
- public String getJobTitle() {
- return this.jobTitle;
- }
-
- /**
- * Gets the phone number of the user.
- * @return the phone number of the user.
- */
- public String getPhone() {
- return this.phone;
- }
-
- /**
- * Gets the address of the user.
- * @return the address of the user.
- */
- public String getAddress() {
- return this.address;
- }
-
- /**
- * Gets the URL of the user's avatar.
- * @return the URL of the user's avatar.
- */
- public String getAvatarURL() {
- return this.avatarURL;
- }
-
- @Override
- protected void parseJSONMember(JsonObject.Member member) {
- super.parseJSONMember(member);
-
- JsonValue value = member.getValue();
- String memberName = member.getName();
- if (memberName.equals("login")) {
- this.login = value.asString();
- } else if (memberName.equals("role")) {
- this.role = this.parseRole(value);
- } else if (memberName.equals("language")) {
- this.language = value.asString();
- } else if (memberName.equals("timezone")) {
- this.timezone = value.asString();
- } else if (memberName.equals("space_amount")) {
- this.spaceAmount = Double.valueOf(value.toString()).longValue();
- } else if (memberName.equals("space_used")) {
- this.spaceUsed = Double.valueOf(value.toString()).longValue();
- } else if (memberName.equals("max_upload_size")) {
- this.maxUploadSize = Double.valueOf(value.toString()).longValue();
- } else if (memberName.equals("status")) {
- this.status = this.parseStatus(value);
- } else if (memberName.equals("job_title")) {
- this.jobTitle = value.asString();
- } else if (memberName.equals("phone")) {
- this.phone = value.asString();
- } else if (memberName.equals("address")) {
- this.address = value.asString();
- } else if (memberName.equals("avatar_url")) {
- this.avatarURL = value.asString();
- }
- }
-
- private Role parseRole(JsonValue value) {
- String roleString = value.asString().toUpperCase();
- return Role.valueOf(roleString);
- }
-
- private Status parseStatus(JsonValue value) {
- String statusString = value.asString().toUpperCase();
- return Status.valueOf(statusString);
- }
- }
-}
diff --git a/src/main/java/com/box/sdk/EventListener.java b/src/main/java/com/box/sdk/EventListener.java
deleted file mode 100644
index daef86501..000000000
--- a/src/main/java/com/box/sdk/EventListener.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.box.sdk;
-
-/**
- * The listener interface for receiving events from an {@link EventStream}.
- */
-public interface EventListener {
- /**
- * Invoked when an event is received from the API.
- * @param event the received event.
- */
- void onEvent(BoxEvent event);
-
- /**
- * Invoked when an updated stream position is received from the API.
- * @param position of the stream.
- */
- void onNextPosition(long position);
-
- /**
- * Invoked when an error occurs while waiting for events to be received.
- *
- *
When an EventStream encounters an exception, it will invoke this method on each of its listeners until one
- * of them returns true, indicating that the exception was handled.
- *
- * @param e the exception that was thrown while waiting for events.
- * @return true if the exception was handled; otherwise false.
- */
- boolean onException(Throwable e);
-}
diff --git a/src/main/java/com/box/sdk/EventStream.java b/src/main/java/com/box/sdk/EventStream.java
deleted file mode 100644
index f523aa732..000000000
--- a/src/main/java/com/box/sdk/EventStream.java
+++ /dev/null
@@ -1,206 +0,0 @@
-package com.box.sdk;
-
-import java.util.ArrayList;
-import java.util.Collection;
-
-import com.eclipsesource.json.JsonArray;
-import com.eclipsesource.json.JsonObject;
-import com.eclipsesource.json.JsonValue;
-
-/**
- * Receives real-time events from the API and forwards them to {@link EventListener EventListeners}.
- *
- *
This class handles long polling the Box events endpoint in order to receive real-time user or enterprise events.
- * When an EventStream is started, it begins long polling on a separate thread until the {@link #stop} method is called.
- * Since the API may return duplicate events, EventStream also maintains a small cache of the most recently received
- * event IDs in order to automatically deduplicate events.
- *
- */
-public class EventStream {
- private static final int LIMIT = 800;
- private static final URLTemplate EVENT_URL = new URLTemplate("events?limit=" + LIMIT + "&stream_position=%s");
- private static final int STREAM_POSITION_NOW = -1;
-
- private final BoxAPIConnection api;
- private final long startingPosition;
- private final Collection listeners;
- private final Object listenerLock;
-
- private LRUCache receivedEvents;
- private boolean started;
- private Poller poller;
- private Thread pollerThread;
-
- /**
- * Constructs an EventStream using an API connection.
- * @param api the API connection to use.
- */
- public EventStream(BoxAPIConnection api) {
- this(api, STREAM_POSITION_NOW);
- }
-
- /**
- * Constructs an EventStream using an API connection and a starting initial position.
- * @param api the API connection to use.
- * @param startingPosition the starting position of the event stream.
- */
- public EventStream(BoxAPIConnection api, long startingPosition) {
- this.api = api;
- this.startingPosition = startingPosition;
- this.listeners = new ArrayList();
- this.listenerLock = new Object();
- }
-
- /**
- * Adds a listener that will be notified when an event is received.
- * @param listener the listener to add.
- */
- public void addListener(EventListener listener) {
- synchronized (this.listenerLock) {
- this.listeners.add(listener);
- }
- }
-
- /**
- * Indicates whether or not this EventStream has been started.
- * @return true if this EventStream has been started; otherwise false.
- */
- public boolean isStarted() {
- return this.started;
- }
-
- /**
- * Stops this EventStream and disconnects from the API.
- * @throws IllegalStateException if the EventStream is already stopped.
- */
- public void stop() {
- if (!this.started) {
- throw new IllegalStateException("Cannot stop the EventStream because it isn't started.");
- }
-
- this.started = false;
- this.pollerThread.interrupt();
- }
-
- /**
- * Starts this EventStream and begins long polling the API.
- * @throws IllegalStateException if the EventStream is already started.
- */
- public void start() {
- if (this.started) {
- throw new IllegalStateException("Cannot start the EventStream because it isn't stopped.");
- }
-
- final long initialPosition;
-
- if (this.startingPosition == STREAM_POSITION_NOW) {
- BoxAPIRequest request = new BoxAPIRequest(this.api, EVENT_URL.build(this.api.getBaseURL(), "now"), "GET");
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
- initialPosition = jsonObject.get("next_stream_position").asLong();
- } else {
- initialPosition = this.startingPosition;
- }
-
- this.poller = new Poller(initialPosition);
-
- this.pollerThread = new Thread(this.poller);
- this.pollerThread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
- public void uncaughtException(Thread t, Throwable e) {
- EventStream.this.notifyException(e);
- }
- });
- this.pollerThread.start();
-
- this.started = true;
- }
-
- /**
- * Indicates whether or not an event ID is a duplicate.
- *
- *
This method can be overridden by a subclass in order to provide custom de-duping logic.
- *
- * @param eventID the event ID.
- * @return true if the event is a duplicate; otherwise false.
- */
- protected boolean isDuplicate(String eventID) {
- if (this.receivedEvents == null) {
- this.receivedEvents = new LRUCache();
- }
-
- return !this.receivedEvents.add(eventID);
- }
-
- private void notifyNextPosition(long position) {
- synchronized (this.listenerLock) {
- for (EventListener listener : this.listeners) {
- listener.onNextPosition(position);
- }
- }
- }
-
- private void notifyEvent(BoxEvent event) {
- synchronized (this.listenerLock) {
- boolean isDuplicate = this.isDuplicate(event.getID());
- if (!isDuplicate) {
- for (EventListener listener : this.listeners) {
- listener.onEvent(event);
- }
- }
- }
- }
-
- private void notifyException(Throwable e) {
- if (e instanceof InterruptedException && !this.started) {
- return;
- }
-
- this.stop();
- synchronized (this.listenerLock) {
- for (EventListener listener : this.listeners) {
- if (listener.onException(e)) {
- return;
- }
- }
- }
- }
-
- private class Poller implements Runnable {
- private final long initialPosition;
-
- private RealtimeServerConnection server;
-
- public Poller(long initialPosition) {
- this.initialPosition = initialPosition;
- this.server = new RealtimeServerConnection(EventStream.this.api);
- }
-
- @Override
- public void run() {
- long position = this.initialPosition;
- while (!Thread.interrupted()) {
- if (this.server.getRemainingRetries() == 0) {
- this.server = new RealtimeServerConnection(EventStream.this.api);
- }
-
- if (this.server.waitForChange(position)) {
- if (Thread.interrupted()) {
- return;
- }
-
- BoxAPIRequest request = new BoxAPIRequest(EventStream.this.api,
- EVENT_URL.build(EventStream.this.api.getBaseURL(), position), "GET");
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
- JsonArray entriesArray = jsonObject.get("entries").asArray();
- for (JsonValue entry : entriesArray) {
- BoxEvent event = new BoxEvent(EventStream.this.api, entry.asObject());
- EventStream.this.notifyEvent(event);
- }
- position = jsonObject.get("next_stream_position").asLong();
- EventStream.this.notifyNextPosition(position);
- }
- }
- }
- }
-}
diff --git a/src/main/java/com/box/sdk/FileUploadParams.java b/src/main/java/com/box/sdk/FileUploadParams.java
deleted file mode 100644
index 4836fe825..000000000
--- a/src/main/java/com/box/sdk/FileUploadParams.java
+++ /dev/null
@@ -1,129 +0,0 @@
-package com.box.sdk;
-
-import java.io.InputStream;
-import java.util.Date;
-
-/**
- * Contains parameters for configuring an upload to Box.
- */
-public class FileUploadParams {
- private InputStream content;
- private String name;
- private Date created;
- private Date modified;
- private long size;
- private ProgressListener listener;
-
- /**
- * Constructs a new FileUploadParams with default parameters.
- */
- public FileUploadParams() { }
-
- /**
- * Gets the content that will be uploaded to Box.
- * @return an InputStream that reads the content to be uploaded to Box.
- */
- public InputStream getContent() {
- return this.content;
- }
-
- /**
- * Sets the content that will be uploaded to Box.
- * @param content an InputStream that reads from the content to be uploaded to Box.
- * @return this FileUploadParams object for chaining.
- */
- public FileUploadParams setContent(InputStream content) {
- this.content = content;
- return this;
- }
-
- /**
- * Gets the name that will be given to the uploaded file.
- * @return the name that will be given to the uploaded file.
- */
- public String getName() {
- return this.name;
- }
-
- /**
- * Sets the name that will be given to the uploaded file.
- * @param name the name that will be given to the uploaded file.
- * @return this FileUploadParams object for chaining.
- */
- public FileUploadParams setName(String name) {
- this.name = name;
- return this;
- }
-
- /**
- * Gets the content created date that will be given to the uploaded file.
- * @return the content created date that will be given to the uploaded file.
- */
- public Date getCreated() {
- return this.created;
- }
-
- /**
- * Sets the content created date that will be given to the uploaded file.
- * @param created the content created date that will be given to the uploaded file.
- * @return this FileUploadParams object for chaining.
- */
- public FileUploadParams setCreated(Date created) {
- this.created = created;
- return this;
- }
-
- /**
- * Gets the content modified date that will be given to the uploaded file.
- * @return the content modified date that will be given to the uploaded file.
- */
- public Date getModified() {
- return this.modified;
- }
-
- /**
- * Sets the content modified date that will be given to the uploaded file.
- * @param modified the content modified date that will be given to the uploaded file.
- * @return this FileUploadParams object for chaining.
- */
- public FileUploadParams setModified(Date modified) {
- this.modified = modified;
- return this;
- }
-
- /**
- * Gets the size of the file's content used for monitoring the upload's progress.
- * @return the size of the file's content.
- */
- public long getSize() {
- return this.size;
- }
-
- /**
- * Sets the size of the file content used for monitoring the upload's progress.
- * @param size the size of the file's content.
- * @return this FileUploadParams object for chaining.
- */
- public FileUploadParams setSize(long size) {
- this.size = size;
- return this;
- }
-
- /**
- * Gets the ProgressListener that will be used for monitoring the upload's progress.
- * @return the ProgressListener that will be used for monitoring the upload's progress.
- */
- public ProgressListener getProgressListener() {
- return this.listener;
- }
-
- /**
- * Sets the ProgressListener that will be used for monitoring the upload's progress.
- * @param listener the listener that will be used for monitoring the upload's progress.
- * @return this FileUploadParams object for chaining.
- */
- public FileUploadParams setProgressListener(ProgressListener listener) {
- this.listener = listener;
- return this;
- }
-}
diff --git a/src/main/java/com/box/sdk/Filter.java b/src/main/java/com/box/sdk/Filter.java
deleted file mode 100644
index 795826582..000000000
--- a/src/main/java/com/box/sdk/Filter.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package com.box.sdk;
-
-interface Filter {
- boolean shouldInclude(T object);
-}
diff --git a/src/main/java/com/box/sdk/JSONIterator.java b/src/main/java/com/box/sdk/JSONIterator.java
deleted file mode 100644
index 8fc19a7c3..000000000
--- a/src/main/java/com/box/sdk/JSONIterator.java
+++ /dev/null
@@ -1,108 +0,0 @@
-package com.box.sdk;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-import com.eclipsesource.json.JsonArray;
-import com.eclipsesource.json.JsonObject;
-import com.eclipsesource.json.JsonValue;
-
-class JSONIterator implements Iterator {
- private final BoxAPIConnection api;
- private final URL url;
-
- private long limit;
- private long offset;
- private long totalCount;
- private boolean hasMorePages;
- private Iterator currentPage;
- private JsonObject nextJsonObject;
- private Filter filter;
-
- public JSONIterator(BoxAPIConnection api, URL url, long limit) {
- this.api = api;
- this.url = url;
- this.limit = limit;
- }
-
- public boolean hasNext() {
- if (this.nextJsonObject == null) {
- this.nextJsonObject = this.loadNextJsonObject();
- }
-
- return this.nextJsonObject != null;
- }
-
- public JsonObject next() {
- if (this.nextJsonObject == null) {
- this.nextJsonObject = this.loadNextJsonObject();
- }
-
- if (this.nextJsonObject == null) {
- throw new NoSuchElementException();
- }
-
- JsonObject next = this.nextJsonObject;
- this.nextJsonObject = null;
- return next;
- }
-
- public void remove() {
- throw new UnsupportedOperationException();
- }
-
- public void setFilter(Filter filter) {
- this.filter = filter;
- }
-
- private void loadNextPage() {
- String existingQuery = this.url.getQuery();
- QueryStringBuilder builder = new QueryStringBuilder(existingQuery);
- builder.appendParam("limit", this.limit);
- builder.appendParam("offset", this.offset);
-
- URL url;
- try {
- url = builder.addToURL(this.url);
- } catch (MalformedURLException e) {
- throw new BoxAPIException("Couldn't append a query string to the provided URL.");
- }
-
- BoxAPIRequest request = new BoxAPIRequest(this.api, url, "GET");
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- String json = response.getJSON();
-
- JsonObject jsonObject = JsonObject.readFrom(json);
- String totalCountString = jsonObject.get("total_count").toString();
- this.totalCount = Double.valueOf(totalCountString).longValue();
- String offsetString = jsonObject.get("offset").toString();
- this.hasMorePages = (this.offset + this.limit) < this.totalCount;
- this.offset = Double.valueOf(offsetString).longValue() + this.limit;
-
- JsonArray jsonArray = jsonObject.get("entries").asArray();
- this.currentPage = jsonArray.iterator();
- }
-
- private JsonObject loadNextJsonObject() {
- if (this.currentPage == null) {
- this.loadNextPage();
- }
-
- while (this.currentPage.hasNext() || this.hasMorePages) {
- while (this.currentPage.hasNext()) {
- JsonObject jsonObject = this.currentPage.next().asObject();
- if (this.filter.shouldInclude(jsonObject)) {
- return jsonObject;
- }
- }
-
- if (this.hasMorePages) {
- this.loadNextPage();
- }
- }
-
- return null;
- }
-}
diff --git a/src/main/java/com/box/sdk/LRUCache.java b/src/main/java/com/box/sdk/LRUCache.java
deleted file mode 100644
index 77e791e7f..000000000
--- a/src/main/java/com/box/sdk/LRUCache.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package com.box.sdk;
-
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-
-class LRUCache {
- static final int MAX_SIZE = 512;
-
- private final LinkedHashSet linkedHashSet;
-
- public LRUCache() {
- this.linkedHashSet = new LinkedHashSet(MAX_SIZE);
- }
-
- boolean add(E item) {
- boolean newItem = !this.linkedHashSet.remove(item);
- this.linkedHashSet.add(item);
-
- if (this.linkedHashSet.size() >= MAX_SIZE) {
- Iterator it = this.linkedHashSet.iterator();
- it.next();
- it.remove();
- }
-
- return newItem;
- }
-}
diff --git a/src/main/java/com/box/sdk/Metadata.java b/src/main/java/com/box/sdk/Metadata.java
deleted file mode 100644
index 393fe1aee..000000000
--- a/src/main/java/com/box/sdk/Metadata.java
+++ /dev/null
@@ -1,172 +0,0 @@
-package com.box.sdk;
-
-import com.eclipsesource.json.JsonArray;
-import com.eclipsesource.json.JsonObject;
-import com.eclipsesource.json.JsonValue;
-
-/**
- * The Metadata class represents one type instance of Box metadata.
- *
- * Learn more about Box metadata:
- * https://developers.box.com/metadata-api/
- */
-public class Metadata {
- private final JsonObject values;
- private JsonArray operations;
-
- /**
- * Creates an empty metadata.
- */
- public Metadata() {
- this.values = new JsonObject();
- }
-
- /**
- * Creates a new metadata.
- * @param values the initial metadata values.
- */
- Metadata(JsonObject values) {
- this.values = values;
- }
-
- /**
- * Creates a copy of another metadata.
- * @param other the other metadata object to copy.
- */
- public Metadata(Metadata other) {
- this.values = new JsonObject(other.values);
- }
-
- /**
- * Returns the 36 character UUID to identify the metadata object.
- * @return the metadata ID.
- */
- public String getID() {
- return this.get("/$id");
- }
-
- /**
- * Returns the metadata type.
- * @return the metadata type.
- */
- public String getTypeName() {
- return this.get("/$type");
- }
-
- /**
- * Returns the parent object ID (typically the file ID).
- * @return the parent object ID.
- */
- public String getParentID() {
- return this.get("/$parent");
- }
-
- /**
- * Adds a new metdata value.
- * @param path the path that designates the key. Must be prefixed with a "/".
- * @param value the value.
- * @return this metadata object.
- */
- public Metadata add(String path, String value) {
- this.values.add(this.pathToProperty(path), value);
- this.addOp("add", path, value);
- return this;
- }
-
- /**
- * Replaces an existing metdata value.
- * @param path the path that designates the key. Must be prefixed with a "/".
- * @param value the value.
- * @return this metadata object.
- */
- public Metadata replace(String path, String value) {
- this.values.set(this.pathToProperty(path), value);
- this.addOp("replace", path, value);
- return this;
- }
-
- /**
- * Removes an existing metadata value.
- * @param path the path that designates the key. Must be prefixed with a "/".
- * @return this metadata object.
- */
- public Metadata remove(String path) {
- this.values.remove(this.pathToProperty(path));
- this.addOp("remove", path, null);
- return this;
- }
-
- /**
- * Tests that a property has the expected value.
- * @param path the path that designates the key. Must be prefixed with a "/".
- * @param value the expected value.
- * @return this metadata object.
- */
- public Metadata test(String path, String value) {
- this.addOp("test", path, value);
- return this;
- }
-
- /**
- * Returns a value.
- * @param path the path that designates the key. Must be prefixed with a "/".
- * @return the metadata property value.
- */
- public String get(String path) {
- final JsonValue value = this.values.get(this.pathToProperty(path));
- if (value == null) {
- return null;
- }
- return value.asString();
- }
-
- /**
- * Returns the JSON patch string with all operations.
- * @return the JSON patch string.
- */
- public String getPatch() {
- if (this.operations == null) {
- return "[]";
- }
- return this.operations.toString();
- }
-
- /**
- * Returns the JSON representation of this metadata.
- * @return the JSON representation of this metadata.
- */
- @Override
- public String toString() {
- return this.values.toString();
- }
-
- /**
- * Converts a JSON patch path to a JSON property name.
- * Currently the metadata API only supports flat maps.
- * @param path the path that designates the key. Must be prefixed with a "/".
- * @return the JSON property name.
- */
- private String pathToProperty(String path) {
- if (path == null || !path.startsWith("/")) {
- throw new IllegalArgumentException("Path must be prefixed with a \"/\".");
- }
- return path.substring(1);
- }
-
- /**
- * Adds a patch operation.
- * @param op the operation type. Must be add, replace, remove, or test.
- * @param path the path that designates the key. Must be prefixed with a "/".
- * @param value the value to be set.
- */
- private void addOp(String op, String path, String value) {
- if (this.operations == null) {
- this.operations = new JsonArray();
- }
-
- this.operations.add(new JsonObject()
- .add("op", op)
- .add("path", path)
- .add("value", value));
- }
-}
diff --git a/src/main/java/com/box/sdk/PartialCollection.java b/src/main/java/com/box/sdk/PartialCollection.java
deleted file mode 100644
index db4274905..000000000
--- a/src/main/java/com/box/sdk/PartialCollection.java
+++ /dev/null
@@ -1,132 +0,0 @@
-package com.box.sdk;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-
-/**
- * A collection that contains a subset of items that are a part of a larger collection. The items within a partial
- * collection begin at an offset within the full collection and end at a specified limit. Note that the actual size of a
- * partial collection may be less than its limit since the limit only specifies the maximum size. For example, if
- * there's a full collection with a size of 3, then a partial collection with offset 0 and limit 3 would be equal to a
- * partial collection with offset 0 and limit 100.
- * @param the type of elements in this partial collection.
- */
-public class PartialCollection implements Collection {
- private final Collection collection;
- private final long offset;
- private final long limit;
- private final long fullSize;
-
- /**
- * Constructs a PartialCollection with a specified offset, limit, and full size.
- * @param offset the offset within in the full collection.
- * @param limit the maximum number of items after the offset.
- * @param fullSize the total number of items in the full collection.
- */
- public PartialCollection(long offset, long limit, long fullSize) {
- this.collection = new ArrayList();
- this.offset = offset;
- this.limit = limit;
- this.fullSize = fullSize;
- }
-
- /**
- * Gets the offset within the full collection where this collection's items begin.
- * @return the offset within the full collection where this collection's items begin.
- */
- public long offset() {
- return this.offset;
- }
-
- /**
- * Gets the maximum number of items within the full collection that begin at {@link #offset}.
- * @return the maximum number of items within the full collection that begin at the offset.
- */
- public long limit() {
- return this.limit;
- }
-
- /**
- * Gets the size of the full collection that this partial collection is based off of.
- * @return the size of the full collection that this partial collection is based off of.
- */
- public long fullSize() {
- return this.fullSize;
- }
-
- @Override
- public boolean add(E e) {
- return this.collection.add(e);
- }
-
- @Override
- public boolean addAll(Collection extends E> c) {
- return this.collection.addAll(c);
- }
-
- @Override
- public void clear() {
- this.collection.clear();
- }
-
- @Override
- public boolean contains(Object o) {
- return this.collection.contains(o);
- }
-
- @Override
- public boolean containsAll(Collection> c) {
- return this.collection.containsAll(c);
- }
-
- @Override
- public boolean equals(Object o) {
- return this.collection.equals(o);
- }
-
- @Override
- public int hashCode() {
- return this.collection.hashCode();
- }
-
- @Override
- public boolean isEmpty() {
- return this.collection.isEmpty();
- }
-
- @Override
- public Iterator iterator() {
- return this.collection.iterator();
- }
-
- @Override
- public boolean remove(Object o) {
- return this.collection.remove(o);
- }
-
- @Override
- public boolean removeAll(Collection> c) {
- return this.collection.removeAll(c);
- }
-
- @Override
- public boolean retainAll(Collection> c) {
- return this.collection.retainAll(c);
- }
-
- @Override
- public int size() {
- return this.collection.size();
- }
-
- @Override
- public Object[] toArray() {
- return this.collection.toArray();
- }
-
- @Override
- public T[] toArray(T[] a) {
- return this.collection.toArray(a);
- }
-}
diff --git a/src/main/java/com/box/sdk/ProgressInputStream.java b/src/main/java/com/box/sdk/ProgressInputStream.java
deleted file mode 100644
index 5cf468e71..000000000
--- a/src/main/java/com/box/sdk/ProgressInputStream.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package com.box.sdk;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * An {@link InputStream} that can report the progress of reading from another InputStream to a
- * {@link ProgressListener}.
- */
-class ProgressInputStream extends InputStream {
- private final InputStream stream;
- private final ProgressListener listener;
-
- private long total;
- private long totalRead;
- private int progress;
-
- /**
- * Constructs a ProgressInputStream that wraps another InputStream.
- * @param stream the stream whose progress will be monitored.
- * @param listener the listener that will receive progress updates.
- * @param total the total number of bytes that are expected to be read from the stream.
- */
- public ProgressInputStream(InputStream stream, ProgressListener listener, long total) {
- this.stream = stream;
- this.listener = listener;
- this.total = total;
- }
-
- /**
- * Gets the total number of bytes that are expected to be read from the stream.
- * @return the total number of bytes.
- */
- public long getTotal() {
- return this.total;
- }
-
- /**
- * Sets the total number of bytes that are expected to be read from the stream.
- * @param total the total number of bytes
- */
- public void setTotal(long total) {
- this.total = total;
- }
-
- @Override
- public void close() throws IOException {
- this.stream.close();
- }
-
- @Override
- public int read() throws IOException {
- int read = this.stream.read();
- this.totalRead++;
- this.listener.onProgressChanged(this.totalRead, this.total);
-
- return read;
- }
-
- @Override
- public int read(byte[] b, int off, int len) throws IOException {
- int read = this.stream.read(b, off, len);
- this.totalRead += read;
- this.listener.onProgressChanged(this.totalRead, this.total);
-
- return read;
- }
-}
diff --git a/src/main/java/com/box/sdk/ProgressListener.java b/src/main/java/com/box/sdk/ProgressListener.java
deleted file mode 100644
index f6c4e584d..000000000
--- a/src/main/java/com/box/sdk/ProgressListener.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.box.sdk;
-
-/**
- * The listener interface for monitoring the progress of a long-running API call.
- */
-public interface ProgressListener {
-
- /**
- * Invoked when the progress of the API call changes.
- * @param numBytes the number of bytes completed.
- * @param totalBytes the total number of bytes.
- */
- void onProgressChanged(long numBytes, long totalBytes);
-}
diff --git a/src/main/java/com/box/sdk/ProgressOutputStream.java b/src/main/java/com/box/sdk/ProgressOutputStream.java
deleted file mode 100644
index 58a1f9150..000000000
--- a/src/main/java/com/box/sdk/ProgressOutputStream.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package com.box.sdk;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-/**
- * An {@link OutputStream} that can report the progress of writing to another OutputStream to a
- * {@link ProgressListener}.
- */
-class ProgressOutputStream extends OutputStream {
- private final OutputStream stream;
- private final ProgressListener listener;
-
- private long total;
- private long totalWritten;
- private int progress;
-
- public ProgressOutputStream(OutputStream stream, ProgressListener listener, long total) {
- this.stream = stream;
- this.listener = listener;
- this.total = total;
- }
-
- public long getTotal() {
- return this.total;
- }
-
- public void setTotal(long total) {
- this.total = total;
- }
-
- @Override
- public void close() throws IOException {
- this.stream.close();
- }
-
- @Override
- public void write(byte[] b) throws IOException {
- this.stream.write(b);
- this.totalWritten += b.length;
- this.listener.onProgressChanged(this.totalWritten, this.total);
- }
-
- @Override
- public void write(byte[] b, int off, int len) throws IOException {
- this.stream.write(b, off, len);
- if (len < b.length) {
- this.totalWritten += len;
- } else {
- this.totalWritten += b.length;
- }
- this.listener.onProgressChanged(this.totalWritten, this.total);
- }
-
- @Override
- public void write(int b) throws IOException {
- this.stream.write(b);
- this.totalWritten++;
- this.listener.onProgressChanged(this.totalWritten, this.total);
- }
-}
diff --git a/src/main/java/com/box/sdk/QueryStringBuilder.java b/src/main/java/com/box/sdk/QueryStringBuilder.java
deleted file mode 100644
index 4b866727f..000000000
--- a/src/main/java/com/box/sdk/QueryStringBuilder.java
+++ /dev/null
@@ -1,131 +0,0 @@
-package com.box.sdk;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-
-class QueryStringBuilder {
- private final StringBuilder stringBuilder;
-
- QueryStringBuilder() {
- this.stringBuilder = new StringBuilder();
- }
-
- QueryStringBuilder(String existing) {
- if (existing == null) {
- this.stringBuilder = new StringBuilder();
- } else {
- this.stringBuilder = new StringBuilder(existing);
- }
- }
-
- QueryStringBuilder appendParam(String key, String... fields) {
- StringBuilder valuesBuilder = new StringBuilder();
- for (String field : fields) {
- valuesBuilder.append(field);
- valuesBuilder.append(",");
- }
- valuesBuilder.deleteCharAt(valuesBuilder.length() - 1);
-
- this.appendParam(key, valuesBuilder.toString());
- return this;
- }
-
- QueryStringBuilder appendParam(String key, String value) {
- if (this.stringBuilder.length() == 0) {
- this.stringBuilder.append('?');
- } else {
- this.stringBuilder.append('&');
- }
-
- this.stringBuilder.append(key);
- this.stringBuilder.append('=');
- this.stringBuilder.append(this.encode(value));
- return this;
- }
-
- QueryStringBuilder appendParam(String key, long value) {
- return this.appendParam(key, Long.toString(value));
- }
-
- URL addToURL(URL existing) throws MalformedURLException {
- String existingQuery = existing.getQuery();
- if (existingQuery == null || existingQuery.equals("")) {
- return new URL(existing.toString() + this.toString());
- }
-
- return new URL(existing.toString().replace(existingQuery, this.toString()));
- }
-
- @Override
- public String toString() {
- return this.stringBuilder.toString();
- }
-
- private String encode(String unencoded) {
- StringBuilder encodedBuilder = new StringBuilder();
- for (int i = 0, n = unencoded.length(); i < n; i++) {
- char c = unencoded.charAt(i);
- switch (c) {
- case ' ':
- encodedBuilder.append('+');
- break;
- case '!':
- encodedBuilder.append("%21");
- break;
- case '#':
- encodedBuilder.append("%23");
- break;
- case '$':
- encodedBuilder.append("%24");
- break;
- case '&':
- encodedBuilder.append("%26");
- break;
- case '\'':
- encodedBuilder.append("%27");
- break;
- case '(':
- encodedBuilder.append("%28");
- break;
- case ')':
- encodedBuilder.append("%29");
- break;
- case '+':
- encodedBuilder.append("%2b");
- break;
- case ',':
- encodedBuilder.append("%2c");
- break;
- case '/':
- encodedBuilder.append("%2f");
- break;
- case ':':
- encodedBuilder.append("%3a");
- break;
- case ';':
- encodedBuilder.append("%3b");
- break;
- case '=':
- encodedBuilder.append("%3d");
- break;
- case '?':
- encodedBuilder.append("%3f");
- break;
- case '@':
- encodedBuilder.append("%40");
- break;
- case '[':
- encodedBuilder.append("%5b");
- break;
- case ']':
- encodedBuilder.append("%5d");
- break;
- default:
- encodedBuilder.append(c);
- break;
- }
- }
-
- return encodedBuilder.toString();
- }
-}
diff --git a/src/main/java/com/box/sdk/RealtimeServerConnection.java b/src/main/java/com/box/sdk/RealtimeServerConnection.java
deleted file mode 100644
index 82e461ef0..000000000
--- a/src/main/java/com/box/sdk/RealtimeServerConnection.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package com.box.sdk;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-
-import com.eclipsesource.json.JsonArray;
-import com.eclipsesource.json.JsonObject;
-
-class RealtimeServerConnection {
- private static final URLTemplate EVENT_URL = new URLTemplate("events");
- private static final URLTemplate EVENT_POSITION_URL = new URLTemplate("events?stream_position=%s");
-
- private final BoxAPIConnection api;
- private final int timeout;
- private final String serverURLString;
-
- private int retries;
- private BoxJSONResponse response;
-
- RealtimeServerConnection(BoxAPIConnection api) {
- BoxAPIRequest request = new BoxAPIRequest(api, EVENT_URL.build(api.getBaseURL()), "OPTIONS");
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
- JsonArray entries = jsonObject.get("entries").asArray();
- JsonObject firstEntry = entries.get(0).asObject();
- this.serverURLString = firstEntry.get("url").asString();
- this.retries = Integer.parseInt(firstEntry.get("max_retries").asString());
- this.timeout = firstEntry.get("retry_timeout").asInt();
- this.api = api;
- }
-
- int getRemainingRetries() {
- return this.retries;
- }
-
- boolean waitForChange(long position) {
- if (this.retries < 1) {
- throw new IllegalStateException("No more retries are allowed.");
- }
-
- URL url;
- try {
- String u = this.serverURLString + "&stream_position=" + position;
- url = new URL(u);
- } catch (MalformedURLException e) {
- throw new BoxAPIException("The long poll URL was malformed.", e);
- }
-
- while (this.retries > 0) {
- this.retries--;
- try {
- BoxAPIRequest request = new BoxAPIRequest(this.api, url, "GET");
- request.setTimeout(this.timeout * 1000);
- this.response = (BoxJSONResponse) request.send();
- JsonObject jsonObject = JsonObject.readFrom(this.response.getJSON());
- String message = jsonObject.get("message").asString();
- if (message.equals("new_change")) {
- return true;
- }
- } catch (BoxAPIException e) {
- break;
- }
- }
-
- return false;
- }
-}
diff --git a/src/main/java/com/box/sdk/RequestInterceptor.java b/src/main/java/com/box/sdk/RequestInterceptor.java
deleted file mode 100644
index 40b4adafc..000000000
--- a/src/main/java/com/box/sdk/RequestInterceptor.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package com.box.sdk;
-
-/**
- * The interface for intercepting requests to the Box API.
- *
- *
An interceptor may handle a request in any way it sees fit. It may update a request before it's sent, or it may
- * choose to return a custom response. If an interceptor returns a null response, then the request will continue to be
- * sent to the API along with any changes that the interceptor may have made to it.
- *
- *
public BoxAPIResponse onRequest(BoxAPIRequest request) {
- * request.addHeader("My-Header", "My-Value");
- *
- * // Returning null means the request will be sent along with our new header.
- * return null;
- *}
- *
- *
However, if a response is returned, then the request won't be sent and the interceptor's response will take the
- * place of the normal response.
- *
- *
public BoxAPIResponse onRequest(BoxAPIRequest request) {
- * // Returning our own response means the request won't be sent at all.
- * return new BoxAPIResponse();
- *}
- *
- *
A RequestInterceptor can be very useful for testing purposes. Requests to the Box API can be intercepted and fake
- * responses can be returned, allowing you to effectively test your code without needing to actually communicate with
- * the Box API.
- */
-public interface RequestInterceptor {
- /**
- * Invoked when a request is about to be sent to the API.
- * @param request the request that is about to be sent.
- * @return an optional response to the request. If the response is null, then the request will continue to
- * be sent to the Box API.
- */
- BoxAPIResponse onRequest(BoxAPIRequest request);
-}
diff --git a/src/main/java/com/box/sdk/SharedLinkAPIConnection.java b/src/main/java/com/box/sdk/SharedLinkAPIConnection.java
deleted file mode 100644
index 0d5c0a693..000000000
--- a/src/main/java/com/box/sdk/SharedLinkAPIConnection.java
+++ /dev/null
@@ -1,134 +0,0 @@
-package com.box.sdk;
-
-/**
- * This API connection uses a shared link (along with an optional password) to authenticate with the Box API. It wraps a
- * preexisting BoxAPIConnection in order to provide additional access to items that are accessible with a shared link.
- */
-class SharedLinkAPIConnection extends BoxAPIConnection {
- private final BoxAPIConnection wrappedConnection;
- private final String sharedLink;
- private final String sharedLinkPassword;
-
- SharedLinkAPIConnection(BoxAPIConnection connection, String sharedLink) {
- this(connection, sharedLink, null);
- }
-
- SharedLinkAPIConnection(BoxAPIConnection connection, String sharedLink, String sharedLinkPassword) {
- super(null);
-
- this.wrappedConnection = connection;
- this.sharedLink = sharedLink;
- this.sharedLinkPassword = sharedLinkPassword;
- }
-
- @Override
- public long getExpires() {
- return this.wrappedConnection.getExpires();
- }
-
- @Override
- public void setExpires(long milliseconds) {
- this.wrappedConnection.setExpires(milliseconds);
- }
-
- @Override
- public String getBaseURL() {
- return this.wrappedConnection.getBaseURL();
- }
-
- @Override
- public void setBaseURL(String baseURL) {
- this.wrappedConnection.setBaseURL(baseURL);
- }
-
- @Override
- public String getBaseUploadURL() {
- return this.wrappedConnection.getBaseUploadURL();
- }
-
- @Override
- public void setBaseUploadURL(String baseUploadURL) {
- this.wrappedConnection.setBaseUploadURL(baseUploadURL);
- }
-
- @Override
- public String getUserAgent() {
- return this.wrappedConnection.getUserAgent();
- }
-
- @Override
- public void setUserAgent(String userAgent) {
- this.wrappedConnection.setUserAgent(userAgent);
- }
-
- @Override
- public String getAccessToken() {
- return this.wrappedConnection.getAccessToken();
- }
-
- @Override
- public void setAccessToken(String accessToken) {
- this.wrappedConnection.setAccessToken(accessToken);
- }
-
- @Override
- public String getRefreshToken() {
- return this.wrappedConnection.getRefreshToken();
- }
-
- @Override
- public void setRefreshToken(String refreshToken) {
- this.wrappedConnection.setRefreshToken(refreshToken);
- }
-
- @Override
- public void setAutoRefresh(boolean autoRefresh) {
- this.wrappedConnection.setAutoRefresh(autoRefresh);
- }
-
- @Override
- public boolean getAutoRefresh() {
- return this.wrappedConnection.getAutoRefresh();
- }
-
- @Override
- public int getMaxRequestAttempts() {
- return this.wrappedConnection.getMaxRequestAttempts();
- }
-
- @Override
- public void setMaxRequestAttempts(int attempts) {
- this.wrappedConnection.setMaxRequestAttempts(attempts);
- }
-
- @Override
- public boolean canRefresh() {
- return this.wrappedConnection.canRefresh();
- }
-
- @Override
- public boolean needsRefresh() {
- return this.wrappedConnection.needsRefresh();
- }
-
- @Override
- public void refresh() {
- this.wrappedConnection.refresh();
- }
-
- /**
- * Gets the shared link used for accessing shared items.
- * @return the shared link used for accessing shared items.
- */
- String getSharedLink() {
- return this.sharedLink;
- }
-
- /**
- * Gets the shared link password used for accessing shared items.
- * @return the shared link password used for accessing shared items.
- */
- String getSharedLinkPassword() {
- return this.sharedLinkPassword;
- }
-}
diff --git a/src/main/java/com/box/sdk/StandardCharsets.java b/src/main/java/com/box/sdk/StandardCharsets.java
deleted file mode 100644
index 8b77db633..000000000
--- a/src/main/java/com/box/sdk/StandardCharsets.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.box.sdk;
-
-import java.nio.charset.Charset;
-
-/**
- * Constant definitions for the standard Charsets.
- *
- * NB: Replace with java.nio.charset.StandardCharsets when we drop 1.6 support.
- */
-public final class StandardCharsets {
-
- /**
- * Eight-bit UCS Transformation Format.
- */
- public static final Charset UTF_8 = Charset.forName("UTF-8");
-
- private StandardCharsets() {
- throw new UnsupportedOperationException();
- }
-}
diff --git a/src/main/java/com/box/sdk/Time.java b/src/main/java/com/box/sdk/Time.java
deleted file mode 100644
index bc5881b2f..000000000
--- a/src/main/java/com/box/sdk/Time.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.box.sdk;
-
-class Time {
- private static final ThreadLocal