diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..91354c172 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,8 @@ +version: 2 +updates: + - package-ecosystem: maven + directory: "/" + schedule: + interval: daily + time: "09:00" + open-pull-requests-limit: 10 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 000000000..f5877a770 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,33 @@ +name: build +on: + push: + branches: + - master + - /\d\.0\.0-RC/ + pull_request: + branches: + - master + - /\d\.0\.0-RC/ +jobs: + builds-tests-coverage: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'adopt' + - uses: actions/cache@v4 + with: + path: ~/.m2 + key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} + restore-keys: ${{ runner.os }}-m2 + - name: Run build steps and generate coverage report + run: | + mvn verify javadoc:javadoc jacoco:report -Pcoverage -B -V + - name: Upload coverage report to Codecov + uses: codecov/codecov-action@v5 + with: + file: ./**/target/site/jacoco/jacoco.xml + name: codecov + fail_ci_if_error: false diff --git a/.sonar.settings b/.sonar.settings new file mode 100644 index 000000000..1611fb1fa --- /dev/null +++ b/.sonar.settings @@ -0,0 +1,2 @@ +# Settings for sonar scan +gdc.java_version=openjdk-17 diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 994f14fb7..000000000 --- a/.travis.yml +++ /dev/null @@ -1,15 +0,0 @@ -language: java -# Skip the Travis Installation Phase (installation of dependencies: `mvn install -DskipTests=true`) -install: true -# Customized build command (default is only `mvn test`) -script: mvn verify javadoc:javadoc coveralls:report -Pcoverage -B -V -jdk: - - oraclejdk8 -branches: - only: - - master - - /\d\.0\.0-RC/ -# Cache Maven repo between Travis builds -cache: - directories: - - '$HOME/.m2/repository' diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index a734e49fb..ad99aa3bf 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,5 +1,5 @@ # Contributor Code of Conduct -This project adheres to No Code of Conduct. We are all adults. We accept anyone's contributions. Nothing else matters. +This project adheres to No Code of Conduct. We are all adults. We accept anyone's contributions. Nothing else matters. For more information please visit the [No Code of Conduct](https://github.com/domgetter/NCoC) homepage. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3871b4af5..150b45ca6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -5,73 +5,92 @@ Below are few **rules, recommendations and best practices** we try to follow whe ## Paperwork ### Committer + * The **commit message**: - * must be written in the **imperative mood** - * must clearly **explain rationale** behind this change (describe _why_ you are doing the change rather than _what_ you are changing) + * must be written in the **imperative mood** + * must clearly **explain rationale** behind this change (describe _why_ you are doing the change rather than _what_ + you are changing) * The **pull request**: - * with non-trivial change must be **[associated with an issue](https://help.github.com/articles/closing-issues-via-commit-messages/)** + * with non-trivial, non-dependencies change must be * + *[associated with an issue](https://help.github.com/articles/closing-issues-via-commit-messages/)** * Add usage examples of new high level functionality to -[documentation](https://github.com/gooddata/gooddata-java/wiki/Code-Examples). + [documentation](https://github.com/gooddata/gooddata-java/wiki/Code-Examples). ### Reviewer + Ensure pull request and issues are - * **properly labeled** (trivial/bug/enhancement/backward incompatible/...) - * marked with exactly one **milestone version** + +* **properly labeled** (trivial/bug/enhancement/backward incompatible/...) +* marked with exactly one **milestone version** ## Design ### Structure + * **Package names** for DTOs and services should be named in the same manner as REST API. * Don't create single implementation interfaces for services. ### DTOs + * All DTOs which can be updated should be **mutable**. Please keep mutable only the fields which are subject of change, -the rest should be immutable. + the rest should be immutable. * Create method named `String getUri()` to provide **URI string to self**. -* Introduce **constants**: -```java -public static final String URI = "/gdc/someresource/{resource-id}"; -public static final UriTemplate TEMPLATE = new UriTemplate(URI); -``` +* Introduce **constant** with URI: + * ```java + public static final String URI = "/gdc/someresource/{resource-id}"; + ``` + * If you need also constants with `UriTemplate`, do not put them into DTOs not to drag Spring dependency into model + module. * Put _Jackson_ annotations on getters rather then on fields. * Consider the **visibility** - use `package protected` when DTO is not intended for SDK user, but is needed -in related service. + in related service. * Test all DTOs using _[JsonUnit](https://github.com/lukas-krecan/JsonUnit)_. * **Naming**: - * `Uri` for _URI string_ of some resource - * `Link` for structure containing at least _category_ (e.g. "self") and _URI string_ - (can contain also others like _title_, _summary_, etc.) + * `Uri` for _URI string_ of some resource + * `Link` for structure containing at least _category_ (e.g. "self") and _URI string_ + (can contain also others like _title_, _summary_, etc.) ### Enums + * Use enums sparingly, because they don't work with REST API changes (eg. new value added on the backend) **never use -them when deserializing**. + them when deserializing**. * Where make sense, use overloaded methods with an enum argument as well as `String` argument. ### Services + * When programming client for some polling return [`FutureResult`](src/main/java/com/gooddata/FutureResult.java) -to enable user asynchronous call. + to enable user asynchronous call. * Create custom [`GoodDataException`](src/main/java/com/gooddata/GoodDataException.java) when you feel the case -is specific enough. + is specific enough. * Prefer DTOs to `String` or primitive arguments. * **Method naming**: - * `get*()` when searching form single object (throw exception when no or multiple objects are found, - never return `null`) - * `find*()` when searching for multiple objects (collection of objects, never return `null`) - * `list*()` when listing whole or paged collection of objects (return collection or collection wrapped by DTO) - * `remove*()` (i.e. `remove(Project project)`) instead od `delete*()` -* Write **integration tests** for services using _[Jadler](https://github.com/jadler-mocking/jadler/wiki)_. -* If it is possible write **acceptance tests** to be run with the real backend. + * `get*()` when searching form single object (throw exception when no or multiple objects are found, + never return `null`) + * `find*()` when searching for multiple objects (collection of objects, never return `null`) + * `list*()` when listing whole or paged collection of objects (return collection or collection wrapped by DTO) + * `remove*()` (i.e. `remove(Project project)`) instead od `delete*()` +* In addition to unit tests, write also **integration tests** and **acceptance tests** if possible. See "What to test + where" in "Best practices" below. * Update [documentation](https://github.com/gooddata/gooddata-java/wiki/Code-Examples) with usage examples. ## Best practices -* **Test class naming**: - * `*Test` unit tests, but avoid service tests using mocked `RestTemplate` - use integration test - * `*IT` integration tests (see [`AbstractGoodDataIT`](src/test/java/com/gooddata/AbstractGoodDataIT.java)) - * `*AT` acceptance tests + +* **What to test where**: + * `*Test` = unit tests + * focus on verifying bussiness logic, corner cases, various input combinations, etc. + * avoid service tests using mocked `RestTemplate` - use integration tests with mocked API responses instead + * `*IT` = integration tests + * focus on verifying all possible outcomes of API calls + * see common ancestor [`AbstractGoodDataIT`](src/test/java/com/gooddata/AbstractGoodDataIT.java) setting + up [Jadler](https://github.com/jadler-mocking/jadler/wiki) for API mocking + * `*AT` = acceptance tests + * focus on verifying the happy path against the real backend (so we're sure mocks in ITs are correct) + * see common ancestor [`AbstractGoodDataAT`](src/test/java/com/gooddata/AbstractGoodDataAT.java) setting up + GoodData endpoint based on passed environment variables * Everything public should be **documented** using _javadoc_. * When you need some **utility code**, look for handy utilities in used libraries first (e.g. _Spring_ has -its `StreamUtils`, `FileCopyUtils`, ...). When you decide to create new utility class, -use _abstract utility class pattern_. + its `StreamUtils`, `FileCopyUtils`, ...). When you decide to create new utility class, + use _abstract utility class pattern_. ## Release candidates diff --git a/LICENSE.txt b/LICENSE.txt index 33b622ec7..4c1fba780 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -2,7 +2,7 @@ GoodData Java SDK BSD License -Copyright (c) 2014, GoodData Corporation +Copyright (c) 2014-2025, GoodData Corporation Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -25,3 +25,4058 @@ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +================================================================================ +This product includes a number of subcomponents with separate copyright notices and license terms below. +Your use of these subcomponents is subject to the terms and conditions of the subcomponent's license. +================================================================================ + +================================================================================ + TABLE OF CONTENTS + +================================================================================ +PART 1: SUBCOMPONENTS + +- AOP alliance (1.0) [public-domain] +- Apache Ant Core (1.10.3) [Apache-2.0] +- Apache Ant Launcher (1.10.3) [Apache-2.0] +- Apache Commons IO (2.21.0) [Apache-2.0] +- Apache Commons Lang (3.20.0) [Apache-2.0] +- Apache Groovy (4.0.28) [Apache-2.0] +- gooddata-http-client (3.0.0-SNAPSHOT) [BSD-3-Clause] +- gooddata-rest-common (3.0.0) [BSD-3-Clause] +- Gson (2.3.1) [Apache-2.0] +- Guava: Google Core Libraries for Java (17.0) [Apache-2.0, CC0-1.0] +- Hamcrest (2.2) [BSD-3-Clause] +- Hamcrest Core (2.2) [BSD-3-Clause] +- Jackson-annotations (2.13.0) [Apache-2.0] +- Jackson-core (2.13.0) [Apache-2.0] +- jackson-databind (2.13.4) [Apache-2.0] +- jadler-all (1.3.1) [MIT, Apache-2.0] +- jadler-core (1.3.1) [MIT, Apache-2.0] +- jakarta.inject (1) [Apache-2.0] +- jcommander (1.78) [Apache-2.0] +- JSON in Java (20090211) [JSON] +- json-unit (2.36.0) [Apache-2.0] +- json-unit-core (2.36.0) [Apache-2.0] +- JSONassert (1.2.3) [Apache-2.0] +- JUnit (4.12) [CPL-1.0] +- Mockito (5.14.2) [MIT, Apache-2.0] +- Objenesis (3.2) [MIT] +- Sardine WebDAV client (5.13) [Apache-2.0] +- Shazamcrest (0.11) [Apache-2.0] +- SLF4J API Module (2.0.17) [MIT] +- SLF4J Simple Binding (2.0.17) [MIT] +- SnakeYAML (1.21) [Apache-2.0, Multi-license: LGPL-2.1-or-later OR GPL-2.0-or-later OR EPL-1.0 OR BSD-3-Clause OR Apache-2.0] +- Spock Framework - Core Module (2.4-M1-groovy-4.0) [Apache-2.0] +- Spring Beans (6.0.15) [Apache-2.0] +- Spring Context (6.0.15) [Apache-2.0] +- Spring Core (6.0.15) [BSD-3-Clause, Apache-2.0] +- Spring Retry (2.0.12) [Apache-2.0] +- Spring Web (6.0.15) [Apache-2.0] +- testng (7.11.0) [Apache-2.0, AML] + +PART 2: LICENSES APPENDIX +Apache 2.0 +Creative commons Zero v1.0 Universal + +[END TABLE OF CONTENTS] +================================================================================ +PART 1: SUBCOMPONENTS +================================================================================ + +-------------------------------------------------------------------------------- +AOP alliance (1.0) +-------------------------------------------------------------------------------- + +* Declared Licenses * +public-domain + + +-------------------------------------------------------------------------------- +Apache Ant Core (1.10.3) +-------------------------------------------------------------------------------- + +* Declared Licenses * +Apache-2.0 + +/* + * Apache License + * Version 2.0, January 2004 + * http://www.apache.org/licenses/ + * + * TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + * + * 1. Definitions. + * + * "License" shall mean the terms and conditions for use, reproduction, + * and distribution as defined by Sections 1 through 9 of this document. + * + * "Licensor" shall mean the copyright owner or entity authorized by + * the copyright owner that is granting the License. + * + * "Legal Entity" shall mean the union of the acting entity and all + * other entities that control, are controlled by, or are under common + * control with that entity. For the purposes of this definition, + * "control" means (i) the power, direct or indirect, to cause the + * direction or management of such entity, whether by contract or + * otherwise, or (ii) ownership of fifty percent (50%) or more of the + * outstanding shares, or (iii) beneficial ownership of such entity. + * + * "You" (or "Your") shall mean an individual or Legal Entity + * exercising permissions granted by this License. + * + * "Source" form shall mean the preferred form for making modifications, + * including but not limited to software source code, documentation + * source, and configuration files. + * + * "Object" form shall mean any form resulting from mechanical + * transformation or translation of a Source form, including but + * not limited to compiled object code, generated documentation, + * and conversions to other media types. + * + * "Work" shall mean the work of authorship, whether in Source or + * Object form, made available under the License, as indicated by a + * copyright notice that is included in or attached to the work + * (an example is provided in the Appendix below). + * + * "Derivative Works" shall mean any work, whether in Source or Object + * form, that is based on (or derived from) the Work and for which the + * editorial revisions, annotations, elaborations, or other modifications + * represent, as a whole, an original work of authorship. For the purposes + * of this License, Derivative Works shall not include works that remain + * separable from, or merely link (or bind by name) to the interfaces of, + * the Work and Derivative Works thereof. + * + * "Contribution" shall mean any work of authorship, including + * the original version of the Work and any modifications or additions + * to that Work or Derivative Works thereof, that is intentionally + * submitted to Licensor for inclusion in the Work by the copyright owner + * or by an individual or Legal Entity authorized to submit on behalf of + * the copyright owner. For the purposes of this definition, "submitted" + * means any form of electronic, verbal, or written communication sent + * to the Licensor or its representatives, including but not limited to + * communication on electronic mailing lists, source code control systems, + * and issue tracking systems that are managed by, or on behalf of, the + * Licensor for the purpose of discussing and improving the Work, but + * excluding communication that is conspicuously marked or otherwise + * designated in writing by the copyright owner as "Not a Contribution." + * + * "Contributor" shall mean Licensor and any individual or Legal Entity + * on behalf of whom a Contribution has been received by Licensor and + * subsequently incorporated within the Work. + * + * 2. Grant of Copyright License. Subject to the terms and conditions of + * this License, each Contributor hereby grants to You a perpetual, + * worldwide, non-exclusive, no-charge, royalty-free, irrevocable + * copyright license to reproduce, prepare Derivative Works of, + * publicly display, publicly perform, sublicense, and distribute the + * Work and such Derivative Works in Source or Object form. + * + * 3. Grant of Patent License. Subject to the terms and conditions of + * this License, each Contributor hereby grants to You a perpetual, + * worldwide, non-exclusive, no-charge, royalty-free, irrevocable + * (except as stated in this section) patent license to make, have made, + * use, offer to sell, sell, import, and otherwise transfer the Work, + * where such license applies only to those patent claims licensable + * by such Contributor that are necessarily infringed by their + * Contribution(s) alone or by combination of their Contribution(s) + * with the Work to which such Contribution(s) was submitted. If You + * institute patent litigation against any entity (including a + * cross-claim or counterclaim in a lawsuit) alleging that the Work + * or a Contribution incorporated within the Work constitutes direct + * or contributory patent infringement, then any patent licenses + * granted to You under this License for that Work shall terminate + * as of the date such litigation is filed. + * + * 4. Redistribution. You may reproduce and distribute copies of the + * Work or Derivative Works thereof in any medium, with or without + * modifications, and in Source or Object form, provided that You + * meet the following conditions: + * + * (a) You must give any other recipients of the Work or + * Derivative Works a copy of this License; and + * + * (b) You must cause any modified files to carry prominent notices + * stating that You changed the files; and + * + * (c) You must retain, in the Source form of any Derivative Works + * that You distribute, all copyright, patent, trademark, and + * attribution notices from the Source form of the Work, + * excluding those notices that do not pertain to any part of + * the Derivative Works; and + * + * (d) If the Work includes a "NOTICE" text file as part of its + * distribution, then any Derivative Works that You distribute must + * include a readable copy of the attribution notices contained + * within such NOTICE file, excluding those notices that do not + * pertain to any part of the Derivative Works, in at least one + * of the following places: within a NOTICE text file distributed + * as part of the Derivative Works; within the Source form or + * documentation, if provided along with the Derivative Works; or, + * within a display generated by the Derivative Works, if and + * wherever such third-party notices normally appear. The contents + * of the NOTICE file are for informational purposes only and + * do not modify the License. You may add Your own attribution + * notices within Derivative Works that You distribute, alongside + * or as an addendum to the NOTICE text from the Work, provided + * that such additional attribution notices cannot be construed + * as modifying the License. + * + * You may add Your own copyright statement to Your modifications and + * may provide additional or different license terms and conditions + * for use, reproduction, or distribution of Your modifications, or + * for any such Derivative Works as a whole, provided Your use, + * reproduction, and distribution of the Work otherwise complies with + * the conditions stated in this License. + * + * 5. Submission of Contributions. Unless You explicitly state otherwise, + * any Contribution intentionally submitted for inclusion in the Work + * by You to the Licensor shall be under the terms and conditions of + * this License, without any additional terms or conditions. + * Notwithstanding the above, nothing herein shall supersede or modify + * the terms of any separate license agreement you may have executed + * with Licensor regarding such Contributions. + * + * 6. Trademarks. This License does not grant permission to use the trade + * names, trademarks, service marks, or product names of the Licensor, + * except as required for reasonable and customary use in describing the + * origin of the Work and reproducing the content of the NOTICE file. + * + * 7. Disclaimer of Warranty. Unless required by applicable law or + * agreed to in writing, Licensor provides the Work (and each + * Contributor provides its Contributions) on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied, including, without limitation, any warranties or conditions + * of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + * PARTICULAR PURPOSE. You are solely responsible for determining the + * appropriateness of using or redistributing the Work and assume any + * risks associated with Your exercise of permissions under this License. + * + * 8. Limitation of Liability. In no event and under no legal theory, + * whether in tort (including negligence), contract, or otherwise, + * unless required by applicable law (such as deliberate and grossly + * negligent acts) or agreed to in writing, shall any Contributor be + * liable to You for damages, including any direct, indirect, special, + * incidental, or consequential damages of any character arising as a + * result of this License or out of the use or inability to use the + * Work (including but not limited to damages for loss of goodwill, + * work stoppage, computer failure or malfunction, or any and all + * other commercial damages or losses), even if such Contributor + * has been advised of the possibility of such damages. + * + * 9. Accepting Warranty or Additional Liability. While redistributing + * the Work or Derivative Works thereof, You may choose to offer, + * and charge a fee for, acceptance of support, warranty, indemnity, + * or other liability obligations and/or rights consistent with this + * License. However, in accepting such obligations, You may act only + * on Your own behalf and on Your sole responsibility, not on behalf + * of any other Contributor, and only if You agree to indemnify, + * defend, and hold each Contributor harmless for any liability + * incurred by, or claims asserted against, such Contributor by reason + * of your accepting any such warranty or additional liability. + * + * END OF TERMS AND CONDITIONS + * + * APPENDIX: How to apply the Apache License to your work. + * + * To apply the Apache License to your work, attach the following + * boilerplate notice, with the fields enclosed by brackets "[]" + * replaced with your own identifying information. (Don't include + * the brackets!) The text should be enclosed in the appropriate + * comment syntax for the file format. We also recommend that a + * file or class name and description of purpose be included on the + * same "printed page" as the copyright notice for easier + * identification within third-party archives. + * + * Copyright [yyyy] [name of copyright owner] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +W3C� SOFTWARE NOTICE AND LICENSE +http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + +This work (and included software, documentation such as READMEs, or other +related items) is being provided by the copyright holders under the following +license. By obtaining, using and/or copying this work, you (the licensee) agree +that you have read, understood, and will comply with the following terms and +conditions. + +Permission to copy, modify, and distribute this software and its documentation, +with or without modification, for any purpose and without fee or royalty is +hereby granted, provided that you include the following on ALL copies of the +software and documentation or portions thereof, including modifications: + + 1. The full text of this NOTICE in a location viewable to users of the + redistributed or derivative work. + 2. Any pre-existing intellectual property disclaimers, notices, or terms + and conditions. If none exist, the W3C Software Short Notice should be + included (hypertext is preferred, text is permitted) within the body + of any redistributed or derivative code. + 3. Notice of any changes or modifications to the files, including the date + changes were made. (We recommend you provide URIs to the location from + which the code is derived.) + +THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE +NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT +THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY +PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. + +COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR DOCUMENTATION. + +The name and trademarks of copyright holders may NOT be used in advertising or +publicity pertaining to the software without specific, written prior permission. +Title to copyright in this software and any associated documentation will at +all times remain with copyright holders. + +____________________________________ + +This formulation of W3C's notice and license became active on December 31 2002. +This version removes the copyright ownership notice such that this license can +be used with materials other than those owned by the W3C, reflects that ERCIM +is now a host of the W3C, includes references to this specific dated version of +the license, and removes the ambiguous grant of "use". Otherwise, this version +is the same as the previous version and is written so as to preserve the Free +Software Foundation's assessment of GPL compatibility and OSI's certification +under the Open Source Definition. Please see our Copyright FAQ for common +questions about using materials from our site, including specific terms and +conditions for packages like libwww, Amaya, and Jigsaw. Other questions about +this notice can be directed to site-policy@w3.org. + +Joseph Reagle + +This license came from: http://www.megginson.com/SAX/copying.html + However please note future versions of SAX may be covered + under http://saxproject.org/?selected=pd + +SAX2 is Free! + +I hereby abandon any property rights to SAX 2.0 (the Simple API for +XML), and release all of the SAX 2.0 source code, compiled code, and +documentation contained in this distribution into the Public Domain. +SAX comes with NO WARRANTY or guarantee of fitness for any +purpose. + +David Megginson, david@megginson.com +2000-05-05 + + + +-------------------------------------------------------------------------------- +Apache Ant Launcher (1.10.3) +-------------------------------------------------------------------------------- + +* Declared Licenses * +Apache-2.0 + +/* + * Apache License + * Version 2.0, January 2004 + * http://www.apache.org/licenses/ + * + * TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + * + * 1. Definitions. + * + * "License" shall mean the terms and conditions for use, reproduction, + * and distribution as defined by Sections 1 through 9 of this document. + * + * "Licensor" shall mean the copyright owner or entity authorized by + * the copyright owner that is granting the License. + * + * "Legal Entity" shall mean the union of the acting entity and all + * other entities that control, are controlled by, or are under common + * control with that entity. For the purposes of this definition, + * "control" means (i) the power, direct or indirect, to cause the + * direction or management of such entity, whether by contract or + * otherwise, or (ii) ownership of fifty percent (50%) or more of the + * outstanding shares, or (iii) beneficial ownership of such entity. + * + * "You" (or "Your") shall mean an individual or Legal Entity + * exercising permissions granted by this License. + * + * "Source" form shall mean the preferred form for making modifications, + * including but not limited to software source code, documentation + * source, and configuration files. + * + * "Object" form shall mean any form resulting from mechanical + * transformation or translation of a Source form, including but + * not limited to compiled object code, generated documentation, + * and conversions to other media types. + * + * "Work" shall mean the work of authorship, whether in Source or + * Object form, made available under the License, as indicated by a + * copyright notice that is included in or attached to the work + * (an example is provided in the Appendix below). + * + * "Derivative Works" shall mean any work, whether in Source or Object + * form, that is based on (or derived from) the Work and for which the + * editorial revisions, annotations, elaborations, or other modifications + * represent, as a whole, an original work of authorship. For the purposes + * of this License, Derivative Works shall not include works that remain + * separable from, or merely link (or bind by name) to the interfaces of, + * the Work and Derivative Works thereof. + * + * "Contribution" shall mean any work of authorship, including + * the original version of the Work and any modifications or additions + * to that Work or Derivative Works thereof, that is intentionally + * submitted to Licensor for inclusion in the Work by the copyright owner + * or by an individual or Legal Entity authorized to submit on behalf of + * the copyright owner. For the purposes of this definition, "submitted" + * means any form of electronic, verbal, or written communication sent + * to the Licensor or its representatives, including but not limited to + * communication on electronic mailing lists, source code control systems, + * and issue tracking systems that are managed by, or on behalf of, the + * Licensor for the purpose of discussing and improving the Work, but + * excluding communication that is conspicuously marked or otherwise + * designated in writing by the copyright owner as "Not a Contribution." + * + * "Contributor" shall mean Licensor and any individual or Legal Entity + * on behalf of whom a Contribution has been received by Licensor and + * subsequently incorporated within the Work. + * + * 2. Grant of Copyright License. Subject to the terms and conditions of + * this License, each Contributor hereby grants to You a perpetual, + * worldwide, non-exclusive, no-charge, royalty-free, irrevocable + * copyright license to reproduce, prepare Derivative Works of, + * publicly display, publicly perform, sublicense, and distribute the + * Work and such Derivative Works in Source or Object form. + * + * 3. Grant of Patent License. Subject to the terms and conditions of + * this License, each Contributor hereby grants to You a perpetual, + * worldwide, non-exclusive, no-charge, royalty-free, irrevocable + * (except as stated in this section) patent license to make, have made, + * use, offer to sell, sell, import, and otherwise transfer the Work, + * where such license applies only to those patent claims licensable + * by such Contributor that are necessarily infringed by their + * Contribution(s) alone or by combination of their Contribution(s) + * with the Work to which such Contribution(s) was submitted. If You + * institute patent litigation against any entity (including a + * cross-claim or counterclaim in a lawsuit) alleging that the Work + * or a Contribution incorporated within the Work constitutes direct + * or contributory patent infringement, then any patent licenses + * granted to You under this License for that Work shall terminate + * as of the date such litigation is filed. + * + * 4. Redistribution. You may reproduce and distribute copies of the + * Work or Derivative Works thereof in any medium, with or without + * modifications, and in Source or Object form, provided that You + * meet the following conditions: + * + * (a) You must give any other recipients of the Work or + * Derivative Works a copy of this License; and + * + * (b) You must cause any modified files to carry prominent notices + * stating that You changed the files; and + * + * (c) You must retain, in the Source form of any Derivative Works + * that You distribute, all copyright, patent, trademark, and + * attribution notices from the Source form of the Work, + * excluding those notices that do not pertain to any part of + * the Derivative Works; and + * + * (d) If the Work includes a "NOTICE" text file as part of its + * distribution, then any Derivative Works that You distribute must + * include a readable copy of the attribution notices contained + * within such NOTICE file, excluding those notices that do not + * pertain to any part of the Derivative Works, in at least one + * of the following places: within a NOTICE text file distributed + * as part of the Derivative Works; within the Source form or + * documentation, if provided along with the Derivative Works; or, + * within a display generated by the Derivative Works, if and + * wherever such third-party notices normally appear. The contents + * of the NOTICE file are for informational purposes only and + * do not modify the License. You may add Your own attribution + * notices within Derivative Works that You distribute, alongside + * or as an addendum to the NOTICE text from the Work, provided + * that such additional attribution notices cannot be construed + * as modifying the License. + * + * You may add Your own copyright statement to Your modifications and + * may provide additional or different license terms and conditions + * for use, reproduction, or distribution of Your modifications, or + * for any such Derivative Works as a whole, provided Your use, + * reproduction, and distribution of the Work otherwise complies with + * the conditions stated in this License. + * + * 5. Submission of Contributions. Unless You explicitly state otherwise, + * any Contribution intentionally submitted for inclusion in the Work + * by You to the Licensor shall be under the terms and conditions of + * this License, without any additional terms or conditions. + * Notwithstanding the above, nothing herein shall supersede or modify + * the terms of any separate license agreement you may have executed + * with Licensor regarding such Contributions. + * + * 6. Trademarks. This License does not grant permission to use the trade + * names, trademarks, service marks, or product names of the Licensor, + * except as required for reasonable and customary use in describing the + * origin of the Work and reproducing the content of the NOTICE file. + * + * 7. Disclaimer of Warranty. Unless required by applicable law or + * agreed to in writing, Licensor provides the Work (and each + * Contributor provides its Contributions) on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied, including, without limitation, any warranties or conditions + * of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + * PARTICULAR PURPOSE. You are solely responsible for determining the + * appropriateness of using or redistributing the Work and assume any + * risks associated with Your exercise of permissions under this License. + * + * 8. Limitation of Liability. In no event and under no legal theory, + * whether in tort (including negligence), contract, or otherwise, + * unless required by applicable law (such as deliberate and grossly + * negligent acts) or agreed to in writing, shall any Contributor be + * liable to You for damages, including any direct, indirect, special, + * incidental, or consequential damages of any character arising as a + * result of this License or out of the use or inability to use the + * Work (including but not limited to damages for loss of goodwill, + * work stoppage, computer failure or malfunction, or any and all + * other commercial damages or losses), even if such Contributor + * has been advised of the possibility of such damages. + * + * 9. Accepting Warranty or Additional Liability. While redistributing + * the Work or Derivative Works thereof, You may choose to offer, + * and charge a fee for, acceptance of support, warranty, indemnity, + * or other liability obligations and/or rights consistent with this + * License. However, in accepting such obligations, You may act only + * on Your own behalf and on Your sole responsibility, not on behalf + * of any other Contributor, and only if You agree to indemnify, + * defend, and hold each Contributor harmless for any liability + * incurred by, or claims asserted against, such Contributor by reason + * of your accepting any such warranty or additional liability. + * + * END OF TERMS AND CONDITIONS + * + * APPENDIX: How to apply the Apache License to your work. + * + * To apply the Apache License to your work, attach the following + * boilerplate notice, with the fields enclosed by brackets "[]" + * replaced with your own identifying information. (Don't include + * the brackets!) The text should be enclosed in the appropriate + * comment syntax for the file format. We also recommend that a + * file or class name and description of purpose be included on the + * same "printed page" as the copyright notice for easier + * identification within third-party archives. + * + * Copyright [yyyy] [name of copyright owner] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +W3C� SOFTWARE NOTICE AND LICENSE +http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + +This work (and included software, documentation such as READMEs, or other +related items) is being provided by the copyright holders under the following +license. By obtaining, using and/or copying this work, you (the licensee) agree +that you have read, understood, and will comply with the following terms and +conditions. + +Permission to copy, modify, and distribute this software and its documentation, +with or without modification, for any purpose and without fee or royalty is +hereby granted, provided that you include the following on ALL copies of the +software and documentation or portions thereof, including modifications: + + 1. The full text of this NOTICE in a location viewable to users of the + redistributed or derivative work. + 2. Any pre-existing intellectual property disclaimers, notices, or terms + and conditions. If none exist, the W3C Software Short Notice should be + included (hypertext is preferred, text is permitted) within the body + of any redistributed or derivative code. + 3. Notice of any changes or modifications to the files, including the date + changes were made. (We recommend you provide URIs to the location from + which the code is derived.) + +THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE +NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT +THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY +PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. + +COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR DOCUMENTATION. + +The name and trademarks of copyright holders may NOT be used in advertising or +publicity pertaining to the software without specific, written prior permission. +Title to copyright in this software and any associated documentation will at +all times remain with copyright holders. + +____________________________________ + +This formulation of W3C's notice and license became active on December 31 2002. +This version removes the copyright ownership notice such that this license can +be used with materials other than those owned by the W3C, reflects that ERCIM +is now a host of the W3C, includes references to this specific dated version of +the license, and removes the ambiguous grant of "use". Otherwise, this version +is the same as the previous version and is written so as to preserve the Free +Software Foundation's assessment of GPL compatibility and OSI's certification +under the Open Source Definition. Please see our Copyright FAQ for common +questions about using materials from our site, including specific terms and +conditions for packages like libwww, Amaya, and Jigsaw. Other questions about +this notice can be directed to site-policy@w3.org. + +Joseph Reagle + +This license came from: http://www.megginson.com/SAX/copying.html + However please note future versions of SAX may be covered + under http://saxproject.org/?selected=pd + +SAX2 is Free! + +I hereby abandon any property rights to SAX 2.0 (the Simple API for +XML), and release all of the SAX 2.0 source code, compiled code, and +documentation contained in this distribution into the Public Domain. +SAX comes with NO WARRANTY or guarantee of fitness for any +purpose. + +David Megginson, david@megginson.com +2000-05-05 + + + +-------------------------------------------------------------------------------- +Apache Commons IO (2.11.0) +-------------------------------------------------------------------------------- + +* Declared Licenses * +Apache-2.0 + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + + +-------------------------------------------------------------------------------- +Apache Commons Lang (3.12.0) +-------------------------------------------------------------------------------- + +* Declared Licenses * +Apache-2.0 + +Apache Commons Lang +Copyright 2001-2021 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (https://www.apache.org/). + + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + + +-------------------------------------------------------------------------------- +Apache Groovy (3.0.11) +-------------------------------------------------------------------------------- + +* Declared Licenses * +Apache-2.0 + +Copyright 2013 Terence Parr, Sam Harwell + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +See the License for the specific language governing permissions and limitations under the License. + + +-------------------------------------------------------------------------------- +Apache Groovy (2.5.7) +-------------------------------------------------------------------------------- + +* Declared Licenses * +Apache-2.0 + +Copyright ownership. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +See the License for the specific language governing permissions and limitations under the License. + + +-------------------------------------------------------------------------------- +Apache Groovy (2.5.4) +-------------------------------------------------------------------------------- + +* Declared Licenses * +Apache-2.0 + +Copyright ownership. The ASF licenses this file + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +See the License for the specific language governing permissions and limitations under the License. + + +-------------------------------------------------------------------------------- +Apache Groovy (2.5.4) +-------------------------------------------------------------------------------- + +* Declared Licenses * +Apache-2.0 + +Copyright ownership. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +See the License for the specific language governing permissions and limitations under the License. + + +-------------------------------------------------------------------------------- +Apache Groovy (2.5.4) +-------------------------------------------------------------------------------- + +* Declared Licenses * +Apache-2.0 + +Copyright ownership. The ASF licenses this file + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +See the License for the specific language governing permissions and limitations under the License. + + +-------------------------------------------------------------------------------- +Apache Groovy (2.5.4) +-------------------------------------------------------------------------------- + +* Declared Licenses * +Apache-2.0 + +Copyright ownership. The ASF licenses this file + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +See the License for the specific language governing permissions and limitations under the License. + + +-------------------------------------------------------------------------------- +Apache Groovy (2.5.4) +-------------------------------------------------------------------------------- + +* Declared Licenses * +Apache-2.0 + +Copyright ownership. The ASF licenses this file + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +See the License for the specific language governing permissions and limitations under the License. + + +-------------------------------------------------------------------------------- +Apache Groovy (2.5.4) +-------------------------------------------------------------------------------- + +* Declared Licenses * +Apache-2.0 + +Copyright ownership. The ASF licenses this file + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +See the License for the specific language governing permissions and limitations under the License. + + +-------------------------------------------------------------------------------- +Apache Groovy (2.5.4) +-------------------------------------------------------------------------------- + +* Declared Licenses * +Apache-2.0 + +Copyright ownership. The ASF licenses this file + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +See the License for the specific language governing permissions and limitations under the License. + + +-------------------------------------------------------------------------------- +Apache HttpClient (4.5.13) +-------------------------------------------------------------------------------- + +* Declared Licenses * +Apache-2.0 + + +Apache HttpClient +Copyright 1999-2020 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). +__________________ +* Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + + +-------------------------------------------------------------------------------- +Apache HttpCore (4.4.15) +-------------------------------------------------------------------------------- + +* Declared Licenses * +Apache-2.0 + +Apache HttpCore +Copyright 2005-2021 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). +_____________ + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + + +-------------------------------------------------------------------------------- +Byte Buddy (without dependencies) (1.12.1) +-------------------------------------------------------------------------------- + +* Declared Licenses * + + +* Other Licenses * +BSD-3-Clause, Apache-2.0 + + +// ASM: a very small and fast Java bytecode manipulation framework +// Copyright (c) 2000-2011 INRIA, France Telecom +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// 3. Neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +// THE POSSIBILITY OF SUCH DAMAGE. + + + * Copyright 2014 - Present Rafael Winterhalter + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + + +-------------------------------------------------------------------------------- +Byte Buddy agent (1.12.1) +-------------------------------------------------------------------------------- + +* Declared Licenses * +Apache-2.0 + +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + + +-------------------------------------------------------------------------------- +cglib-nodep (3.3.0) +-------------------------------------------------------------------------------- + +* Declared Licenses * +Apache-2.0 + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + +-------------------------------------------------------------------------------- +EqualsVerifier | release normal jar (3.7.2) +-------------------------------------------------------------------------------- + +* Declared Licenses * +Apache-2.0 + +Copyright 2022, EqualsVerifier | release normal jar Contributors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +See the License for the specific language governing permissions and limitations under the License. + + +-------------------------------------------------------------------------------- +EqualsVerifier | release normal jar (3.10) +-------------------------------------------------------------------------------- + +* Declared Licenses * +Apache-2.0 + +Copyright 2022, EqualsVerifier | release normal jar Contributors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +See the License for the specific language governing permissions and limitations under the License. + + +-------------------------------------------------------------------------------- +gooddata-http-client (1.0.0) +-------------------------------------------------------------------------------- + +* Declared Licenses * +BSD-3-Clause + +Copyright (c) 2007-2016, GoodData . All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- +gooddata-http-client (1.0.0+java7.fix1) +-------------------------------------------------------------------------------- + +* Declared Licenses * +BSD-3-Clause + +Copyright (c) 2007-2016, GoodData . All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- +gooddata-rest-common (2.0.0) +-------------------------------------------------------------------------------- + +* Declared Licenses * +BSD-3-Clause + +Copyright (c) 2004-2017, GoodData . All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- +Gson (2.3.1) +-------------------------------------------------------------------------------- + +* Declared Licenses * +Apache-2.0 + +Copyright 2008 Google Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +See the License for the specific language governing permissions and limitations under the License. + + +-------------------------------------------------------------------------------- +Guava: Google Core Libraries for Java (17.0) +-------------------------------------------------------------------------------- + +* Declared Licenses * + + +* Other Licenses * +Apache-2.0, CC0-1.0 + + + * Copyright (C) 2008 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + + + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/publicdomain/zero/1.0/ + + +-------------------------------------------------------------------------------- +Hamcrest (2.2) +-------------------------------------------------------------------------------- + +* Declared Licenses * +BSD-3-Clause + +Copyright (c) 2022, Hamcrest Contributors . All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- +Hamcrest Core (2.2) +-------------------------------------------------------------------------------- + +* Declared Licenses * +BSD-3-Clause + +Copyright (c) 2022, Hamcrest Core Contributors . All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- +Jackson-annotations (2.13.0) +-------------------------------------------------------------------------------- + +* Declared Licenses * +Apache-2.0 + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + +-------------------------------------------------------------------------------- +Jackson-core (2.13.0) +-------------------------------------------------------------------------------- + +* Declared Licenses * +Apache-2.0 + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + +-------------------------------------------------------------------------------- +jackson-databind (2.13.0) +-------------------------------------------------------------------------------- + +* Declared Licenses * +Apache-2.0 + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + +-------------------------------------------------------------------------------- +jackson-databind (2.13.3) +-------------------------------------------------------------------------------- + +* Declared Licenses * +Apache-2.0 + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + +-------------------------------------------------------------------------------- +jadler-all (1.3.1) +-------------------------------------------------------------------------------- + +* Declared Licenses * + + +* Other Licenses * +MIT, Apache-2.0 + + +Copyright (c) 2012 - 2016 Jadler contributors +This program is made available under the terms of the MIT License. + + + ~ Copyright (c) 2007-2011 Sonatype, Inc. All rights reserved. + ~ + ~ This program is licensed to you under the Apache License Version 2.0, + ~ and you may not use this file except in compliance with the Apache License Version 2.0. + ~ You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0. + ~ + ~ Unless required by applicable law or agreed to in writing, + ~ software distributed under the Apache License Version 2.0 is distributed on an + ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the Apache License Version 2.0 for the specific language governing permissions and limitations there under. + --> + + +-------------------------------------------------------------------------------- +jadler-core (1.3.1) +-------------------------------------------------------------------------------- + +* Declared Licenses * + + +* Other Licenses * +MIT, Apache-2.0 + + +Copyright (c) 2012 - 2016 Jadler contributors +This program is made available under the terms of the MIT License. + + + ~ Copyright (c) 2007-2011 Sonatype, Inc. All rights reserved. + ~ + ~ This program is licensed to you under the Apache License Version 2.0, + ~ and you may not use this file except in compliance with the Apache License Version 2.0. + ~ You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0. + ~ + ~ Unless required by applicable law or agreed to in writing, + ~ software distributed under the Apache License Version 2.0 is distributed on an + ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the Apache License Version 2.0 for the specific language governing permissions and limitations there under. + + +-------------------------------------------------------------------------------- +jakarta.inject (1) +-------------------------------------------------------------------------------- + +* Declared Licenses * +Apache-2.0 + +Copyright 2009 The JSR-330 Expert Group + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +See the License for the specific language governing permissions and limitations under the License. + + +-------------------------------------------------------------------------------- +jcommander (1.78) +-------------------------------------------------------------------------------- + +* Declared Licenses * +Apache-2.0 + +Copyright 2010 the original author or authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +See the License for the specific language governing permissions and limitations under the License. + + +-------------------------------------------------------------------------------- +JSON in Java (20090211) +-------------------------------------------------------------------------------- + +* Declared Licenses * +JSON + +Copyright (c) 2002 JSON.org +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +The Software shall be used for Good, not Evil. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +-------------------------------------------------------------------------------- +json-unit (2.28.0) +-------------------------------------------------------------------------------- + +* Declared Licenses * +Apache-2.0 + +Copyright 2009-2019 the original author or authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +See the License for the specific language governing permissions and limitations under the License. + + +-------------------------------------------------------------------------------- +json-unit (2.35.0) +-------------------------------------------------------------------------------- + +* Declared Licenses * +Apache-2.0 + +Copyright 2009-2019 the original author or authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +See the License for the specific language governing permissions and limitations under the License. + + +-------------------------------------------------------------------------------- +json-unit-core (2.28.0) +-------------------------------------------------------------------------------- + +* Declared Licenses * +Apache-2.0 + +Copyright 2009-2019 the original author or authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +See the License for the specific language governing permissions and limitations under the License. + + +-------------------------------------------------------------------------------- +json-unit-core (2.35.0) +-------------------------------------------------------------------------------- + +* Declared Licenses * +Apache-2.0 + +Copyright 2009-2019 the original author or authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +See the License for the specific language governing permissions and limitations under the License. + + +-------------------------------------------------------------------------------- +JSONassert (1.2.3) +-------------------------------------------------------------------------------- + +* Declared Licenses * +Apache-2.0 + +Copyright 2007-2011 Sonatype, Inc. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +See the License for the specific language governing permissions and limitations under the License. + + +-------------------------------------------------------------------------------- +JUnit (4.12) +-------------------------------------------------------------------------------- + +* Declared Licenses * +CPL-1.0 + +THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. +DEFINITIONS +"Contribution" means: + a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and + b) in the case of each subsequent Contributor: + i) changes to the Program, and + ii) additions to the Program; +where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. +"Contributor" means any person or entity that distributes the Program. +"Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. +"Program" means the Contributions distributed in accordance with this Agreement. +"Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. +GRANT OF RIGHTS + a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. + b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. + c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. + d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. +REQUIREMENTS +A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: + a) it complies with the terms and conditions of this Agreement; and + b) its license agreement: + i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; + ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; + iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and + iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. +When the Program is made available in source code form: + a) it must be made available under this Agreement; and + b) a copy of this Agreement must be included with each copy of the Program. + Contributors may not remove or alter any copyright notices contained within the Program. + Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. +COMMERCIAL DISTRIBUTION +Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. +For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. +NO WARRANTY +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. +DISCLAIMER OF LIABILITY +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. +GENERAL +If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. +If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, if Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. +All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. +Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. +This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. + + +-------------------------------------------------------------------------------- +Mockito (4.6.1) +-------------------------------------------------------------------------------- + +* Declared Licenses * + + +* Other Licenses * +MIT, Apache-2.0 + + +The MIT License + +Copyright (c) 2007 Mockito contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +Copyright 2022, Mockito Contributors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +See the License for the specific language governing permissions and limitations under the License. + + +-------------------------------------------------------------------------------- +Mockito (4.1.0) +-------------------------------------------------------------------------------- + +* Declared Licenses * + + +* Other Licenses * +MIT, Apache-2.0 + + +The MIT License + +Copyright (c) 2007 Mockito contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +Copyright 2022, Mockito Contributors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +See the License for the specific language governing permissions and limitations under the License. + + +-------------------------------------------------------------------------------- +Objenesis (3.2) +-------------------------------------------------------------------------------- + +* Declared Licenses * +MIT + +Copyright (c) 2022, Objenesis Contributors +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +-------------------------------------------------------------------------------- +Sardine WebDAV client (5.10) +-------------------------------------------------------------------------------- + +* Declared Licenses * +Apache-2.0 + +Copyright 2009-2011 Jon Stevens et al. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +See the License for the specific language governing permissions and limitations under the License. + + +-------------------------------------------------------------------------------- +Shazamcrest (0.11) +-------------------------------------------------------------------------------- + +* Declared Licenses * +Apache-2.0 + +Copyright 2011 Google Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +See the License for the specific language governing permissions and limitations under the License. + + +-------------------------------------------------------------------------------- +SLF4J API Module (2.0.0-alpha7) +-------------------------------------------------------------------------------- + +* Declared Licenses * +MIT + +Copyright (c) 2004-2017 QOS.ch + All rights reserved. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +-------------------------------------------------------------------------------- +SLF4J Simple Binding (2.0.0-alpha7) +-------------------------------------------------------------------------------- + +* Declared Licenses * +MIT + +Copyright (c) 2004-2022 QOS.ch Sarl (Switzerland) +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +-------------------------------------------------------------------------------- +SnakeYAML (1.21) +-------------------------------------------------------------------------------- + +* Declared Licenses * + + +* Other Licenses * +Apache-2.0, Multi-license: LGPL-2.1-or-later OR GPL-2.0-or-later OR EPL-1.0 OR BSD-3-Clause OR Apache-2.0 + + + * Copyright (c) 2008, http://www.snakeyaml.org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + + +// Copyright 2003-2010 Christian d'Heureuse, Inventec Informatik AG, Zurich, Switzerland +// www.source-code.biz, www.inventec.ch/chdh +// +// This module is multi-licensed and may be used under the terms +// of any of the following licenses: +// +// EPL, Eclipse Public License, V1.0 or later, http://www.eclipse.org/legal +// LGPL, GNU Lesser General Public License, V2.1 or later, http://www.gnu.org/licenses/lgpl.html +// GPL, GNU General Public License, V2 or later, http://www.gnu.org/licenses/gpl.html +// AL, Apache License, V2.0 or later, http://www.apache.org/licenses +// BSD, BSD License, http://www.opensource.org/licenses/bsd-license.php +// +// Please contact the author if you need another license. +// This module is provided "as is", without warranties of any kind. + +package org.yaml.snakeyaml.external.biz.base64Coder; + +/** + * A Base64 encoder/decoder. + * + *

+ * This class is used to encode and decode data in Base64 format as described in + * RFC 1521. + * + *

+ * Project home page: www. + * source-code.biz/base64coder/java
+ * Author: Christian d'Heureuse, Inventec Informatik AG, Zurich, Switzerland
+ * Multi-licensed: EPL / LGPL / GPL / AL / BSD. + + +-------------------------------------------------------------------------------- +Spock Framework - Core Module (2.2-M1-groovy-4.0) +-------------------------------------------------------------------------------- + +* Declared Licenses * +Apache-2.0 + +Copyright 2012 the original author or authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +See the License for the specific language governing permissions and limitations under the License. + + +-------------------------------------------------------------------------------- +Spock Framework - Core Module (1.3-groovy-2.5) +-------------------------------------------------------------------------------- + +* Declared Licenses * +Apache-2.0 + +Copyright 2012 the original author or authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +See the License for the specific language governing permissions and limitations under the License. + + +-------------------------------------------------------------------------------- +Spring Beans (5.3.20) +-------------------------------------------------------------------------------- + +* Declared Licenses * +Apache-2.0 + +Copyright 2002-2021 the original author or authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +See the License for the specific language governing permissions and limitations under the License. + + +-------------------------------------------------------------------------------- +Spring Beans (5.3.13) +-------------------------------------------------------------------------------- + +* Declared Licenses * +Apache-2.0 + +Copyright 2002-2021 the original author or authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +See the License for the specific language governing permissions and limitations under the License. + + +-------------------------------------------------------------------------------- +Spring Commons Logging Bridge (5.3.13) +-------------------------------------------------------------------------------- + +* Declared Licenses * +Apache-2.0 + +Copyright ownership. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +See the License for the specific language governing permissions and limitations under the License. + + +-------------------------------------------------------------------------------- +Spring Context (5.3.20) +-------------------------------------------------------------------------------- + +* Declared Licenses * +Apache-2.0 + +Copyright 2002-2019 the original author or authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +See the License for the specific language governing permissions and limitations under the License. + + +-------------------------------------------------------------------------------- +Spring Core (5.3.20) +-------------------------------------------------------------------------------- + +* Declared Licenses * + + +* Other Licenses * +BSD-3-Clause, Apache-2.0 + + +// ASM: a very small and fast Java bytecode manipulation framework +// Copyright (c) 2000-2011 INRIA, France Telecom +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// 3. Neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +// THE POSSIBILITY OF SUCH DAMAGE. + + + * Copyright 2002-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + + +-------------------------------------------------------------------------------- +Spring Core (5.3.13) +-------------------------------------------------------------------------------- + +* Declared Licenses * + + +* Other Licenses * +BSD-3-Clause, Apache-2.0 + + +// ASM: a very small and fast Java bytecode manipulation framework +// Copyright (c) 2000-2011 INRIA, France Telecom +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// 3. Neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +// THE POSSIBILITY OF SUCH DAMAGE. + + + * Copyright 2002-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + + +-------------------------------------------------------------------------------- +Spring Retry (1.3.1) +-------------------------------------------------------------------------------- + +* Declared Licenses * +Apache-2.0 + +Copyright 2006-2007 the original author or authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +See the License for the specific language governing permissions and limitations under the License. + + +-------------------------------------------------------------------------------- +Spring Web (5.3.20) +-------------------------------------------------------------------------------- + +* Declared Licenses * +Apache-2.0 + +Copyright 2002-2021 the original author or authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +See the License for the specific language governing permissions and limitations under the License. + + +-------------------------------------------------------------------------------- +Spring Web (5.3.13) +-------------------------------------------------------------------------------- + +* Declared Licenses * +Apache-2.0 + +Copyright 2002-2021 the original author or authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +See the License for the specific language governing permissions and limitations under the License. + + +-------------------------------------------------------------------------------- +testng (7.3.0) +-------------------------------------------------------------------------------- + +* Declared Licenses * +Apache-2.0 + +Copyright 2022, testng Contributors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +See the License for the specific language governing permissions and limitations under the License. + + +* Other Licenses * +AML + + +Copyright: Copyright (c) 2006 by Apple Computer, Inc., All Rights Reserved. +IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. ("Apple") in consideration of your agreement to the following terms, and your use, installation, modification or redistribution of this Apple software constitutes acceptance of these terms. If you do not agree with these terms, please do not use, install, modify or redistribute this Apple software. +In consideration of your agreement to abide by the following terms, and subject to these terms, Apple grants you a personal, non-exclusive license, under Apple's copyrights in this original Apple software (the "Apple Software"), to use, reproduce, modify and redistribute the Apple Software, with or without modifications, in source and/or binary forms; provided that if you redistribute the Apple Software in its entirety and without modifications, you must retain this notice and the following text and disclaimers in all such redistributions of the Apple Software. Neither the name, trademarks, service marks or logos of Apple Computer, Inc. may be used to endorse or promote products derived from the Apple Software without specific prior written permission from Apple. Except as expressly stated in this notice, no other rights or licenses, express or implied, are granted by Apple herein, including but not limited to any patent rights that may be infringed by your derivative works or by other works in which the Apple Software may be incorporated. +The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- +testng (7.6.0) +-------------------------------------------------------------------------------- + +* Declared Licenses * +Apache-2.0 + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +================================================================================ +PART 2: LICENSES APPENDIX +================================================================================ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +================================================================================ + +Creative Commons Legal Code + +CC0 1.0 Universal + +CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER. + +Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer exclusive Copyright and Related Rights (defined below) upon the creator and subsequent owner(s) (each and all, an "owner") of an original work of authorship and/or a database (each, a "Work"). +Certain owners wish to permanently relinquish those rights to a Work for the purpose of contributing to a commons of creative, cultural and scientific works ("Commons") that the public can reliably and without fear of later claims of infringement build upon, modify, incorporate in other works, reuse and redistribute as freely as possible in any form whatsoever and for any purposes, including without limitation commercial purposes. These owners may contribute to the Commons to promote the ideal of a free culture and the further production of creative, cultural and scientific works, or to gain reputation or greater distribution for their Work in part through the use and efforts of others. +For these and/or other purposes and motivations, and without any expectation of additional consideration or compensation, the person associating CC0 with a Work (the "Affirmer"), to the extent that he or she is an owner of Copyright and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and publicly distribute the Work under its terms, with knowledge of his or her Copyright and Related Rights in the Work and the meaning and intended legal effect of CC0 on those rights. + 1. Copyright and Related Rights. A Work made available under CC0 may be protected by copyright and related or neighboring rights ("Copyright and Related Rights"). Copyright and Related Rights include, but are not limited to, the following: + i. the right to reproduce, adapt, distribute, perform, display, communicate, and translate a Work; + ii. moral rights retained by the original author(s) and/or performer(s); + iii. publicity and privacy rights pertaining to a person's image or likeness depicted in a Work; + iv. rights protecting against unfair competition in regards to a Work, subject to the limitations in paragraph 4(a), below; + v. rights protecting the extraction, dissemination, use and reuse of data in a Work; + vi. database rights (such as those arising under Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, and under any national implementation thereof, including any amended or successor version of such directive); and + vii. other similar, equivalent or corresponding rights throughout the world based on applicable law or treaty, and any national implementations thereof. + 2. Waiver. To the greatest extent permitted by, but not in contravention of, applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and unconditionally waives, abandons, and surrenders all of Affirmer's Copyright and Related Rights and associated claims and causes of action, whether now known or unknown (including existing as well as future claims and causes of action), in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each member of the public at large and to the detriment of Affirmer's heirs and successors, fully intending that such Waiver shall not be subject to revocation, rescission, cancellation, termination, or any other legal or equitable action to disrupt the quiet enjoyment of the Work by the public as contemplated by Affirmer's express Statement of Purpose. + 3. Public License Fallback. Should any part of the Waiver for any reason be judged legally invalid or ineffective under applicable law, then the Waiver shall be preserved to the maximum extent permitted taking into account Affirmer's express Statement of Purpose. In addition, to the extent the Waiver is so judged Affirmer hereby grants to each affected person a royalty-free, non transferable, non sublicensable, non exclusive, irrevocable and unconditional license to exercise Affirmer's Copyright and Related Rights in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "License"). The License shall be deemed effective as of the date CC0 was applied by Affirmer to the Work. Should any part of the License for any reason be judged legally invalid or ineffective under applicable law, such partial invalidity or ineffectiveness shall not invalidate the remainder of the License, and in such case Affirmer hereby affirms that he or she will not (i) exercise any of his or her remaining Copyright and Related Rights in the Work or (ii) assert any associated claims and causes of action with respect to the Work, in either case contrary to Affirmer's express Statement of Purpose. + 4. Limitations and Disclaimers. + a. No trademark or patent rights held by Affirmer are waived, abandoned, surrendered, licensed or otherwise affected by this document. + b. Affirmer offers the Work as-is and makes no representations or warranties of any kind concerning the Work, express, implied, statutory or otherwise, including without limitation warranties of title, merchantability, fitness for a particular purpose, non infringement, or the absence of latent or other defects, accuracy, or the present or absence of errors, whether or not discoverable, all to the greatest extent permissible under applicable law. + c. Affirmer disclaims responsibility for clearing rights of other persons that may apply to the Work or any use thereof, including without limitation any person's Copyright and Related Rights in the Work. Further, Affirmer disclaims responsibility for obtaining any necessary consents, permissions or other rights required for any use of the Work. + d. Affirmer understands and acknowledges that Creative Commons is not a party to this document and has no duty or obligation with respect to this CC0 or use of the Work. + +-------------------------------------------------------------------------------- +-------------------------------------------------------------------------------- + +Report Generated by FOSSA on 2022-6-9 diff --git a/README.md b/README.md index 62d132fb3..3153b328c 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,64 @@ -# GoodData Java SDK [![Build Status](https://travis-ci.org/gooddata/gooddata-java.png?branch=master)](https://travis-ci.org/gooddata/gooddata-java) [![Javadocs](http://javadoc.io/badge/com.gooddata/gooddata-java.svg)](http://javadoc.io/doc/com.gooddata/gooddata-java) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.gooddata/gooddata-java/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.gooddata/gooddata-java) +# GoodData Java SDK + +[![Build Status](https://github.com/gooddata/gooddata-java/actions/workflows/build.yml/badge.svg?branch=master)](https://github.com/gooddata/gooddata-java/actions/workflows/build.yml) +[![Coverage Status](https://codecov.io/gh/gooddata/gooddata-java/branch/master/graph/badge.svg)](https://app.codecov.io/gh/gooddata/gooddata-java/branch/master) +[![Stability: Active](https://masterminds.github.io/stability/active.svg)](https://masterminds.github.io/stability/active.html) +[![License](https://img.shields.io/badge/license-BSD-blue.svg)](LICENSE.txt) +[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fgooddata%2Fgooddata-java.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2Fgooddata%2Fgooddata-java?ref=badge_shield) + +[![Javadocs](https://javadoc.io/badge/com.gooddata/gooddata-java.svg)](https://javadoc.io/doc/com.gooddata/gooddata-java) +[![Javadocs Model](https://javadoc.io/badge2/com.gooddata/gooddata-java-model/javadoc--model.svg)](https://javadoc.io/doc/com.gooddata/gooddata-java-model) +[![Maven Central](https://img.shields.io/maven-central/v/com.gooddata/gooddata-java)](https://central.sonatype.com/artifact/com.gooddata/gooddata-java) +[![Release](https://img.shields.io/github/v/release/gooddata/gooddata-java?sort=semver)](https://github.com/gooddata/gooddata-java/releases) The *GoodData Java SDK* encapsulates the REST API of the **GoodData Platform**. + +**The project is currently NOT in "active development". Meaning that feature request may or may not be implemented. +You are welcomed to [contribute your code](CONTRIBUTING.md) and create +an [issue](https://github.com/gooddata/gooddata-java/issues).** + The first version was implemented during the [All Data Hackathon](http://hackathon.gooddata.com) April 10 - 11 2014. -It is free and open-source software provided "as-is" under the [BSD License](LICENSE.txt) as an official project by [GoodData Corporation](http://www.gooddata.com). +It is free and open-source software provided "as-is" under the [BSD License](LICENSE.txt) as an official project +by [GoodData Corporation](http://www.gooddata.com). + +## Supported versions + +In order to make the user experience with integrating GoodData Java SDK as smooth and secure as possible and to ensure +that the SDK is using the latest features of the platform, we only provide support to the most recent major version of +Java SDK. + +The most recent major will be supported in the following mode: + +- The latest major version will receive new functionality and bug fixes. These changes will be applied on top of last + released version. +- GoodData customer support will provide support for the latest major version only. + +- The customers are encouraged to always use the latest version of the Java SDK. +- In case of using older versions, the user might face API incompatibility, performance or security issues. + +Please follow the [upgrade instructions](https://github.com/gooddata/gooddata-java/wiki/Upgrading) to update to the +newest version. + +### Version 5.0 Release Notes + +**Version 5.0.0** represents a major modernization release with the following key updates: + +- **Java 17**: Minimum runtime requirement upgraded from Java 11 +- **Spring 6**: Framework upgraded from Spring 5.x to Spring 6.0.15 +- **Apache HTTP Client 5**: Primary HTTP client upgraded from version 4.5.x to 5.5.1 +- **Enhanced Compatibility**: Improved support for modern Java environments and cloud platforms + +This release maintains API compatibility while modernizing the underlying infrastructure for better performance, +security, and future extensibility. + +## Modules + +The *GoodData Java SDK* contains following modules: + +* [gooddata-java](./gooddata-java) - The GoodData API client (depends on `gooddata-java-model`). +* [gooddata-java-model](./gooddata-java-model) - Lightweight library containing only GoodData API structures. +* [gooddata-java-parent](./pom.xml) - Parent for *GoodData Java SDK* libraries (just a wrapper around `gooddata-java` + and `gooddata-java-model`). ## Usage @@ -12,10 +68,12 @@ The *GoodData Java SDK* is available in Maven Central Repository, to use it from com.gooddata gooddata-java - 2.34.0+api1 + {MAJOR}.{MINOR}.{PATCH}+api{API} ``` -See [releases page](https://github.com/gooddata/gooddata-java/releases) for information about versions and notable changes, + +See [releases page](https://github.com/gooddata/gooddata-java/releases) for information about versions and notable +changes, the [Upgrading Guide](https://github.com/gooddata/gooddata-java/wiki/Upgrading) will navigate you through changes between major versions. @@ -25,34 +83,143 @@ or [Wiki](https://github.com/gooddata/gooddata-java/wiki) for and [Extensibility How-To](https://github.com/gooddata/gooddata-java/wiki/Extending). ### API version -Since *GoodData Java SDK* version *2.32.0* API versioning is supported. The API version, GoodData Java is compatible with, is marked in artifact version using `+api` suffix (i.e. `2.32.0+api1` is compatible with API version `1`). + +Since *GoodData Java SDK* version *2.32.0* API versioning is supported. The API version, GoodData Java is compatible +with, is marked in artifact version using `+api` suffix (i.e. `2.32.0+api1` is compatible with API version `1`). ### Dependencies The *GoodData Java SDK* uses: -* the [GoodData HTTP client](https://github.com/gooddata/gooddata-http-client) version 0.9.3 or later -* the *Apache HTTP Client* version 4.5 or later (for white-labeled domains at least version 4.3.2 is required) -* the *Spring Framework* version 4.3.* -* the *Jackson JSON Processor* version 2.* -* the *Slf4j API* version 1.7.* -* the *Java Development Kit (JDK)* version 8 or later + +* the [GoodData HTTP client](https://github.com/gooddata/gooddata-http-client) version 3.0.0 +* the *Apache HTTP Client* version 5.5.1 +* the *Apache HTTP Client* version 4.5.13 (for compatibility with Sardine WebDAV library) +* the *Spring Framework* version 6.0.15 +* the *Jackson JSON Processor* version 2.13.4 +* the *Slf4j API* version 2.0.17 +* the *Java Development Kit (JDK)* version 17 or later to build + +### Migration from version 4.x to 5.0 + +**Version 5.0 introduces several significant upgrades that may require code changes in your application:** + +#### Breaking Changes + +1. **Java Runtime Requirement**: Minimum Java version is now **Java 17** (previously Java 11) +2. **Spring Framework**: Upgraded from Spring 5.x to **Spring 6.0.15** +3. **Apache HTTP Client**: Primary HTTP client upgraded from version 4.5.x to **version 5.5.1** +4. **SLF4J**: Upgraded from version 1.7.x to **version 2.0.17** + +#### Migration Steps + +**1. Update Java Runtime** +- Ensure your application runs on Java 17 or later +- Update your build tools (Maven/Gradle) to use Java 17 + +**2. Spring Framework Compatibility** +- If your application uses Spring Framework, upgrade to Spring 6.x or later +- Review Spring 6 migration guide for additional breaking changes: https://github.com/spring-projects/spring-framework/wiki/Upgrading-to-Spring-Framework-6.x +- Update Spring Boot to version 3.0+ if applicable + +**3. Dependency Updates** +Update your `pom.xml` or `build.gradle`: + +```xml + + + com.gooddata + gooddata-java + 5.0.0+api3 + + + + + org.springframework + spring-core + 6.0.15 + + + + + org.slf4j + slf4j-api + 2.0.17 + +``` + +**4. HTTP Client Configuration** +- The SDK now internally uses Apache HTTP Client 5.x +- If you customize HTTP client settings via `GoodDataSettings`, the API remains compatible +- Custom HTTP interceptors or low-level HTTP client configurations may need updates + +**5. Testing** +- Thoroughly test your application after upgrade +- Pay special attention to HTTP client behavior, especially with authentication and connection pooling +- Verify logging functionality works as expected with SLF4J 2.x + +#### Compatibility Notes + +- **API Compatibility**: The public SDK API remains largely backward compatible +- **Internal Changes**: HTTP client implementation has been modernized but SDK interfaces are unchanged +- **Jakarta EE**: Spring 6 uses Jakarta EE namespaces instead of Java EE (affects annotations if you use them directly) + +#### Known Migration Issues and Solutions + +**1. ClassNotFoundException for Apache HTTP Client classes** +If you see errors like `ClassNotFoundException: org.apache.http.impl.client.HttpClientBuilder`: +- Remove any direct dependencies on Apache HTTP Client 4.x from your project +- The SDK now uses HTTP Client 5.x internally, which has different package names + +**2. Spring Boot Applications** +- Ensure you're using Spring Boot 3.0+ which includes Spring 6 +- Update your `@SpringBootApplication` and other Spring annotations if needed +- Check Spring Boot 3.0 migration guide for additional changes + +**3. Logging Configuration** +- SLF4J 2.x has some configuration changes compared to 1.7.x +- Update your `logback.xml` or `log4j2.xml` if you use advanced logging features +- Basic logging configuration should work without changes + +**4. Build Tools** +```xml + + + 17 + 17 + +``` + +```gradle +// Gradle: Ensure Java 17 in your build.gradle +java { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 +} +``` + +For additional help, please refer to the [upgrading wiki page](https://github.com/gooddata/gooddata-java/wiki/Upgrading) +or [create an issue](https://github.com/gooddata/gooddata-java/issues) if you encounter problems during migration. ##### Retry of failed API calls -You can retry your failed requests since version *2.34.0*. Turn it on by configuring +You can retry your failed requests since *GoodData Java SDK* version *2.34.0*. Turn it on by configuring [RetrySettings](https://github.com/gooddata/gooddata-java/blob/master/src/main/java/com/gooddata/retry/RetrySettings.java) and add [Spring retry](https://github.com/spring-projects/spring-retry) to your classpath: + ```xml org.springframework.retry spring-retry - ${spring.retry.version} + 2.0.12 ``` +**Note**: Spring Retry 2.0.12 is compatible with Spring 6. If you're upgrading from prior versions of the SDK, +ensure you also upgrade your Spring Retry dependency to version 2.x for compatibility. + ### Logging -The *GoodData Java SDK* logs using `slf4j-api`. Please adjust your logging configuration for +The *GoodData Java SDK* logs using `slf4j-api`. Please adjust your logging configuration for `com.gooddata.sdk.*` loggers or alternatively turn the logging off using following dependency: ```xml @@ -62,12 +229,20 @@ The *GoodData Java SDK* logs using `slf4j-api`. Please adjust your logging confi ``` +### Date/Time + +The *GoodData Java SDK* is using Java 8 Date/Time API (JSR 310) for all Date / Time / Zone public facing types. +Good SO thread about differences between various types in Java Date/Time API: https://stackoverflow.com/a/32443004 + ## Development Build the library with `mvn package`, see the [Testing](https://github.com/gooddata/gooddata-java/wiki/Testing) page for different testing methods. +For releasing see [Releasing How-To](https://github.com/gooddata/gooddata-java/wiki/Releasing). + ## Contribute Found a bug? Please create an [issue](https://github.com/gooddata/gooddata-java/issues). Missing functionality? -[Contribute your code](CONTRIBUTING.md). +[Contribute your code](CONTRIBUTING.md). Any questions about GoodData or this library? Check +out [the GoodData community website](http://community.gooddata.com/). diff --git a/bugs-exclude.xml b/bugs-exclude.xml new file mode 100644 index 000000000..629a72fe5 --- /dev/null +++ b/bugs-exclude.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/bugs-include.xml b/bugs-include.xml new file mode 100644 index 000000000..5926b1f8b --- /dev/null +++ b/bugs-include.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/findBugsFilter.xml b/findBugsFilter.xml deleted file mode 100644 index 6a8d28dac..000000000 --- a/findBugsFilter.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/gooddata-java-model/pom.xml b/gooddata-java-model/pom.xml new file mode 100644 index 000000000..1263350d4 --- /dev/null +++ b/gooddata-java-model/pom.xml @@ -0,0 +1,107 @@ + + + 4.0.0 + + gooddata-java-model + ${project.artifactId} + + + gooddata-java-parent + com.gooddata + 5.0.2+api3-SNAPSHOT + + + + + com.gooddata + gooddata-rest-common + + + com.fasterxml.jackson.core + jackson-core + + + com.fasterxml.jackson.core + jackson-annotations + + + com.fasterxml.jackson.core + jackson-databind + + + org.apache.commons + commons-lang3 + + + + org.testng + testng + test + + + org.mockito + mockito-core + test + + + org.hamcrest + hamcrest + test + + + net.javacrumbs.json-unit + json-unit + test + + + net.javacrumbs.json-unit + json-unit-core + test + + + com.shazam + shazamcrest + test + + + nl.jqno.equalsverifier + equalsverifier + test + + + commons-io + commons-io + test + + + org.spockframework + spock-core + test + + + org.apache.groovy + groovy + test + + + cglib + cglib-nodep + test + + + org.springframework + spring-web + test + + + + + + + org.codehaus.gmavenplus + gmavenplus-plugin + + + + + diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/account/Account.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/account/Account.java new file mode 100644 index 000000000..d0f0b6ae1 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/account/Account.java @@ -0,0 +1,234 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.account; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonView; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.util.UriHelper; + +import java.util.List; + +/** + * Account setting + */ +@JsonTypeName("accountSetting") +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +public class Account { + + public static final String URI = "/gdc/account/profile/{id}"; + public static final String ACCOUNTS_URI = "/gdc/account/domains/{organization_name}/users"; + public static final String ACCOUNT_BY_EMAIL_URI = ACCOUNTS_URI + "?login={email}"; + + public static final String LOGIN_URI = "/gdc/account/login/{id}"; + + public static final String CURRENT_ID = "current"; + + private final String login; + @JsonIgnore + private final Links links; + @JsonView(UpdateView.class) + private String email; + @JsonView(UpdateView.class) + private String password; + @JsonView(UpdateView.class) + private String verifyPassword; + @JsonView(UpdateView.class) + private String firstName; + @JsonView(UpdateView.class) + private String lastName; + @JsonView(UpdateView.class) + private List ipWhitelist; + @JsonView(UpdateView.class) + private List authenticationModes; + + @JsonCreator + private Account( + @JsonProperty("login") String login, + @JsonProperty("email") String email, + @JsonProperty("password") String password, + @JsonProperty("verifyPassword") String verifyPassword, + @JsonProperty("firstName") String firstName, + @JsonProperty("lastName") String lastName, + @JsonProperty("ipWhitelist") List ipWhitelist, + @JsonProperty("authenticationModes") List authenticationModes, + @JsonProperty("links") Links links + ) { + this.login = login; + this.email = email; + this.password = password; + this.verifyPassword = verifyPassword; + this.firstName = firstName; + this.lastName = lastName; + this.ipWhitelist = ipWhitelist; + this.authenticationModes = authenticationModes; + this.links = links; + } + + public Account(final String login, + final String email, + final String password, + final String firstName, + final String lastName, + final List ipWhitelist, + final List authenticationModes) { + this(login, email, password, password, firstName, lastName, ipWhitelist, authenticationModes, null); + } + + public Account(String firstName, String lastName, Links links) { + this(null, null, null, null, firstName, lastName, null, null, links); + } + + /** + * Account creation constructor + * + * @param email email + * @param firstName first name + * @param lastName last name + * @param password password + */ + public Account(String email, String password, String firstName, String lastName) { + this(email, email, password, password, firstName, lastName, null, null, null); + } + + /** + * Extract Account's ID from Account's URI + * + * @param uri Account's URI + * @return Account's ID extracted from URI + */ + public static String getId(String uri) { + return UriHelper.getLastUriPart(uri); + } + + public String getLogin() { + return login; + } + + public String getEmail() { + return email; + } + + public void setEmail(final String email) { + this.email = email; + } + + public String getPassword() { + return password; + } + + public void setPassword(final String password) { + this.password = password; + } + + public String getVerifyPassword() { + return verifyPassword; + } + + public void setVerifyPassword(final String verifyPassword) { + this.verifyPassword = verifyPassword; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(final String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(final String lastName) { + this.lastName = lastName; + } + + @JsonIgnore + public String getUri() { + return links.getSelf(); + } + + @JsonIgnore + public String getProjectsUri() { + return links.getProjects(); + } + + @JsonIgnore + public String getId() { + return getId(getUri()); + } + + public List getIpWhitelist() { + return ipWhitelist; + } + + public void setIpWhitelist(final List ipWhitelist) { + this.ipWhitelist = ipWhitelist; + } + + public List getAuthenticationModes() { + return authenticationModes; + } + + public void setAuthenticationModes(final List authenticationModes) { + this.authenticationModes = authenticationModes; + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this, "password", "verifyPassword"); + } + + /** + * Enumeration type representing GoodData authentication mode. + */ + public enum AuthenticationMode { + /** + * User can be authenticated using password + */ + PASSWORD, + /** + * User can be authenticated via SSO + */ + SSO + } + + @JsonIgnoreProperties(ignoreUnknown = true) + private static class Links { + private final String self; + private final String projects; + + @JsonCreator + public Links(@JsonProperty("self") String self, @JsonProperty("projects") String projects) { + this.self = self; + this.projects = projects; + } + + public String getSelf() { + return self; + } + + public String getProjects() { + return projects; + } + } + + /** + * Class representing update view of account + */ + public static class UpdateView { + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/account/Accounts.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/account/Accounts.java new file mode 100644 index 000000000..82c1a3c78 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/account/Accounts.java @@ -0,0 +1,34 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.account; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeInfo.Id; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.gooddata.sdk.common.collections.Page; +import com.gooddata.sdk.common.collections.Paging; + +import java.util.List; +import java.util.Map; + +/** + * List of accounts. Deserialization only. + */ +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = Id.NAME) +@JsonTypeName(Accounts.ROOT_NODE) +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonDeserialize(using = AccountsDeserializer.class) +public class Accounts extends Page { + + static final String ROOT_NODE = "accountSettings"; + + + Accounts(final List items, final Paging paging, final Map links) { + super(items, paging, links); + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/account/AccountsDeserializer.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/account/AccountsDeserializer.java new file mode 100644 index 000000000..f03c4b243 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/account/AccountsDeserializer.java @@ -0,0 +1,24 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.account; + +import com.gooddata.sdk.common.collections.PageDeserializer; +import com.gooddata.sdk.common.collections.Paging; + +import java.util.List; +import java.util.Map; + +class AccountsDeserializer extends PageDeserializer { + + protected AccountsDeserializer() { + super(Account.class); + } + + @Override + protected Accounts createPage(final List items, final Paging paging, final Map links) { + return new Accounts(items, paging, links); + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/account/SeparatorSettings.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/account/SeparatorSettings.java new file mode 100644 index 000000000..3f94eabc3 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/account/SeparatorSettings.java @@ -0,0 +1,74 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ + +package com.gooddata.sdk.model.account; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; + +import java.io.Serializable; + +/** + * Default thousand and decimal separator settings configured for a profile. + * Deserialization only. + */ +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonTypeName("separators") +@JsonIgnoreProperties(ignoreUnknown = true) +public class SeparatorSettings implements Serializable { + + public static final String URI = "/gdc/account/profile/{id}/settings/separators"; + private static final long serialVersionUID = 446547615105910660L; + private final String thousand; + private final String decimal; + private final Links links; + + @JsonCreator + private SeparatorSettings( + @JsonProperty("thousand") final String thousand, + @JsonProperty("decimal") final String decimal, + @JsonProperty("links") final Links links) { + this.thousand = thousand; + this.decimal = decimal; + this.links = links; + } + + public String getThousand() { + return thousand; + } + + public String getDecimal() { + return decimal; + } + + public String getSelfLink() { + return links.self; + } + + @Override + public String toString() { + return GoodDataToStringBuilder.toString(this); + } + + @JsonIgnoreProperties(ignoreUnknown = true) + private static class Links implements Serializable { + private final String self; + + @JsonCreator + private Links(@JsonProperty("self") final String self) { + this.self = self; + } + + @Override + public String toString() { + return GoodDataToStringBuilder.toString(this); + } + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/auditevent/AccessLog.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/auditevent/AccessLog.java new file mode 100644 index 000000000..8bed61789 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/auditevent/AccessLog.java @@ -0,0 +1,96 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.auditevent; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.ISOZonedDateTime; + +import java.time.ZonedDateTime; + +/** + * Model class, used for special audit log events/access logs directly from haproxy, + * that represents access logs for particular hosts. + */ +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonTypeName("accessLog") +@JsonIgnoreProperties(ignoreUnknown = true) +public class AccessLog { + + public static final String RESOURCE_URI = "/gdc/domains/{domainId}/accessLogs"; + + private final String id; + private final String host; + private final String path; + private final String method; + private final String code; + private final String size; + private final String userIp; + @ISOZonedDateTime + private final ZonedDateTime occurred; + @ISOZonedDateTime + private final ZonedDateTime recorded; + + @JsonCreator + public AccessLog(@JsonProperty("id") String id, @JsonProperty("host") String host, @JsonProperty("path") String path, + @JsonProperty("method") String method, @JsonProperty("code") String code, @JsonProperty("size") String size, + @JsonProperty("userIp") String userIp, @JsonProperty("occurred") ZonedDateTime occurred, @JsonProperty("recorded") ZonedDateTime recorded) { + this.id = id; + this.host = host; + this.path = path; + this.method = method; + this.code = code; + this.size = size; + this.userIp = userIp; + this.occurred = occurred; + this.recorded = recorded; + } + + public String getId() { + return id; + } + + public String getHost() { + return host; + } + + public String getPath() { + return path; + } + + public String getMethod() { + return method; + } + + public String getCode() { + return code; + } + + public String getSize() { + return size; + } + + public String getUserIp() { + return userIp; + } + + public ZonedDateTime getOccurred() { + return occurred; + } + + public ZonedDateTime getRecorded() { + return recorded; + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/auditevent/AccessLogs.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/auditevent/AccessLogs.java new file mode 100644 index 000000000..b45655fc8 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/auditevent/AccessLogs.java @@ -0,0 +1,39 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.auditevent; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.gooddata.sdk.common.collections.Page; +import com.gooddata.sdk.common.collections.Paging; + +import java.util.List; +import java.util.Map; + +@JsonTypeInfo( + include = JsonTypeInfo.As.WRAPPER_OBJECT, + use = JsonTypeInfo.Id.NAME +) +@JsonTypeName("accessLogs") +@JsonIgnoreProperties( + ignoreUnknown = true +) +@JsonSerialize( + using = AccessLogsSerializer.class +) +@JsonDeserialize( + using = AccessLogsDeserializer.class +) +public class AccessLogs extends Page { + static final String ROOT_NODE = "accessLogs"; + + public AccessLogs(List items, Paging paging, Map links) { + super(items, paging, links); + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/auditevent/AccessLogsDeserializer.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/auditevent/AccessLogsDeserializer.java new file mode 100644 index 000000000..857547c4a --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/auditevent/AccessLogsDeserializer.java @@ -0,0 +1,24 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.auditevent; + +import com.gooddata.sdk.common.collections.PageDeserializer; +import com.gooddata.sdk.common.collections.Paging; + +import java.util.List; +import java.util.Map; + +public class AccessLogsDeserializer extends PageDeserializer { + + public AccessLogsDeserializer() { + super(AccessLog.class); + } + + @Override + protected AccessLogs createPage(List items, Paging paging, Map links) { + return new AccessLogs(items, paging, links); + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/auditevent/AccessLogsSerializer.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/auditevent/AccessLogsSerializer.java new file mode 100644 index 000000000..4c901162c --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/auditevent/AccessLogsSerializer.java @@ -0,0 +1,14 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.auditevent; + +import com.gooddata.sdk.common.collections.PageSerializer; + +public class AccessLogsSerializer extends PageSerializer { + public AccessLogsSerializer() { + super(AccessLogs.ROOT_NODE); + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/auditevent/AuditEvent.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/auditevent/AuditEvent.java new file mode 100644 index 000000000..554441574 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/auditevent/AuditEvent.java @@ -0,0 +1,130 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.auditevent; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.ISOZonedDateTime; + +import java.time.ZonedDateTime; +import java.util.Map; + +/** + * Audit event + */ +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonTypeName(AuditEvent.ROOT_NODE) +@JsonIgnoreProperties(ignoreUnknown = true) +public class AuditEvent { + + public static final String GDC_URI = "/gdc"; + public static final String USER_URI = GDC_URI + "/account/profile/{userId}/auditEvents"; + public static final String ADMIN_URI = GDC_URI + "/domains/{domainId}/auditEvents"; + + static final String ROOT_NODE = "event"; + + private final String id; + + private final String userLogin; + + /** + * the time the event occurred + */ + @ISOZonedDateTime + private final ZonedDateTime occurred; + + /** + * the time event was recorded by audit system + */ + @ISOZonedDateTime + private final ZonedDateTime recorded; + + private final String userIp; + + private final boolean success; + + private final String type; + + @JsonInclude(JsonInclude.Include.NON_EMPTY) + private final Map params; + + @JsonInclude(JsonInclude.Include.NON_EMPTY) + private final Map links; + + @JsonCreator + public AuditEvent(@JsonProperty("id") String id, + @JsonProperty("userLogin") String userLogin, + @JsonProperty("occurred") ZonedDateTime occurred, + @JsonProperty("recorded") ZonedDateTime recorded, + @JsonProperty("userIp") String userIp, + @JsonProperty("success") boolean success, + @JsonProperty("type") String type, + @JsonProperty("params") Map params, + @JsonProperty("links") Map links) { + this.id = id; + this.userLogin = userLogin; + this.occurred = occurred; + this.recorded = recorded; + this.userIp = userIp; + this.success = success; + this.type = type; + this.params = params; + this.links = links; + } + + public String getId() { + return id; + } + + public String getUserLogin() { + return userLogin; + } + + /** + * the time the event occurred + */ + public ZonedDateTime getOccurred() { + return occurred; + } + + /** + * the time event was recorded by audit system + */ + public ZonedDateTime getRecorded() { + return recorded; + } + + public String getUserIp() { + return userIp; + } + + public boolean isSuccess() { + return success; + } + + public String getType() { + return type; + } + + public Map getParams() { + return params; + } + + public Map getLinks() { + return links; + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } + +} diff --git a/src/main/java/com/gooddata/auditevent/AuditEvents.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/auditevent/AuditEvents.java similarity index 80% rename from src/main/java/com/gooddata/auditevent/AuditEvents.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/auditevent/AuditEvents.java index 892adb7b7..e60324e1c 100644 --- a/src/main/java/com/gooddata/auditevent/AuditEvents.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/auditevent/AuditEvents.java @@ -1,17 +1,17 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.auditevent; +package com.gooddata.sdk.model.auditevent; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.gooddata.collections.PageableList; -import com.gooddata.collections.Paging; +import com.gooddata.sdk.common.collections.Page; +import com.gooddata.sdk.common.collections.Paging; import java.util.List; import java.util.Map; @@ -24,7 +24,7 @@ @JsonIgnoreProperties(ignoreUnknown = true) @JsonSerialize(using = AuditEventsSerializer.class) @JsonDeserialize(using = AuditEventsDeserializer.class) -public class AuditEvents extends PageableList { +public class AuditEvents extends Page { static final String ROOT_NODE = "events"; diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/auditevent/AuditEventsDeserializer.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/auditevent/AuditEventsDeserializer.java new file mode 100644 index 000000000..4ab1dd022 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/auditevent/AuditEventsDeserializer.java @@ -0,0 +1,24 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.auditevent; + +import com.gooddata.sdk.common.collections.PageDeserializer; +import com.gooddata.sdk.common.collections.Paging; + +import java.util.List; +import java.util.Map; + +class AuditEventsDeserializer extends PageDeserializer { + + protected AuditEventsDeserializer() { + super(AuditEvent.class); + } + + @Override + protected AuditEvents createPage(final List items, final Paging paging, final Map links) { + return new AuditEvents(items, paging, links); + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/auditevent/AuditEventsSerializer.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/auditevent/AuditEventsSerializer.java new file mode 100644 index 000000000..8d36cc8b3 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/auditevent/AuditEventsSerializer.java @@ -0,0 +1,15 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.auditevent; + +import com.gooddata.sdk.common.collections.PageSerializer; + +class AuditEventsSerializer extends PageSerializer { + + public AuditEventsSerializer() { + super(AuditEvents.ROOT_NODE); + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/connector/ConnectorType.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/connector/ConnectorType.java new file mode 100644 index 000000000..c7b602e25 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/connector/ConnectorType.java @@ -0,0 +1,29 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.connector; + +/** + * Enum containing implemented connector types (currently version 4 of Zendesk connector only). + */ +public enum ConnectorType { + + ZENDESK4(Zendesk4Settings.URL); + + //URL of the settings endpoint (which is not equal for individual connector types) + private final String settingsUrl; + + ConnectorType(String settingsUrl) { + this.settingsUrl = settingsUrl; + } + + public String getName() { + return name().toLowerCase(); + } + + public String getSettingsUrl() { + return settingsUrl; + } +} diff --git a/src/main/java/com/gooddata/connector/Integration.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/connector/Integration.java similarity index 93% rename from src/main/java/com/gooddata/connector/Integration.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/connector/Integration.java index 42199b169..4a5040878 100644 --- a/src/main/java/com/gooddata/connector/Integration.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/connector/Integration.java @@ -1,9 +1,9 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.connector; +package com.gooddata.sdk.model.connector; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; @@ -12,9 +12,9 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; -import static com.gooddata.util.Validate.notEmpty; +import static com.gooddata.sdk.common.util.Validate.notEmpty; /** * Connector integration (i.e. one instance of configured ETL for loading of one GDC project). @@ -26,12 +26,11 @@ public class Integration { public static final String URL = "/gdc/projects/{project}/connectors/{connector}/integration"; - - private String projectTemplate; - private boolean active; private final IntegrationProcessStatus lastFinishedProcess; private final IntegrationProcessStatus lastSuccessfulProcess; private final IntegrationProcessStatus runningProcess; + private String projectTemplate; + private boolean active; public Integration(final String projectTemplate) { this(projectTemplate, true, null, null, null); diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/connector/IntegrationProcessStatus.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/connector/IntegrationProcessStatus.java new file mode 100644 index 000000000..df309dcbf --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/connector/IntegrationProcessStatus.java @@ -0,0 +1,98 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.connector; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.ISOZonedDateTime; +import com.gooddata.sdk.model.util.UriHelper; + +import java.time.ZonedDateTime; +import java.util.Map; + +import static com.gooddata.sdk.common.util.Validate.notNullState; + +/** + * Connector process (i.e. single ETL run) status used in integration object. Deserialization only. + */ +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +public class IntegrationProcessStatus { + + public static final String URI = "/gdc/projects/{project}/connectors/{connector}/integration/processes/{process}"; + private static final String SELF_LINK = "self"; + + private final Status status; + @ISOZonedDateTime + private final ZonedDateTime started; + @ISOZonedDateTime + private final ZonedDateTime finished; + private final Map links; + + @JsonCreator + protected IntegrationProcessStatus(@JsonProperty("status") Status status, + @JsonProperty("started") ZonedDateTime started, + @JsonProperty("finished") ZonedDateTime finished, + @JsonProperty("links") Map links) { + this.status = status; + this.started = started; + this.finished = finished; + this.links = links; + } + + public Status getStatus() { + return status; + } + + public ZonedDateTime getStarted() { + return started; + } + + public ZonedDateTime getFinished() { + return finished; + } + + /** + * Returns true when the connector process has already finished (no matter if it was successful). + * NOTE: It also returns false in case of inability to resolve the code (e.g. API change) + * + * @return true when the connector process has already finished, false otherwise + */ + @JsonIgnore + public boolean isFinished() { + return status != null && status.isFinished(); + } + + /** + * Returns true when the connector process failed. + * NOTE: It also returns false in case of inability to resolve the code (e.g. API change) + * + * @return true when the connector process failed, false otherwise + */ + @JsonIgnore + public boolean isFailed() { + return status != null && status.isFailed(); + } + + @JsonIgnore + public String getUri() { + return notNullState(links, "links").get(SELF_LINK); + } + + @JsonIgnore + public String getId() { + return UriHelper.getLastUriPart(getUri()); + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/connector/ProcessExecution.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/connector/ProcessExecution.java new file mode 100644 index 000000000..e1ec36c69 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/connector/ProcessExecution.java @@ -0,0 +1,26 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.connector; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; + +/** + * Connector process execution (i.e. definition for single ETL run). Serialization only. + */ +@JsonTypeName("process") +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +public interface ProcessExecution { + + @JsonIgnore + ConnectorType getConnectorType(); + +} diff --git a/src/main/java/com/gooddata/connector/ProcessStatus.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/connector/ProcessStatus.java similarity index 79% rename from src/main/java/com/gooddata/connector/ProcessStatus.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/connector/ProcessStatus.java index b5063031e..a8665cbb6 100644 --- a/src/main/java/com/gooddata/connector/ProcessStatus.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/connector/ProcessStatus.java @@ -1,19 +1,19 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.connector; +package com.gooddata.sdk.model.connector; -import com.gooddata.util.ISODateTimeDeserializer; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import org.joda.time.DateTime; +import com.gooddata.sdk.common.util.ISOZonedDateTimeDeserializer; +import java.time.ZonedDateTime; import java.util.Map; /** @@ -29,8 +29,8 @@ public class ProcessStatus extends IntegrationProcessStatus { @JsonCreator ProcessStatus(@JsonProperty("status") Status status, - @JsonProperty("started") @JsonDeserialize(using = ISODateTimeDeserializer.class) DateTime started, - @JsonProperty("finished") @JsonDeserialize(using = ISODateTimeDeserializer.class) DateTime finished, + @JsonProperty("started") @JsonDeserialize(using = ISOZonedDateTimeDeserializer.class) ZonedDateTime started, //TODO check if necessary + @JsonProperty("finished") @JsonDeserialize(using = ISOZonedDateTimeDeserializer.class) ZonedDateTime finished, @JsonProperty("links") Map links) { super(status, started, finished, links); } diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/connector/Reload.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/connector/Reload.java new file mode 100644 index 000000000..cc9c46d08 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/connector/Reload.java @@ -0,0 +1,148 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.connector; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; + +import java.util.Map; +import java.util.Optional; + +/** + * Connector reload. + */ +@JsonTypeName("reload") +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +public class Reload { + + public static final String URL = "/gdc/projects/{project}/connectors/zendesk4/integration/reloads"; + + public static final String CHATS_START_TIME_PROPERTY = "chats"; + public static final String AGENT_TIMELINE_START_TIME_PROPERTY = "agentTimeline"; + + /** + * Reload was scheduled but not yet started. + */ + public static final String STATUS_DO = "DO"; + + /** + * Reload is running. + */ + public static final String STATUS_RUNNING = "RUNNING"; + + /** + * Reload was successfully finished. + */ + public static final String STATUS_FINISHED = "FINISHED"; + + /** + * Reload wasn't started because reload window was missed. + */ + public static final String STATUS_MISSED = "MISSED"; + + /** + * Reload finished with error. + */ + public static final String STATUS_ERROR = "ERROR"; + + private static final String SELF_LINK = "self"; + private static final String PROCESS_LINK = "process"; + private static final String INTEGRATION_LINK = "integration"; + + + private final Integer id; + + private final Map startTimes; + + private final String status; + + private final String processId; + + private final Map links; + + public Reload(Map startTimes) { + this(null, startTimes, null, null, null); + } + + @JsonCreator + public Reload( + @JsonProperty("id") final Integer id, + @JsonProperty("startTimes") final Map startTimes, + @JsonProperty("status") final String status, + @JsonProperty("processId") final String processId, + @JsonProperty("links") final Map links) { + this.id = id; + this.startTimes = startTimes; + this.status = status; + this.processId = processId; + this.links = links; + } + + public Integer getId() { + return id; + } + + public Map getStartTimes() { + return startTimes; + } + + @JsonIgnore + public Long getChatsStartTime() { + return startTimes.get(CHATS_START_TIME_PROPERTY); + } + + @JsonIgnore + public Long getAgentTimelineStartTime() { + return startTimes.get(AGENT_TIMELINE_START_TIME_PROPERTY); + } + + public String getStatus() { + return status; + } + + public String getProcessId() { + return processId; + } + + public Map getLinks() { + return links; + } + + /** + * @return URI to itself. + */ + @JsonIgnore + public Optional getUri() { + return getLink(SELF_LINK); + } + + /** + * @return URI to running process. Is empty if reload wasn't started yet. + */ + @JsonIgnore + public Optional getProcessUri() { + return getLink(PROCESS_LINK); + } + + /** + * @return URI to integration. + */ + @JsonIgnore + public Optional getIntegrationUri() { + return getLink(INTEGRATION_LINK); + } + + private Optional getLink(final String linkName) { + return links != null ? Optional.ofNullable(links.get(linkName)) : Optional.empty(); + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/connector/Settings.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/connector/Settings.java new file mode 100644 index 000000000..a7e2810ba --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/connector/Settings.java @@ -0,0 +1,26 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.connector; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; + +/** + * Connector integration settings. + */ +@JsonTypeName("settings") +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +public interface Settings { + + @JsonIgnore + ConnectorType getConnectorType(); + +} diff --git a/src/main/java/com/gooddata/connector/Status.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/connector/Status.java similarity index 86% rename from src/main/java/com/gooddata/connector/Status.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/connector/Status.java index 03b0fa7dd..0144b3bb9 100644 --- a/src/main/java/com/gooddata/connector/Status.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/connector/Status.java @@ -1,19 +1,19 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.connector; +package com.gooddata.sdk.model.connector; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; -import static com.gooddata.connector.Status.Code.ERROR; -import static com.gooddata.connector.Status.Code.SYNCHRONIZED; -import static com.gooddata.connector.Status.Code.USER_ERROR; +import static com.gooddata.sdk.model.connector.Status.Code.ERROR; +import static com.gooddata.sdk.model.connector.Status.Code.SYNCHRONIZED; +import static com.gooddata.sdk.model.connector.Status.Code.USER_ERROR; /** * Connector process status. Deserialization only. @@ -67,6 +67,10 @@ public boolean isFailed() { return ERROR.name().equalsIgnoreCase(code) || USER_ERROR.name().equalsIgnoreCase(code); } + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } /** * Enum of connector process status codes @@ -75,9 +79,4 @@ public enum Code { NEW, SCHEDULED, DOWNLOADING, DOWNLOADED, TRANSFORMING, TRANSFORMED, UPLOADING, UPLOADED, SYNCHRONIZED, ERROR, USER_ERROR } - - @Override - public String toString() { - return GoodDataToStringBuilder.defaultToString(this); - } } diff --git a/src/main/java/com/gooddata/connector/Zendesk4ProcessExecution.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/connector/Zendesk4ProcessExecution.java similarity index 86% rename from src/main/java/com/gooddata/connector/Zendesk4ProcessExecution.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/connector/Zendesk4ProcessExecution.java index 7649bff7e..197be0f1d 100644 --- a/src/main/java/com/gooddata/connector/Zendesk4ProcessExecution.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/connector/Zendesk4ProcessExecution.java @@ -1,26 +1,26 @@ /* - * Copyright (C) 2004-2018, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.connector; - -import static com.gooddata.connector.ConnectorType.ZENDESK4; -import static com.gooddata.util.Validate.notEmpty; -import static com.gooddata.util.Validate.notNull; +package com.gooddata.sdk.model.connector; import com.fasterxml.jackson.annotation.JsonAnyGetter; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.gooddata.util.GoodDataToStringBuilder; -import com.gooddata.util.ISODateTimeSerializer; -import org.joda.time.DateTime; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.ISOZonedDateTimeSerializer; +import java.time.ZonedDateTime; import java.util.Map; import java.util.TreeMap; +import static com.gooddata.sdk.common.util.Validate.notEmpty; +import static com.gooddata.sdk.common.util.Validate.notNull; +import static com.gooddata.sdk.model.connector.ConnectorType.ZENDESK4; + /** * Zendesk 4 (Insights) connector process execution (i.e. definition for single ETL run). Serialization only. */ @@ -34,7 +34,7 @@ public class Zendesk4ProcessExecution implements ProcessExecution { private Boolean recoveryInProgress; - private Map startTimes; + private Map startTimes; private DownloadParams downloadParams; @@ -87,13 +87,13 @@ public void setRecoveryInProgress(final Boolean recoveryInProgress) { } @JsonAnyGetter - @JsonSerialize(contentUsing = ISODateTimeSerializer.class) - public Map getStartTimes() { + @JsonSerialize(contentUsing = ISOZonedDateTimeSerializer.class) + public Map getStartTimes() { return startTimes; } - public void setStartTime(final String resource, final DateTime startTime) { + public void setStartTime(final String resource, final ZonedDateTime startTime) { notEmpty(resource, "resource"); notNull(startTime, "startTime"); @@ -110,15 +110,15 @@ public DownloadParams getDownloadParams() { return downloadParams; } + public void setDownloadParams(DownloadParams downloadParams) { + this.downloadParams = downloadParams; + } + @JsonProperty("downloadParams") private DownloadParams getDownloadParamsPlain() { return downloadParams; } - public void setDownloadParams(DownloadParams downloadParams) { - this.downloadParams = downloadParams; - } - @Override public String toString() { return GoodDataToStringBuilder.defaultToString(this); @@ -144,7 +144,8 @@ public DownloadParams(Boolean useBackup) { this(useBackup, null, null); } - private DownloadParams() {} + private DownloadParams() { + } @JsonProperty("useBackup") public Boolean getUseBackup() { diff --git a/src/main/java/com/gooddata/connector/Zendesk4Settings.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/connector/Zendesk4Settings.java similarity index 89% rename from src/main/java/com/gooddata/connector/Zendesk4Settings.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/connector/Zendesk4Settings.java index 16d80a904..287b69340 100644 --- a/src/main/java/com/gooddata/connector/Zendesk4Settings.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/connector/Zendesk4Settings.java @@ -1,16 +1,16 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.connector; +package com.gooddata.sdk.model.connector; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; -import static com.gooddata.util.Validate.notEmpty; -import static com.gooddata.connector.ConnectorType.ZENDESK4; +import static com.gooddata.sdk.common.util.Validate.notEmpty; +import static com.gooddata.sdk.model.connector.ConnectorType.ZENDESK4; /** * Zendesk 4 (Insights) connector settings. @@ -18,13 +18,12 @@ public class Zendesk4Settings implements Settings { public static final String URL = "/gdc/projects/{project}/connectors/zendesk4/integration/settings"; - - private String apiUrl; - private String zopimUrl; - private String account; private final String type; private final String syncTime; private final String syncTimeZone; + private String apiUrl; + private String zopimUrl; + private String account; public Zendesk4Settings(final String apiUrl) { this(apiUrl, null, null, null, null, null); @@ -86,13 +85,13 @@ public ConnectorType getConnectorType() { return ZENDESK4; } - /** - * Type of Zendesk account. - */ - public enum Zendesk4Type {plus, enterprise} - @Override public String toString() { return GoodDataToStringBuilder.defaultToString(this); } + + /** + * Type of Zendesk account. + */ + public enum Zendesk4Type {plus, enterprise} } diff --git a/src/main/java/com/gooddata/dataload/OutputStage.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataload/OutputStage.java similarity index 86% rename from src/main/java/com/gooddata/dataload/OutputStage.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataload/OutputStage.java index 36fcac257..314e3edee 100644 --- a/src/main/java/com/gooddata/dataload/OutputStage.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataload/OutputStage.java @@ -1,11 +1,9 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.dataload; - -import static com.gooddata.util.Validate.notNullState; +package com.gooddata.sdk.model.dataload; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; @@ -14,11 +12,13 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.util.GoodDataToStringBuilder; -import org.springframework.web.util.UriTemplate; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.warehouse.WarehouseSchema; import java.util.Map; +import static com.gooddata.sdk.common.util.Validate.notNullState; + /** * Output stage. * For each project there is always one output stage, which always exists. @@ -30,16 +30,14 @@ public class OutputStage { public static final String URI = "/gdc/dataload/projects/{id}/outputStage"; - public static final UriTemplate TEMPLATE = new UriTemplate(URI); private static final String SELF_LINK = "self"; private static final String OUTPUT_STAGE_DIFF = "outputStageDiff"; private static final String DATALOAD_PROCESS = "dataloadProcess"; - + private final Map links; private String schema; private String clientId; private String outputStagePrefix; - private final Map links; @JsonCreator private OutputStage(@JsonProperty("schema") final String schema, @@ -57,7 +55,7 @@ public Map getLinks() { } /** - * get datawarehouse schema uri {@link com.gooddata.warehouse.WarehouseSchema} + * get datawarehouse schema uri {@link WarehouseSchema} * * @return warehouse schema, can be null. */ @@ -72,7 +70,7 @@ public void setSchemaUri(final String schemaUri) { } /** - * check if there is associated schema {@link com.gooddata.warehouse.WarehouseSchema} with this output stage + * check if there is associated schema {@link WarehouseSchema} with this output stage * * @return true if there is associated schema, else false */ diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataload/processes/AsyncTask.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataload/processes/AsyncTask.java new file mode 100644 index 000000000..5d145923d --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataload/processes/AsyncTask.java @@ -0,0 +1,58 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.dataload.processes; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; + +/** + * Asynchronous task containing link for polling. + * This task differs from {@link com.gooddata.sdk.model.gdc.AsyncTask} in links field. + * Deserialization only. + */ +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonTypeName("asyncTask") +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +public class AsyncTask { + + @JsonProperty + private final Links links; + + @JsonCreator + private AsyncTask(@JsonProperty("links") Links links) { + this.links = links; + } + + public AsyncTask(final String uri) { + this.links = new Links(uri); + } + + @JsonIgnore + public String getUri() { + return links.getPoll(); + } + + private static class Links { + + private final String poll; + + @JsonCreator + private Links(@JsonProperty("poll") String poll) { + this.poll = poll; + } + + public String getPoll() { + return poll; + } + } + +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataload/processes/DataloadProcess.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataload/processes/DataloadProcess.java new file mode 100644 index 000000000..689453d40 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataload/processes/DataloadProcess.java @@ -0,0 +1,136 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.dataload.processes; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.util.UriHelper; + +import java.util.Collections; +import java.util.Map; +import java.util.Set; + +import static com.gooddata.sdk.common.util.Validate.notEmpty; +import static com.gooddata.sdk.common.util.Validate.notNull; +import static com.gooddata.sdk.common.util.Validate.notNullState; + +/** + * Dataload process. + */ +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonTypeName("process") +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +public class DataloadProcess { + + public static final String URI = "/gdc/projects/{projectId}/dataload/processes/{processId}"; + + private static final String SELF_LINK = "self"; + private static final String EXECUTIONS_LINK = "executions"; + + private String name; + private String type; + private Set executables; + private Map links; + private String path; + + public DataloadProcess(String name, String type) { + this.name = notEmpty(name, "name"); + this.type = notEmpty(type, "type"); + } + + /** + * Use this constructor, when you want to deploy process from appstore. + * + * @param name name + * @param type type + * @param appstorePath valid path to brick in appstore + */ + public DataloadProcess(String name, String type, String appstorePath) { + this(name, type); + this.path = appstorePath; + } + + public DataloadProcess(String name, ProcessType type) { + this(name, notNull(type, "type").toString()); + } + + @JsonCreator + private DataloadProcess(@JsonProperty("name") String name, @JsonProperty("type") String type, + @JsonProperty("executables") Set executables, + @JsonProperty("links") Map links) { + this(name, type); + this.executables = executables != null ? Collections.unmodifiableSet(executables) : null; + this.links = links; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + @JsonIgnore + public Set getExecutables() { + return executables; + } + + @JsonIgnore + public String getUri() { + return notNullState(links, "links").get(SELF_LINK); + } + + @JsonIgnore + public String getId() { + return UriHelper.getLastUriPart(getUri()); + } + + @JsonIgnore + public String getExecutionsUri() { + return notNullState(links, "links").get(EXECUTIONS_LINK); + } + + @JsonIgnore + public String getSourceUri() { + return getUri() + "/source"; + } + + public void validateExecutable(final String executable) { + if (getExecutables() != null && !getExecutables().isEmpty() && + !getExecutables().contains(executable)) { + throw new IllegalArgumentException("Executable " + executable + " not found in process executables " + getExecutables()); + } + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataload/processes/DataloadProcesses.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataload/processes/DataloadProcesses.java new file mode 100644 index 000000000..307eed7bf --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataload/processes/DataloadProcesses.java @@ -0,0 +1,45 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.dataload.processes; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.account.Account; + +import java.util.Collection; +import java.util.List; + +/** + * List of dataload processes. Deserialization only. + */ +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonTypeName("processes") +@JsonIgnoreProperties(ignoreUnknown = true) +public class DataloadProcesses { + public static final String URI = "/gdc/projects/{projectId}/dataload/processes"; + + public static final String USER_PROCESSES_URI = Account.URI + "/dataload/processes"; + + private final List items; + + @JsonCreator + DataloadProcesses(@JsonProperty("items") List items) { + this.items = items; + } + + public Collection getItems() { + return items; + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataload/processes/ProcessExecution.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataload/processes/ProcessExecution.java new file mode 100644 index 000000000..9a8a064f0 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataload/processes/ProcessExecution.java @@ -0,0 +1,73 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.dataload.processes; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; + +import java.util.HashMap; +import java.util.Map; + +import static com.gooddata.sdk.common.util.Validate.notEmpty; +import static com.gooddata.sdk.common.util.Validate.notNull; + +/** + * Dataload process execution. Serialization only. + */ +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonTypeName("execution") +@JsonIgnoreProperties(ignoreUnknown = true) +public class ProcessExecution { + + private final String executionsUri; + + private final String executable; + private final Map params; + private final Map hiddenParams; + + public ProcessExecution(DataloadProcess process, String executable) { + this(process, executable, new HashMap<>(), new HashMap<>()); + } + + public ProcessExecution(DataloadProcess process, String executable, Map params) { + this(process, executable, params, new HashMap<>()); + } + + public ProcessExecution(DataloadProcess process, String executable, Map params, Map hiddenParams) { + notNull(process, "process"); + this.executionsUri = notEmpty(process.getExecutionsUri(), "process executions link"); + this.executable = executable; + this.params = notNull(params, "params"); + this.hiddenParams = notNull(hiddenParams, "hiddenParams"); + + process.validateExecutable(executable); + } + + public String getExecutable() { + return executable; + } + + public Map getParams() { + return params; + } + + public Map getHiddenParams() { + return hiddenParams; + } + + @JsonIgnore + public String getExecutionsUri() { + return executionsUri; + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this, "hiddenParams", "executionsUri"); + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataload/processes/ProcessExecutionDetail.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataload/processes/ProcessExecutionDetail.java new file mode 100644 index 000000000..57b9b8c6f --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataload/processes/ProcessExecutionDetail.java @@ -0,0 +1,121 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.dataload.processes; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.gooddata.sdk.common.gdc.ErrorStructure; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.ISOZonedDateTime; + +import java.net.URI; +import java.time.ZonedDateTime; +import java.util.Map; + +import static com.gooddata.sdk.common.util.Validate.notEmpty; +import static com.gooddata.sdk.common.util.Validate.notNull; +import static com.gooddata.sdk.common.util.Validate.notNullState; + +/** + * Dataload process execution detail. Deserialization only. + */ +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonTypeName("executionDetail") +@JsonIgnoreProperties(ignoreUnknown = true) +public class ProcessExecutionDetail { + + private static final String LOG_LINK = "log"; + private static final String SELF_LINK = "self"; + private static final String EXECUTION_LINK = "poll"; + private static final String STATUS_OK = "OK"; + private final String status; + + @ISOZonedDateTime + private final ZonedDateTime created; + @ISOZonedDateTime + private final ZonedDateTime started; + @ISOZonedDateTime + private final ZonedDateTime updated; + @ISOZonedDateTime + private final ZonedDateTime finished; + + private final ErrorStructure error; + private final Map links; + + @JsonCreator + private ProcessExecutionDetail(@JsonProperty("status") String status, + @JsonProperty("created") ZonedDateTime created, + @JsonProperty("started") ZonedDateTime started, + @JsonProperty("updated") ZonedDateTime updated, + @JsonProperty("finished") ZonedDateTime finished, + @JsonProperty("error") ErrorStructure error, + @JsonProperty("links") Map links) { + this.status = notEmpty(status, "status"); + this.created = notNull(created, "created"); + this.started = started; + this.updated = updated; + this.finished = finished; + this.error = error; + this.links = links; + } + + public static URI uriFromExecutionUri(URI executionUri) { + return URI.create(executionUri.toString() + "/detail"); + } + + public String getStatus() { + return status; + } + + public ZonedDateTime getCreated() { + return created; + } + + public ZonedDateTime getStarted() { + return started; + } + + public ZonedDateTime getUpdated() { + return updated; + } + + public ZonedDateTime getFinished() { + return finished; + } + + public ErrorStructure getError() { + return error; + } + + @JsonIgnore + public String getLogUri() { + return notNullState(links, "links").get(LOG_LINK); + } + + @JsonIgnore + public String getUri() { + return notNullState(links, "links").get(SELF_LINK); + } + + @JsonIgnore + public String getExecutionUri() { + return notNullState(links, "links").get(EXECUTION_LINK); + } + + @JsonIgnore + public boolean isSuccess() { + return STATUS_OK.equals(status); + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataload/processes/ProcessExecutionTask.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataload/processes/ProcessExecutionTask.java new file mode 100644 index 000000000..8fe5169ec --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataload/processes/ProcessExecutionTask.java @@ -0,0 +1,43 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.dataload.processes; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; + +import java.util.Map; + +import static com.gooddata.sdk.common.util.Validate.notNullState; + +/** + * Process execution task. Deserialization only + */ +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonTypeName("executionTask") +@JsonIgnoreProperties(ignoreUnknown = true) +public class ProcessExecutionTask { + + private static final String POLL_LINK = "poll"; + private static final String DETAIL_LINK = "detail"; + + private final Map links; + + @JsonCreator + private ProcessExecutionTask(@JsonProperty("links") Map links) { + this.links = links; + } + + public String getPollUri() { + return notNullState(links, "links").get(POLL_LINK); + } + + public String getDetailUri() { + return notNullState(links, "links").get(DETAIL_LINK); + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataload/processes/ProcessType.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataload/processes/ProcessType.java new file mode 100644 index 000000000..1d32f2a12 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataload/processes/ProcessType.java @@ -0,0 +1,17 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.dataload.processes; + +/** + * Represents type of dataload process. Please note that this enumeration must not be complete. + */ +public enum ProcessType { + GRAPH, + RUBY, + JAVASCRIPT, + GROOVY, + DATALOAD +} diff --git a/src/main/java/com/gooddata/dataload/processes/Schedule.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataload/processes/Schedule.java similarity index 85% rename from src/main/java/com/gooddata/dataload/processes/Schedule.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataload/processes/Schedule.java index fda4b1f87..e7e113c3c 100644 --- a/src/main/java/com/gooddata/dataload/processes/Schedule.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataload/processes/Schedule.java @@ -1,32 +1,31 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.dataload.processes; +package com.gooddata.sdk.model.dataload.processes; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.gooddata.util.GoodDataToStringBuilder; -import com.gooddata.util.ISODateTimeDeserializer; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; -import org.joda.time.Duration; -import org.springframework.web.util.UriTemplate; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.ISOZonedDateTimeDeserializer; +import com.gooddata.sdk.model.util.UriHelper; +import java.time.Duration; +import java.time.ZonedDateTime; import java.util.Collections; import java.util.HashMap; import java.util.Map; -import static com.gooddata.util.Validate.notEmpty; -import static com.gooddata.util.Validate.notNull; -import static com.gooddata.util.Validate.notNullState; +import static com.gooddata.sdk.common.util.Validate.notEmpty; +import static com.gooddata.sdk.common.util.Validate.notNull; +import static com.gooddata.sdk.common.util.Validate.notNullState; /** * Schedule. @@ -38,7 +37,6 @@ public class Schedule { public static final String URI = "/gdc/projects/{projectId}/schedules/{scheduleId}"; - public static final UriTemplate TEMPLATE = new UriTemplate(URI); private static final String SELF_LINK = "self"; private static final String EXECUTIONS_LINK = "executions"; @@ -48,16 +46,16 @@ public class Schedule { private static final String EXECUTABLE = "EXECUTABLE"; private final String type; + private final ZonedDateTime nextExecutionTime; + private final int consecutiveFailedExecutionCount; + private final Map params; + private final Map links; private String state; private String cron; private String timezone; private Integer reschedule; private String triggerScheduleId; private String name; - private final DateTime nextExecutionTime; - private final int consecutiveFailedExecutionCount; - private final Map params; - private final Map links; public Schedule(final DataloadProcess process, final String executable, final String cron) { this(process, executable); @@ -66,8 +64,9 @@ public Schedule(final DataloadProcess process, final String executable, final St /** * Creates schedule, which is triggered by execution of different schedule - * @param process process to create schedule for - * @param executable executable to be scheduled for execution + * + * @param process process to create schedule for + * @param executable executable to be scheduled for execution * @param triggerSchedule schedule, which will trigger created schedule */ public Schedule(final DataloadProcess process, final String executable, final Schedule triggerSchedule) { @@ -94,7 +93,7 @@ private Schedule(@JsonProperty("type") final String type, @JsonProperty("state") final String state, @JsonProperty("cron") final String cron, @JsonProperty("timezone") final String timezone, - @JsonProperty("nextExecutionTime") @JsonDeserialize(using = ISODateTimeDeserializer.class) DateTime nextExecutionTime, + @JsonProperty("nextExecutionTime") @JsonDeserialize(using = ISOZonedDateTimeDeserializer.class) ZonedDateTime nextExecutionTime, @JsonProperty("consecutiveFailedExecutionCount") final int consecutiveFailedExecutionCount, @JsonProperty("params") final Map params, @JsonProperty("reschedule") final Integer reschedule, @@ -188,8 +187,14 @@ public void setTimezone(final String timezone) { this.timezone = timezone; } + @JsonIgnore + public void setTimezone(final ZonedDateTime timezone) { + this.timezone = notNull(timezone, "timezone").getZone().getId(); + } + /** * Duration after a failed execution of the schedule is executed again + * * @return reschedule duration in minutes */ @JsonProperty("reschedule") @@ -199,19 +204,21 @@ public Integer getRescheduleInMinutes() { /** * Duration after a failed execution of the schedule is executed again + * * @return reschedule duration in minutes */ @JsonIgnore public Duration getReschedule() { - return reschedule != null ? Duration.standardMinutes(getRescheduleInMinutes()) : null; + return reschedule != null ? Duration.ofMinutes(getRescheduleInMinutes()) : null; } /** * Duration after a failed execution of the schedule is executed again + * * @param reschedule this duration should not be too low, because it can be rejected by REST API (e.g. 15 minutes or more) */ public void setReschedule(Duration reschedule) { - this.reschedule = notNull(reschedule, "reschedule").toStandardMinutes().getMinutes(); + this.reschedule = Long.valueOf(notNull(reschedule, "reschedule").toMinutes()).intValue(); } public String getTriggerScheduleId() { @@ -231,12 +238,7 @@ public void setName(final String name) { } @JsonIgnore - public void setTimezone(final DateTimeZone timezone) { - this.timezone = notNull(timezone, "timezone").getID(); - } - - @JsonIgnore - public DateTime getNextExecutionTime() { + public ZonedDateTime getNextExecutionTime() { return nextExecutionTime; } @@ -252,7 +254,7 @@ public String getUri() { @JsonIgnore public String getId() { - return TEMPLATE.match(getUri()).get("scheduleId"); + return UriHelper.getLastUriPart(getUri()); } @JsonIgnore diff --git a/src/main/java/com/gooddata/dataload/processes/ScheduleExecution.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataload/processes/ScheduleExecution.java similarity index 81% rename from src/main/java/com/gooddata/dataload/processes/ScheduleExecution.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataload/processes/ScheduleExecution.java index 2270d5ba9..2ff82dd9a 100644 --- a/src/main/java/com/gooddata/dataload/processes/ScheduleExecution.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataload/processes/ScheduleExecution.java @@ -1,11 +1,9 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.dataload.processes; - -import static com.gooddata.util.Validate.notNullState; +package com.gooddata.sdk.model.dataload.processes; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; @@ -15,15 +13,16 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.gooddata.util.ISODateTimeDeserializer; -import org.joda.time.DateTime; -import org.springframework.web.util.UriTemplate; +import com.gooddata.sdk.common.util.ISOZonedDateTimeDeserializer; +import java.time.ZonedDateTime; import java.util.Arrays; import java.util.HashSet; import java.util.Map; import java.util.Set; +import static com.gooddata.sdk.common.util.Validate.notNullState; + /** * Schedule execution */ @@ -34,20 +33,20 @@ public class ScheduleExecution { public static final String URI = "/gdc/projects/{projectId}/schedules/{scheduleId}/executions/{executionId}"; - public static final UriTemplate TEMPLATE = new UriTemplate(URI); private static final Set FINISHED_STATUSES = new HashSet<>(Arrays.asList("OK", "ERROR", "CANCELED", "TIMEOUT")); - private DateTime created; + private ZonedDateTime created; private String status; private String trigger; private String processLastDeployedBy; - private Map links; + private Map links; - ScheduleExecution() {} + public ScheduleExecution() { + } @JsonCreator - private ScheduleExecution(@JsonProperty("createdTime") @JsonDeserialize(using = ISODateTimeDeserializer.class) DateTime created, + private ScheduleExecution(@JsonProperty("createdTime") @JsonDeserialize(using = ISOZonedDateTimeDeserializer.class) ZonedDateTime created, @JsonProperty("status") String executionStatus, @JsonProperty("trigger") String trigger, @JsonProperty("processLastDeployedBy") String processLastDeployedBy, @@ -67,7 +66,7 @@ public Map getLinks() { return links; } - public DateTime getCreated() { + public ZonedDateTime getCreated() { return created; } diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataload/processes/ScheduleState.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataload/processes/ScheduleState.java new file mode 100644 index 000000000..553d6632e --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataload/processes/ScheduleState.java @@ -0,0 +1,13 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.dataload.processes; + +/** + * Dataload schedule state. + */ +public enum ScheduleState { + ENABLED, DISABLED +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataload/processes/Schedules.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataload/processes/Schedules.java new file mode 100644 index 000000000..2443ff04e --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataload/processes/Schedules.java @@ -0,0 +1,30 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.dataload.processes; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.gooddata.sdk.common.collections.Page; +import com.gooddata.sdk.common.collections.Paging; + +import java.util.List; + +/** + * List of schedules. Deserialization only. + */ +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonTypeName("schedules") +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonDeserialize(using = SchedulesDeserializer.class) +public class Schedules extends Page { + public static final String URI = "/gdc/projects/{projectId}/schedules"; + + Schedules(final List items, final Paging paging) { + super(items, paging); + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataload/processes/SchedulesDeserializer.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataload/processes/SchedulesDeserializer.java new file mode 100644 index 000000000..7c21903e1 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataload/processes/SchedulesDeserializer.java @@ -0,0 +1,24 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.dataload.processes; + +import com.gooddata.sdk.common.collections.PageDeserializer; +import com.gooddata.sdk.common.collections.Paging; + +import java.util.List; +import java.util.Map; + +class SchedulesDeserializer extends PageDeserializer { + + protected SchedulesDeserializer() { + super(Schedule.class); + } + + @Override + protected Schedules createPage(final List items, final Paging paging, final Map links) { + return new Schedules(items, paging); + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/DatasetLinks.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/DatasetLinks.java new file mode 100644 index 000000000..3b0027c49 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/DatasetLinks.java @@ -0,0 +1,28 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.dataset; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.gooddata.sdk.model.gdc.AboutLinks; + +import java.util.List; + +/** + * Dataset links. + * Deserialization only. + */ +public class DatasetLinks extends AboutLinks { + + public static final String URI = "/gdc/md/{project}/ldm/singleloadinterface"; + + @JsonCreator + public DatasetLinks(@JsonProperty("category") String category, @JsonProperty("summary") String summary, + @JsonProperty("links") List links) { + super(category, summary, null, links); + } + +} diff --git a/src/main/java/com/gooddata/dataset/DatasetManifest.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/DatasetManifest.java similarity index 88% rename from src/main/java/com/gooddata/dataset/DatasetManifest.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/DatasetManifest.java index 47c0f99c9..63563f952 100644 --- a/src/main/java/com/gooddata/dataset/DatasetManifest.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/DatasetManifest.java @@ -1,29 +1,29 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.dataset; +package com.gooddata.sdk.model.dataset; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.gooddata.util.BooleanDeserializer; -import com.gooddata.util.BooleanIntegerSerializer; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.BooleanDeserializer; +import com.gooddata.sdk.common.util.BooleanIntegerSerializer; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.io.InputStream; import java.util.List; import java.util.Map; -import static com.gooddata.util.Validate.notEmpty; -import static com.gooddata.util.Validate.notNull; +import static com.gooddata.sdk.common.util.Validate.notEmpty; +import static com.gooddata.sdk.common.util.Validate.notNull; /** @@ -48,6 +48,7 @@ public DatasetManifest(String dataSet) { /** * Create dataset upload manifest. + * * @param dataSet dataset name * @param source source CSV */ @@ -86,6 +87,7 @@ public void setFile(String file) { /** * Set upload mode for all parts of this dataset manifest + * * @param uploadMode upload mode */ public void setUploadMode(final UploadMode uploadMode) { @@ -97,8 +99,9 @@ public void setUploadMode(final UploadMode uploadMode) { /** * Map the given CSV column name to the dataset field + * * @param columnName column name - * @param populates dataset field + * @param populates dataset field */ public void setMapping(final String columnName, final String populates) { notNull(columnName, "columnName"); @@ -144,10 +147,10 @@ public static class Part { @JsonCreator public Part(@JsonProperty("mode") String uploadMode, - @JsonProperty("columnName") String columnName, - @JsonProperty("populates") List populates, - @JsonProperty("referenceKey") @JsonDeserialize(using = BooleanDeserializer.class) Boolean referenceKey, - @JsonProperty("constraints") Map constraints) { + @JsonProperty("columnName") String columnName, + @JsonProperty("populates") List populates, + @JsonProperty("referenceKey") @JsonDeserialize(using = BooleanDeserializer.class) Boolean referenceKey, + @JsonProperty("constraints") Map constraints) { this.uploadMode = uploadMode; this.columnName = columnName; this.populates = populates; diff --git a/src/main/java/com/gooddata/dataset/DatasetManifests.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/DatasetManifests.java similarity index 79% rename from src/main/java/com/gooddata/dataset/DatasetManifests.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/DatasetManifests.java index c6e8b0106..41dade477 100644 --- a/src/main/java/com/gooddata/dataset/DatasetManifests.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/DatasetManifests.java @@ -1,27 +1,28 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.dataset; +package com.gooddata.sdk.model.dataset; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.util.Collection; -import static com.gooddata.util.Validate.notNull; +import static com.gooddata.sdk.common.util.Validate.notNull; /** * Encapsulates list of {@link DatasetManifest}. */ -class DatasetManifests { +public class DatasetManifests { private final Collection manifests; /** * Construct object. + * * @param manifests dataset upload manifests */ @JsonCreator diff --git a/src/main/java/com/gooddata/dataset/DatasetNotFoundException.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/DatasetNotFoundException.java similarity index 81% rename from src/main/java/com/gooddata/dataset/DatasetNotFoundException.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/DatasetNotFoundException.java index 4c5009774..32704688a 100644 --- a/src/main/java/com/gooddata/dataset/DatasetNotFoundException.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/DatasetNotFoundException.java @@ -1,13 +1,13 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.dataset; +package com.gooddata.sdk.model.dataset; -import static java.lang.String.format; +import com.gooddata.sdk.common.GoodDataException; -import com.gooddata.GoodDataException; +import static java.lang.String.format; /** * Represents error when dataset of the given id was not found diff --git a/src/main/java/com/gooddata/dataset/EtlMode.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/EtlMode.java similarity index 88% rename from src/main/java/com/gooddata/dataset/EtlMode.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/EtlMode.java index decf8fb3f..4299adde8 100644 --- a/src/main/java/com/gooddata/dataset/EtlMode.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/EtlMode.java @@ -1,9 +1,9 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.dataset; +package com.gooddata.sdk.model.dataset; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @@ -11,13 +11,13 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; @JsonTypeName("etlMode") @JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(JsonInclude.Include.NON_NULL) -class EtlMode { +public class EtlMode { public static final String URL = "/gdc/md/{project}/etl/mode"; diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/EtlModeType.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/EtlModeType.java new file mode 100644 index 000000000..8492b9898 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/EtlModeType.java @@ -0,0 +1,21 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.dataset; + +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * Enum containing ETL mode types. + */ +public enum EtlModeType { + + SLI, DLI, VOID; + + @JsonValue + public String getName() { + return name(); + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/LookupMode.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/LookupMode.java new file mode 100644 index 000000000..2f39b6118 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/LookupMode.java @@ -0,0 +1,21 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.dataset; + +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * Enum containing ETL lookup modes. + */ +public enum LookupMode { + + RECREATE; + + @JsonValue + public String getName() { + return name().toLowerCase(); + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/MaqlDml.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/MaqlDml.java new file mode 100644 index 000000000..fac9510fb --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/MaqlDml.java @@ -0,0 +1,21 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.dataset; + +import com.gooddata.sdk.model.gdc.AbstractMaql; + +/** + * MAQL DML statement. + * Serialization only. + */ +public class MaqlDml extends AbstractMaql { + + public static final String URI = "/gdc/md/{project}/dml/manage"; + + public MaqlDml(final String maql) { + super(maql); + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/Pull.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/Pull.java new file mode 100644 index 000000000..56eeaf5b7 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/Pull.java @@ -0,0 +1,37 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.dataset; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; + +/** + * ETL Pull input DTO (for internal use). + * Serialization only. + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +public class Pull { + + public static final String URI = "/gdc/md/{projectId}/etl/pull2"; + + @JsonProperty("pullIntegration") + private final String remoteDir; + + + public Pull(String remoteDir) { + this.remoteDir = remoteDir; + } + + public String getRemoteDir() { + return remoteDir; + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } +} diff --git a/src/main/java/com/gooddata/dataset/PullTask.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/PullTask.java similarity index 78% rename from src/main/java/com/gooddata/dataset/PullTask.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/PullTask.java index 7da660d8f..f1aedb205 100644 --- a/src/main/java/com/gooddata/dataset/PullTask.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/PullTask.java @@ -1,19 +1,18 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.dataset; - -import static com.gooddata.util.Validate.notEmpty; -import static com.gooddata.util.Validate.notNull; +package com.gooddata.sdk.model.dataset; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import org.springframework.web.util.UriTemplate; + +import static com.gooddata.sdk.common.util.Validate.notEmpty; +import static com.gooddata.sdk.common.util.Validate.notNull; /** * Asynchronous ETL Pull 2 task (for internal use). @@ -22,10 +21,9 @@ @JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) @JsonTypeName("pull2Task") @JsonIgnoreProperties(ignoreUnknown = true) -class PullTask { +public class PullTask { public static final String URI = "/gdc/md/{projectId}/tasks/task/{taskId}"; - public static final UriTemplate TEMPLATE = new UriTemplate(URI); private final Links links; diff --git a/src/main/java/com/gooddata/dataset/TaskState.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/TaskState.java similarity index 89% rename from src/main/java/com/gooddata/dataset/TaskState.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/TaskState.java index 9a7ab835f..e65700f15 100644 --- a/src/main/java/com/gooddata/dataset/TaskState.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/TaskState.java @@ -1,9 +1,9 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.dataset; +package com.gooddata.sdk.model.dataset; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @@ -11,7 +11,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; /** * Update Project Data task status (for internal use). @@ -21,7 +21,7 @@ @JsonTypeName("taskState") @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(JsonInclude.Include.NON_NULL) -class TaskState { +public class TaskState { private static final String OK = "OK"; private static final String ERROR = "ERROR"; diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/Upload.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/Upload.java new file mode 100644 index 000000000..98c3d38db --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/Upload.java @@ -0,0 +1,129 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.dataset; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.gooddata.sdk.common.util.BooleanDeserializer; +import com.gooddata.sdk.common.util.GDZonedDateTimeDeserializer; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; + +import java.time.ZonedDateTime; + +/** + * Contains information about single dataset upload. + * Deserialization only. + */ +@JsonTypeName("dataUpload") +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonIgnoreProperties(ignoreUnknown = true) +public class Upload { + + public static final String URI = "/gdc/md/{projectId}/data/upload/{uploadId}"; + + private final String uri; + private final String status; + private final double progress; + private final String message; + private final UploadMode uploadMode; + private final Integer size; + private final ZonedDateTime createdAt; + private final ZonedDateTime processedAt; + + Upload(@JsonProperty("msg") String message, + @JsonProperty("progress") Double progress, + @JsonProperty("status") String status, + @JsonProperty("fullUpload") @JsonDeserialize(using = BooleanDeserializer.class) Boolean fullUpload, + @JsonProperty("uri") String uri, + @JsonProperty("createdAt") @JsonDeserialize(using = GDZonedDateTimeDeserializer.class) ZonedDateTime createdAt, + @JsonProperty("fileSize") Integer size, + @JsonProperty("processedAt") @JsonDeserialize(using = GDZonedDateTimeDeserializer.class) ZonedDateTime processedAt) { + + this.uri = uri; + this.status = status; + this.progress = progress != null ? progress : 0; + this.message = message; + this.uploadMode = toUploadMode(fullUpload); + this.size = size; + this.createdAt = createdAt; + this.processedAt = processedAt; + } + + /** + * @return uri link to self + */ + public String getUri() { + return uri; + } + + /** + * @return upload status + */ + public String getStatus() { + return status; + } + + /** + * @return upload progress in percent as floating point number + */ + public double getProgress() { + return progress; + } + + /** + * @return error message if the upload failed, {@code null} otherwise + */ + public String getMessage() { + return message; + } + + /** + * @return {@link UploadMode} of this upload + */ + public UploadMode getUploadMode() { + return uploadMode; + } + + /** + * @return size of the data uploaded by this upload + */ + public Integer getSize() { + return size; + } + + /** + * @return date of creation of this upload + */ + public ZonedDateTime getCreatedAt() { + return createdAt; + } + + /** + * @return date when the upload was processed or {@code null} if upload is still being processed + */ + public ZonedDateTime getProcessedAt() { + return processedAt; + } + + /** + * Converts boolean value containing if the upload is full or incremental load to {@link UploadMode} enum. + */ + private UploadMode toUploadMode(Boolean fullUpload) { + if (fullUpload == null) { + return null; + } + + return fullUpload ? UploadMode.FULL : UploadMode.INCREMENTAL; + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } +} diff --git a/src/main/java/com/gooddata/dataset/UploadMode.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/UploadMode.java similarity index 93% rename from src/main/java/com/gooddata/dataset/UploadMode.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/UploadMode.java index 38bf84500..2c0c67d61 100644 --- a/src/main/java/com/gooddata/dataset/UploadMode.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/UploadMode.java @@ -1,9 +1,9 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.dataset; +package com.gooddata.sdk.model.dataset; import java.util.HashMap; import java.util.Map; diff --git a/src/main/java/com/gooddata/dataset/UploadStatistics.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/UploadStatistics.java similarity index 84% rename from src/main/java/com/gooddata/dataset/UploadStatistics.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/UploadStatistics.java index 4b8ac9489..540d76653 100644 --- a/src/main/java/com/gooddata/dataset/UploadStatistics.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/UploadStatistics.java @@ -1,17 +1,15 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.dataset; +package com.gooddata.sdk.model.dataset; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; - -import com.gooddata.util.GoodDataToStringBuilder; -import org.springframework.web.util.UriTemplate; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.util.HashMap; import java.util.Map; @@ -25,7 +23,6 @@ public class UploadStatistics { public static final String URI = "/gdc/md/{projectId}/data/uploads_info"; - public static final UriTemplate URI_TEMPLATE = new UriTemplate(URI); private final Map statusesCount; diff --git a/src/main/java/com/gooddata/dataset/Uploads.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/Uploads.java similarity index 83% rename from src/main/java/com/gooddata/dataset/Uploads.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/Uploads.java index b11c569e6..1b44c8735 100644 --- a/src/main/java/com/gooddata/dataset/Uploads.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/Uploads.java @@ -1,15 +1,15 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.dataset; +package com.gooddata.sdk.model.dataset; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.util.Collection; @@ -20,7 +20,7 @@ @JsonTypeName("dataUploads") @JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) @JsonIgnoreProperties(ignoreUnknown = true) -class Uploads { +public class Uploads { private final Collection uploads; @@ -31,7 +31,7 @@ class Uploads { /** * @return all items of uploads collection */ - Collection items() { + public Collection items() { return uploads; } diff --git a/src/main/java/com/gooddata/dataset/UploadsInfo.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/UploadsInfo.java similarity index 85% rename from src/main/java/com/gooddata/dataset/UploadsInfo.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/UploadsInfo.java index f4109dac0..80b8dcdd8 100644 --- a/src/main/java/com/gooddata/dataset/UploadsInfo.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/dataset/UploadsInfo.java @@ -1,24 +1,23 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.dataset; - -import static com.gooddata.util.Validate.notEmpty; +package com.gooddata.sdk.model.dataset; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.md.Meta; -import com.gooddata.util.GoodDataToStringBuilder; -import org.springframework.web.util.UriTemplate; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.md.Meta; import java.util.Collection; import java.util.HashMap; import java.util.Map; +import static com.gooddata.sdk.common.util.Validate.notEmpty; + /** * Contains information about dataset uploads for every single dataset in the project. * For more about dataset uploads information, see {@link DataSet}. @@ -27,10 +26,9 @@ @JsonTypeName("dataSetsInfo") @JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) @JsonIgnoreProperties(ignoreUnknown = true) -class UploadsInfo { +public class UploadsInfo { - static final String URI = "/gdc/md/{projectId}/data/sets"; - static final UriTemplate URI_TEMPLATE = new UriTemplate(URI); + public static final String URI = "/gdc/md/{projectId}/data/sets"; private final Map datasets = new HashMap<>(); @@ -49,7 +47,7 @@ class UploadsInfo { * @param datasetId dataset identifier * @return {@link DataSet} object */ - DataSet getDataSet(String datasetId) { + public DataSet getDataSet(String datasetId) { notEmpty(datasetId, "datasetId"); final DataSet dataSet = datasets.get(datasetId); @@ -72,11 +70,11 @@ public String toString() { *

  • uri to all uploads for the given dataset
  • *
  • last upload
  • * - * + *

    * Deserialization only. */ @JsonIgnoreProperties(ignoreUnknown = true) - static class DataSet { + public static class DataSet { private final Meta meta; private final String datasetUploadsUri; @@ -94,21 +92,21 @@ private DataSet( /** * @return dataset identifier */ - String getDatasetId() { + public String getDatasetId() { return meta.getIdentifier(); } /** * @return URI for all uploads of this dataset */ - String getUploadsUri() { + public String getUploadsUri() { return datasetUploadsUri; } /** * @return {@link Upload} uri of the last upload */ - String getLastUploadUri() { + public String getLastUploadUri() { return lastUpload.uri; } diff --git a/src/main/java/com/gooddata/executeafm/Execution.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/Execution.java similarity index 84% rename from src/main/java/com/gooddata/executeafm/Execution.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/Execution.java index e9cf09748..807f94382 100644 --- a/src/main/java/com/gooddata/executeafm/Execution.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/Execution.java @@ -1,18 +1,18 @@ /* - * Copyright (C) 2007-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.executeafm; +package com.gooddata.sdk.model.executeafm; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.executeafm.afm.Afm; -import com.gooddata.executeafm.resultspec.ResultSpec; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.executeafm.afm.Afm; +import com.gooddata.sdk.model.executeafm.resultspec.ResultSpec; /** * Represents structure for triggering execution of contained AFM (Attributes Filters Metrics). diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/IdentifierObjQualifier.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/IdentifierObjQualifier.java new file mode 100644 index 000000000..52305268d --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/IdentifierObjQualifier.java @@ -0,0 +1,51 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.executeafm; + +import com.fasterxml.jackson.annotation.JsonRootName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.md.Obj; + +import java.io.Serializable; +import java.util.Objects; + +/** + * Qualifies metadata {@link Obj} using an identifier + */ +@JsonRootName("identifier") +public final class IdentifierObjQualifier implements ObjQualifier, Serializable { + + private static final long serialVersionUID = 4398691769334257408L; + private final String identifier; + + public IdentifierObjQualifier(final String identifier) { + this.identifier = identifier; + } + + @JsonValue + public String getIdentifier() { + return identifier; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + IdentifierObjQualifier that = (IdentifierObjQualifier) o; + return Objects.equals(identifier, that.identifier); + } + + @Override + public int hashCode() { + return Objects.hash(identifier); + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/LocalIdentifierQualifier.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/LocalIdentifierQualifier.java new file mode 100644 index 000000000..5a49c4dbc --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/LocalIdentifierQualifier.java @@ -0,0 +1,61 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.executeafm; + +import com.fasterxml.jackson.annotation.JsonRootName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; + +import java.io.Serializable; +import java.util.Objects; + +import static org.apache.commons.lang3.Validate.notNull; + +/** + * Qualifies AFM object using an local identifier + */ +@JsonRootName("localIdentifier") +public final class LocalIdentifierQualifier implements Qualifier, Serializable { + + private static final long serialVersionUID = -7856385638703759024L; + + private final String localIdentifier; + + /** + * Creates a new instance of {@link LocalIdentifierQualifier}. + * + * @param localIdentifier The local identifier value. + */ + public LocalIdentifierQualifier(final String localIdentifier) { + this.localIdentifier = notNull(localIdentifier, "localIdentifier"); + } + + /** + * @return local identifier value + */ + @JsonValue + public String getLocalIdentifier() { + return localIdentifier; + } + + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + final LocalIdentifierQualifier that = (LocalIdentifierQualifier) o; + return Objects.equals(localIdentifier, that.localIdentifier); + } + + @Override + public int hashCode() { + return Objects.hash(localIdentifier); + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/ObjQualifier.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/ObjQualifier.java new file mode 100644 index 000000000..8f125fab9 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/ObjQualifier.java @@ -0,0 +1,30 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.executeafm; + +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.gooddata.sdk.model.md.Obj; + +/** + * Qualifies metadata {@link Obj} + */ +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonSubTypes({ + @JsonSubTypes.Type(value = UriObjQualifier.class, name = "uri"), + @JsonSubTypes.Type(value = IdentifierObjQualifier.class, name = "identifier") +}) +public interface ObjQualifier extends Qualifier { + + /** + * Returns the qualifier in the form of uri. Default implementation throws {@link UnsupportedOperationException} + * + * @return uri qualifier + */ + default String getUri() { + throw new UnsupportedOperationException("This qualifier has no URI"); + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/Qualifier.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/Qualifier.java new file mode 100644 index 000000000..dda15d711 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/Qualifier.java @@ -0,0 +1,22 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.executeafm; + +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.gooddata.sdk.model.md.Obj; + +/** + * Qualifies metadata {@link Obj} or local AFM object + */ +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonSubTypes({ + @JsonSubTypes.Type(value = ObjQualifier.class), + @JsonSubTypes.Type(value = LocalIdentifierQualifier.class, name = "localIdentifier") +}) +public interface Qualifier { + +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/ResultPage.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/ResultPage.java new file mode 100644 index 000000000..1839ca11b --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/ResultPage.java @@ -0,0 +1,56 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.executeafm; + +import com.gooddata.sdk.model.executeafm.response.ExecutionResponse; +import com.gooddata.sdk.model.executeafm.result.ExecutionResult; + +import java.util.List; + +import static com.gooddata.sdk.common.util.Validate.notEmpty; +import static java.util.stream.Collectors.joining; + +/** + * Represents page of {@link ExecutionResult} to be requested, using + * {@link com.gooddata.sdk.executeafm.ExecuteAfmService#getResult(ExecutionResponse, ResultPage)} + */ +public class ResultPage { + + private final List offsets; + private final List limits; + + /** + * Creates new instance + * + * @param offsets list of page offsets + * @param limits list of page limits + */ + public ResultPage(final List offsets, final List limits) { + this.offsets = notEmpty(offsets, "offsets"); + this.limits = notEmpty(limits, "limits"); + if (offsets.size() != limits.size()) { + throw new IllegalArgumentException("Offsets and limits can't have different size."); + } + } + + private static String toQueryParam(final List list) { + return list.stream().map(String::valueOf).collect(joining("%2C")); + } + + /** + * @return page offsets joined and URL-encoded to be used as query parameter + */ + public String getOffsetsQueryParam() { + return toQueryParam(offsets); + } + + /** + * @return page limits joined and URL-encoded to be used as query parameter + */ + public String getLimitsQueryParam() { + return toQueryParam(limits); + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/UriObjQualifier.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/UriObjQualifier.java new file mode 100644 index 000000000..55944043e --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/UriObjQualifier.java @@ -0,0 +1,53 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.executeafm; + +import com.fasterxml.jackson.annotation.JsonRootName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.md.Obj; + +import java.io.Serializable; +import java.util.Objects; + +/** + * Qualifies metadata {@link Obj} using an URI + */ +@JsonRootName("uri") +public final class UriObjQualifier implements ObjQualifier, Serializable { + + private static final long serialVersionUID = 5505403156762360659L; + private final String uri; + + public UriObjQualifier(final String uri) { + this.uri = uri; + } + + @JsonValue + @Override + public String getUri() { + return uri; + } + + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (!(o instanceof UriObjQualifier)) return false; + + final UriObjQualifier that = (UriObjQualifier) o; + return Objects.equals(uri, that.uri); + } + + @Override + public int hashCode() { + return Objects.hash(uri); + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } +} diff --git a/src/main/java/com/gooddata/executeafm/VisualizationExecution.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/VisualizationExecution.java similarity index 82% rename from src/main/java/com/gooddata/executeafm/VisualizationExecution.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/VisualizationExecution.java index 5be7ddf1e..9ab1be7d6 100644 --- a/src/main/java/com/gooddata/executeafm/VisualizationExecution.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/VisualizationExecution.java @@ -1,21 +1,19 @@ /* - * Copyright (C) 2004-2018, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.executeafm; +package com.gooddata.sdk.model.executeafm; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.executeafm.afm.CompatibilityFilter; -import com.gooddata.executeafm.resultspec.ResultSpec; +import com.gooddata.sdk.model.executeafm.afm.filter.CompatibilityFilter; +import com.gooddata.sdk.model.executeafm.resultspec.ResultSpec; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; /** @@ -42,14 +40,14 @@ public VisualizationExecution(final String reference) { } /** - * @param reference reference uri to visualization object metadata - * @param filters additional filters which should be merged + * @param reference reference uri to visualization object metadata + * @param filters additional filters which should be merged * @param resultSpec result specification of executed viz. object */ @JsonCreator VisualizationExecution(@JsonProperty("reference") final String reference, - @JsonProperty("filters") final List filters, - @JsonProperty("resultSpec") final ResultSpec resultSpec) { + @JsonProperty("filters") final List filters, + @JsonProperty("resultSpec") final ResultSpec resultSpec) { this.reference = reference; this.resultSpec = resultSpec; this.filters = filters; @@ -67,13 +65,13 @@ public List getFilters() { } /** - * Sets the result specification and returns this instance + * Sets additional filters to this execution. * - * @param resultSpec result specification of executed viz. object + * @param filters additional filters * @return updated execution */ - public VisualizationExecution setResultSpec(final ResultSpec resultSpec) { - this.resultSpec = resultSpec; + public VisualizationExecution setFilters(final List filters) { + this.filters = filters; return this; } @@ -85,13 +83,13 @@ public ResultSpec getResultSpec() { } /** - * Sets additional filters to this execution. + * Sets the result specification and returns this instance * - * @param filters additional filters + * @param resultSpec result specification of executed viz. object * @return updated execution */ - public VisualizationExecution setFilters(final List filters) { - this.filters = filters; + public VisualizationExecution setResultSpec(final ResultSpec resultSpec) { + this.resultSpec = resultSpec; return this; } } diff --git a/src/main/java/com/gooddata/executeafm/afm/Afm.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/Afm.java similarity index 93% rename from src/main/java/com/gooddata/executeafm/afm/Afm.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/Afm.java index 308d55aef..4bd2bc35b 100644 --- a/src/main/java/com/gooddata/executeafm/afm/Afm.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/Afm.java @@ -1,22 +1,23 @@ /* - * Copyright (C) 2007-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.executeafm.afm; +package com.gooddata.sdk.model.executeafm.afm; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.executeafm.afm.filter.CompatibilityFilter; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.Optional; -import static com.gooddata.util.Validate.notNull; +import static com.gooddata.sdk.common.util.Validate.notNull; import static java.lang.String.format; /** @@ -44,8 +45,15 @@ public Afm(@JsonProperty("attributes") final List attributes, public Afm() { } + private static T getIdentifiable(final List toSearch, final String localIdentifier) { + return Optional.ofNullable(toSearch) + .flatMap(a -> a.stream().filter(i -> Objects.equals(localIdentifier, i.getLocalIdentifier())).findFirst()) + .orElseThrow(() -> new IllegalArgumentException(format("Item of localIdentifier=%s not found", localIdentifier))); + } + /** * Find {@link AttributeItem} within attributes by given localIdentifier + * * @param localIdentifier identifier used for search * @return found attribute or throws exception */ @@ -56,6 +64,7 @@ public AttributeItem getAttribute(final String localIdentifier) { /** * Find {@link MeasureItem} within measures by given localIdentifier + * * @param localIdentifier identifier used for search * @return found measure or throws exception */ @@ -133,10 +142,4 @@ public String toString() { return GoodDataToStringBuilder.defaultToString(this); } - private static T getIdentifiable(final List toSearch, final String localIdentifier) { - return Optional.ofNullable(toSearch) - .flatMap(a -> a.stream().filter(i -> Objects.equals(localIdentifier, i.getLocalIdentifier())).findFirst()) - .orElseThrow(() -> new IllegalArgumentException(format("Item of localIdentifier=%s not found", localIdentifier))); - } - } diff --git a/src/main/java/com/gooddata/executeafm/afm/Aggregation.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/Aggregation.java similarity index 80% rename from src/main/java/com/gooddata/executeafm/afm/Aggregation.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/Aggregation.java index 6b58d5973..e30c65bf0 100644 --- a/src/main/java/com/gooddata/executeafm/afm/Aggregation.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/Aggregation.java @@ -1,9 +1,9 @@ /* - * Copyright (C) 2007-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.executeafm.afm; +package com.gooddata.sdk.model.executeafm.afm; import com.fasterxml.jackson.annotation.JsonValue; diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/ArithmeticMeasureDefinition.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/ArithmeticMeasureDefinition.java new file mode 100644 index 000000000..77fa740c6 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/ArithmeticMeasureDefinition.java @@ -0,0 +1,90 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.executeafm.afm; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonRootName; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.executeafm.ObjQualifier; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +/** + * Arithmetic measure definition representing aggregation of existing measures, for example sum of measures, difference,... + */ +@JsonRootName(PreviousPeriodMeasureDefinition.NAME) +public class ArithmeticMeasureDefinition implements MeasureDefinition { + + static final String NAME = "arithmeticMeasure"; + private static final long serialVersionUID = -2597112924341600780L; + private final List measureIdentifiers; + private final String operator; + + /** + * Constructor of {@link ArithmeticMeasureDefinition} + * + * @param measureIdentifiers local identifiers of measures + * @param operator operator used for aggregation, for example sum, difference, multiplication, ratio, growth + */ + @JsonCreator + public ArithmeticMeasureDefinition( + @JsonProperty("measureIdentifiers") final List measureIdentifiers, + @JsonProperty("operator") final String operator) { + this.measureIdentifiers = measureIdentifiers; + this.operator = operator; + } + + /** + * no qualifiers are used, only local identifiers are used see {@link ArithmeticMeasureDefinition#getOperator()} + * + * @return empty set + */ + @Override + public Collection getObjQualifiers() { + return Collections.EMPTY_SET; //has no qualifiers + } + + /** + * no conversion is done, because this definition uses only local identifiers + * + * @return this instance + */ + @Override + public MeasureDefinition withObjUriQualifiers(ObjQualifierConverter objQualifierConverter) { + return this; //nothing to convert + } + + @Override + public boolean isAdHoc() { + return true; + } + + /** + * get local identifiers of used measures + * + * @return local identifiers of measure + */ + public List getMeasureIdentifiers() { + return measureIdentifiers; + } + + /** + * get used operator + * + * @return used operator + */ + public String getOperator() { + return operator; + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } +} diff --git a/src/main/java/com/gooddata/executeafm/afm/AttributeItem.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/AttributeItem.java similarity index 81% rename from src/main/java/com/gooddata/executeafm/afm/AttributeItem.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/AttributeItem.java index ba1e13ced..8f49bb864 100644 --- a/src/main/java/com/gooddata/executeafm/afm/AttributeItem.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/AttributeItem.java @@ -1,15 +1,16 @@ /* - * Copyright (C) 2007-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.executeafm.afm; +package com.gooddata.sdk.model.executeafm.afm; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import com.gooddata.executeafm.ObjQualifier; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.executeafm.ObjQualifier; +import com.gooddata.sdk.model.md.AttributeDisplayForm; import java.io.Serializable; import java.util.Objects; @@ -28,9 +29,10 @@ public class AttributeItem implements LocallyIdentifiable, Serializable { /** * Creates new instance - * @param displayForm qualifier of {@link com.gooddata.md.AttributeDisplayForm} representing the attribute + * + * @param displayForm qualifier of {@link AttributeDisplayForm} representing the attribute * @param localIdentifier local identifier, unique within {@link Afm} - * @param alias attribute alias + * @param alias attribute alias */ @JsonCreator public AttributeItem(@JsonProperty("displayForm") final ObjQualifier displayForm, @@ -43,7 +45,8 @@ public AttributeItem(@JsonProperty("displayForm") final ObjQualifier displayForm /** * Creates new instance - * @param displayForm qualifier of {@link com.gooddata.md.AttributeDisplayForm} representing the attribute + * + * @param displayForm qualifier of {@link AttributeDisplayForm} representing the attribute * @param localIdentifier local identifier, unique within {@link Afm} */ public AttributeItem(final ObjQualifier displayForm, final String localIdentifier) { @@ -57,7 +60,7 @@ public String getLocalIdentifier() { } /** - * @return qualifier of {@link com.gooddata.md.AttributeDisplayForm} representing the attribute + * @return qualifier of {@link AttributeDisplayForm} representing the attribute */ public ObjQualifier getDisplayForm() { return displayForm; @@ -72,6 +75,7 @@ public String getAlias() { /** * Sets attribute alias (used as header in result) + * * @param alias alias */ public void setAlias(final String alias) { diff --git a/src/main/java/com/gooddata/executeafm/afm/DerivedMeasureDefinition.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/DerivedMeasureDefinition.java similarity index 83% rename from src/main/java/com/gooddata/executeafm/afm/DerivedMeasureDefinition.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/DerivedMeasureDefinition.java index 5ca66998a..365b111da 100644 --- a/src/main/java/com/gooddata/executeafm/afm/DerivedMeasureDefinition.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/DerivedMeasureDefinition.java @@ -1,9 +1,9 @@ /* - * Copyright (C) 2007-2018, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.executeafm.afm; +package com.gooddata.sdk.model.executeafm.afm; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonSubTypes; @@ -11,11 +11,12 @@ import java.util.Objects; -import static com.gooddata.util.Validate.notNull; +import static com.gooddata.sdk.common.util.Validate.notNull; /** * The superclass of the {@link MeasureDefinition} classes that are derived from the master measure and have the identifier of the master measure. */ +@SuppressWarnings("deprecation") @JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) @JsonSubTypes({ @JsonSubTypes.Type(value = PopMeasureDefinition.class, name = PopMeasureDefinition.NAME), @@ -31,11 +32,8 @@ public abstract class DerivedMeasureDefinition implements MeasureDefinition { /** * Create a new instance of {@link DerivedMeasureDefinition}. * - * @param measureIdentifier - * The local identifier of the master measure this derived measure refers to. The parameter must not be null. - * - * @throws IllegalArgumentException - * Thrown when required parameter is null. + * @param measureIdentifier The local identifier of the master measure this derived measure refers to. The parameter must not be null. + * @throws IllegalArgumentException Thrown when required parameter is null. */ DerivedMeasureDefinition(final String measureIdentifier) { this.measureIdentifier = notNull(measureIdentifier, "measureIdentifier"); diff --git a/src/main/java/com/gooddata/executeafm/afm/LocallyIdentifiable.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/LocallyIdentifiable.java similarity index 78% rename from src/main/java/com/gooddata/executeafm/afm/LocallyIdentifiable.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/LocallyIdentifiable.java index 35fc366e5..5c556d91c 100644 --- a/src/main/java/com/gooddata/executeafm/afm/LocallyIdentifiable.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/LocallyIdentifiable.java @@ -1,9 +1,9 @@ /* - * Copyright (C) 2007-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.executeafm.afm; +package com.gooddata.sdk.model.executeafm.afm; /** * Marker interface for all locally identifiable objects having local identifier in AFM diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/MeasureDefinition.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/MeasureDefinition.java new file mode 100644 index 000000000..e48df6116 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/MeasureDefinition.java @@ -0,0 +1,76 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.executeafm.afm; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.gooddata.sdk.model.executeafm.IdentifierObjQualifier; +import com.gooddata.sdk.model.executeafm.ObjQualifier; +import com.gooddata.sdk.model.md.Metric; +import com.gooddata.sdk.model.md.visualization.VOPopMeasureDefinition; +import com.gooddata.sdk.model.md.visualization.VOSimpleMeasureDefinition; + +import java.io.Serializable; +import java.util.Collection; + +@SuppressWarnings("deprecation") +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonSubTypes({ + @JsonSubTypes.Type(value = SimpleMeasureDefinition.class, name = SimpleMeasureDefinition.NAME), + @JsonSubTypes.Type(value = PopMeasureDefinition.class, name = PopMeasureDefinition.NAME), + @JsonSubTypes.Type(value = VOSimpleMeasureDefinition.class, name = VOSimpleMeasureDefinition.NAME), + @JsonSubTypes.Type(value = VOPopMeasureDefinition.class, name = VOPopMeasureDefinition.NAME), + @JsonSubTypes.Type(value = OverPeriodMeasureDefinition.class, name = OverPeriodMeasureDefinition.NAME), + @JsonSubTypes.Type(value = PreviousPeriodMeasureDefinition.class, name = PreviousPeriodMeasureDefinition.NAME), + @JsonSubTypes.Type(value = ArithmeticMeasureDefinition.class, name = ArithmeticMeasureDefinition.NAME) +}) +public interface MeasureDefinition extends Serializable { + + /** + * Returns the definition in the form of uri of {@link Metric}. + * Default implementation throws {@link UnsupportedOperationException} + * + * @return uri of the measure + */ + @JsonIgnore + default String getUri() { + throw new UnsupportedOperationException("This definition has no URI"); + } + + /** + * Returns all the qualifiers used by the measure definition and its encapsulated objects. + *

    + * This information comes handy if it is necessary, for example, to convert the measure definition to use just the URI object qualifiers instead of the + * identifier object qualifiers. It can be used to gather these for a conversion service. + * + * @return all the qualifiers the measure definition uses, even in its encapsulated objects (apart from the measure filters) + */ + @JsonIgnore + Collection getObjQualifiers(); + + /** + * Copy itself using the given object qualifier converter in case when {@link IdentifierObjQualifier} instances are used in the object otherwise the + * original object is returned. + *

    + * The provided converter must be able to handle the conversion for the qualifiers that are of the {@link IdentifierObjQualifier} type that are used by + * this object or its encapsulated child objects. + * + * @param objQualifierConverter The function that converts identifier qualifiers to the matching URI qualifiers. In case when the object uses the identifier qualifiers, it + * will return a new copy of itself or its encapsulated objects that used URI qualifiers, otherwise the original object is returned. + * The parameter must not be null. + * @return copy of itself with replaced qualifiers in case when some {@link IdentifierObjQualifier} were used, otherwise original object is returned. + * @throws IllegalArgumentException The exception is thrown when conversion for the identifier qualifier used by this measure definition could not be made by the provided + * converter or when provided converter is null. + */ + MeasureDefinition withObjUriQualifiers(ObjQualifierConverter objQualifierConverter); + + /** + * @return true if this definition represents ad hoc specified measure, false otherwise + */ + @JsonIgnore + boolean isAdHoc(); +} diff --git a/src/main/java/com/gooddata/executeafm/afm/MeasureItem.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/MeasureItem.java similarity index 93% rename from src/main/java/com/gooddata/executeafm/afm/MeasureItem.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/MeasureItem.java index f536dfa8f..a22d2c914 100644 --- a/src/main/java/com/gooddata/executeafm/afm/MeasureItem.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/MeasureItem.java @@ -1,15 +1,15 @@ /* - * Copyright (C) 2007-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.executeafm.afm; +package com.gooddata.sdk.model.executeafm.afm; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.io.Serializable; import java.util.Objects; @@ -63,6 +63,7 @@ public String getAlias() { /** * Sets measure alias (will be used as header in result) + * * @param alias alias */ public void setAlias(final String alias) { @@ -78,6 +79,7 @@ public String getFormat() { /** * Sets measure format (used to format measure values in result) + * * @param format */ public void setFormat(final String format) { @@ -103,7 +105,7 @@ public boolean equals(Object o) { if (o == null || getClass() != o.getClass()) return false; MeasureItem that = (MeasureItem) o; return Objects.equals(definition, that.definition) && - Objects.equals(localIdentifier, that.localIdentifier); + Objects.equals(localIdentifier, that.localIdentifier); } @Override diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/NativeTotalItem.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/NativeTotalItem.java new file mode 100644 index 000000000..fdb5af35b --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/NativeTotalItem.java @@ -0,0 +1,60 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.executeafm.afm; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; + +import java.util.Collections; +import java.util.List; + +import static com.gooddata.sdk.common.util.Validate.notEmpty; + +/** + * Native total definition + */ +public class NativeTotalItem { + private final String measureIdentifier; + private final List attributeIdentifiers; + + /** + * Native total definition + * + * @param measureIdentifier measure on which is total defined + * @param attributeIdentifiers subset of internal attribute identifiers in AFM defining total placement + */ + @JsonCreator + public NativeTotalItem( + @JsonProperty("measureIdentifier") final String measureIdentifier, + @JsonProperty("attributeIdentifiers") final List attributeIdentifiers) { + this.measureIdentifier = notEmpty(measureIdentifier, "measureIdentifier"); + this.attributeIdentifiers = attributeIdentifiers == null ? Collections.emptyList() : attributeIdentifiers; + } + + /** + * internal identifier of measure in AFM, on which is total defined + * + * @return measure + */ + public String getMeasureIdentifier() { + return measureIdentifier; + } + + /** + * subset of internal attribute identifiers in AFM defining total placement + * + * @return list of identifiers (never null) + */ + public List getAttributeIdentifiers() { + return attributeIdentifiers; + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/ObjIdentifierUtilities.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/ObjIdentifierUtilities.java new file mode 100644 index 000000000..035a5243c --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/ObjIdentifierUtilities.java @@ -0,0 +1,67 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.executeafm.afm; + +import com.gooddata.sdk.model.executeafm.IdentifierObjQualifier; +import com.gooddata.sdk.model.executeafm.ObjQualifier; +import com.gooddata.sdk.model.executeafm.UriObjQualifier; + +import java.util.function.Function; + +import static com.gooddata.sdk.common.util.Validate.notNull; +import static java.lang.String.format; + +/** + * The utilities for conversion of the objects that use {@link IdentifierObjQualifier} to objects that use {@link UriObjQualifier}. + */ +abstract class ObjIdentifierUtilities { + + /** + * Copy {@code objectToBeCopied} via provided {@code objectCopyFactory} in case when {@code qualifierForPossibleConversion} is of {@link + * IdentifierObjQualifier} type. Otherwise the original object is returned. + * + * @param objectToBeCopied The object that should be copied in case {@code qualifierForPossibleConversion} is of {@link IdentifierObjQualifier} type. The parameter must + * not be null. + * @param qualifierForPossibleConversion The qualifier that defines if {@code objectToBeCopied} will be copied or not. In case when it is of the {@link IdentifierObjQualifier} type, + * it will be converted via {@code qualifierConverter} and used in copy of the {@code objectToBeCopied}. The parameter must not be null. + * @param objectCopyFactory The factory method that accepts the result of the {@code qualifierForPossibleConversion} conversion in form of {@link UriObjQualifier} and + * returns new copy of the {@code objectToBeCopied}. The parameter must not be null. + * @param qualifierConverter The convert that can convert {@code qualifierForPossibleConversion} into its matching {@link UriObjQualifier} form. The parameter must not be + * null. + * @param The type of the object that should be copied. + * @return Copy of the {@code objectToBeCopied} in case when {@code qualifierForPossibleConversion} was of {@link IdentifierObjQualifier} type. Otherwise + * the original object is returned. + * @throws IllegalArgumentException The exception is thrown when required parameter is null. + */ + static R copyIfNecessary(final R objectToBeCopied, + final ObjQualifier qualifierForPossibleConversion, + final Function objectCopyFactory, + final ObjQualifierConverter qualifierConverter) { + notNull(objectToBeCopied, "objectToBeCopied"); + notNull(qualifierForPossibleConversion, "qualifierForPossibleConversion"); + notNull(objectCopyFactory, "objectCopyFactory"); + notNull(qualifierConverter, "qualifierConverter"); + + if (qualifierForPossibleConversion instanceof IdentifierObjQualifier) { + final IdentifierObjQualifier identifierQualifierToConvert = (IdentifierObjQualifier) qualifierForPossibleConversion; + return copyWithUriQualifier(identifierQualifierToConvert, objectCopyFactory, qualifierConverter); + } + return objectToBeCopied; + } + + private static R copyWithUriQualifier(final IdentifierObjQualifier identifierQualifierToConvert, + final Function objectCopyFactory, + final ObjQualifierConverter qualifierConverter) { + return qualifierConverter.convertToUriQualifier(identifierQualifierToConvert) + .map(objectCopyFactory) + .orElseThrow(() -> buildExceptionForFailedConversion(identifierQualifierToConvert)); + } + + private static IllegalArgumentException buildExceptionForFailedConversion(final IdentifierObjQualifier qualifierFailedToConvert) { + return new IllegalArgumentException(format("Supplied converter does not provide conversion for '%s'!", qualifierFailedToConvert)); + } + +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/ObjQualifierConverter.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/ObjQualifierConverter.java new file mode 100644 index 000000000..4196d64fa --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/ObjQualifierConverter.java @@ -0,0 +1,26 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.executeafm.afm; + +import com.gooddata.sdk.model.executeafm.IdentifierObjQualifier; +import com.gooddata.sdk.model.executeafm.UriObjQualifier; + +import java.util.Optional; + +/** + * The interface of the function that converts {@link IdentifierObjQualifier} to the matching {@link UriObjQualifier}. + */ +@FunctionalInterface +public interface ObjQualifierConverter { + + /** + * Convert provided {@link IdentifierObjQualifier} to the matching {@link UriObjQualifier}. + * + * @param identifierObjQualifier The identifier that must be converted. + * @return The optional matching {@link UriObjQualifier} obtained by the conversion. + */ + Optional convertToUriQualifier(IdentifierObjQualifier identifierObjQualifier); +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/OverPeriodDateAttribute.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/OverPeriodDateAttribute.java new file mode 100644 index 000000000..4c45443fa --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/OverPeriodDateAttribute.java @@ -0,0 +1,82 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.executeafm.afm; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.executeafm.ObjQualifier; + +import java.io.Serializable; +import java.util.Objects; + +import static com.gooddata.sdk.common.util.Validate.notNull; + +/** + * Definition of the {@link OverPeriodMeasureDefinition} attribute. + */ +public class OverPeriodDateAttribute implements Serializable { + + private static final long serialVersionUID = 2311364644023464059L; + + private final ObjQualifier attribute; + private final Integer periodsAgo; + + /** + * Create a new instance of {@link OverPeriodDateAttribute}. + * + * @param attribute The {@link ObjQualifier} of the attribute from the date data set that defines the PoP period and date data set. The parameter must not be + * null. + * @param periodsAgo The number of periods defined by the {@code attribute} about which this period will be shifted about. The positive number shifts the period to + * the past, the negative to the future. The parameter must not be null. + * @throws IllegalArgumentException Thrown when one of the required parameter is null. + */ + @JsonCreator + public OverPeriodDateAttribute( + @JsonProperty("attribute") final ObjQualifier attribute, + @JsonProperty("periodsAgo") final Integer periodsAgo) { + this.attribute = notNull(attribute, "attribute"); + this.periodsAgo = notNull(periodsAgo, "periodsAgo"); + } + + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + final OverPeriodDateAttribute that = (OverPeriodDateAttribute) o; + return Objects.equals(attribute, that.attribute) && + Objects.equals(periodsAgo, that.periodsAgo); + } + + @Override + public int hashCode() { + return Objects.hash(attribute, periodsAgo); + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } + + /** + * The {@link ObjQualifier} of the attribute from the date data set that defines the PoP period. + * + * @return The date data set attribute that defines the PoP attribute. + */ + public ObjQualifier getAttribute() { + return attribute; + } + + /** + * The number of periods defined by the {@code attribute} about which this period will be shifted about. The positive number shifts the period to + * the past, the negative to the future. + * + * @return The number of periods the data will be shifted about. + */ + public Integer getPeriodsAgo() { + return periodsAgo; + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/OverPeriodMeasureDefinition.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/OverPeriodMeasureDefinition.java new file mode 100644 index 000000000..0b29a36b3 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/OverPeriodMeasureDefinition.java @@ -0,0 +1,113 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.executeafm.afm; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonRootName; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.executeafm.ObjQualifier; + +import java.util.Collection; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +import static com.gooddata.sdk.common.util.Validate.notEmpty; +import static com.gooddata.sdk.common.util.Validate.notNull; +import static com.gooddata.sdk.model.executeafm.afm.OverPeriodMeasureDefinition.NAME; + +/** + * Definition of the period over period measure that is used for the Same period last year and Same period 2 years back comparisons. + */ +@JsonRootName(NAME) +public class OverPeriodMeasureDefinition extends DerivedMeasureDefinition { + + static final String NAME = "overPeriodMeasure"; + private static final long serialVersionUID = -8904516814279504098L; + private final List dateAttributes; + + /** + * Create a new instance of {@link OverPeriodMeasureDefinition}. + * + * @param measureIdentifier The local identifier of the measure this PoP measure refers to. The parameter must not be null. + * @param dateAttributes The date attributes that defines how this measure will be shifted in time. The parameter must not be null. + * @throws IllegalArgumentException Thrown when {@code dateAttributes} list is empty or required parameter is null. + */ + @JsonCreator + public OverPeriodMeasureDefinition( + @JsonProperty("measureIdentifier") final String measureIdentifier, + @JsonProperty("dateAttributes") final List dateAttributes) { + super(measureIdentifier); + this.dateAttributes = notEmpty(dateAttributes, "dateAttributes"); + } + + @Override + public Collection getObjQualifiers() { + return this.dateAttributes.stream() + .map(OverPeriodDateAttribute::getAttribute) + .collect(Collectors.toSet()); + } + + @Override + public MeasureDefinition withObjUriQualifiers(final ObjQualifierConverter objQualifierConverter) { + notNull(objQualifierConverter, "objQualifierConverter"); + return new OverPeriodMeasureDefinition(measureIdentifier, copyAttributesWithUriQualifiers(objQualifierConverter)); + } + + private List copyAttributesWithUriQualifiers(final ObjQualifierConverter objQualifierConverter) { + return dateAttributes.stream() + .map(attribute -> copyWithUriQualifier(attribute, objQualifierConverter)) + .collect(Collectors.toList()); + } + + private OverPeriodDateAttribute copyWithUriQualifier(final OverPeriodDateAttribute attribute, final ObjQualifierConverter objQualifierConverter) { + return ObjIdentifierUtilities.copyIfNecessary( + attribute, + attribute.getAttribute(), + uriObjQualifier -> new OverPeriodDateAttribute(uriObjQualifier, attribute.getPeriodsAgo()), + objQualifierConverter + ); + } + + /** + * Determine if measure is ad-hoc, i.e., if it does not exist in the catalog and was created on fly. + * + * @return always true ({@link OverPeriodMeasureDefinition} is always ad-hoc) + */ + @Override + public boolean isAdHoc() { + return true; + } + + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + final OverPeriodMeasureDefinition that = (OverPeriodMeasureDefinition) o; + return Objects.equals(dateAttributes, that.dateAttributes); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), dateAttributes); + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } + + /** + * The date attributes that defines how this measure will be shifted in time. + * + * @return The list of date attributes. + */ + public List getDateAttributes() { + return dateAttributes; + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/PopMeasureDefinition.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/PopMeasureDefinition.java new file mode 100644 index 000000000..966618f1f --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/PopMeasureDefinition.java @@ -0,0 +1,99 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.executeafm.afm; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonRootName; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.executeafm.ObjQualifier; + +import java.util.Collection; +import java.util.Collections; +import java.util.Objects; + +import static com.gooddata.sdk.model.executeafm.afm.PopMeasureDefinition.NAME; + +/** + * Definition of so called "period over period" measure. + * + * @deprecated Use {@link OverPeriodMeasureDefinition} with {@link OverPeriodDateAttribute#getPeriodsAgo()} set to {@code 1} instead. + * Let's remove it once it's removed from API. + */ +@Deprecated +@JsonRootName(NAME) +@JsonInclude(JsonInclude.Include.NON_NULL) +public class PopMeasureDefinition extends DerivedMeasureDefinition { + + static final String NAME = "popMeasure"; + private static final long serialVersionUID = 1430640153994197345L; + private final ObjQualifier popAttribute; + + /** + * Creates new definition from given measure identifier referencing another measure in {@link Afm} and given attribute qualifier (should qualify date + * attribute) + * + * @param measureIdentifier measure identifier + * @param popAttribute "period over period" date attribute + */ + @JsonCreator + public PopMeasureDefinition(@JsonProperty("measureIdentifier") final String measureIdentifier, + @JsonProperty("popAttribute") final ObjQualifier popAttribute) { + super(measureIdentifier); + this.popAttribute = popAttribute; + } + + @Override + public MeasureDefinition withObjUriQualifiers(final ObjQualifierConverter objQualifierConverter) { + return ObjIdentifierUtilities.copyIfNecessary( + this, + popAttribute, + uriObjQualifier -> new PopMeasureDefinition(measureIdentifier, uriObjQualifier), + objQualifierConverter + ); + } + + /** + * Determine if measure is ad-hoc + * + * @return always true (PopMeasure is always ad-hoc) + */ + @Override + public boolean isAdHoc() { + return true; + } + + public ObjQualifier getPopAttribute() { + return popAttribute; + } + + @Override + public Collection getObjQualifiers() { + return popAttribute == null + ? Collections.emptySet() + : Collections.singleton(popAttribute); + } + + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + final PopMeasureDefinition that = (PopMeasureDefinition) o; + return Objects.equals(popAttribute, that.popAttribute); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), popAttribute); + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/PreviousPeriodDateDataSet.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/PreviousPeriodDateDataSet.java new file mode 100644 index 000000000..c00744557 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/PreviousPeriodDateDataSet.java @@ -0,0 +1,82 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.executeafm.afm; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.executeafm.ObjQualifier; +import com.gooddata.sdk.model.executeafm.afm.filter.DateFilter; + +import java.io.Serializable; +import java.util.Objects; + +import static com.gooddata.sdk.common.util.Validate.notNull; + +/** + * Definition of the {@link PreviousPeriodMeasureDefinition} data set. + */ +public class PreviousPeriodDateDataSet implements Serializable { + + private static final long serialVersionUID = 2311364644023464059L; + + private final ObjQualifier dataSet; + private final Integer periodsAgo; + + /** + * Create a new instance of {@link PreviousPeriodDateDataSet}. + * + * @param dataSet The {@link ObjQualifier} of the data set that match one of the {@link DateFilter} in the execution. The parameter must not be null. + * @param periodsAgo The number of periods defined by the matching date filter which this period will be shifted about. The positive number shifts the period to + * the past, the negative to the future. The parameter must not be null. + * @throws IllegalArgumentException Thrown when one of the required parameter is null. + */ + @JsonCreator + public PreviousPeriodDateDataSet( + @JsonProperty("dataSet") final ObjQualifier dataSet, + @JsonProperty("periodsAgo") final Integer periodsAgo) { + this.dataSet = notNull(dataSet, "dataSet"); + this.periodsAgo = notNull(periodsAgo, "periodsAgo"); + } + + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + final PreviousPeriodDateDataSet that = (PreviousPeriodDateDataSet) o; + return Objects.equals(dataSet, that.dataSet) && + Objects.equals(periodsAgo, that.periodsAgo); + } + + @Override + public int hashCode() { + return Objects.hash(dataSet, periodsAgo); + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } + + /** + * The {@link ObjQualifier} of the data set that match one of the {@link DateFilter} in the execution. + * + * @return The data set for matching of the AFM filter. + */ + public ObjQualifier getDataSet() { + return dataSet; + } + + /** + * The number of periods defined by the matching date filter which this period will be shifted about. The positive number shifts the period to + * the past, the negative to the future. + * + * @return The number of periods the data will be shifted about. + */ + public Integer getPeriodsAgo() { + return periodsAgo; + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/PreviousPeriodMeasureDefinition.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/PreviousPeriodMeasureDefinition.java new file mode 100644 index 000000000..096cb8be1 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/PreviousPeriodMeasureDefinition.java @@ -0,0 +1,113 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.executeafm.afm; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonRootName; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.executeafm.ObjQualifier; + +import java.util.Collection; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +import static com.gooddata.sdk.common.util.Validate.notEmpty; +import static com.gooddata.sdk.common.util.Validate.notNull; +import static com.gooddata.sdk.model.executeafm.afm.PreviousPeriodMeasureDefinition.NAME; + +/** + * Definition of the period over period measure that is used for the Previous period comparison. + */ +@JsonRootName(NAME) +public class PreviousPeriodMeasureDefinition extends DerivedMeasureDefinition { + + static final String NAME = "previousPeriodMeasure"; + private static final long serialVersionUID = -4741355657671354062L; + private final List dateDataSets; + + /** + * Create a new instance of {@link PreviousPeriodMeasureDefinition}. + * + * @param measureIdentifier The local identifier of the measure this PoP measure refers to. The parameter must not be null. + * @param dateDataSets The date data sets that defines how this measure will be shifted in time. The parameter must not be null. + * @throws IllegalArgumentException Thrown when {@code attributes} list is empty or required parameter is null. + */ + @JsonCreator + public PreviousPeriodMeasureDefinition( + @JsonProperty("measureIdentifier") final String measureIdentifier, + @JsonProperty("dateDataSets") final List dateDataSets) { + super(measureIdentifier); + this.dateDataSets = notEmpty(dateDataSets, "dateDataSets"); + } + + @Override + public Collection getObjQualifiers() { + return this.dateDataSets.stream() + .map(PreviousPeriodDateDataSet::getDataSet) + .collect(Collectors.toSet()); + } + + @Override + public MeasureDefinition withObjUriQualifiers(final ObjQualifierConverter objQualifierConverter) { + notNull(objQualifierConverter, "objQualifierConverter"); + return new PreviousPeriodMeasureDefinition(measureIdentifier, copyDataSetsWithUriQualifiers(objQualifierConverter)); + } + + private List copyDataSetsWithUriQualifiers(final ObjQualifierConverter objQualifierConverter) { + return dateDataSets.stream() + .map(dataSet -> copyWithUriQualifier(dataSet, objQualifierConverter)) + .collect(Collectors.toList()); + } + + private PreviousPeriodDateDataSet copyWithUriQualifier(final PreviousPeriodDateDataSet dataSet, final ObjQualifierConverter objQualifierConverter) { + return ObjIdentifierUtilities.copyIfNecessary( + dataSet, + dataSet.getDataSet(), + uriObjQualifier -> new PreviousPeriodDateDataSet(uriObjQualifier, dataSet.getPeriodsAgo()), + objQualifierConverter + ); + } + + /** + * Determine if measure is ad-hoc, i.e., if it does not exist in the catalog and was created on fly. + * + * @return always true ({@link PreviousPeriodMeasureDefinition} is always ad-hoc) + */ + @Override + public boolean isAdHoc() { + return true; + } + + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + final PreviousPeriodMeasureDefinition that = (PreviousPeriodMeasureDefinition) o; + return Objects.equals(dateDataSets, that.dateDataSets); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), dateDataSets); + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } + + /** + * The date data sets that defines how this measure will be shifted in time. + * + * @return The list of date data sets. + */ + public List getDateDataSets() { + return dateDataSets; + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/SimpleMeasureDefinition.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/SimpleMeasureDefinition.java new file mode 100644 index 000000000..23eefe764 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/SimpleMeasureDefinition.java @@ -0,0 +1,233 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.executeafm.afm; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonRootName; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.executeafm.ObjQualifier; +import com.gooddata.sdk.model.executeafm.afm.filter.FilterItem; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +import static com.gooddata.sdk.common.util.Validate.notNull; +import static com.gooddata.sdk.model.executeafm.afm.SimpleMeasureDefinition.NAME; +import static java.util.Arrays.asList; + +/** + * Definition of simple measure + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonRootName(NAME) +public class SimpleMeasureDefinition implements MeasureDefinition { + + static final String NAME = "measure"; + private static final long serialVersionUID = -385490772711914776L; + private final ObjQualifier item; + private String aggregation; + private Boolean computeRatio; + private List filters; + + public SimpleMeasureDefinition(final ObjQualifier item) { + this.item = item; + } + + /** + * Creates new definition + * + * @param item item which is measured, can be attribute, fact or another measure + * @param aggregation additional aggregation applied + * @param computeRatio whether should be shown as ratio + * @param filters additional filters applied + */ + @JsonCreator + public SimpleMeasureDefinition(@JsonProperty("item") final ObjQualifier item, + @JsonProperty("aggregation") final String aggregation, + @JsonProperty("computeRatio") final Boolean computeRatio, + @JsonProperty("filters") final List filters) { + this.item = item; + this.aggregation = aggregation; + this.computeRatio = computeRatio; + this.filters = filters; + } + + /** + * Creates new definition + * + * @param item item which is measured, can be attribute, fact or another measure + * @param aggregation additional aggregation applied + * @param computeRatio whether should be shown as ratio + * @param filters additional filters applied + */ + public SimpleMeasureDefinition(final ObjQualifier item, final Aggregation aggregation, final Boolean computeRatio, + final List filters) { + this(item, notNull(aggregation, "aggregation").toString(), computeRatio, filters); + } + + /** + * Creates new definition + * + * @param item item which is measured, can be attribute, fact or another measure + * @param aggregation additional aggregation applied + * @param computeRatio whether should be shown as ratio + * @param filters additional filters applied + */ + public SimpleMeasureDefinition(final ObjQualifier item, final Aggregation aggregation, final Boolean computeRatio, final FilterItem... filters) { + this(item, aggregation, computeRatio, asList(filters)); + } + + @Override + public MeasureDefinition withObjUriQualifiers(final ObjQualifierConverter objQualifierConverter) { + return ObjIdentifierUtilities.copyIfNecessary( + this, + item, + uriObjQualifier -> new SimpleMeasureDefinition(uriObjQualifier, aggregation, computeRatio, filters), + objQualifierConverter + ); + } + + @Override + public boolean isAdHoc() { + return hasAggregation() || hasComputeRatio() || hasFilters(); + } + + @Override + public String getUri() { + return getItem().getUri(); + } + + @Override + public Collection getObjQualifiers() { + return item == null + ? Collections.emptySet() + : Collections.singleton(item); + } + + /** + * @return measured item, can be attribute, fact or another measure + */ + public ObjQualifier getItem() { + return item; + } + + /** + * @return additional aggregation applied + */ + public String getAggregation() { + return aggregation; + } + + /** + * Set additional aggregation applied + * + * @param aggregation additional aggregation applied + */ + public void setAggregation(final String aggregation) { + this.aggregation = aggregation; + } + + /** + * Set additional aggregation applied + * + * @param aggregation additional aggregation applied + */ + public void setAggregation(final Aggregation aggregation) { + setAggregation(notNull(aggregation, "aggregation").toString()); + } + + /** + * @return true when should be shown as ratio, false otherwise + */ + public Boolean getComputeRatio() { + return computeRatio; + } + + /** + * Set whether should be shown as ratio + * + * @param computeRatio whether should be shown as ratio + */ + public void setComputeRatio(final Boolean computeRatio) { + this.computeRatio = computeRatio; + } + + /** + * @return additional filters applied + */ + public List getFilters() { + return filters; + } + + /** + * Set additional filters applied + * + * @param filters additional filters applied + */ + public void setFilters(final List filters) { + this.filters = filters; + } + + /** + * Apply additional filter + * + * @param filter filter to be applied + */ + public void addFilter(final FilterItem filter) { + if (filters == null) { + filters = new ArrayList<>(); + } + filters.add(notNull(filter, "filter")); + } + + /** + * @return true when filters are set, false otherwise + */ + public boolean hasFilters() { + return filters != null && !filters.isEmpty(); + } + + /** + * @return true when computeRatio is set, false otherwise + */ + public boolean hasComputeRatio() { + return computeRatio != null && computeRatio; + } + + /** + * @return true when additional aggregation is set, false otherwise + */ + public boolean hasAggregation() { + return aggregation != null; + } + + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + final SimpleMeasureDefinition that = (SimpleMeasureDefinition) o; + return Objects.equals(item, that.item) && + Objects.equals(aggregation, that.aggregation) && + Objects.equals(computeRatio, that.computeRatio) && + Objects.equals(filters, that.filters); + } + + @Override + public int hashCode() { + return Objects.hash(item, aggregation, computeRatio, filters); + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } +} + diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/AbsoluteDateFilter.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/AbsoluteDateFilter.java new file mode 100644 index 000000000..2e6d87022 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/AbsoluteDateFilter.java @@ -0,0 +1,91 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.executeafm.afm.filter; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonRootName; +import com.gooddata.sdk.common.util.GDLocalDate; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.executeafm.ObjQualifier; +import com.gooddata.sdk.model.executeafm.UriObjQualifier; + +import java.time.LocalDate; +import java.util.Objects; + +/** + * Represents {@link DateFilter} specifying exact from and to dates. + */ +@JsonRootName(AbsoluteDateFilter.NAME) +public class AbsoluteDateFilter extends DateFilter { + + static final String NAME = "absoluteDateFilter"; + private static final long serialVersionUID = -1857726227400504182L; + @GDLocalDate + private final LocalDate from; + @GDLocalDate + private final LocalDate to; + + /** + * Creates new filter instance + * + * @param dataSet qualifier of date dimension dataset + * @param from date from + * @param to date to + */ + @JsonCreator + public AbsoluteDateFilter(@JsonProperty("dataSet") final ObjQualifier dataSet, + @JsonProperty("from") final LocalDate from, + @JsonProperty("to") final LocalDate to) { + super(dataSet); + this.from = from; + this.to = to; + } + + /** + * @return date from + */ + public LocalDate getFrom() { + return from; + } + + /** + * @return date to + */ + public LocalDate getTo() { + return to; + } + + @Override + public FilterItem withObjUriQualifier(final UriObjQualifier qualifier) { + return new AbsoluteDateFilter(qualifier, from, to); + } + + @Override + @JsonIgnore + public boolean isAllTimeSelected() { + return getFrom() == null || getTo() == null; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + AbsoluteDateFilter that = (AbsoluteDateFilter) o; + return super.equals(that) && Objects.equals(from, that.from) && Objects.equals(to, that.to); + } + + @Override + public int hashCode() { + return Objects.hash(from, to, super.hashCode()); + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } +} diff --git a/src/main/java/com/gooddata/executeafm/afm/AttributeFilter.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/AttributeFilter.java similarity index 86% rename from src/main/java/com/gooddata/executeafm/afm/AttributeFilter.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/AttributeFilter.java index 2f8185ebe..8edd5ff31 100644 --- a/src/main/java/com/gooddata/executeafm/afm/AttributeFilter.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/AttributeFilter.java @@ -1,16 +1,16 @@ /* - * Copyright (C) 2007-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.executeafm.afm; +package com.gooddata.sdk.model.executeafm.afm.filter; -import com.gooddata.executeafm.ObjQualifier; +import com.gooddata.sdk.model.executeafm.ObjQualifier; import java.io.Serializable; import java.util.Objects; -import static com.gooddata.util.Validate.notNull; +import static com.gooddata.sdk.common.util.Validate.notNull; /** * Represents filter by attribute. @@ -22,6 +22,7 @@ public abstract class AttributeFilter implements FilterItem, Serializable { /** * Creates new filter + * * @param displayForm qualifier of attribute's display form to be filtered */ AttributeFilter(final ObjQualifier displayForm) { diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/AttributeFilterElements.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/AttributeFilterElements.java new file mode 100644 index 000000000..1f01f6e81 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/AttributeFilterElements.java @@ -0,0 +1,88 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.executeafm.afm.filter; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +import java.io.IOException; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; + +import static com.fasterxml.jackson.databind.JsonMappingException.from; + +/** + * Represents elements, which can be used as value of "in" or "notIn" by {@link AttributeFilter}. + */ +@JsonSerialize(using = AttributeFilterElements.Serializer.class) +@JsonDeserialize(using = AttributeFilterElements.Deserializer.class) +public interface AttributeFilterElements { + + /** + * Elements the filter refers to. + * + * @return filter elements. + */ + List getElements(); + + class Serializer extends JsonSerializer { + + private static void serializeWrapped(String name, AttributeFilterElements elements, JsonGenerator jg, SerializerProvider serializerProvider) throws IOException { + jg.writeStartObject(); + serializerProvider.defaultSerializeField(name, elements.getElements(), jg); + jg.writeEndObject(); + } + + @Override + public void serialize(AttributeFilterElements elements, JsonGenerator jg, SerializerProvider serializerProvider) throws IOException { + if (elements instanceof UriAttributeFilterElements) { + serializeWrapped(UriAttributeFilterElements.NAME, elements, jg, serializerProvider); + } else if (elements instanceof ValueAttributeFilterElements) { + serializeWrapped(ValueAttributeFilterElements.NAME, elements, jg, serializerProvider); + } else { + serializerProvider.defaultSerializeValue(elements.getElements(), jg); + } + } + } + + class Deserializer extends JsonDeserializer { + + private static List nodeToElements(JsonNode node) { + return StreamSupport.stream(node.spliterator(), false).map(JsonNode::textValue).collect(Collectors.toList()); + } + + @Override + public AttributeFilterElements deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { + final JsonNode node = jp.readValueAsTree(); + switch (node.getNodeType()) { + case ARRAY: + return new UriAttributeFilterElements(nodeToElements(node)); + case OBJECT: + final JsonNode uris = node.findValue(UriAttributeFilterElements.NAME); + if (uris != null) { + return new UriAttributeFilterElements(nodeToElements(uris)); + } + final JsonNode values = node.findValue(ValueAttributeFilterElements.NAME); + if (values != null) { + return new ValueAttributeFilterElements(nodeToElements(values)); + } + throw from(jp, "Unknown type of AttributeFilterElements"); + default: + throw from(jp, "Unknown value of type: " + jp.currentToken()); + } + } + } + + +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/ComparisonCondition.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/ComparisonCondition.java new file mode 100644 index 000000000..1de8df6f2 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/ComparisonCondition.java @@ -0,0 +1,111 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.executeafm.afm.filter; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonRootName; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Objects; + +import static org.apache.commons.lang3.Validate.notNull; + +/** + * Condition of {@link MeasureValueFilter} that compares measure values against a single value. + */ +@JsonRootName(ComparisonCondition.NAME) +public class ComparisonCondition extends MeasureValueFilterCondition implements Serializable { + + static final String NAME = "comparison"; + + private static final long serialVersionUID = 2944349621407799356L; + + private final String operator; + private final BigDecimal value; + + @JsonCreator + public ComparisonCondition( + @JsonProperty("operator") final String operator, + @JsonProperty("value") final BigDecimal value, + @JsonProperty("treatNullValuesAs") final BigDecimal treatNullValuesAs + ) { + super(treatNullValuesAs); + this.operator = notNull(operator, "operator"); + this.value = notNull(value, "value"); + } + + /** + * Creates a new {@link ComparisonCondition} instance. + * + * @param operator The operator of the condition . + * @param value The value of the condition. + */ + public ComparisonCondition( + final ComparisonConditionOperator operator, + final BigDecimal value + ) { + this(notNull(operator, "operator").toString(), value, null); + } + + /** + * Creates a new {@link ComparisonCondition} instance. + * + * @param operator The operator of the condition . + * @param value The value of the condition. + * @param treatNullValuesAs The number that will be used instead of compared values that are null. + */ + public ComparisonCondition( + final ComparisonConditionOperator operator, + final BigDecimal value, + final BigDecimal treatNullValuesAs + ) { + this(notNull(operator, "operator").toString(), value, treatNullValuesAs); + } + + /** + * @return comparison condition operator + */ + @JsonIgnore + public ComparisonConditionOperator getOperator() { + return ComparisonConditionOperator.of(operator); + } + + @JsonProperty("operator") + public String getStringOperator() { + return this.operator; + } + + /** + * @return comparison condition value + */ + public BigDecimal getValue() { + return value; + } + + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + final ComparisonCondition that = (ComparisonCondition) o; + return Objects.equals(operator, that.operator) && + Objects.equals(value, that.value); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), operator, value); + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/ComparisonConditionOperator.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/ComparisonConditionOperator.java new file mode 100644 index 000000000..76a223612 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/ComparisonConditionOperator.java @@ -0,0 +1,45 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.executeafm.afm.filter; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import static com.gooddata.sdk.common.util.Validate.notNull; +import static java.lang.String.format; +import static java.util.Arrays.stream; +import static java.util.stream.Collectors.joining; + +/** + * Represents all the possible operators of {@link ComparisonCondition} + */ +public enum ComparisonConditionOperator { + GREATER_THAN, + GREATER_THAN_OR_EQUAL_TO, + LESS_THAN, + LESS_THAN_OR_EQUAL_TO, + EQUAL_TO, + NOT_EQUAL_TO; + + @JsonCreator + public static ComparisonConditionOperator of(String operator) { + notNull(operator, "operator"); + try { + return ComparisonConditionOperator.valueOf(operator); + } catch (IllegalArgumentException e) { + throw new UnsupportedOperationException( + format("Unknown value for comparison condition operator: \"%s\", supported values are: [%s]", + operator, stream(ComparisonConditionOperator.values()).map(Enum::name).collect(joining(","))), + e); + } + } + + @JsonValue + @Override + public String toString() { + return name(); + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/CompatibilityFilter.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/CompatibilityFilter.java new file mode 100644 index 000000000..fc1596f8a --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/CompatibilityFilter.java @@ -0,0 +1,20 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.executeafm.afm.filter; + +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; + +/** + * Covers all the AFM execution filters including the "deprecated" ones. + */ +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonSubTypes({ + @JsonSubTypes.Type(value = ExpressionFilter.class, name = ExpressionFilter.NAME), + @JsonSubTypes.Type(value = ExtendedFilter.class), +}) +public interface CompatibilityFilter { +} diff --git a/src/main/java/com/gooddata/executeafm/afm/DateFilter.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/DateFilter.java similarity index 87% rename from src/main/java/com/gooddata/executeafm/afm/DateFilter.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/DateFilter.java index 3d33dd23c..84b9e5e52 100644 --- a/src/main/java/com/gooddata/executeafm/afm/DateFilter.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/DateFilter.java @@ -1,18 +1,18 @@ /* - * Copyright (C) 2007-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.executeafm.afm; +package com.gooddata.sdk.model.executeafm.afm.filter; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import com.gooddata.executeafm.ObjQualifier; +import com.gooddata.sdk.model.executeafm.ObjQualifier; import java.io.Serializable; import java.util.Objects; -import static com.gooddata.util.Validate.notNull; +import static com.gooddata.sdk.common.util.Validate.notNull; /** * Represents filter by date. @@ -25,6 +25,7 @@ public abstract class DateFilter implements FilterItem, Serializable { /** * Creates new filter + * * @param dataSet qualifier of date dimension dataSet */ DateFilter(final ObjQualifier dataSet) { diff --git a/src/main/java/com/gooddata/executeafm/afm/ExpressionFilter.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/ExpressionFilter.java similarity index 89% rename from src/main/java/com/gooddata/executeafm/afm/ExpressionFilter.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/ExpressionFilter.java index 615fa3b04..df8b94969 100644 --- a/src/main/java/com/gooddata/executeafm/afm/ExpressionFilter.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/ExpressionFilter.java @@ -1,14 +1,14 @@ /* - * Copyright (C) 2007-2018, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.executeafm.afm; +package com.gooddata.sdk.model.executeafm.afm.filter; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonRootName; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.util.Objects; @@ -22,6 +22,7 @@ public final class ExpressionFilter implements CompatibilityFilter { /** * Creates new instance + * * @param value expression value */ @JsonCreator diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/ExtendedFilter.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/ExtendedFilter.java new file mode 100644 index 000000000..ea0726cc4 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/ExtendedFilter.java @@ -0,0 +1,18 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.executeafm.afm.filter; + +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; + +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonSubTypes({ + @JsonSubTypes.Type(value = FilterItem.class), + @JsonSubTypes.Type(value = MeasureValueFilter.class, name = MeasureValueFilter.NAME), + @JsonSubTypes.Type(value = RankingFilter.class, name = RankingFilter.NAME), +}) +public interface ExtendedFilter { +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/FilterItem.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/FilterItem.java new file mode 100644 index 000000000..be2525a0b --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/FilterItem.java @@ -0,0 +1,41 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.executeafm.afm.filter; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.gooddata.sdk.model.executeafm.ObjQualifier; +import com.gooddata.sdk.model.executeafm.UriObjQualifier; +import com.gooddata.sdk.model.md.Obj; + +/** + * Covers all the filters which can be used within AFM + */ +@JsonSubTypes({ + @JsonSubTypes.Type(value = PositiveAttributeFilter.class, name = PositiveAttributeFilter.NAME), + @JsonSubTypes.Type(value = NegativeAttributeFilter.class, name = NegativeAttributeFilter.NAME), + @JsonSubTypes.Type(value = AbsoluteDateFilter.class, name = AbsoluteDateFilter.NAME), + @JsonSubTypes.Type(value = RelativeDateFilter.class, name = RelativeDateFilter.NAME) +}) +public interface FilterItem extends CompatibilityFilter, ExtendedFilter { + + + /** + * Get qualifier of {@link Obj} to which the filter relates. + * + * @return filtered object qualifier + */ + @JsonIgnore + ObjQualifier getObjQualifier(); + + /** + * Copy itself using given uri qualifier + * + * @param qualifier qualifier to use for the new filter + * @return self copy with given qualifier + */ + FilterItem withObjUriQualifier(UriObjQualifier qualifier); +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/MeasureValueFilter.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/MeasureValueFilter.java new file mode 100644 index 000000000..e42ef87aa --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/MeasureValueFilter.java @@ -0,0 +1,101 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.executeafm.afm.filter; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonRootName; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.executeafm.Qualifier; +import com.gooddata.sdk.model.executeafm.UriObjQualifier; + +import java.io.Serializable; +import java.util.Objects; + +import static org.apache.commons.lang3.Validate.notNull; + +/** + * Represents measure value filter applied on an insight. + */ +@JsonRootName(MeasureValueFilter.NAME) +@JsonInclude(JsonInclude.Include.NON_NULL) +public class MeasureValueFilter implements ExtendedFilter, CompatibilityFilter, Serializable { + + public static final String NAME = "measureValueFilter"; + + private static final long serialVersionUID = -3038654904981929337L; + + private final Qualifier measure; + private final MeasureValueFilterCondition condition; + + /** + * Creates a new {@link MeasureValueFilter} instance without specified condition {@link MeasureValueFilterCondition} + * It represents use-case with not active filter in insight which could be modified later. + * + * @param measure The qualifier of referenced measure. + */ + public MeasureValueFilter(final Qualifier measure) { + this(measure, null); + } + + /** + * Creates a new {@link MeasureValueFilter} instance. + * + * @param measure The qualifier of referenced measure. + * @param condition The condition applied to a sliced measure value. (Optional) + */ + @JsonCreator + public MeasureValueFilter( + @JsonProperty("measure") final Qualifier measure, + @JsonProperty("condition") final MeasureValueFilterCondition condition) { + this.measure = notNull(measure, "measure"); + this.condition = condition; + } + + /** + * Copy itself using given uri qualifier + * + * @param qualifier qualifier to use for the new filter + * @return self copy with given qualifier + */ + public MeasureValueFilter withUriObjQualifier(final UriObjQualifier qualifier) { + return new MeasureValueFilter(qualifier, this.condition); + } + + /** + * @return qualifier of referenced measure + */ + public Qualifier getMeasure() { + return measure; + } + + /** + * @return condition applied to a sliced measure value + */ + public MeasureValueFilterCondition getCondition() { + return condition; + } + + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + final MeasureValueFilter that = (MeasureValueFilter) o; + return Objects.equals(measure, that.measure) && + Objects.equals(condition, that.condition); + } + + @Override + public int hashCode() { + return Objects.hash(measure, condition); + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/MeasureValueFilterCondition.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/MeasureValueFilterCondition.java new file mode 100644 index 000000000..43aa9d4f8 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/MeasureValueFilterCondition.java @@ -0,0 +1,55 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.executeafm.afm.filter; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Objects; + +/** + * Covers all the conditions that can be used within {@link MeasureValueFilter}. + *

    + * Contains shared functionality to set a custom value instead of {@code null} measure + * values against the condition's value will be compared to. + */ +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonSubTypes({ + @JsonSubTypes.Type(value = ComparisonCondition.class, name = ComparisonCondition.NAME), + @JsonSubTypes.Type(value = RangeCondition.class, name = RangeCondition.NAME) +}) +@JsonInclude(JsonInclude.Include.NON_NULL) +public abstract class MeasureValueFilterCondition implements Serializable { + private static final long serialVersionUID = 7845069496955848265L; + + private final BigDecimal treatNullValuesAs; + + public MeasureValueFilterCondition(final BigDecimal treatNullValuesAs) { + this.treatNullValuesAs = treatNullValuesAs; + } + + @JsonProperty + public BigDecimal getTreatNullValuesAs() { + return treatNullValuesAs; + } + + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + final MeasureValueFilterCondition that = (MeasureValueFilterCondition) o; + return Objects.equals(treatNullValuesAs, that.treatNullValuesAs); + } + + @Override + public int hashCode() { + return Objects.hash(treatNullValuesAs); + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/NegativeAttributeFilter.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/NegativeAttributeFilter.java new file mode 100644 index 000000000..909c66d4f --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/NegativeAttributeFilter.java @@ -0,0 +1,103 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.executeafm.afm.filter; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonRootName; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.executeafm.ObjQualifier; +import com.gooddata.sdk.model.executeafm.UriObjQualifier; + +import java.util.List; +import java.util.Objects; + +import static java.util.Arrays.asList; + +/** + * Filter of attribute filtering by NOT IN expression + */ +@JsonRootName(NegativeAttributeFilter.NAME) +public class NegativeAttributeFilter extends AttributeFilter { + + static final String NAME = "negativeAttributeFilter"; + private static final long serialVersionUID = -6202625318104289333L; + private final AttributeFilterElements notIn; + + /** + * Creates new instance of given display form and not in list + * + * @param displayForm display form + * @param notIn list of not in elements + * @deprecated for compatibility with version 2.x only, use {@link #NegativeAttributeFilter(ObjQualifier, AttributeFilterElements)} instead + */ + @Deprecated + public NegativeAttributeFilter(@JsonProperty("displayForm") final ObjQualifier displayForm, + @JsonProperty("notIn") final List notIn) { + this(displayForm, new SimpleAttributeFilterElements(notIn)); + } + + /** + * Creates new instance of given display form and not in list + * + * @param displayForm display form + * @param notIn not in elements (uris or values) + */ + @JsonCreator + public NegativeAttributeFilter(@JsonProperty("displayForm") final ObjQualifier displayForm, + @JsonProperty("notIn") final AttributeFilterElements notIn) { + super(displayForm); + this.notIn = notIn; + } + + /** + * @deprecated for compatibility with version 2.x only, use {@link #NegativeAttributeFilter(ObjQualifier, AttributeFilterElements)} instead + */ + @Deprecated + public NegativeAttributeFilter(final ObjQualifier displayForm, final String... notIn) { + this(displayForm, asList(notIn)); + } + + /** + * @return not in elements + */ + public AttributeFilterElements getNotIn() { + return notIn; + } + + /** + * @return true if filter contains no elements, false otherwise + */ + @JsonIgnore + public boolean isAllSelected() { + return notIn.getElements().isEmpty(); + } + + @Override + public FilterItem withObjUriQualifier(final UriObjQualifier qualifier) { + return new NegativeAttributeFilter(qualifier, notIn); + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + NegativeAttributeFilter that = (NegativeAttributeFilter) o; + return super.equals(that) && Objects.equals(notIn, that.notIn); + } + + @Override + public int hashCode() { + return Objects.hash(notIn, super.hashCode()); + } + +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/PositiveAttributeFilter.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/PositiveAttributeFilter.java new file mode 100644 index 000000000..432870895 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/PositiveAttributeFilter.java @@ -0,0 +1,92 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.executeafm.afm.filter; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonRootName; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.executeafm.ObjQualifier; +import com.gooddata.sdk.model.executeafm.UriObjQualifier; + +import java.util.List; +import java.util.Objects; + +import static java.util.Arrays.asList; + +/** + * Filter of attribute filtering by IN expression + */ +@JsonRootName(PositiveAttributeFilter.NAME) +public class PositiveAttributeFilter extends AttributeFilter { + + static final String NAME = "positiveAttributeFilter"; + private static final long serialVersionUID = 1934771670274345290L; + private final AttributeFilterElements in; + + /** + * Creates new instance of given display form and in list + * + * @param displayForm display form + * @param in list of in elements + * @deprecated for compatibility with version 2.x only, use {@link #PositiveAttributeFilter(ObjQualifier, AttributeFilterElements)} instead + */ + @Deprecated + public PositiveAttributeFilter(final ObjQualifier displayForm, final List in) { + this(displayForm, new SimpleAttributeFilterElements(in)); + } + + /** + * Creates new instance of given display form and in list + * + * @param displayForm display form + * @param in in elements (uris or values) + */ + @JsonCreator + public PositiveAttributeFilter(@JsonProperty("displayForm") final ObjQualifier displayForm, + @JsonProperty("in") final AttributeFilterElements in) { + super(displayForm); + this.in = in; + } + + /** + * @deprecated for compatibility with version 2.x only, use {@link #PositiveAttributeFilter(ObjQualifier, AttributeFilterElements)} instead + */ + @Deprecated + public PositiveAttributeFilter(final ObjQualifier displayForm, final String... in) { + this(displayForm, asList(in)); + } + + /** + * @return in elements + */ + public AttributeFilterElements getIn() { + return in; + } + + @Override + public FilterItem withObjUriQualifier(final UriObjQualifier qualifier) { + return new PositiveAttributeFilter(qualifier, in); + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + PositiveAttributeFilter that = (PositiveAttributeFilter) o; + return super.equals(that) && Objects.equals(in, that.in); + } + + @Override + public int hashCode() { + return Objects.hash(in, super.hashCode()); + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/RangeCondition.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/RangeCondition.java new file mode 100644 index 000000000..016164c58 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/RangeCondition.java @@ -0,0 +1,123 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.executeafm.afm.filter; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonRootName; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Objects; + +import static org.apache.commons.lang3.Validate.notNull; + +/** + * Condition of {@link MeasureValueFilter} that compares measure values against two values. + */ +@JsonRootName(RangeCondition.NAME) +public class RangeCondition extends MeasureValueFilterCondition implements Serializable { + + static final String NAME = "range"; + + private static final long serialVersionUID = -1219122779136638864L; + + private final String operator; + private final BigDecimal from; + private final BigDecimal to; + + @JsonCreator + public RangeCondition( + @JsonProperty("operator") final String operator, + @JsonProperty("from") final BigDecimal from, + @JsonProperty("to") final BigDecimal to, + @JsonProperty("treatNullValuesAs") final BigDecimal treatNullValuesAs) { + super(treatNullValuesAs); + this.operator = notNull(operator, "operator"); + this.from = notNull(from, "from"); + this.to = notNull(to, "to"); + } + + /** + * Creates a new {@link RangeCondition} instance. + * + * @param operator The operator of the range condition. + * @param from The left boundary value. + * @param to The right boundary value. + */ + public RangeCondition( + final RangeConditionOperator operator, + final BigDecimal from, + final BigDecimal to) { + this(notNull(operator, "operator").toString(), from, to, null); + } + + /** + * Creates a new {@link RangeCondition} instance. + * + * @param operator The operator of the range condition. + * @param from The left boundary value. + * @param to The right boundary value. + * @param treatNullValuesAs The number that will be used instead of compared values that are null. + */ + public RangeCondition( + final RangeConditionOperator operator, + final BigDecimal from, + final BigDecimal to, + final BigDecimal treatNullValuesAs) { + this(notNull(operator, "operator").toString(), from, to, treatNullValuesAs); + } + + /** + * @return range condition operator + */ + @JsonIgnore + public RangeConditionOperator getOperator() { + return RangeConditionOperator.of(operator); + } + + @JsonProperty("operator") + public String getStringOperator() { + return this.operator; + } + + /** + * @return left boundary of the range + */ + public BigDecimal getFrom() { + return from; + } + + /** + * @return right boundary of the range + */ + public BigDecimal getTo() { + return to; + } + + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + final RangeCondition that = (RangeCondition) o; + return Objects.equals(operator, that.operator) && + Objects.equals(from, that.from) && + Objects.equals(to, that.to); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), operator, from, to); + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/RangeConditionOperator.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/RangeConditionOperator.java new file mode 100644 index 000000000..2c895d034 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/RangeConditionOperator.java @@ -0,0 +1,41 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.executeafm.afm.filter; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import static com.gooddata.sdk.common.util.Validate.notNull; +import static java.lang.String.format; +import static java.util.Arrays.stream; +import static java.util.stream.Collectors.joining; + +/** + * Represents all the possible operators of {@link RangeCondition}. + */ +public enum RangeConditionOperator { + BETWEEN, + NOT_BETWEEN; + + @JsonCreator + public static RangeConditionOperator of(String operator) { + notNull(operator, "operator"); + try { + return RangeConditionOperator.valueOf(operator); + } catch (IllegalArgumentException e) { + throw new UnsupportedOperationException( + format("Unknown value for range condition operator: \"%s\", supported values are: [%s]", + operator, stream(RangeConditionOperator.values()).map(Enum::name).collect(joining(","))), + e); + } + } + + @JsonValue + @Override + public String toString() { + return name(); + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/RankingFilter.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/RankingFilter.java new file mode 100644 index 000000000..709a45f2e --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/RankingFilter.java @@ -0,0 +1,202 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ + +package com.gooddata.sdk.model.executeafm.afm.filter; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonRootName; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.executeafm.IdentifierObjQualifier; +import com.gooddata.sdk.model.executeafm.ObjQualifier; +import com.gooddata.sdk.model.executeafm.Qualifier; +import com.gooddata.sdk.model.executeafm.afm.ObjQualifierConverter; + +import java.io.Serializable; +import java.util.Collection; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static com.gooddata.sdk.common.util.Validate.notNull; +import static java.lang.String.format; + +/** + * Represents a ranking filter applied on an insight. + */ +@JsonRootName(RankingFilter.NAME) +@JsonInclude(JsonInclude.Include.NON_NULL) +public class RankingFilter implements ExtendedFilter, CompatibilityFilter, Serializable { + + public static final String NAME = "rankingFilter"; + + private static final long serialVersionUID = 2642298346540031612L; + + private final List measures; + private final List attributes; + private final String operator; + private final Integer value; + + /** + * Creates a new {@link RankingFilter} instance. + * + * @param measures measures on which is the ranking applied. Must not be null. + * @param attributes attributes that define ranking granularity. Optional, can be null. + * @param operator operator that defines the type of ranking. + * @param value number of requested ranked records. + * @throws NullPointerException thrown when required parameter is not provided. + */ + @JsonCreator + public RankingFilter( + @JsonProperty("measures") final List measures, + @JsonProperty("attributes") final List attributes, + @JsonProperty("operator") final String operator, + @JsonProperty("value") final Integer value) { + this.measures = notNull(measures, "measures must not be null!"); + this.attributes = attributes; + this.operator = notNull(operator, "operator must not be null!"); + this.value = notNull(value, "value must not be null!"); + } + + public RankingFilter( + final List measures, + final List attributes, + final RankingFilterOperator operator, + final Integer value) { + this(measures, attributes, notNull(operator, "operator must not be null!").name(), value); + } + + private static IllegalArgumentException buildExceptionForFailedConversion(final IdentifierObjQualifier qualifierFailedToConvert) { + return new IllegalArgumentException(format("Supplied converter does not provide conversion for '%s'!", qualifierFailedToConvert)); + } + + /** + * Returns all the qualifiers used by the ranking filter. + *

    + * This information comes handy if it is necessary, for example, to convert the ranking filter to use just + * the URI object qualifiers instead of the identifier object qualifiers. It can be used to gather these + * for a conversion service. + * + * @return all the qualifiers the ranking filter uses + */ + @JsonIgnore + public Collection getObjQualifiers() { + return Stream.concat( + this.measures.stream(), + this.attributes == null ? Stream.empty() : this.attributes.stream() + ) + .filter(ObjQualifier.class::isInstance) + .map(ObjQualifier.class::cast) + .collect(Collectors.toSet()); + } + + /** + * Copy itself using the given object qualifier converter in case when {@link IdentifierObjQualifier} instances are used in the object otherwise the + * original object is returned. + *

    + * The provided converter must be able to handle the conversion for the qualifiers that are of the {@link IdentifierObjQualifier} type that are used by + * this object or its encapsulated child objects. + * + * @param objQualifierConverter The function that converts identifier qualifiers to the matching URI qualifiers. In case when the object uses the + * identifier qualifiers, it + * will return a new copy of itself or its encapsulated objects that used URI qualifiers, otherwise the original object is returned. + * The parameter must not be null. + * @return copy of itself with replaced qualifiers in case when some {@link IdentifierObjQualifier} were used, otherwise original object is returned. + * @throws IllegalArgumentException The exception is thrown when conversion for the identifier qualifier used by this ranking filter could not be + * made by the provided + * converter or when provided converter is null. + */ + public RankingFilter withObjUriQualifiers(final ObjQualifierConverter objQualifierConverter) { + notNull(objQualifierConverter, "objQualifierConverter"); + + return new RankingFilter( + translateIdentifierQualifiers(this.measures, objQualifierConverter), + attributes == null ? null : translateIdentifierQualifiers(this.attributes, objQualifierConverter), + operator, + value + ); + } + + private List translateIdentifierQualifiers(final List qualifiers, final ObjQualifierConverter objQualifierConverter) { + return qualifiers.stream() + .map(qualifier -> translateIdentifierQualifier(qualifier, objQualifierConverter)) + .collect(Collectors.toList()); + } + + private Qualifier translateIdentifierQualifier(final Qualifier qualifier, final ObjQualifierConverter objQualifierConverter) { + if (qualifier instanceof IdentifierObjQualifier) { + final IdentifierObjQualifier identifierQualifierToConvert = (IdentifierObjQualifier) qualifier; + return objQualifierConverter.convertToUriQualifier(identifierQualifierToConvert) + .orElseThrow(() -> buildExceptionForFailedConversion(identifierQualifierToConvert)); + } + return qualifier; + } + + /** + * @return measures on which is the ranking applied + */ + public List getMeasures() { + return measures; + } + + /** + * @return granularity of the ranking + */ + public List getAttributes() { + return attributes; + } + + /** + * Get operator as an enum constant for easier programmatic access. + * + * @return ranking operator constant + */ + @JsonIgnore + public RankingFilterOperator getOperator() { + return RankingFilterOperator.of(this.operator); + } + + /** + * Get operator as a string representation of the {@link RankingFilterOperator} enum constant as it was parsed from the JSON. + * + * @return string operator provided at the time of the filter instance creation + */ + @JsonProperty("operator") + public String getOperatorAsString() { + return operator; + } + + /** + * @return number of ranked records + */ + public Integer getValue() { + return value; + } + + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + final RankingFilter that = (RankingFilter) o; + return Objects.equals(measures, that.measures) && + Objects.equals(attributes, that.attributes) && + Objects.equals(operator, that.operator) && + Objects.equals(value, that.value); + } + + @Override + public int hashCode() { + return Objects.hash(measures, attributes, operator, value); + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/RankingFilterOperator.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/RankingFilterOperator.java new file mode 100644 index 000000000..4a532fc70 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/RankingFilterOperator.java @@ -0,0 +1,42 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ + +package com.gooddata.sdk.model.executeafm.afm.filter; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import static com.gooddata.sdk.common.util.Validate.notNull; +import static java.lang.String.format; +import static java.util.Arrays.stream; +import static java.util.stream.Collectors.joining; + +/** + * Represents all the possible operators of {@link RankingFilter}. + */ +public enum RankingFilterOperator { + TOP, + BOTTOM; + + @JsonCreator + public static RankingFilterOperator of(final String operator) { + notNull(operator, "operator"); + try { + return RankingFilterOperator.valueOf(operator); + } catch (IllegalArgumentException e) { + throw new UnsupportedOperationException( + format("Unknown value for ranking filter operator: \"%s\", supported values are: [%s]", + operator, stream(RankingFilterOperator.values()).map(Enum::name).collect(joining(","))), + e); + } + } + + @JsonValue + @Override + public String toString() { + return name(); + } +} diff --git a/src/main/java/com/gooddata/executeafm/afm/RelativeDateFilter.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/RelativeDateFilter.java similarity index 84% rename from src/main/java/com/gooddata/executeafm/afm/RelativeDateFilter.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/RelativeDateFilter.java index ec7496558..0cef6d2a7 100644 --- a/src/main/java/com/gooddata/executeafm/afm/RelativeDateFilter.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/RelativeDateFilter.java @@ -1,21 +1,21 @@ /* - * Copyright (C) 2007-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.executeafm.afm; +package com.gooddata.sdk.model.executeafm.afm.filter; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonRootName; -import com.gooddata.executeafm.ObjQualifier; -import com.gooddata.executeafm.UriObjQualifier; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.executeafm.ObjQualifier; +import com.gooddata.sdk.model.executeafm.UriObjQualifier; import java.util.Objects; -import static com.gooddata.util.Validate.notEmpty; +import static com.gooddata.sdk.common.util.Validate.notEmpty; /** @@ -24,19 +24,19 @@ @JsonRootName(RelativeDateFilter.NAME) public class RelativeDateFilter extends DateFilter { - private static final long serialVersionUID = 7257627800833737063L; static final String NAME = "relativeDateFilter"; - + private static final long serialVersionUID = 7257627800833737063L; private final String granularity; private final Integer from; private final Integer to; /** * Creates new instance - * @param dataSet qualifier of date dimension dataSet + * + * @param dataSet qualifier of date dimension dataSet * @param granularity granularity specified as type GDC date attribute type - * @param from from - * @param to to + * @param from from + * @param to to */ @JsonCreator public RelativeDateFilter(@JsonProperty("dataSet") final ObjQualifier dataSet, diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/SimpleAttributeFilterElements.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/SimpleAttributeFilterElements.java new file mode 100644 index 000000000..dce54c676 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/SimpleAttributeFilterElements.java @@ -0,0 +1,36 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.executeafm.afm.filter; + +import java.io.Serializable; +import java.util.List; + +import static com.gooddata.sdk.common.util.Validate.notNull; + +/** + * {@link AttributeFilterElements} represented by simple array. + * + * @deprecated It has the same semantic as {@link UriAttributeFilterElements}. + * Preserved because of compatibility and will be removed in future API version. + */ +@Deprecated +public class SimpleAttributeFilterElements implements AttributeFilterElements, Serializable { + + private static final long serialVersionUID = -2935674265292888490L; + + private final List elements; + + public SimpleAttributeFilterElements(final List elements) { + this.elements = notNull(elements, "elements"); + } + + @Override + public List getElements() { + return elements; + } + + +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/UriAttributeFilterElements.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/UriAttributeFilterElements.java new file mode 100644 index 000000000..c7d5aa4dd --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/UriAttributeFilterElements.java @@ -0,0 +1,71 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.executeafm.afm.filter; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; + +import java.io.Serializable; +import java.util.List; +import java.util.Objects; + +import static java.util.Arrays.asList; + +/** + * {@link AttributeFilterElements} represented by uris of elements. + */ +public final class UriAttributeFilterElements implements AttributeFilterElements, Serializable { + + static final String NAME = "uris"; + private static final long serialVersionUID = -588170788038973574L; + private final List uris; + + /** + * Creates new instance of given attribute elements' uris. + * + * @param uris elements' uris. + */ + @JsonCreator + public UriAttributeFilterElements(final List uris) { + this.uris = uris; + } + + /** + * Creates new instance of given attribute elements' uris. + * + * @param uris elements' uris. + */ + public UriAttributeFilterElements(String... uris) { + this(asList(uris)); + } + + public List getUris() { + return uris; + } + + @Override + public List getElements() { + return getUris(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + UriAttributeFilterElements that = (UriAttributeFilterElements) o; + return Objects.equals(uris, that.uris); + } + + @Override + public int hashCode() { + return Objects.hash(uris); + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/ValueAttributeFilterElements.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/ValueAttributeFilterElements.java new file mode 100644 index 000000000..d46faa45d --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/afm/filter/ValueAttributeFilterElements.java @@ -0,0 +1,71 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.executeafm.afm.filter; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; + +import java.io.Serializable; +import java.util.List; +import java.util.Objects; + +import static java.util.Arrays.asList; + +/** + * {@link AttributeFilterElements} represented by values of elements. + */ +public final class ValueAttributeFilterElements implements AttributeFilterElements, Serializable { + + static final String NAME = "values"; + private static final long serialVersionUID = 8162844914489089022L; + private final List values; + + /** + * Creates new instance of given attribute elements' values. + * + * @param values elements' values. + */ + @JsonCreator + public ValueAttributeFilterElements(final List values) { + this.values = values; + } + + /** + * Creates new instance of given attribute elements' values. + * + * @param values elements' values. + */ + public ValueAttributeFilterElements(String... values) { + this(asList(values)); + } + + public List getValues() { + return values; + } + + @Override + public List getElements() { + return getValues(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ValueAttributeFilterElements that = (ValueAttributeFilterElements) o; + return Objects.equals(values, that.values); + } + + @Override + public int hashCode() { + return Objects.hash(values); + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/response/AttributeHeader.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/response/AttributeHeader.java new file mode 100644 index 000000000..606ea32c8 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/response/AttributeHeader.java @@ -0,0 +1,163 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.executeafm.response; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonRootName; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.executeafm.afm.Afm; +import com.gooddata.sdk.model.executeafm.afm.AttributeItem; +import com.gooddata.sdk.model.executeafm.afm.LocallyIdentifiable; + +import java.util.List; + +import static com.gooddata.sdk.common.util.Validate.notEmpty; +import static com.gooddata.sdk.common.util.Validate.notNull; + +/** + * Header of an attribute. + */ +@JsonRootName(AttributeHeader.NAME) +public class AttributeHeader implements Header, LocallyIdentifiable { + + static final String NAME = "attributeHeader"; + + private final String name; + private final String localIdentifier; + private final String uri; + private final String identifier; + private final String type; + private final AttributeInHeader formOf; + + private List totalItems; + + /** + * Creates new header + * + * @param name name + * @param localIdentifier local identifier + * @param uri uri + * @param identifier identifier + * @param formOf info about attribute which this header's display form is form of + */ + public AttributeHeader(final String name, final String localIdentifier, final String uri, final String identifier, final AttributeInHeader formOf) { + this(name, localIdentifier, uri, identifier, formOf, null); + } + + /** + * Creates new header + * + * @param name name + * @param localIdentifier local identifier + * @param uri uri + * @param identifier identifier + * @param formOf info about attribute which this header's display form is form of + * @param totalHeaderItems total header items + */ + public AttributeHeader(@JsonProperty("name") final String name, + @JsonProperty("localIdentifier") final String localIdentifier, + @JsonProperty("uri") final String uri, + @JsonProperty("identifier") final String identifier, + @JsonProperty("formOf") final AttributeInHeader formOf, + @JsonProperty("totalItems") final List totalHeaderItems) { + this(name, localIdentifier, uri, identifier, null, formOf, totalHeaderItems); + } + + /** + * Creates new header + * + * @param name name + * @param localIdentifier local identifier + * @param uri uri + * @param identifier identifier + * @param type type + * @param formOf info about attribute which this header's display form is form of + * @param totalHeaderItems total header items + */ + @JsonCreator + public AttributeHeader(@JsonProperty("name") final String name, + @JsonProperty("localIdentifier") final String localIdentifier, + @JsonProperty("uri") final String uri, + @JsonProperty("identifier") final String identifier, + @JsonProperty("type") final String type, + @JsonProperty("formOf") final AttributeInHeader formOf, + @JsonProperty("totalItems") final List totalHeaderItems) { + this.name = notEmpty(name, "name"); + this.localIdentifier = notEmpty(localIdentifier, "localIdentifier"); + this.uri = notEmpty(uri, "uri"); + this.identifier = notEmpty(identifier, "identifier"); + this.type = type; + this.formOf = notNull(formOf, "formOf"); + this.totalItems = totalHeaderItems; + } + + /** + * Header name, an attribute's display form title, or specified alias. + * + * @return header name + */ + public String getName() { + return name; + } + + /** + * Local identifier referencing header's {@link AttributeItem} + * within {@link Afm} + * + * @return attribute's local identifier + */ + @Override + public String getLocalIdentifier() { + return localIdentifier; + } + + /** + * Uri of attribute's display form + * + * @return uri + */ + public String getUri() { + return uri; + } + + /** + * Metadata identifier of attribute's display form + * + * @return identifier + */ + public String getIdentifier() { + return identifier; + } + + /** + * Metadata type of attribute's display form + * + * @return type + */ + public String getType() { + return type; + } + + public AttributeInHeader getFormOf() { + return formOf; + } + + /** + * Totals' headers belonging to the same level as this header. + * + * @return lists of totals' header + */ + public List getTotalItems() { + return totalItems; + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } + +} diff --git a/src/main/java/com/gooddata/executeafm/response/AttributeInHeader.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/response/AttributeInHeader.java similarity index 88% rename from src/main/java/com/gooddata/executeafm/response/AttributeInHeader.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/response/AttributeInHeader.java index 49f800807..0b5628c61 100644 --- a/src/main/java/com/gooddata/executeafm/response/AttributeInHeader.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/response/AttributeInHeader.java @@ -1,16 +1,16 @@ /* - * Copyright (C) 2007-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.executeafm.response; +package com.gooddata.sdk.model.executeafm.response; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; -import static com.gooddata.util.Validate.notEmpty; +import static com.gooddata.sdk.common.util.Validate.notEmpty; /** * Represents attribute in {@link AttributeHeader} @@ -23,8 +23,9 @@ public class AttributeInHeader { /** * Creates new instance - * @param name attribute's title - * @param uri attribute's uri + * + * @param name attribute's title + * @param uri attribute's uri * @param identifier attribute's identifier */ @JsonCreator diff --git a/src/main/java/com/gooddata/executeafm/response/ExecutionResponse.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/response/ExecutionResponse.java similarity index 80% rename from src/main/java/com/gooddata/executeafm/response/ExecutionResponse.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/response/ExecutionResponse.java index 3e2f8d7ac..daf20ac38 100644 --- a/src/main/java/com/gooddata/executeafm/response/ExecutionResponse.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/response/ExecutionResponse.java @@ -1,9 +1,9 @@ /* - * Copyright (C) 2007-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.executeafm.response; +package com.gooddata.sdk.model.executeafm.response; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; @@ -11,20 +11,21 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.executeafm.Execution; +import com.gooddata.sdk.model.executeafm.result.ExecutionResult; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import static com.gooddata.util.Validate.notEmpty; -import static com.gooddata.util.Validate.notNull; -import static com.gooddata.util.Validate.notNullState; -import static org.apache.commons.lang3.ArrayUtils.toObject; +import static com.gooddata.sdk.common.util.Validate.notEmpty; +import static com.gooddata.sdk.common.util.Validate.notNull; +import static com.gooddata.sdk.common.util.Validate.notNullState; /** - * Represents response on {@link com.gooddata.executeafm.Execution} request. - * Provides the dimensions with headers and the (polling) uri to {@link com.gooddata.executeafm.result.ExecutionResult} + * Represents response on {@link Execution} request. + * Provides the dimensions with headers and the (polling) uri to {@link ExecutionResult} * (so called dataResult). */ @JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) @@ -39,7 +40,8 @@ public class ExecutionResponse { /** * Creates new instance of given dimensions and execution result uri. - * @param dimensions dimensions + * + * @param dimensions dimensions * @param executionResultUri execution result uri */ public ExecutionResponse(final List dimensions, final String executionResultUri) { @@ -56,6 +58,7 @@ private ExecutionResponse(@JsonProperty("dimensions") final List getDimensions() { @@ -64,6 +67,7 @@ public List getDimensions() { /** * Map of response's links. + * * @return links */ public Map getLinks() { @@ -72,6 +76,7 @@ public Map getLinks() { /** * Uri referencing the data result location. + * * @return execution result uri or throws exception in case the link doesn't exist */ @JsonIgnore diff --git a/src/main/java/com/gooddata/executeafm/response/Header.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/response/Header.java similarity index 78% rename from src/main/java/com/gooddata/executeafm/response/Header.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/response/Header.java index 6a518e6f1..6830f752c 100644 --- a/src/main/java/com/gooddata/executeafm/response/Header.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/response/Header.java @@ -1,16 +1,13 @@ /* - * Copyright (C) 2007-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.executeafm.response; +package com.gooddata.sdk.model.executeafm.response; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; -import com.gooddata.util.GoodDataToStringBuilder; - -import java.util.List; /** * {@link ResultDimension}'s header. diff --git a/src/main/java/com/gooddata/executeafm/response/MeasureGroupHeader.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/response/MeasureGroupHeader.java similarity index 86% rename from src/main/java/com/gooddata/executeafm/response/MeasureGroupHeader.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/response/MeasureGroupHeader.java index 7231c2372..cd5ad03d6 100644 --- a/src/main/java/com/gooddata/executeafm/response/MeasureGroupHeader.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/response/MeasureGroupHeader.java @@ -1,14 +1,14 @@ /* - * Copyright (C) 2007-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.executeafm.response; +package com.gooddata.sdk.model.executeafm.response; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonRootName; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.util.List; @@ -24,6 +24,7 @@ public class MeasureGroupHeader implements Header { /** * Creates new header + * * @param items header items */ @JsonCreator @@ -33,6 +34,7 @@ public MeasureGroupHeader(@JsonProperty("items") final List i /** * Header items for particular measures + * * @return header items */ public List getItems() { diff --git a/src/main/java/com/gooddata/executeafm/response/MeasureHeaderItem.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/response/MeasureHeaderItem.java similarity index 85% rename from src/main/java/com/gooddata/executeafm/response/MeasureHeaderItem.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/response/MeasureHeaderItem.java index 6fa020687..9e89c228e 100644 --- a/src/main/java/com/gooddata/executeafm/response/MeasureHeaderItem.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/response/MeasureHeaderItem.java @@ -1,20 +1,21 @@ /* - * Copyright (C) 2007-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.executeafm.response; +package com.gooddata.sdk.model.executeafm.response; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.executeafm.afm.Afm; -import com.gooddata.executeafm.afm.LocallyIdentifiable; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.executeafm.afm.Afm; +import com.gooddata.sdk.model.executeafm.afm.LocallyIdentifiable; +import com.gooddata.sdk.model.executeafm.afm.MeasureItem; -import static com.gooddata.util.Validate.notEmpty; +import static com.gooddata.sdk.common.util.Validate.notEmpty; /** * Header of particular measure. @@ -51,6 +52,7 @@ public MeasureHeaderItem(@JsonProperty("name") final String name, /** * Header name, can be measure title, or specified alias + * * @return name */ public String getName() { @@ -65,8 +67,9 @@ public String getFormat() { } /** - * Local identifier, referencing the {@link com.gooddata.executeafm.afm.MeasureItem} + * Local identifier, referencing the {@link MeasureItem} * in {@link Afm} + * * @return local identifier */ @Override @@ -81,23 +84,25 @@ public String getUri() { return uri; } - /** - * @return Measure metadata identifier - */ - public String getIdentifier() { - return identifier; - } - /** * Set measure uri + * * @param uri measure uri */ public void setUri(final String uri) { this.uri = uri; } + /** + * @return Measure metadata identifier + */ + public String getIdentifier() { + return identifier; + } + /** * Set measure metadata identifier + * * @param identifier */ public void setIdentifier(final String identifier) { diff --git a/src/main/java/com/gooddata/executeafm/response/ResultDimension.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/response/ResultDimension.java similarity index 80% rename from src/main/java/com/gooddata/executeafm/response/ResultDimension.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/response/ResultDimension.java index 0e803e8cb..a25bfb91d 100644 --- a/src/main/java/com/gooddata/executeafm/response/ResultDimension.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/response/ResultDimension.java @@ -1,21 +1,22 @@ /* - * Copyright (C) 2007-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.executeafm.response; +package com.gooddata.sdk.model.executeafm.response; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.executeafm.result.ExecutionResult; import java.util.List; import static java.util.Arrays.asList; /** - * Describes single dimension of the {@link com.gooddata.executeafm.result.ExecutionResult}. + * Describes single dimension of the {@link ExecutionResult}. */ @JsonInclude(JsonInclude.Include.NON_NULL) public class ResultDimension { @@ -23,6 +24,7 @@ public class ResultDimension { /** * Creates the result dimension of given headers + * * @param headers headers */ @JsonCreator @@ -32,6 +34,7 @@ public ResultDimension(@JsonProperty("headers") final List

    headers) { /** * Creates the result dimension of given headers + * * @param headers headers */ public ResultDimension(final Header... headers) { diff --git a/src/main/java/com/gooddata/executeafm/response/TotalHeaderItem.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/response/TotalHeaderItem.java similarity index 81% rename from src/main/java/com/gooddata/executeafm/response/TotalHeaderItem.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/response/TotalHeaderItem.java index 271f1fc99..5eb38cc67 100644 --- a/src/main/java/com/gooddata/executeafm/response/TotalHeaderItem.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/response/TotalHeaderItem.java @@ -1,18 +1,18 @@ /* - * Copyright (C) 2007-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.executeafm.response; +package com.gooddata.sdk.model.executeafm.response; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.md.report.Total; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.md.report.Total; -import static com.gooddata.util.Validate.notNull; +import static com.gooddata.sdk.common.util.Validate.notNull; /** * Header of total @@ -25,6 +25,7 @@ public class TotalHeaderItem { /** * Creates new header + * * @param name total name */ @JsonCreator @@ -34,6 +35,7 @@ public TotalHeaderItem(@JsonProperty("name") final String name) { /** * Creates new header + * * @param total total value */ public TotalHeaderItem(final Total total) { diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/result/AttributeHeaderItem.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/result/AttributeHeaderItem.java new file mode 100644 index 000000000..8971ded4c --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/result/AttributeHeaderItem.java @@ -0,0 +1,48 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.executeafm.result; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonRootName; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; + +import static com.gooddata.sdk.model.executeafm.result.AttributeHeaderItem.NAME; + +/** + * Header item for attribute + */ +@JsonRootName(NAME) +public class AttributeHeaderItem extends ResultHeaderItem { + + static final String NAME = "attributeHeaderItem"; + + private final String uri; + + /** + * Creates new header item + * + * @param name name of item (usually attribute element title) + * @param uri uri of item (usually attribute element uri) + */ + @JsonCreator + public AttributeHeaderItem(@JsonProperty("name") final String name, @JsonProperty("uri") final String uri) { + super(name); + this.uri = uri; + } + + /** + * @return item uri + */ + public String getUri() { + return uri; + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } +} diff --git a/src/main/java/com/gooddata/executeafm/result/Data.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/result/Data.java similarity index 96% rename from src/main/java/com/gooddata/executeafm/result/Data.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/result/Data.java index edc8e821b..e8638cf83 100644 --- a/src/main/java/com/gooddata/executeafm/result/Data.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/result/Data.java @@ -1,9 +1,9 @@ /* - * Copyright (C) 2007-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.executeafm.result; +package com.gooddata.sdk.model.executeafm.result; import com.fasterxml.jackson.annotation.JsonValue; import com.fasterxml.jackson.core.JsonParser; diff --git a/src/main/java/com/gooddata/executeafm/result/DataList.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/result/DataList.java similarity index 85% rename from src/main/java/com/gooddata/executeafm/result/DataList.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/result/DataList.java index 762261ceb..ba2da8143 100644 --- a/src/main/java/com/gooddata/executeafm/result/DataList.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/result/DataList.java @@ -1,17 +1,17 @@ /* - * Copyright (C) 2007-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.executeafm.result; +package com.gooddata.sdk.model.executeafm.result; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import static com.gooddata.util.Validate.notNull; +import static com.gooddata.sdk.common.util.Validate.notNull; import static java.util.stream.Collectors.toList; /** @@ -21,6 +21,7 @@ public class DataList extends ArrayList implements Data { /** * Creates new instance of given list of data + * * @param values list to use as values, can't be null */ public DataList(final List values) { @@ -29,6 +30,7 @@ public DataList(final List values) { /** * Creates new instance by transforming the given array to list of simple or null values + * * @param array array of values */ DataList(final String[] array) { @@ -37,6 +39,7 @@ public DataList(final List values) { /** * Creates new instance by transforming the given array to list of data lists of simple or null values + * * @param array array of values */ DataList(final String[][] array) { @@ -44,7 +47,7 @@ public DataList(final List values) { } private static Data simpleValue(final String value) { - return value == null ? Data.NULL : new DataValue(value); + return value == null ? NULL : new DataValue(value); } @Override diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/result/DataValue.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/result/DataValue.java new file mode 100644 index 000000000..2ed9372bb --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/result/DataValue.java @@ -0,0 +1,68 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.executeafm.result; + +import com.fasterxml.jackson.annotation.JsonValue; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; + +import static com.gooddata.sdk.common.util.Validate.notNull; + +/** + * Simple value type of {@link Data}. Wrapper of textual value. + */ +public class DataValue implements Data { + + private final String value; + + /** + * Creates new instance of given value. + * + * @param value textual value, can't be null + */ + public DataValue(final String value) { + this.value = notNull(value, "value"); + } + + @JsonValue + private String getValue() { + return value; + } + + @Override + public boolean isList() { + return false; + } + + @Override + public boolean isValue() { + return true; + } + + @Override + public String textValue() { + return value; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + DataValue dataValue = (DataValue) o; + + return value != null ? value.equals(dataValue.value) : dataValue.value == null; + } + + @Override + public int hashCode() { + return value != null ? value.hashCode() : 0; + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } +} diff --git a/src/main/java/com/gooddata/executeafm/result/ExecutionResult.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/result/ExecutionResult.java similarity index 89% rename from src/main/java/com/gooddata/executeafm/result/ExecutionResult.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/result/ExecutionResult.java index 243884d34..82a1f656d 100644 --- a/src/main/java/com/gooddata/executeafm/result/ExecutionResult.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/result/ExecutionResult.java @@ -1,24 +1,25 @@ /* - * Copyright (C) 2007-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.executeafm.result; +package com.gooddata.sdk.model.executeafm.result; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.executeafm.Execution; import java.util.ArrayList; import java.util.List; -import static com.gooddata.util.Validate.notNull; +import static com.gooddata.sdk.common.util.Validate.notNull; /** - * Data result of the {@link com.gooddata.executeafm.Execution}. + * Data result of the {@link Execution}. */ @JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) @JsonTypeName("executionResult") @@ -35,7 +36,8 @@ public class ExecutionResult { /** * Creates new result - * @param data result data + * + * @param data result data * @param paging result paging */ public ExecutionResult(final String[] data, final Paging paging) { @@ -45,7 +47,8 @@ public ExecutionResult(final String[] data, final Paging paging) { /** * Creates new result - * @param data result data + * + * @param data result data * @param paging result paging */ public ExecutionResult(final String[][] data, final Paging paging) { @@ -55,10 +58,11 @@ public ExecutionResult(final String[][] data, final Paging paging) { /** * Creates new result - * @param data result data - * @param paging result paging + * + * @param data result data + * @param paging result paging * @param headerItems items for headers, for each header in each dimension, there is a list of header items - * @param totals data of totals, for each total in each dimension, there is a list of total's values + * @param totals data of totals, for each total in each dimension, there is a list of total's values */ @JsonCreator ExecutionResult(@JsonProperty("data") final DataList data, @@ -98,6 +102,7 @@ public List>> getHeaderItems() { /** * Sets header items, for each header in each dimension, there is a list of header items + * * @param headerItems header items */ public void setHeaderItems(final List>> headerItems) { @@ -106,6 +111,7 @@ public void setHeaderItems(final List>> headerItems) /** * Add header items for next dimension (this method will add dimension in header items) + * * @param items header items for one dimension */ public void addHeaderItems(final List> items) { @@ -124,6 +130,7 @@ public List>> getTotals() { /** * Sets total data, for each total in each dimension, there is a list of total's values + * * @param totals totals data */ public void setTotals(final List>> totals) { @@ -162,6 +169,7 @@ public List getWarnings() { /** * Sets warnings for this result + * * @param warnings result's warning */ public void setWarnings(final List warnings) { diff --git a/src/main/java/com/gooddata/executeafm/result/Paging.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/result/Paging.java similarity index 87% rename from src/main/java/com/gooddata/executeafm/result/Paging.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/result/Paging.java index b73a2053b..0443db0c9 100644 --- a/src/main/java/com/gooddata/executeafm/result/Paging.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/result/Paging.java @@ -1,17 +1,17 @@ /* - * Copyright (C) 2007-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.executeafm.result; +package com.gooddata.sdk.model.executeafm.result; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.util.List; -import static com.gooddata.util.Validate.notEmpty; +import static com.gooddata.sdk.common.util.Validate.notEmpty; import static java.util.Arrays.asList; import static org.apache.commons.lang3.ArrayUtils.toObject; @@ -31,9 +31,10 @@ public Paging() { /** * Creates new paging - * @param count multiple dimensions count + * + * @param count multiple dimensions count * @param offset multiple dimensions offset - * @param total multiple dimensions total + * @param total multiple dimensions total */ @JsonCreator public Paging(@JsonProperty("count") final List count, @@ -67,6 +68,7 @@ public List getTotal() { /** * Sets count compound of given elements, each element per dimension + * * @param count count elements * @return this */ @@ -77,6 +79,7 @@ public Paging count(final int... count) { /** * Sets size compound of given elements, each element per dimension + * * @param total size elements * @return this */ @@ -87,6 +90,7 @@ public Paging total(final int... total) { /** * Sets size compound of given elements, each element per dimension + * * @param offset size elements * @return this */ diff --git a/src/main/java/com/gooddata/executeafm/result/ResultHeaderItem.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/result/ResultHeaderItem.java similarity index 84% rename from src/main/java/com/gooddata/executeafm/result/ResultHeaderItem.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/result/ResultHeaderItem.java index bd0e727fb..35ad52a8e 100644 --- a/src/main/java/com/gooddata/executeafm/result/ResultHeaderItem.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/result/ResultHeaderItem.java @@ -1,15 +1,15 @@ /* - * Copyright (C) 2007-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.executeafm.result; +package com.gooddata.sdk.model.executeafm.result; import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; -import static com.gooddata.util.Validate.notNull; +import static com.gooddata.sdk.common.util.Validate.notNull; /** * Represent header items available in {@link ExecutionResult} diff --git a/src/main/java/com/gooddata/executeafm/result/ResultMeasureHeaderItem.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/result/ResultMeasureHeaderItem.java similarity index 81% rename from src/main/java/com/gooddata/executeafm/result/ResultMeasureHeaderItem.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/result/ResultMeasureHeaderItem.java index 4fd098f89..ad33f4482 100644 --- a/src/main/java/com/gooddata/executeafm/result/ResultMeasureHeaderItem.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/result/ResultMeasureHeaderItem.java @@ -1,15 +1,15 @@ /* - * Copyright (C) 2007-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.executeafm.result; +package com.gooddata.sdk.model.executeafm.result; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonRootName; -import static com.gooddata.executeafm.result.ResultMeasureHeaderItem.NAME; +import static com.gooddata.sdk.model.executeafm.result.ResultMeasureHeaderItem.NAME; /** * Header item for measure @@ -23,7 +23,8 @@ public class ResultMeasureHeaderItem extends ResultHeaderItem { /** * Creates new instance of given header name and order - * @param name header name + * + * @param name header name * @param order measure order within measureGroup */ @JsonCreator diff --git a/src/main/java/com/gooddata/executeafm/result/ResultTotalHeaderItem.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/result/ResultTotalHeaderItem.java similarity index 82% rename from src/main/java/com/gooddata/executeafm/result/ResultTotalHeaderItem.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/result/ResultTotalHeaderItem.java index 40eaa7ba4..8eaa8e1dc 100644 --- a/src/main/java/com/gooddata/executeafm/result/ResultTotalHeaderItem.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/result/ResultTotalHeaderItem.java @@ -1,18 +1,18 @@ /* - * Copyright (C) 2007-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.executeafm.result; +package com.gooddata.sdk.model.executeafm.result; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonRootName; -import com.gooddata.md.report.Total; +import com.gooddata.sdk.model.md.report.Total; -import static com.gooddata.executeafm.result.ResultTotalHeaderItem.NAME; -import static com.gooddata.util.Validate.notEmpty; -import static com.gooddata.util.Validate.notNull; +import static com.gooddata.sdk.common.util.Validate.notEmpty; +import static com.gooddata.sdk.common.util.Validate.notNull; +import static com.gooddata.sdk.model.executeafm.result.ResultTotalHeaderItem.NAME; /** * Header item for total. @@ -26,6 +26,7 @@ public class ResultTotalHeaderItem extends ResultHeaderItem { /** * Creates new instance of given total type, type is used for the name as well + * * @param type total type */ public ResultTotalHeaderItem(final String type) { @@ -34,6 +35,7 @@ public ResultTotalHeaderItem(final String type) { /** * Creates new instance of given total type, type is used for the name as well + * * @param type total type */ public ResultTotalHeaderItem(final Total type) { @@ -42,6 +44,7 @@ public ResultTotalHeaderItem(final Total type) { /** * Creates new instance of given header name and total type + * * @param name header name * @param type total type */ @@ -53,6 +56,7 @@ public ResultTotalHeaderItem(@JsonProperty("name") final String name, @JsonPrope /** * Creates new instance of given header name and total type + * * @param name header name * @param type total type */ diff --git a/src/main/java/com/gooddata/executeafm/result/Warning.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/result/Warning.java similarity index 86% rename from src/main/java/com/gooddata/executeafm/result/Warning.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/result/Warning.java index 845bc4eb4..33a9b0e47 100644 --- a/src/main/java/com/gooddata/executeafm/result/Warning.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/result/Warning.java @@ -1,18 +1,18 @@ /* - * Copyright (C) 2007-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.executeafm.result; +package com.gooddata.sdk.model.executeafm.result; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.util.List; -import static com.gooddata.util.Validate.notEmpty; -import static com.gooddata.util.Validate.notNull; +import static com.gooddata.sdk.common.util.Validate.notEmpty; +import static com.gooddata.sdk.common.util.Validate.notNull; import static java.util.Collections.emptyList; /** @@ -25,8 +25,9 @@ public class Warning { /** * Creates new instance + * * @param warningCode error code - * @param message message + * @param message message */ public Warning(final String warningCode, final String message) { this(warningCode, message, emptyList()); @@ -34,9 +35,10 @@ public Warning(final String warningCode, final String message) { /** * Creates new instance + * * @param warningCode error code - * @param message message - * @param parameters message's parameters + * @param message message + * @param parameters message's parameters */ @JsonCreator public Warning(@JsonProperty("warningCode") final String warningCode, diff --git a/src/main/java/com/gooddata/executeafm/resultspec/AttributeLocatorItem.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/resultspec/AttributeLocatorItem.java similarity index 88% rename from src/main/java/com/gooddata/executeafm/resultspec/AttributeLocatorItem.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/resultspec/AttributeLocatorItem.java index 773204dd7..0f185c2e5 100644 --- a/src/main/java/com/gooddata/executeafm/resultspec/AttributeLocatorItem.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/resultspec/AttributeLocatorItem.java @@ -1,16 +1,16 @@ /* - * Copyright (C) 2007-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.executeafm.resultspec; +package com.gooddata.sdk.model.executeafm.resultspec; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import static com.fasterxml.jackson.annotation.JsonTypeInfo.As; import static com.fasterxml.jackson.annotation.JsonTypeInfo.Id; diff --git a/src/main/java/com/gooddata/executeafm/resultspec/AttributeSortAggregation.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/resultspec/AttributeSortAggregation.java similarity index 82% rename from src/main/java/com/gooddata/executeafm/resultspec/AttributeSortAggregation.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/resultspec/AttributeSortAggregation.java index e239c43ec..7609010d6 100644 --- a/src/main/java/com/gooddata/executeafm/resultspec/AttributeSortAggregation.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/resultspec/AttributeSortAggregation.java @@ -1,10 +1,10 @@ /* - * Copyright (C) 2007-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.executeafm.resultspec; +package com.gooddata.sdk.model.executeafm.resultspec; import com.fasterxml.jackson.annotation.JsonValue; diff --git a/src/main/java/com/gooddata/executeafm/resultspec/AttributeSortItem.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/resultspec/AttributeSortItem.java similarity index 93% rename from src/main/java/com/gooddata/executeafm/resultspec/AttributeSortItem.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/resultspec/AttributeSortItem.java index efd78ce32..cf23e0605 100644 --- a/src/main/java/com/gooddata/executeafm/resultspec/AttributeSortItem.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/resultspec/AttributeSortItem.java @@ -1,20 +1,20 @@ /* - * Copyright (C) 2007-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.executeafm.resultspec; +package com.gooddata.sdk.model.executeafm.resultspec; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import static com.fasterxml.jackson.annotation.JsonTypeInfo.As; import static com.fasterxml.jackson.annotation.JsonTypeInfo.Id; -import static com.gooddata.util.Validate.notNull; +import static com.gooddata.sdk.common.util.Validate.notNull; /** * Define sort by specific attribute diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/resultspec/Dimension.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/resultspec/Dimension.java new file mode 100644 index 000000000..dd3f14a95 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/resultspec/Dimension.java @@ -0,0 +1,104 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.executeafm.resultspec; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.executeafm.afm.Afm; + +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +import static com.gooddata.sdk.common.util.Validate.notNull; +import static java.util.Arrays.asList; + +/** + * Dimension content definition. Dimension contains one or more attributes. + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +public class Dimension { + + /** + * Marker element to be used within itemIdentifiers marking the placement of measures + */ + public static final String MEASURE_GROUP = "measureGroup"; + + private final List itemIdentifiers; + private Set totals; + + /** + * Creates new instance + * + * @param itemIdentifiers identifiers referencing attributes from {@link Afm} or {@link Dimension#MEASURE_GROUP} + * @param totals set of totals + */ + @JsonCreator + public Dimension( + @JsonProperty("itemIdentifiers") final List itemIdentifiers, + @JsonProperty("totals") final Set totals) { + this.itemIdentifiers = itemIdentifiers; + this.totals = totals; + } + + /** + * Creates new instance + * + * @param itemIdentifiers identifiers referencing attributes from {@link Afm} or {@link Dimension#MEASURE_GROUP} + */ + public Dimension(final List itemIdentifiers) { + this.itemIdentifiers = itemIdentifiers; + } + + /** + * Creates new instance + * + * @param itemIdentifiers identifiers referencing attributes from {@link Afm} or {@link Dimension#MEASURE_GROUP} + */ + public Dimension(final String... itemIdentifiers) { + this(asList(itemIdentifiers)); + } + + public List getItemIdentifiers() { + return itemIdentifiers; + } + + public Set getTotals() { + return totals; + } + + public void setTotals(final Set totals) { + this.totals = totals; + } + + public Dimension addTotal(final TotalItem total) { + if (totals == null) { + setTotals(new HashSet<>()); + } + totals.add(notNull(total, "total")); + return this; + } + + public Set findTotals(final String attrIdentifier) { + final Predicate filter = t -> notNull(attrIdentifier, "attrIdentifier").equals(t.getAttributeIdentifier()); + + if (totals == null) { + return Collections.emptySet(); + } else { + return totals.stream().filter(filter).collect(Collectors.toSet()); + } + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/resultspec/Direction.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/resultspec/Direction.java new file mode 100644 index 000000000..2fa830757 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/resultspec/Direction.java @@ -0,0 +1,19 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.executeafm.resultspec; + +import com.fasterxml.jackson.annotation.JsonValue; + +public enum Direction { + + ASC, DESC; + + @JsonValue + @Override + public String toString() { + return name().toLowerCase(); + } +} diff --git a/src/main/java/com/gooddata/executeafm/resultspec/LocatorItem.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/resultspec/LocatorItem.java similarity index 86% rename from src/main/java/com/gooddata/executeafm/resultspec/LocatorItem.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/resultspec/LocatorItem.java index 3e20e279a..70654df42 100644 --- a/src/main/java/com/gooddata/executeafm/resultspec/LocatorItem.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/resultspec/LocatorItem.java @@ -1,9 +1,9 @@ /* - * Copyright (C) 2007-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.executeafm.resultspec; +package com.gooddata.sdk.model.executeafm.resultspec; import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; diff --git a/src/main/java/com/gooddata/executeafm/resultspec/MeasureLocatorItem.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/resultspec/MeasureLocatorItem.java similarity index 90% rename from src/main/java/com/gooddata/executeafm/resultspec/MeasureLocatorItem.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/resultspec/MeasureLocatorItem.java index d912c287c..0ca8ad407 100644 --- a/src/main/java/com/gooddata/executeafm/resultspec/MeasureLocatorItem.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/resultspec/MeasureLocatorItem.java @@ -1,9 +1,9 @@ /* - * Copyright (C) 2007-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.executeafm.resultspec; +package com.gooddata.sdk.model.executeafm.resultspec; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/src/main/java/com/gooddata/executeafm/resultspec/MeasureSortItem.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/resultspec/MeasureSortItem.java similarity index 87% rename from src/main/java/com/gooddata/executeafm/resultspec/MeasureSortItem.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/resultspec/MeasureSortItem.java index 07c3fea35..ea95fef26 100644 --- a/src/main/java/com/gooddata/executeafm/resultspec/MeasureSortItem.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/resultspec/MeasureSortItem.java @@ -1,20 +1,20 @@ /* - * Copyright (C) 2007-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.executeafm.resultspec; +package com.gooddata.sdk.model.executeafm.resultspec; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.util.List; -import static com.gooddata.util.Validate.notNull; +import static com.gooddata.sdk.common.util.Validate.notNull; import static java.util.Arrays.asList; /** diff --git a/src/main/java/com/gooddata/executeafm/resultspec/ResultSpec.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/resultspec/ResultSpec.java similarity index 87% rename from src/main/java/com/gooddata/executeafm/resultspec/ResultSpec.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/resultspec/ResultSpec.java index bd8e73436..3aebfddff 100644 --- a/src/main/java/com/gooddata/executeafm/resultspec/ResultSpec.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/resultspec/ResultSpec.java @@ -1,20 +1,20 @@ /* - * Copyright (C) 2007-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.executeafm.resultspec; +package com.gooddata.sdk.model.executeafm.resultspec; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import com.gooddata.executeafm.afm.Afm; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.executeafm.afm.Afm; import java.util.ArrayList; import java.util.List; -import static com.gooddata.util.Validate.notNull; +import static com.gooddata.sdk.common.util.Validate.notNull; /** * Represents the result specification of executed {@link Afm} @@ -39,14 +39,14 @@ public List getDimensions() { return dimensions; } - public List getSorts() { - return sorts; - } - public void setDimensions(final List dimensions) { this.dimensions = dimensions; } + public List getSorts() { + return sorts; + } + public void setSorts(final List sorts) { this.sorts = sorts; } diff --git a/src/main/java/com/gooddata/executeafm/resultspec/SortItem.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/resultspec/SortItem.java similarity index 84% rename from src/main/java/com/gooddata/executeafm/resultspec/SortItem.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/resultspec/SortItem.java index 3111af99f..d6891c73b 100644 --- a/src/main/java/com/gooddata/executeafm/resultspec/SortItem.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/resultspec/SortItem.java @@ -1,9 +1,9 @@ /* - * Copyright (C) 2007-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.executeafm.resultspec; +package com.gooddata.sdk.model.executeafm.resultspec; import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; diff --git a/src/main/java/com/gooddata/executeafm/resultspec/TotalItem.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/resultspec/TotalItem.java similarity index 79% rename from src/main/java/com/gooddata/executeafm/resultspec/TotalItem.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/resultspec/TotalItem.java index 2efcde570..b125547a5 100644 --- a/src/main/java/com/gooddata/executeafm/resultspec/TotalItem.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/resultspec/TotalItem.java @@ -1,17 +1,19 @@ /* - * Copyright (C) 2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.executeafm.resultspec; +package com.gooddata.sdk.model.executeafm.resultspec; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import com.gooddata.md.report.Total; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.md.report.Total; import java.util.Objects; -import static com.gooddata.util.Validate.notEmpty; -import static com.gooddata.util.Validate.notNull; +import static com.gooddata.sdk.common.util.Validate.notEmpty; +import static com.gooddata.sdk.common.util.Validate.notNull; /** * Total definition @@ -23,8 +25,9 @@ public class TotalItem { /** * Total definition - * @param measureIdentifier measure on which is total defined - * @param type total type + * + * @param measureIdentifier measure on which is total defined + * @param type total type * @param attributeIdentifier internal attribute identifier in AFM defining total placement */ @JsonCreator @@ -42,6 +45,7 @@ public TotalItem(final String measureIdentifier, final Total total, final String /** * total type + * * @return total type */ public String getType() { @@ -50,6 +54,7 @@ public String getType() { /** * internal measure identifier in AFM, on which is total defined + * * @return measure */ public String getMeasureIdentifier() { @@ -58,6 +63,7 @@ public String getMeasureIdentifier() { /** * internal attribute identifier in AFM defining total placement + * * @return identifier (never null) */ public String getAttributeIdentifier() { diff --git a/src/main/java/com/gooddata/executeafm/resultspec/TotalLocatorItem.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/resultspec/TotalLocatorItem.java similarity index 86% rename from src/main/java/com/gooddata/executeafm/resultspec/TotalLocatorItem.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/resultspec/TotalLocatorItem.java index cda7ea269..8929c5f64 100644 --- a/src/main/java/com/gooddata/executeafm/resultspec/TotalLocatorItem.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/executeafm/resultspec/TotalLocatorItem.java @@ -1,14 +1,14 @@ /* - * Copyright (C) 2004-2018, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.executeafm.resultspec; +package com.gooddata.sdk.model.executeafm.resultspec; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; /** * Holds total type and attribute to which this total corresponds. diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/export/ClientExport.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/export/ClientExport.java new file mode 100644 index 000000000..2258a8f0b --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/export/ClientExport.java @@ -0,0 +1,53 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.export; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; + +import static com.gooddata.sdk.common.util.Validate.notEmpty; +import static com.gooddata.sdk.common.util.Validate.notNull; + +@JsonTypeName("clientExport") +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonInclude(JsonInclude.Include.NON_NULL) +public class ClientExport { + + private static final String DASHBOARD_EXPORT_URI = "/dashboard.html#project=%s&dashboard=%s&tab=%s&export=1"; + + private final String url; + private final String name; + + ClientExport(final String url, final String name) { + this.url = notEmpty(url, "url"); + this.name = notEmpty(name, "name"); + } + + public ClientExport(final String goodDataEndpointUri, final String projectUri, final String dashboardUri, + final String tabId) { + this(notEmpty(goodDataEndpointUri, "goodDataEndpointUri") + + String.format(DASHBOARD_EXPORT_URI, + notNull(projectUri, "projectUri"), + notNull(dashboardUri, "dashboardUri"), + notNull(tabId, "tabId")), + "export.pdf"); + } + + public String getUrl() { + return url; + } + + public String getName() { + return name; + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } +} diff --git a/src/main/java/com/gooddata/export/ExecuteReport.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/export/ExecuteReport.java similarity index 78% rename from src/main/java/com/gooddata/export/ExecuteReport.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/export/ExecuteReport.java index f756a2acc..e5a8bdddb 100644 --- a/src/main/java/com/gooddata/export/ExecuteReport.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/export/ExecuteReport.java @@ -1,16 +1,16 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.export; +package com.gooddata.sdk.model.export; import com.fasterxml.jackson.annotation.JsonProperty; -import com.gooddata.md.report.Report; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.md.report.Report; -import static com.gooddata.util.Validate.notNull; +import static com.gooddata.sdk.common.util.Validate.notNull; /** * Report execution request diff --git a/src/main/java/com/gooddata/export/ExecuteReportDefinition.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/export/ExecuteReportDefinition.java similarity index 81% rename from src/main/java/com/gooddata/export/ExecuteReportDefinition.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/export/ExecuteReportDefinition.java index fe3ea0c8e..2efe1ded7 100644 --- a/src/main/java/com/gooddata/export/ExecuteReportDefinition.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/export/ExecuteReportDefinition.java @@ -1,16 +1,16 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.export; +package com.gooddata.sdk.model.export; import com.fasterxml.jackson.annotation.JsonProperty; -import com.gooddata.md.report.ReportDefinition; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.md.report.ReportDefinition; -import static com.gooddata.util.Validate.notNull; +import static com.gooddata.sdk.common.util.Validate.notNull; /** * Report definition execution request diff --git a/src/main/java/com/gooddata/export/ExportFormat.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/export/ExportFormat.java similarity index 84% rename from src/main/java/com/gooddata/export/ExportFormat.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/export/ExportFormat.java index 6a01c1d0f..2351381ca 100644 --- a/src/main/java/com/gooddata/export/ExportFormat.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/export/ExportFormat.java @@ -1,9 +1,9 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.export; +package com.gooddata.sdk.model.export; import java.util.stream.Stream; @@ -14,13 +14,13 @@ public enum ExportFormat { PDF, XLS, PNG, CSV, HTML, XLSX; - public String getValue() { - return name().toLowerCase(); - } - public static String[] arrayToStringArray(final ExportFormat... formats) { return Stream.of(formats) .map(ExportFormat::getValue) .toArray(String[]::new); } + + public String getValue() { + return name().toLowerCase(); + } } diff --git a/src/main/java/com/gooddata/export/ReportRequest.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/export/ReportRequest.java similarity index 87% rename from src/main/java/com/gooddata/export/ReportRequest.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/export/ReportRequest.java index 290495c06..a45308ee8 100644 --- a/src/main/java/com/gooddata/export/ReportRequest.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/export/ReportRequest.java @@ -1,9 +1,9 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.export; +package com.gooddata.sdk.model.export; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/src/main/java/com/gooddata/featureflag/FeatureFlag.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/featureflag/FeatureFlag.java similarity index 86% rename from src/main/java/com/gooddata/featureflag/FeatureFlag.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/featureflag/FeatureFlag.java index 570f61baa..484ff016a 100644 --- a/src/main/java/com/gooddata/featureflag/FeatureFlag.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/featureflag/FeatureFlag.java @@ -1,18 +1,19 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.featureflag; +package com.gooddata.sdk.model.featureflag; -import static com.gooddata.util.Validate.notNull; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; -import com.gooddata.util.GoodDataToStringBuilder; +import static com.gooddata.sdk.common.util.Validate.notNull; /** * Feature flag is a boolean flag used for enabling / disabling some specific feature of GoodData platform. * It can be used in various scopes (per project, per project group, per user, global etc.). */ +@Deprecated public class FeatureFlag { private final String name; diff --git a/src/main/java/com/gooddata/featureflag/FeatureFlags.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/featureflag/FeatureFlags.java similarity index 81% rename from src/main/java/com/gooddata/featureflag/FeatureFlags.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/featureflag/FeatureFlags.java index a32ad001b..9d81c3811 100644 --- a/src/main/java/com/gooddata/featureflag/FeatureFlags.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/featureflag/FeatureFlags.java @@ -1,17 +1,16 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.featureflag; +package com.gooddata.sdk.model.featureflag; import com.fasterxml.jackson.annotation.JsonAnyGetter; import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.util.GoodDataToStringBuilder; -import org.springframework.web.util.UriTemplate; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.util.Iterator; import java.util.LinkedList; @@ -19,29 +18,29 @@ import java.util.Map; import java.util.Optional; -import static com.gooddata.util.Validate.notEmpty; +import static com.gooddata.sdk.common.util.Validate.notEmpty; +import static com.gooddata.sdk.common.util.Validate.notNull; import static java.util.stream.Collectors.toMap; -import static org.springframework.util.Assert.notNull; +@Deprecated @JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) @JsonTypeName("featureFlags") @JsonIgnoreProperties(ignoreUnknown = true) public class FeatureFlags implements Iterable { public static final String AGGREGATED_FEATURE_FLAGS_URI = "/gdc/internal/projects/{projectId}/featureFlags"; - public static final UriTemplate AGGREGATED_FEATURE_FLAGS_TEMPLATE = new UriTemplate(AGGREGATED_FEATURE_FLAGS_URI); private final List featureFlags = new LinkedList<>(); /** * Adds the feature flag of given name and given value. * - * @param name feature flag name + * @param name feature flag name * @param enabled feature flag value (enabled / disabled) */ @JsonAnySetter public void addFlag(final String name, final boolean enabled) { - notNull(name); + notNull(name, "name"); featureFlags.add(new FeatureFlag(name, enabled)); } @@ -56,6 +55,7 @@ public void removeFlag(final String flagName) { /** * Converts feature flags to map where flags' names are the keys and values are flags' enabled property + * * @return feature flags as map */ @JsonAnyGetter @@ -87,16 +87,13 @@ private Optional findFlag(final String flagName) { public boolean equals(final Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - final FeatureFlags that = (FeatureFlags) o; - - return !(featureFlags != null ? !featureFlags.equals(that.featureFlags) : that.featureFlags != null); - + return featureFlags.equals(that.featureFlags); } @Override public int hashCode() { - return featureFlags != null ? featureFlags.hashCode() : 0; + return featureFlags.hashCode(); } @Override diff --git a/src/main/java/com/gooddata/featureflag/ProjectFeatureFlag.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/featureflag/ProjectFeatureFlag.java similarity index 81% rename from src/main/java/com/gooddata/featureflag/ProjectFeatureFlag.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/featureflag/ProjectFeatureFlag.java index 05a5349c7..664034e8d 100644 --- a/src/main/java/com/gooddata/featureflag/ProjectFeatureFlag.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/featureflag/ProjectFeatureFlag.java @@ -1,21 +1,27 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.featureflag; +package com.gooddata.sdk.model.featureflag; -import com.fasterxml.jackson.annotation.*; -import com.gooddata.util.GoodDataToStringBuilder; -import org.springframework.web.util.UriTemplate; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; -import static com.gooddata.util.Validate.notEmpty; -import static com.gooddata.util.Validate.notNullState; +import static com.gooddata.sdk.common.util.Validate.notEmpty; +import static com.gooddata.sdk.common.util.Validate.notNullState; /** * Project feature flag is a boolean flag used for enabling / disabling some specific feature of GoodData platform * on per project basis. */ +@Deprecated @JsonTypeName("featureFlag") @JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) @JsonIgnoreProperties(ignoreUnknown = true) @@ -23,13 +29,11 @@ public class ProjectFeatureFlag { public static final String PROJECT_FEATURE_FLAG_URI = ProjectFeatureFlags.PROJECT_FEATURE_FLAGS_URI + "/{featureFlag}"; - public static final UriTemplate PROJECT_FEATURE_FLAG_TEMPLATE = new UriTemplate(PROJECT_FEATURE_FLAG_URI); private final String name; - private boolean enabled; - @JsonIgnore private final Links links; + private boolean enabled; /** * Creates new project feature flag which is by default enabled (true). @@ -43,7 +47,7 @@ public ProjectFeatureFlag(String name) { /** * Creates new project feature flag with given value. * - * @param name unique name of feature flag + * @param name unique name of feature flag * @param enabled true (flag enabled) or false (flag disabled) */ public ProjectFeatureFlag(String name, boolean enabled) { diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/featureflag/ProjectFeatureFlags.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/featureflag/ProjectFeatureFlags.java new file mode 100644 index 000000000..bcd2cd37b --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/featureflag/ProjectFeatureFlags.java @@ -0,0 +1,65 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.featureflag; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.project.Project; + +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +import static com.gooddata.sdk.common.util.Validate.notEmpty; + +@Deprecated +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonTypeName("featureFlags") +@JsonIgnoreProperties(ignoreUnknown = true) +public class ProjectFeatureFlags implements Iterable { + + public static final String PROJECT_FEATURE_FLAGS_URI = Project.URI + "/projectFeatureFlags"; + + @JsonProperty("items") + private final List items = new LinkedList<>(); + + @JsonCreator + ProjectFeatureFlags(@JsonProperty("items") List items) { + if (items != null && !items.isEmpty()) { + this.items.addAll(items); + } + } + + @Override + public Iterator iterator() { + return items.iterator(); + } + + /** + * Returns true if the project feature flag with given name exists and is enabled, false otherwise. + * + * @param flagName the name of project feature flag + * @return true if the project feature flag with given name exists and is enabled, false otherwise + */ + public boolean isEnabled(final String flagName) { + notEmpty(flagName, "flagName"); + for (final ProjectFeatureFlag flag : items) { + if (flagName.equalsIgnoreCase(flag.getName())) { + return flag.isEnabled(); + } + } + return false; + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } +} diff --git a/src/main/java/com/gooddata/gdc/AboutLinks.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/gdc/AboutLinks.java similarity index 82% rename from src/main/java/com/gooddata/gdc/AboutLinks.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/gdc/AboutLinks.java index ad9fbbbb8..14e57a9b0 100644 --- a/src/main/java/com/gooddata/gdc/AboutLinks.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/gdc/AboutLinks.java @@ -1,12 +1,17 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.gdc; +package com.gooddata.sdk.model.gdc; -import com.fasterxml.jackson.annotation.*; -import com.gooddata.util.GoodDataToStringBuilder; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.util.Collection; import java.util.List; @@ -79,6 +84,10 @@ public Link(@JsonProperty("identifier") String identifier, @JsonProperty("link") this.summary = summary; } + public Link(String identifier, String uri, String title) { + this(identifier, uri, title, null, null); + } + public String getIdentifier() { return identifier; } @@ -87,15 +96,6 @@ public String getUri() { return uri; } - /** - * @return self URI string - * @deprecated use {@link #getUri()} instead - */ - @Deprecated - public String getLink() { - return getUri(); - } - public String getTitle() { return title; } diff --git a/src/main/java/com/gooddata/gdc/AbstractMaql.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/gdc/AbstractMaql.java similarity index 86% rename from src/main/java/com/gooddata/gdc/AbstractMaql.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/gdc/AbstractMaql.java index a6ff218df..0ebff076d 100644 --- a/src/main/java/com/gooddata/gdc/AbstractMaql.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/gdc/AbstractMaql.java @@ -1,16 +1,16 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.gdc; +package com.gooddata.sdk.model.gdc; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; /** * Abstract MAQL statement. diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/gdc/AsyncTask.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/gdc/AsyncTask.java new file mode 100644 index 000000000..8fd0f34b9 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/gdc/AsyncTask.java @@ -0,0 +1,57 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.gdc; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; + +/** + * Asynchronous task containing link for polling. + * Deserialization only. + */ +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonTypeName("asyncTask") +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +public class AsyncTask { + + @JsonProperty + private final Link link; + + @JsonCreator + private AsyncTask(@JsonProperty("link") Link link) { + this.link = link; + } + + public AsyncTask(final String uri) { + this.link = new Link(uri); + } + + @JsonIgnore + public String getUri() { + return link.getPoll(); + } + + private static class Link { + + private final String poll; + + @JsonCreator + private Link(@JsonProperty("poll") String poll) { + this.poll = poll; + } + + public String getPoll() { + return poll; + } + } + +} diff --git a/src/main/java/com/gooddata/gdc/LinkEntries.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/gdc/LinkEntries.java similarity index 81% rename from src/main/java/com/gooddata/gdc/LinkEntries.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/gdc/LinkEntries.java index 3c36f3cb2..3324c8177 100644 --- a/src/main/java/com/gooddata/gdc/LinkEntries.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/gdc/LinkEntries.java @@ -1,14 +1,14 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.gdc; +package com.gooddata.sdk.model.gdc; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.util.List; @@ -46,15 +46,6 @@ private LinkEntry(@JsonProperty("link") String uri, @JsonProperty("category") St this.category = category; } - /** - * @return self URI string - * @deprecated use {@link #getUri()} instead - */ - @Deprecated - public String getLink() { - return getUri(); - } - public String getUri() { return uri; } diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/gdc/RootLinks.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/gdc/RootLinks.java new file mode 100644 index 000000000..fed0c3402 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/gdc/RootLinks.java @@ -0,0 +1,240 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.gdc; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.gooddata.sdk.common.GoodDataException; + +import java.util.List; + +/** + * GoodData API root links (aka "about" or "home"). + * Deserialization only. + */ +public class RootLinks extends AboutLinks { + + /** + * URI of GoodData API root + */ + public static final String URI = "/gdc"; + + @JsonCreator + public RootLinks(@JsonProperty("links") List links) { + super(null, null, null, links); + } + + /** + * Get GoodData API root URI string + * + * @return GoodData API root URI string + * @throws GoodDataException in case no link with such category found + */ + @JsonIgnore + public String getHomeUri() { + return getLink(LinkCategory.HOME).getUri(); + } + + /** + * Get temporary token generator URI string + * + * @return temporary token generator URI string + * @throws GoodDataException in case no link with such category found + */ + @JsonIgnore + public String getTokenUri() { + return getLink(LinkCategory.TOKEN).getUri(); + } + + /** + * Get authentication service URI string + * + * @return authentication service URI string + * @throws GoodDataException in case no link with such category found + */ + @JsonIgnore + public String getLoginUri() { + return getLink(LinkCategory.LOGIN).getUri(); + } + + /** + * Get metadata resources URI string + * + * @return metadata resources URI string + * @throws GoodDataException in case no link with such category found + */ + @JsonIgnore + public String getMetadataUri() { + return getLink(LinkCategory.METADATA).getUri(); + } + + /** + * Get report execution resource URI string + * + * @return report execution resource URI string + * @throws GoodDataException in case no link with such category found + */ + @JsonIgnore + public String getXTabUri() { + return getLink(LinkCategory.XTAB).getUri(); + } + + /** + * Get URI string of resource used to determine valid attribute values in the context of a report + * + * @return URI string of resource used to determine valid attribute values in the context of a report + * @throws GoodDataException in case no link with such category found + */ + @JsonIgnore + public String getAvailableElementsUri() { + return getLink(LinkCategory.AVAILABLE_ELEMENTS).getUri(); + } + + /** + * Get report exporting resource URI string + * + * @return report exporting resource URI string + * @throws GoodDataException in case no link with such category found + */ + @JsonIgnore + public String getReportExporterUri() { + return getLink(LinkCategory.REPORT_EXPORTER).getUri(); + } + + /** + * Get account manipulation resource URI string + * + * @return account manipulation resource URI string + * @throws GoodDataException in case no link with such category found + */ + @JsonIgnore + public String getAccountUri() { + return getLink(LinkCategory.ACCOUNT).getUri(); + } + + /** + * Get user and project management resource URI string + * + * @return user and project management resource URI string + * @throws GoodDataException in case no link with such category found + */ + @JsonIgnore + public String getProjectsUri() { + return getLink(LinkCategory.PROJECTS).getUri(); + } + + /** + * Get miscellaneous tool resource URI string + * + * @return miscellaneous tool resource URI string + * @throws GoodDataException in case no link with such category found + */ + @JsonIgnore + public String getToolUri() { + return getLink(LinkCategory.TOOL).getUri(); + } + + /** + * Get template resource URI string + * + * @return template resource URI string + * @throws GoodDataException in case no link with such category found + */ + @JsonIgnore + public String getTemplatesUri() { + return getLink(LinkCategory.TEMPLATES).getUri(); + } + + /** + * Get user data staging area URI string + * + * @return user data staging area URI string + * @throws GoodDataException in case no link with such category found + */ + @JsonIgnore + public String getUserStagingUri() { + return getLink(LinkCategory.USER_STAGING).getUri(); + } + + /** + * Get link by category + * + * @param category requested link category + * @return link by given category + * @throws GoodDataException in case no link with such category found + */ + @JsonIgnore + private Link getLink(LinkCategory category) { + for (Link link : getLinks()) { + if (category.value.equals(link.getCategory())) { + return link; + } + } + throw new GoodDataException("No link with such category found"); + } + + /** + * GoodData API root link category enum + */ + private enum LinkCategory { + /** + * GoodData API root + */ + HOME("home"), + /** + * Temporary token generator + */ + TOKEN("token"), + /** + * Authentication service + */ + LOGIN("login"), + /** + * Metadata resources + */ + METADATA("md"), + /** + * Report execution resource + */ + XTAB("xtab"), + /** + * Resource used to determine valid attribute values in the context of a report + */ + AVAILABLE_ELEMENTS("availablelements"), + /** + * Report exporting resource + */ + REPORT_EXPORTER("report-exporter"), + /** + * Resource for logged in account manipulation + */ + ACCOUNT("account"), + /** + * Resource for user and project management + */ + PROJECTS("projects"), + /** + * Miscellaneous resources + */ + TOOL("tool"), + /** + * Template resource - for internal use only + */ + TEMPLATES("templates"), + /** + * User data staging area + */ + USER_STAGING("uploads"); + + private final String value; + + LinkCategory(final String value) { + this.value = value; + } + } + +} \ No newline at end of file diff --git a/src/main/java/com/gooddata/gdc/TaskStatus.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/gdc/TaskStatus.java similarity index 91% rename from src/main/java/com/gooddata/gdc/TaskStatus.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/gdc/TaskStatus.java index 652a58bc3..b9d70dc1b 100644 --- a/src/main/java/com/gooddata/gdc/TaskStatus.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/gdc/TaskStatus.java @@ -1,16 +1,17 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.gdc; +package com.gooddata.sdk.model.gdc; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.gdc.GdcError; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.util.Collection; import java.util.Collections; diff --git a/src/main/java/com/gooddata/gdc/UriResponse.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/gdc/UriResponse.java similarity index 87% rename from src/main/java/com/gooddata/gdc/UriResponse.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/gdc/UriResponse.java index f7b36611a..0aa2201ad 100644 --- a/src/main/java/com/gooddata/gdc/UriResponse.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/gdc/UriResponse.java @@ -1,15 +1,15 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.gdc; +package com.gooddata.sdk.model.gdc; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.io.Serializable; diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/hierarchicalconfig/ConfigItem.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/hierarchicalconfig/ConfigItem.java new file mode 100644 index 000000000..aec37382b --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/hierarchicalconfig/ConfigItem.java @@ -0,0 +1,180 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.hierarchicalconfig; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; + +import static com.gooddata.sdk.common.util.Validate.notEmpty; +import static com.gooddata.sdk.common.util.Validate.notNullState; +import static com.gooddata.sdk.model.hierarchicalconfig.SourceType.CLIENT; +import static com.gooddata.sdk.model.hierarchicalconfig.SourceType.DATA_PRODUCT; +import static com.gooddata.sdk.model.hierarchicalconfig.SourceType.DOMAIN; +import static com.gooddata.sdk.model.hierarchicalconfig.SourceType.PROJECT; +import static com.gooddata.sdk.model.hierarchicalconfig.SourceType.PROJECT_GROUP; +import static com.gooddata.sdk.model.hierarchicalconfig.SourceType.SEGMENT; + +/** + * Contains information about hierarchical configuration object aka platform setting aka feature flag. + * Purpose of config item is carrying information about some specific feature of Gooddata platform. + */ +@JsonTypeName("settingItem") +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +public class ConfigItem { + + public static final String CLIENT_CONFIG_ITEM_URI = CLIENT.getApiUri() + "/{configName}"; + public static final String DATA_PRODUCT_CONFIG_ITEM_URI = DATA_PRODUCT.getApiUri() + "/{configName}"; + public static final String SEGMENT_CONFIG_ITEM_URI = SEGMENT.getApiUri() + "/{configName}"; + public static final String DOMAIN_CONFIG_ITEM_URI = DOMAIN.getApiUri() + "/{configName}"; + public static final String PROJECT_CONFIG_ITEM_URI = PROJECT.getApiUri() + "/{configName}"; + public static final String PROJECT_GROUP_CONFIG_ITEM_URI = PROJECT_GROUP.getApiUri() + "/{configName}"; + + private final String key; + private final String source; + private final Links links; + private String value; + + /** + * Creates new config item with given key/name and value. + * + * @param key unique key/name of config item + * @param value value of config item + */ + public ConfigItem(String key, String value) { + this(notEmpty(key, "key"), notEmpty(value, "value"), null, null); + } + + @JsonCreator + ConfigItem(@JsonProperty("key") String key, @JsonProperty("value") String value, + @JsonProperty("source") String source, @JsonProperty("links") Links links) { + this.key = key; + this.value = value; + this.source = source; + this.links = links; + } + + /** + * Get unique key/name of config item. The same as {@link #getName()}. + */ + @JsonProperty("key") + public String getKey() { + return key; + } + + /** + * Get unique key/name of config item. The same as {@link #getKey()}. + */ + @JsonIgnore + public String getName() { + return key; + } + + @JsonProperty("value") + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + @JsonIgnore + public String getSource() { + return source; + } + + @JsonIgnore + public Links getLinks() { + return links; + } + + /** + * Conversion method from String to Boolean type. + * + * @return returns converted value: true or false + */ + @JsonIgnore + public boolean isEnabled() { + return Boolean.parseBoolean(this.value); + } + + public void setEnabled(Boolean value) { + this.value = String.valueOf(value); + } + + /** + * Conversion method from source to SourceType enum. + * + * @return returns SourceType or null, if source is not recognized + */ + @JsonIgnore + public SourceType getSourceType() { + return SourceType.get(source); + } + + @JsonIgnore + public String getUri() { + return notNullState(links, "links").getSelf(); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + final ConfigItem that = (ConfigItem) o; + + if (value != null ? !value.equals(that.value) : that.value != null) { + return false; + } + return !(key != null ? !key.equals(that.key) : that.key != null); + + } + + @Override + public int hashCode() { + int result = key != null ? key.hashCode() : 0; + result = 31 * result + (value != null ? value.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } + + @JsonIgnoreProperties(ignoreUnknown = true) + static class Links { + private final String self; + + @JsonCreator + public Links(@JsonProperty("self") String self) { + this.self = self; + } + + public String getSelf() { + return self; + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } + } + +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/hierarchicalconfig/ConfigItems.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/hierarchicalconfig/ConfigItems.java new file mode 100644 index 000000000..e09b1b0c7 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/hierarchicalconfig/ConfigItems.java @@ -0,0 +1,93 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.hierarchicalconfig; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import static com.gooddata.sdk.common.util.Validate.notEmpty; +import static com.gooddata.sdk.model.hierarchicalconfig.SourceType.CLIENT; +import static com.gooddata.sdk.model.hierarchicalconfig.SourceType.DATA_PRODUCT; +import static com.gooddata.sdk.model.hierarchicalconfig.SourceType.DOMAIN; +import static com.gooddata.sdk.model.hierarchicalconfig.SourceType.PROJECT; +import static com.gooddata.sdk.model.hierarchicalconfig.SourceType.PROJECT_GROUP; +import static com.gooddata.sdk.model.hierarchicalconfig.SourceType.SEGMENT; + +/** + * Contains collection of config items aka feature flags aka hierarchical config. + */ +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonTypeName("settings") +@JsonIgnoreProperties(ignoreUnknown = true) +public class ConfigItems implements Iterable { + + public static final String CLIENT_CONFIG_ITEMS_URI = CLIENT.getApiUri(); + public static final String DATA_PRODUCT_CONFIG_ITEMS_URI = DATA_PRODUCT.getApiUri(); + public static final String SEGMENT_CONFIG_ITEMS_URI = SEGMENT.getApiUri(); + public static final String DOMAIN_CONFIG_ITEMS_URI = DOMAIN.getApiUri(); + public static final String PROJECT_CONFIG_ITEMS_URI = PROJECT.getApiUri(); + public static final String PROJECT_GROUP_CONFIG_ITEMS_URI = PROJECT_GROUP.getApiUri(); + + @JsonProperty("items") + private final List items = new ArrayList<>(); + + @JsonCreator + public ConfigItems(@JsonProperty("items") List items) { + if (items != null && !items.isEmpty()) { + this.items.addAll(items); + } + } + + @Override + public Iterator iterator() { + return items.iterator(); + } + + /** + * Returns value if config item exists, otherwise returns null. + * + * @param configName the name/key of the config item + * @return value if config item with given name/key exists, null otherwise + */ + public String getValue(final String configName) { + notEmpty(configName, "configName"); + for (final ConfigItem item : items) { + if (configName.equalsIgnoreCase(item.getKey())) { + return item.getValue(); + } + } + return null; + } + + /** + * Returns true if the config item with given name/key exists and is enabled, false otherwise. + * + * @param configName the name/key of config item + * @return true if the config item with given name/key exists and is enabled, false otherwise + */ + public boolean isEnabled(final String configName) { + notEmpty(configName, "configName"); + for (final ConfigItem item : items) { + if (configName.equalsIgnoreCase(item.getKey())) { + return Boolean.parseBoolean(item.getValue()); + } + } + return false; + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/hierarchicalconfig/SourceType.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/hierarchicalconfig/SourceType.java new file mode 100644 index 000000000..4a3a1b0eb --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/hierarchicalconfig/SourceType.java @@ -0,0 +1,88 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.hierarchicalconfig; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.HashMap; +import java.util.Map; + +/** + * Source type defines source of config item and its api uri in case it is manageable. + * For example, the project can inherit config from the domain, but if the config is defined for both: domain and project, + * then config from project takes precedence. + */ +public enum SourceType { + + @JsonProperty("catalog") + CATALOG("catalog", null), + @JsonProperty("client") + CLIENT("client", "/gdc/domains/{domainName}/dataproducts/{dataProductId}/clients/{clientId}/config"), + @JsonProperty("data_product") + DATA_PRODUCT("data_product", "/gdc/domains/{domainName}/dataproducts/{dataProductId}/config"), + @JsonProperty("segment") + SEGMENT("segment", "/gdc/domains/{domainName}/dataproducts/{dataProductId}/segments/{segmentId}/config"), + @JsonProperty("datawarehouse") + DATAWAREHOUSE("datawarehouse", null), + @JsonProperty("domain") + DOMAIN("domain", "/gdc/domains/{domainName}/config"), + @JsonProperty("project") + PROJECT("project", "/gdc/projects/{pid}/config"), + @JsonProperty("project_group") + PROJECT_GROUP("project_group", "/gdc/projectGroups/{projectGroup}/config"), + @JsonProperty("user") + USER("user", null); + + private static final Map lookup = new HashMap<>(); + + static { + for (SourceType c : SourceType.values()) { + lookup.put(c.name, c); + } + } + + /** + * Name of the source type of config item + */ + private final String name; + + /** + * Api uri in case that config item is manageable + */ + private final String apiUri; + + /** + * @param name source of config item + * @param apiUri api uri in case that config item is manageable + */ + SourceType(String name, String apiUri) { + this.name = name; + this.apiUri = apiUri; + } + + /** + * Get source type by string. + * + * @param source name of the source + * @return Source type enum instance according to the given name + */ + public static SourceType get(String source) { + return lookup.get(source); + } + + public String getName() { + return name; + } + + public String getApiUri() { + return apiUri; + } + + @Override + public String toString() { + return this.name; + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/lcm/LcmEntities.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/lcm/LcmEntities.java new file mode 100644 index 000000000..30dd48279 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/lcm/LcmEntities.java @@ -0,0 +1,63 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.lcm; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.gooddata.sdk.common.collections.Page; +import com.gooddata.sdk.common.collections.PageDeserializer; +import com.gooddata.sdk.common.collections.PageSerializer; +import com.gooddata.sdk.common.collections.Paging; + +import java.util.List; +import java.util.Map; + +import static java.util.Arrays.asList; + +/** + * List of {@link LcmEntity}. + */ +@JsonDeserialize(using = LcmEntities.Deserializer.class) +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonTypeName(LcmEntities.ROOT_NODE) +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonSerialize(using = LcmEntities.Serializer.class) +@JsonInclude(JsonInclude.Include.NON_EMPTY) +public class LcmEntities extends Page { + + public static final String URI = "/gdc/account/profile/{profileId}/lcmEntities"; + + static final String ROOT_NODE = "lcmEntities"; + + public LcmEntities(final List items, final Paging paging, final Map links) { + super(items, paging, links); + } + + LcmEntities(final LcmEntity... lcmEntities) { + this(asList(lcmEntities), null, null); + } + + static class Serializer extends PageSerializer { + public Serializer() { + super(ROOT_NODE); + } + } + + static class Deserializer extends PageDeserializer { + protected Deserializer() { + super(LcmEntity.class); + } + + @Override + protected LcmEntities createPage(final List items, final Paging paging, final Map links) { + return new LcmEntities(items, paging, links); + } + } +} diff --git a/src/main/java/com/gooddata/lcm/LcmEntity.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/lcm/LcmEntity.java similarity index 83% rename from src/main/java/com/gooddata/lcm/LcmEntity.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/lcm/LcmEntity.java index 5d753a9d7..17f060ddb 100644 --- a/src/main/java/com/gooddata/lcm/LcmEntity.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/lcm/LcmEntity.java @@ -1,30 +1,31 @@ /* - * Copyright (C) 2007-2018, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.lcm; +package com.gooddata.sdk.model.lcm; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.project.Project; import java.util.Map; import java.util.Objects; -import static com.gooddata.lcm.LcmEntity.LinkCategory.CLIENT; -import static com.gooddata.lcm.LcmEntity.LinkCategory.DATA_PRODUCT; -import static com.gooddata.lcm.LcmEntity.LinkCategory.PROJECT; -import static com.gooddata.lcm.LcmEntity.LinkCategory.SEGMENT; -import static com.gooddata.util.Validate.notEmpty; -import static com.gooddata.util.Validate.notNull; -import static com.gooddata.util.Validate.notNullState; +import static com.gooddata.sdk.common.util.Validate.notEmpty; +import static com.gooddata.sdk.common.util.Validate.notNull; +import static com.gooddata.sdk.common.util.Validate.notNullState; +import static com.gooddata.sdk.model.lcm.LcmEntity.LinkCategory.CLIENT; +import static com.gooddata.sdk.model.lcm.LcmEntity.LinkCategory.DATA_PRODUCT; +import static com.gooddata.sdk.model.lcm.LcmEntity.LinkCategory.PROJECT; +import static com.gooddata.sdk.model.lcm.LcmEntity.LinkCategory.SEGMENT; /** - * Single Life Cycle Management entity representing the relation between {@link com.gooddata.project.Project}, + * Single Life Cycle Management entity representing the relation between {@link Project}, * Client, Segment and DataProduct. */ @JsonIgnoreProperties(ignoreUnknown = true) @@ -40,9 +41,10 @@ public class LcmEntity { /** * Creates new instance of given project id and title - * @param projectId id of the project + * + * @param projectId id of the project * @param projectTitle title of the project - * @param links links + * @param links links */ public LcmEntity(final String projectId, final String projectTitle, final Map links) { this(projectId, projectTitle, null, null, null, links); diff --git a/src/main/java/com/gooddata/lcm/LcmEntityFilter.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/lcm/LcmEntityFilter.java similarity index 87% rename from src/main/java/com/gooddata/lcm/LcmEntityFilter.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/lcm/LcmEntityFilter.java index 055805443..3d04a01ac 100644 --- a/src/main/java/com/gooddata/lcm/LcmEntityFilter.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/lcm/LcmEntityFilter.java @@ -1,12 +1,13 @@ /* - * Copyright (C) 2007-2018, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.lcm; +package com.gooddata.sdk.model.lcm; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; import static java.util.Collections.singletonList; import static org.apache.commons.lang3.StringUtils.isNotBlank; @@ -32,6 +33,7 @@ public LcmEntityFilter() { /** * Adds given data product to this filter. + * * @param dataProduct data product id - must not be empty. * @return this filter */ @@ -44,6 +46,7 @@ public LcmEntityFilter withDataProduct(final String dataProduct) { /** * Adds given segment to this filter. + * * @param segment segment id - must not be empty. * @return this filter */ @@ -56,6 +59,7 @@ public LcmEntityFilter withSegment(final String segment) { /** * Adds given client to this filter. + * * @param client client id - must not be empty. * @return this filter */ @@ -80,10 +84,11 @@ public String getClient() { /** * This filter in the form of query parameters map. + * * @return filter as query params map */ - public MultiValueMap asQueryParams() { - final MultiValueMap params = new LinkedMultiValueMap<>(); + public Map> asQueryParams() { + final Map> params = new LinkedHashMap<>(); if (dataProduct != null) { params.put(DATA_PRODUCT, singletonList(dataProduct)); } diff --git a/src/main/java/com/gooddata/md/AbstractObj.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/AbstractObj.java similarity index 90% rename from src/main/java/com/gooddata/md/AbstractObj.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/AbstractObj.java index 153b939be..44e9bde7d 100644 --- a/src/main/java/com/gooddata/md/AbstractObj.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/AbstractObj.java @@ -1,19 +1,20 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md; +package com.gooddata.sdk.model.md; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; -import com.gooddata.util.GoodDataToStringBuilder; -import org.joda.time.DateTime; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.util.UriHelper; import java.io.Serializable; +import java.time.ZonedDateTime; import java.util.Set; -import static com.gooddata.util.Validate.noNullElements; +import static com.gooddata.sdk.common.util.Validate.noNullElements; /** * Metadata object (common part) @@ -29,6 +30,23 @@ protected AbstractObj(@JsonProperty("meta") Meta meta) { this.meta = meta; } + /** + * Get list of URIs of the given {@link Obj}s + * + * @param objs metadata objects + * @param Obj type + * @return list of URIs + */ + @SafeVarargs + protected static String[] uris(T... objs) { + noNullElements(objs, "objs"); + final String[] uris = new String[objs.length]; + for (int i = 0; i < objs.length; i++) { + uris[i] = objs[i].getUri(); + } + return uris; + } + /** * Returns internally generated ID of the object (that's part of the object URI). * @@ -36,7 +54,7 @@ protected AbstractObj(@JsonProperty("meta") Meta meta) { */ @JsonIgnore public String getId() { - return Obj.OBJ_TEMPLATE.match(getUri()).get("objId"); + return UriHelper.getLastUriPart(getUri()); } @JsonIgnore @@ -50,7 +68,7 @@ public String getContributor() { } @JsonIgnore - public DateTime getCreated() { + public ZonedDateTime getCreated() { return meta.getCreated(); } @@ -73,7 +91,7 @@ public void setTitle(String title) { } @JsonIgnore - public DateTime getUpdated() { + public ZonedDateTime getUpdated() { return meta.getUpdated(); } @@ -168,23 +186,6 @@ public void setFlags(final Set flags) { meta.setFlags(flags); } - /** - * Get list of URIs of the given {@link Obj}s - * - * @param objs metadata objects - * @param Obj type - * @return list of URIs - */ - @SafeVarargs - protected static String[] uris(T... objs) { - noNullElements(objs, "objs"); - final String[] uris = new String[objs.length]; - for (int i = 0; i < objs.length; i++) { - uris[i] = objs[i].getUri(); - } - return uris; - } - @Override public String toString() { return GoodDataToStringBuilder.defaultToString(this); diff --git a/src/main/java/com/gooddata/md/Attachment.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Attachment.java similarity index 89% rename from src/main/java/com/gooddata/md/Attachment.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Attachment.java index 60f9b0994..2dba335f2 100644 --- a/src/main/java/com/gooddata/md/Attachment.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Attachment.java @@ -1,9 +1,9 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md; +package com.gooddata.sdk.model.md; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @@ -11,7 +11,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.io.Serializable; @@ -35,7 +35,9 @@ protected Attachment(@JsonProperty("uri") String uri) { this.uri = uri; } - public String getUri() { return uri; } + public String getUri() { + return uri; + } @Override public boolean equals(Object o) { diff --git a/src/main/java/com/gooddata/md/Attribute.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Attribute.java similarity index 82% rename from src/main/java/com/gooddata/md/Attribute.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Attribute.java index 9cfc72f09..d19b54908 100644 --- a/src/main/java/com/gooddata/md/Attribute.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Attribute.java @@ -1,11 +1,9 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md; - -import static java.util.Arrays.asList; +package com.gooddata.sdk.model.md; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonInclude; @@ -15,6 +13,8 @@ import java.util.Collections; +import static java.util.Arrays.asList; + /** * Attribute of GoodData project dataset */ @@ -30,7 +30,7 @@ private Attribute(@JsonProperty("meta") Meta meta, @JsonProperty("content") Nest /* Just for serialization test */ Attribute(String title, Key primaryKey, Key foreignKey) { - this(new Meta(title), new Content(asList(primaryKey), asList(foreignKey), Collections.emptyList(), null, null, null, null, null, + this(new Meta(title), new Content(asList(primaryKey), asList(foreignKey), Collections.emptyList(), null, null, null, null, null, null, null, null, null, null, null)); } } diff --git a/src/main/java/com/gooddata/md/AttributeDisplayForm.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/AttributeDisplayForm.java similarity index 79% rename from src/main/java/com/gooddata/md/AttributeDisplayForm.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/AttributeDisplayForm.java index a199c5c7e..d86dcd7e6 100644 --- a/src/main/java/com/gooddata/md/AttributeDisplayForm.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/AttributeDisplayForm.java @@ -1,16 +1,21 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md; +package com.gooddata.sdk.model.md; -import com.fasterxml.jackson.annotation.*; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.gooddata.util.BooleanDeserializer; -import com.gooddata.util.BooleanIntegerSerializer; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.BooleanDeserializer; +import com.gooddata.sdk.common.util.BooleanIntegerSerializer; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; /** * Display form of attribute @@ -22,18 +27,13 @@ public class AttributeDisplayForm extends DisplayForm implements Updatable { private static final long serialVersionUID = -7903851496647992573L; - /** @deprecated use {@link #attributeContent} instead */ - @Deprecated - protected final AttributeContent content; - @JsonProperty("content") protected final AttributeContent attributeContent; @JsonCreator private AttributeDisplayForm(@JsonProperty("meta") Meta meta, @JsonProperty("content") AttributeContent content, - @JsonProperty("links") Links links) { + @JsonProperty("links") Links links) { super(meta, content, links); - this.content = content; this.attributeContent = content; } diff --git a/src/main/java/com/gooddata/md/AttributeElement.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/AttributeElement.java similarity index 91% rename from src/main/java/com/gooddata/md/AttributeElement.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/AttributeElement.java index 038a0799a..ffd105b3e 100644 --- a/src/main/java/com/gooddata/md/AttributeElement.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/AttributeElement.java @@ -1,15 +1,15 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md; +package com.gooddata.sdk.model.md; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; /** * Represent one element of attribute values diff --git a/src/main/java/com/gooddata/md/AttributeElements.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/AttributeElements.java similarity index 83% rename from src/main/java/com/gooddata/md/AttributeElements.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/AttributeElements.java index a4b0848f3..025b141de 100644 --- a/src/main/java/com/gooddata/md/AttributeElements.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/AttributeElements.java @@ -1,9 +1,9 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md; +package com.gooddata.sdk.model.md; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @@ -11,12 +11,11 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.util.GoodDataToStringBuilder; -import org.springframework.web.util.UriTemplate; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.util.List; -import static com.gooddata.util.Validate.notNull; +import static com.gooddata.sdk.common.util.Validate.notNull; /** * Represents elements of attribute @@ -25,10 +24,9 @@ @JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(JsonInclude.Include.NON_NULL) -class AttributeElements { +public class AttributeElements { static final String URI = Obj.OBJ_URI + "/elements"; - static final UriTemplate TEMPLATE = new UriTemplate(URI); private final List elements; diff --git a/src/main/java/com/gooddata/md/AttributeSort.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/AttributeSort.java similarity index 85% rename from src/main/java/com/gooddata/md/AttributeSort.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/AttributeSort.java index 380485684..a4d7d8838 100644 --- a/src/main/java/com/gooddata/md/AttributeSort.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/AttributeSort.java @@ -1,12 +1,9 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md; - -import static com.gooddata.util.Validate.notEmpty; -import static com.gooddata.util.Validate.notNull; +package com.gooddata.sdk.model.md; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonParser; @@ -17,11 +14,14 @@ import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.io.IOException; import java.io.Serializable; +import static com.gooddata.sdk.common.util.Validate.notEmpty; +import static com.gooddata.sdk.common.util.Validate.notNull; + /** * Internal representation of attribute sort field. Which can be either plain text value or structure pointing to display form. */ @@ -29,10 +29,9 @@ @JsonSerialize(using = AttributeSort.Serializer.class) class AttributeSort implements Serializable { - private static final long serialVersionUID = -7415504020870223701L; static final String PK = "pk"; static final String BY_USED_DF = "byUsedDF"; - + private static final long serialVersionUID = -7415504020870223701L; private final String value; private final boolean linkType; @@ -69,8 +68,8 @@ public AttributeSort deserialize(JsonParser p, DeserializationContext ctxt) thro } else if (root.isObject()) { return new AttributeSort(root.findValue("uri").textValue(), true); } else { - throw ctxt.mappingException("Only textual or object node expected but %s node found", - root.getNodeType().name()); + return (AttributeSort) ctxt.handleUnexpectedToken(AttributeSort.class, root.asToken(), p, + "Only textual or object node expected but %s node found", root.getNodeType().name()); } } } diff --git a/src/main/java/com/gooddata/md/BulkGet.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/BulkGet.java similarity index 87% rename from src/main/java/com/gooddata/md/BulkGet.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/BulkGet.java index 9d0b4574c..7ca9401fc 100644 --- a/src/main/java/com/gooddata/md/BulkGet.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/BulkGet.java @@ -1,9 +1,9 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md; +package com.gooddata.sdk.model.md; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @@ -11,7 +11,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.util.Collection; @@ -22,7 +22,7 @@ @JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(JsonInclude.Include.NON_NULL) -class BulkGet { +public class BulkGet { public static final String URI = "/gdc/md/{projectId}/objects/get"; diff --git a/src/main/java/com/gooddata/md/BulkGetUris.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/BulkGetUris.java similarity index 81% rename from src/main/java/com/gooddata/md/BulkGetUris.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/BulkGetUris.java index ccede5202..17086a66b 100644 --- a/src/main/java/com/gooddata/md/BulkGetUris.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/BulkGetUris.java @@ -1,18 +1,18 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md; +package com.gooddata.sdk.model.md; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.util.Collection; -import static com.gooddata.util.Validate.notNull; +import static com.gooddata.sdk.common.util.Validate.notNull; /** * Metadata bulk get request body representation. @@ -20,11 +20,11 @@ */ @JsonTypeName("get") @JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) -class BulkGetUris { +public class BulkGetUris { private final Collection items; - BulkGetUris(Collection items) { + public BulkGetUris(Collection items) { notNull(items, "items"); this.items = items; } diff --git a/src/main/java/com/gooddata/md/Column.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Column.java similarity index 93% rename from src/main/java/com/gooddata/md/Column.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Column.java index 604b9499e..ced161e41 100644 --- a/src/main/java/com/gooddata/md/Column.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Column.java @@ -1,16 +1,16 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md; +package com.gooddata.sdk.model.md; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.io.Serializable; @@ -22,16 +22,15 @@ @JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) public class Column extends AbstractObj implements Queryable { - private static final long serialVersionUID = 8235010456787885263L; public static final String TYPE_PK = "pk"; public static final String TYPE_INPUT_PK = "inputpk"; public static final String TYPE_FK = "fk"; public static final String TYPE_FACT = "fact"; public static final String TYPE_DISPLAY_FORM = "displayForm"; - + private static final long serialVersionUID = 8235010456787885263L; private final Content content; - private Column(@JsonProperty("meta") Meta meta, @JsonProperty("content")Content content) { + private Column(@JsonProperty("meta") Meta meta, @JsonProperty("content") Content content) { super(meta); this.content = content; } @@ -107,7 +106,7 @@ private static class Content implements Serializable { @JsonCreator private Content(@JsonProperty("table") String table, @JsonProperty("columnDBName") String columnDBName, - @JsonProperty("columnType") String columnType) { + @JsonProperty("columnType") String columnType) { this.table = table; this.columnDBName = columnDBName; this.columnType = columnType; diff --git a/src/main/java/com/gooddata/md/DashboardAttachment.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/DashboardAttachment.java similarity index 86% rename from src/main/java/com/gooddata/md/DashboardAttachment.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/DashboardAttachment.java index 24e7a36a4..49eb19acd 100644 --- a/src/main/java/com/gooddata/md/DashboardAttachment.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/DashboardAttachment.java @@ -1,13 +1,13 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md; +package com.gooddata.sdk.model.md; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.util.Arrays; import java.util.Collection; @@ -27,18 +27,24 @@ protected DashboardAttachment( @JsonProperty("allTabs") Integer allTabs, @JsonProperty("executionContext") String executionContext, @JsonProperty("tabs") String... tabs - ) { + ) { super(uri); this.allTabs = allTabs; this.tabs = Arrays.asList(tabs); this.executionContext = executionContext; } - public Integer getAllTabs() { return allTabs; } + public Integer getAllTabs() { + return allTabs; + } - public Collection getTabs() { return tabs; } + public Collection getTabs() { + return tabs; + } - public String getExecutionContext() { return executionContext; } + public String getExecutionContext() { + return executionContext; + } @Override public boolean equals(final Object o) { diff --git a/src/main/java/com/gooddata/md/DataLoadingColumn.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/DataLoadingColumn.java similarity index 82% rename from src/main/java/com/gooddata/md/DataLoadingColumn.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/DataLoadingColumn.java index c98d092ea..55f0421e6 100644 --- a/src/main/java/com/gooddata/md/DataLoadingColumn.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/DataLoadingColumn.java @@ -1,9 +1,9 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md; +package com.gooddata.sdk.model.md; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonInclude; @@ -11,9 +11,9 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.gooddata.gdc.UriResponse; -import com.gooddata.util.BooleanDeserializer; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.BooleanDeserializer; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.gdc.UriResponse; import java.io.Serializable; @@ -81,15 +81,15 @@ public boolean isNullable() { } public String getSynchronizeType() { - return content.getColumnSynchronize() != null ? content.getColumnSynchronize().getType() : null; + return content.getColumnSynchronize() != null ? content.getColumnSynchronize().getType() : null; } public Integer getSynchronizeLength() { - return content.getColumnSynchronize() != null ? content.getColumnSynchronize().getLength() : null; + return content.getColumnSynchronize() != null ? content.getColumnSynchronize().getLength() : null; } public Integer getSynchronizePrecision() { - return content.getColumnSynchronize() != null ? content.getColumnSynchronize().getPrecision() : null; + return content.getColumnSynchronize() != null ? content.getColumnSynchronize().getPrecision() : null; } @Override @@ -110,10 +110,10 @@ private static class Content implements Serializable { private final ColumnSynchronize columnSynchronize; private Content(@JsonProperty("column") UriResponse columnUri, @JsonProperty("columnName") String columnName, @JsonProperty("type") String columnType, - @JsonProperty("length") Integer columnLength, @JsonProperty("precision") Integer columnPrecision, - @JsonProperty("columnUnique") @JsonDeserialize(using = BooleanDeserializer.class) boolean columnUnique, - @JsonProperty("columnNull") @JsonDeserialize(using = BooleanDeserializer.class) boolean columnNull, - @JsonProperty("columnSynchronize") ColumnSynchronize columnSynchronize) { + @JsonProperty("length") Integer columnLength, @JsonProperty("precision") Integer columnPrecision, + @JsonProperty("columnUnique") @JsonDeserialize(using = BooleanDeserializer.class) boolean columnUnique, + @JsonProperty("columnNull") @JsonDeserialize(using = BooleanDeserializer.class) boolean columnNull, + @JsonProperty("columnSynchronize") ColumnSynchronize columnSynchronize) { this.columnUri = columnUri; this.columnName = columnName; this.columnType = columnType; @@ -169,7 +169,7 @@ private static class ColumnSynchronize implements Serializable { @JsonCreator private ColumnSynchronize(@JsonProperty("columnType") String type, @JsonProperty("columnLength") Integer length, - @JsonProperty("columnPrecision") Integer precision) { + @JsonProperty("columnPrecision") Integer precision) { this.type = type; this.length = length; this.precision = precision; diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Dataset.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Dataset.java new file mode 100644 index 000000000..d320b2c66 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Dataset.java @@ -0,0 +1,161 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.md; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.gooddata.sdk.common.util.BooleanDeserializer; +import com.gooddata.sdk.common.util.BooleanStringSerializer; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; + +import java.io.Serializable; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import static com.gooddata.sdk.common.util.Validate.notNullState; + +/** + * Represents metadata dataset + */ +@JsonTypeName("dataSet") +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonInclude(JsonInclude.Include.NON_NULL) +public class Dataset extends AbstractObj implements Queryable, Updatable { + + private static final long serialVersionUID = -6510493111358411706L; + private static final String DATA_UPLOADS_LINK = "dataUploads"; + private static final String UPLOAD_CONFIGURATION_LINK = "uploadConfiguration"; + + @JsonProperty("content") + private final Content content; + + @JsonProperty("links") + private final Map links; + + @JsonCreator + private Dataset(@JsonProperty("meta") Meta meta, @JsonProperty("content") Content content, + @JsonProperty("links") Map links) { + super(meta); + this.content = content; + this.links = links; + } + + /* Just for serialization test */ + Dataset(String title) { + this(new Meta(title), new Content(Collections.emptyList(), null, Collections.emptyList(), Collections.emptyList(), + Collections.emptyList(), false), null); + } + + @JsonIgnore + public List getTies() { + return content.getTies(); + } + + @JsonIgnore + public String getMode() { + return content.getMode(); + } + + @JsonIgnore + public List getFacts() { + return content.getFacts(); + } + + @JsonIgnore + public List getDataLoadingColumns() { + return content.getDataLoadingColumns(); + } + + @JsonIgnore + public List getAttributes() { + return content.getAttributes(); + } + + @JsonIgnore + public boolean hasUploadConfiguration() { + return Boolean.TRUE.equals(content.hasUploadConfiguration()); + } + + @JsonIgnore + public String getDataUploadsUri() { + return notNullState(links, "links").get(DATA_UPLOADS_LINK); + } + + @JsonIgnore + public String getUploadConfigurationUri() { + return notNullState(links, "links").get(UPLOAD_CONFIGURATION_LINK); + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } + + @JsonInclude(JsonInclude.Include.NON_NULL) + private static class Content implements Serializable { + + private static final long serialVersionUID = -8819963869909114313L; + private final List ties; + private final String mode; + private final List facts; + private final List dataLoadingColumns; + private final List attributes; + private final Boolean hasUploadConfiguration; + + @JsonCreator + private Content(@JsonProperty("ties") List ties, + @JsonProperty("mode") String mode, + @JsonProperty("facts") List facts, + @JsonProperty("dataLoadingColumns") List dataLoadingColumns, + @JsonProperty("attributes") List attributes, + @JsonProperty("hasUploadConfiguration") @JsonDeserialize(using = BooleanDeserializer.class) Boolean hasUploadConfiguration) { + this.ties = ties; + this.mode = mode; + this.facts = facts; + this.dataLoadingColumns = dataLoadingColumns; + this.attributes = attributes; + this.hasUploadConfiguration = hasUploadConfiguration; + } + + public List getTies() { + return ties; + } + + public String getMode() { + return mode; + } + + public List getFacts() { + return facts; + } + + public List getDataLoadingColumns() { + return dataLoadingColumns; + } + + public List getAttributes() { + return attributes; + } + + @JsonProperty("hasUploadConfiguration") + @JsonSerialize(using = BooleanStringSerializer.class) + public Boolean hasUploadConfiguration() { + return hasUploadConfiguration; + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Dimension.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Dimension.java new file mode 100644 index 000000000..a8331fee1 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Dimension.java @@ -0,0 +1,75 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.md; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; + +import java.io.Serializable; +import java.util.Collection; +import java.util.Collections; + +/** + * Represents metadata dimension. + */ +@JsonTypeName("dimension") +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonInclude(JsonInclude.Include.NON_NULL) +public class Dimension extends AbstractObj implements Queryable, Updatable { + + private static final long serialVersionUID = -6667238416764957848L; + + @JsonProperty("content") + private final Content content; + + @JsonCreator + private Dimension(@JsonProperty("meta") Meta meta, @JsonProperty("content") Content content) { + super(meta); + this.content = content; + } + + /* for serialization test */ + Dimension(String title) { + this(new Meta(title), new Content(Collections.emptyList())); + } + + @JsonIgnore + public Collection getAttributes() { + return content.getAttributes(); + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } + + private static class Content implements Serializable { + + private static final long serialVersionUID = -6382409825359596163L; + + @JsonProperty("attributes") + private final Collection attributes; + + @JsonCreator + public Content(@JsonProperty("attributes") Collection attributes) { + this.attributes = attributes; + } + + public Collection getAttributes() { + return attributes; + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } + } +} diff --git a/src/main/java/com/gooddata/md/DisplayForm.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/DisplayForm.java similarity index 89% rename from src/main/java/com/gooddata/md/DisplayForm.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/DisplayForm.java index a4676467c..06c314136 100644 --- a/src/main/java/com/gooddata/md/DisplayForm.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/DisplayForm.java @@ -1,16 +1,16 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md; +package com.gooddata.sdk.model.md; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.io.Serializable; @@ -31,7 +31,7 @@ public class DisplayForm extends AbstractObj { @JsonCreator protected DisplayForm(@JsonProperty("meta") Meta meta, @JsonProperty("content") Content content, - @JsonProperty("links") Links links) { + @JsonProperty("links") Links links) { super(meta); this.content = content; this.links = links; @@ -57,16 +57,6 @@ public String getType() { return content.getType(); } - /** - * @return elements URI string - * @deprecated use {@link #getElementsUri()} instead - */ - @Deprecated - @JsonIgnore - public String getElementsLink() { - return getElementsUri(); - } - @JsonIgnore public String getElementsUri() { return links.getElements(); diff --git a/src/main/java/com/gooddata/md/Entry.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Entry.java similarity index 76% rename from src/main/java/com/gooddata/md/Entry.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Entry.java index 7a3c6bb51..0de1741cc 100644 --- a/src/main/java/com/gooddata/md/Entry.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Entry.java @@ -1,16 +1,27 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md; +package com.gooddata.sdk.model.md; -import com.fasterxml.jackson.annotation.*; -import com.gooddata.util.*; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import org.joda.time.DateTime; - +import com.gooddata.sdk.common.util.BooleanDeserializer; +import com.gooddata.sdk.common.util.BooleanIntegerSerializer; +import com.gooddata.sdk.common.util.BooleanStringSerializer; +import com.gooddata.sdk.common.util.GDZonedDateTime; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.util.TagsDeserializer; +import com.gooddata.sdk.model.util.TagsSerializer; +import com.gooddata.sdk.model.util.UriHelper; + +import java.time.ZonedDateTime; import java.util.Set; /** @@ -29,8 +40,10 @@ public class Entry { private final Boolean deprecated; private final String identifier; private final Set tags; - private final DateTime created; - private final DateTime updated; + @GDZonedDateTime + private final ZonedDateTime created; + @GDZonedDateTime + private final ZonedDateTime updated; private final Boolean locked; private final Boolean unlisted; @@ -44,8 +57,8 @@ public Entry(@JsonProperty("link") String uri, @JsonProperty("deprecated") @JsonDeserialize(using = BooleanDeserializer.class) Boolean deprecated, @JsonProperty("identifier") String identifier, @JsonProperty("tags") @JsonDeserialize(using = TagsDeserializer.class) Set tags, - @JsonProperty("created") @JsonDeserialize(using = GDDateTimeDeserializer.class) DateTime created, - @JsonProperty("updated") @JsonDeserialize(using = GDDateTimeDeserializer.class) DateTime updated, + @JsonProperty("created") ZonedDateTime created, + @JsonProperty("updated") ZonedDateTime updated, @JsonProperty("locked") @JsonDeserialize(using = BooleanDeserializer.class) Boolean locked, @JsonProperty("unlisted") @JsonDeserialize(using = BooleanDeserializer.class) Boolean unlisted) { this.uri = uri; @@ -63,25 +76,17 @@ public Entry(@JsonProperty("link") String uri, this.unlisted = unlisted; } - /** - * @return self URI string - * @deprecated use {@link #getUri()} instead - */ - @Deprecated - public String getLink() { - return getUri(); - } - /** * Returns internally generated ID of the object (that's part of the object URI). + * * @return internal ID of the object */ @JsonIgnore public String getId() { - return Obj.OBJ_TEMPLATE.match(getUri()).get("objId"); + return UriHelper.getLastUriPart(getUri()); } - @JsonIgnore + @JsonProperty("link") public String getUri() { return uri; } @@ -121,6 +126,7 @@ public Boolean getDeprecated() { /** * Returns user-specified identifier of the object. + * * @return user-specified object identifier */ public String getIdentifier() { @@ -132,13 +138,11 @@ public Set getTags() { return tags; } - @JsonSerialize(using = GDDateTimeSerializer.class) - public DateTime getCreated() { + public ZonedDateTime getCreated() { return created; } - @JsonSerialize(using = GDDateTimeSerializer.class) - public DateTime getUpdated() { + public ZonedDateTime getUpdated() { return updated; } diff --git a/src/main/java/com/gooddata/md/Expression.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Expression.java similarity index 88% rename from src/main/java/com/gooddata/md/Expression.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Expression.java index 9f2e13ae7..a3676f6b2 100644 --- a/src/main/java/com/gooddata/md/Expression.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Expression.java @@ -1,15 +1,15 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md; +package com.gooddata.sdk.model.md; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.io.Serializable; diff --git a/src/main/java/com/gooddata/md/Fact.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Fact.java similarity index 94% rename from src/main/java/com/gooddata/md/Fact.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Fact.java index 737509f56..678ae2e8b 100644 --- a/src/main/java/com/gooddata/md/Fact.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Fact.java @@ -1,9 +1,9 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md; +package com.gooddata.sdk.model.md; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; @@ -11,7 +11,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.io.Serializable; import java.util.Collection; @@ -50,6 +50,7 @@ public Collection getExpressions() { /** * URIs of folders containing this object + * * @return collection of URIs or null */ @JsonIgnore diff --git a/src/main/java/com/gooddata/md/IdentifierAndUri.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/IdentifierAndUri.java similarity index 84% rename from src/main/java/com/gooddata/md/IdentifierAndUri.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/IdentifierAndUri.java index 824b49e7d..643dd93c2 100644 --- a/src/main/java/com/gooddata/md/IdentifierAndUri.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/IdentifierAndUri.java @@ -1,13 +1,13 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md; +package com.gooddata.sdk.model.md; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; /** * Encapsulates identifier and its URI. diff --git a/src/main/java/com/gooddata/md/IdentifierToUri.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/IdentifierToUri.java similarity index 77% rename from src/main/java/com/gooddata/md/IdentifierToUri.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/IdentifierToUri.java index ad3151c2b..db0cd64ab 100644 --- a/src/main/java/com/gooddata/md/IdentifierToUri.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/IdentifierToUri.java @@ -1,26 +1,28 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md; +package com.gooddata.sdk.model.md; import com.fasterxml.jackson.annotation.JsonProperty; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.util.Collection; -import static com.gooddata.util.Validate.notNull; +import static com.gooddata.sdk.common.util.Validate.notNull; /** * Structure with list of symbolic names (identifiers) to be expanded to list of URIs. * Serialization only. + *

    + * See also {@link UriToIdentifier}. */ -class IdentifierToUri { +public class IdentifierToUri { private final Collection identifiers; - IdentifierToUri(final Collection identifiers) { + public IdentifierToUri(final Collection identifiers) { notNull(identifiers, "identifiers"); this.identifiers = identifiers; } diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/IdentifiersAndUris.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/IdentifiersAndUris.java new file mode 100644 index 000000000..d4fbc6ba7 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/IdentifiersAndUris.java @@ -0,0 +1,75 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.md; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * Encapsulates list of identifiers and their URIs. + * Deserialization only. + */ +public class IdentifiersAndUris { + + public static final String URI = "/gdc/md/{projectId}/identifiers"; + + private final List identifiersAndUris; + + @JsonCreator + IdentifiersAndUris(@JsonProperty("identifiers") List identifiersAndUris) { + this.identifiersAndUris = identifiersAndUris; + } + + public List getUris() { + return identifiersAndUris.stream().map(IdentifierAndUri::getUri).collect(Collectors.toList()); + } + + @Deprecated + public Map asMap() { + return asIdentifierToUri(); + } + + /** + * Get values as identifier to URI map. + * + * @return map with identifiers as keys, URI as values + */ + public Map asIdentifierToUri() { + if (identifiersAndUris == null) { + return Collections.emptyMap(); + } + + final Map identifierToUri = identifiersAndUris.stream() + .collect(Collectors.toMap(IdentifierAndUri::getIdentifier, IdentifierAndUri::getUri)); + return Collections.unmodifiableMap(identifierToUri); + } + + /** + * Get values as URI to identifier map. + * + * @return map with URI as keys, identifiers as values + */ + public Map asUriToIdentifier() { + if (identifiersAndUris == null) { + return Collections.emptyMap(); + } + + final Map uriToIdentifier = identifiersAndUris.stream() + .collect(Collectors.toMap(IdentifierAndUri::getUri, IdentifierAndUri::getIdentifier)); + return Collections.unmodifiableMap(uriToIdentifier); + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } +} diff --git a/src/main/java/com/gooddata/md/InUseMany.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/InUseMany.java similarity index 80% rename from src/main/java/com/gooddata/md/InUseMany.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/InUseMany.java index 6d4bac964..6886c24d8 100644 --- a/src/main/java/com/gooddata/md/InUseMany.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/InUseMany.java @@ -1,29 +1,29 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md; +package com.gooddata.sdk.model.md; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.gooddata.util.BooleanDeserializer; -import com.gooddata.util.BooleanStringSerializer; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.BooleanDeserializer; +import com.gooddata.sdk.common.util.BooleanStringSerializer; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.util.Collection; import java.util.HashSet; import java.util.Set; -import static com.gooddata.util.Validate.noNullElements; -import static com.gooddata.util.Validate.notEmpty; -import static com.gooddata.util.Validate.notNull; +import static com.gooddata.sdk.common.util.Validate.noNullElements; +import static com.gooddata.sdk.common.util.Validate.notEmpty; +import static com.gooddata.sdk.common.util.Validate.notNull; import static java.beans.Introspector.decapitalize; /** @@ -33,7 +33,7 @@ @JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(JsonInclude.Include.NON_NULL) -class InUseMany { +public class InUseMany { public static final String USEDBY_URI = "/gdc/md/{projectId}/usedby2"; @@ -45,8 +45,8 @@ class InUseMany { @JsonCreator InUseMany(@JsonProperty("uris") Collection uris, - @JsonProperty("nearest") @JsonDeserialize(using = BooleanDeserializer.class) boolean nearest, - @JsonProperty("types") Set types) { + @JsonProperty("nearest") @JsonDeserialize(using = BooleanDeserializer.class) boolean nearest, + @JsonProperty("types") Set types) { this.uris = notEmpty(uris, "uris"); this.types = types; @@ -58,7 +58,7 @@ public InUseMany(Collection uris, boolean nearest, Class. this.uris = notNull(uris, "uris"); noNullElements(type, "type"); this.types = new HashSet<>(); - for (Class t: type) { + for (Class t : type) { this.types.add(decapitalize(t.getSimpleName())); } this.nearest = nearest; diff --git a/src/main/java/com/gooddata/md/Key.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Key.java similarity index 88% rename from src/main/java/com/gooddata/md/Key.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Key.java index 36c897703..d9c9b2024 100644 --- a/src/main/java/com/gooddata/md/Key.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Key.java @@ -1,15 +1,15 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md; +package com.gooddata.sdk.model.md; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.io.Serializable; diff --git a/src/main/java/com/gooddata/md/MaqlAst.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/MaqlAst.java similarity index 93% rename from src/main/java/com/gooddata/md/MaqlAst.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/MaqlAst.java index fd950630f..9b9be2384 100644 --- a/src/main/java/com/gooddata/md/MaqlAst.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/MaqlAst.java @@ -1,14 +1,14 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md; +package com.gooddata.sdk.model.md; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.io.Serializable; import java.util.Arrays; diff --git a/src/main/java/com/gooddata/md/Meta.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Meta.java similarity index 78% rename from src/main/java/com/gooddata/md/Meta.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Meta.java index 9633059bc..790efcf58 100644 --- a/src/main/java/com/gooddata/md/Meta.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Meta.java @@ -1,9 +1,9 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md; +package com.gooddata.sdk.model.md; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; @@ -12,17 +12,17 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.gooddata.util.BooleanDeserializer; -import com.gooddata.util.BooleanIntegerSerializer; -import com.gooddata.util.BooleanStringSerializer; -import com.gooddata.util.GDDateTimeDeserializer; -import com.gooddata.util.GDDateTimeSerializer; -import com.gooddata.util.GoodDataToStringBuilder; -import com.gooddata.util.TagsDeserializer; -import com.gooddata.util.TagsSerializer; -import org.joda.time.DateTime; +import com.gooddata.sdk.common.util.BooleanDeserializer; +import com.gooddata.sdk.common.util.BooleanIntegerSerializer; +import com.gooddata.sdk.common.util.BooleanStringSerializer; +import com.gooddata.sdk.common.util.GDZonedDateTime; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.util.TagsDeserializer; +import com.gooddata.sdk.model.util.TagsSerializer; +import com.gooddata.sdk.model.util.UriHelper; import java.io.Serializable; +import java.time.ZonedDateTime; import java.util.Set; import static org.apache.commons.lang3.StringUtils.substring; @@ -40,8 +40,10 @@ public class Meta implements Serializable { private String author; private String contributor; - private DateTime created; - private DateTime updated; + @GDZonedDateTime + private ZonedDateTime created; + @GDZonedDateTime + private ZonedDateTime updated; private String summary; private String title; private String category; @@ -58,8 +60,8 @@ public class Meta implements Serializable { @JsonCreator protected Meta(@JsonProperty("author") String author, @JsonProperty("contributor") String contributor, - @JsonProperty("created") @JsonDeserialize(using = GDDateTimeDeserializer.class) DateTime created, - @JsonProperty("updated") @JsonDeserialize(using = GDDateTimeDeserializer.class) DateTime updated, + @JsonProperty("created") ZonedDateTime created, + @JsonProperty("updated") ZonedDateTime updated, @JsonProperty("summary") String summary, @JsonProperty("title") String title, @JsonProperty("category") String category, @@ -81,34 +83,6 @@ protected Meta(@JsonProperty("author") String author, this.flags = flags; } - /** - * @param author - * @param contributor - * @param created - * @param updated - * @param summary - * @param title - * @param category - * @param tags - * @param uri - * @param identifier - * @param deprecated - * @param production - * @param locked - * @param unlisted - * @param sharedWithSomeone - * @deprecated use {@link #Meta(String, String, DateTime, DateTime, String, String, String, Set, - * String, String, Boolean, Boolean, Boolean, Boolean, Boolean, Set)} instead - */ - @Deprecated - public Meta(String author, String contributor, DateTime created, DateTime updated, String summary, - String title, String category, Set tags, String uri, String identifier, - Boolean deprecated, Boolean production, Boolean locked, Boolean unlisted, - Boolean sharedWithSomeone) { - this(author, contributor, created, updated, summary, title, category, tags, uri, identifier, - deprecated, production, locked, unlisted, sharedWithSomeone, null); - } - /** * Constructor with "extra" flags argument * @@ -129,7 +103,7 @@ public Meta(String author, String contributor, DateTime created, DateTime update * @param sharedWithSomeone * @param flags */ - public Meta(String author, String contributor, DateTime created, DateTime updated, String summary, + public Meta(String author, String contributor, ZonedDateTime created, ZonedDateTime updated, String summary, String title, String category, Set tags, String uri, String identifier, Boolean deprecated, Boolean production, Boolean locked, Boolean unlisted, Boolean sharedWithSomeone, Set flags) { @@ -167,7 +141,7 @@ public Meta(String title, String summary) { */ @JsonIgnore public String getId() { - return Obj.OBJ_TEMPLATE.match(getUri()).get("objId"); + return UriHelper.getLastUriPart(getUri()); } public String getAuthor() { @@ -178,8 +152,7 @@ public String getContributor() { return contributor; } - @JsonSerialize(using = GDDateTimeSerializer.class) - public DateTime getCreated() { + public ZonedDateTime getCreated() { return created; } @@ -199,8 +172,7 @@ public void setTitle(String title) { this.title = title; } - @JsonSerialize(using = GDDateTimeSerializer.class) - public DateTime getUpdated() { + public ZonedDateTime getUpdated() { return updated; } diff --git a/src/main/java/com/gooddata/md/Metric.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Metric.java similarity index 95% rename from src/main/java/com/gooddata/md/Metric.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Metric.java index 853c660bb..ccea81426 100644 --- a/src/main/java/com/gooddata/md/Metric.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Metric.java @@ -1,9 +1,9 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md; +package com.gooddata.sdk.model.md; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; @@ -12,7 +12,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.io.Serializable; import java.util.Collection; @@ -58,6 +58,7 @@ public MaqlAst getMaqlAst() { /** * URIs of folders containing this object + * * @return collection of URIs or null */ @JsonIgnore @@ -75,15 +76,12 @@ private static class Content implements Serializable { private static final long serialVersionUID = 7959588028233637749L; private final String expression; - + private final Collection folders; @JsonProperty("format") private String format; - @JsonProperty("tree") private MaqlAst maqlAst; - private final Collection folders; - @JsonCreator public Content(@JsonProperty("expression") String expression, @JsonProperty("folders") Collection folders) { this.expression = expression; @@ -100,22 +98,22 @@ public String getExpression() { return expression; } - public void setFormat(final String format) { - this.format = format; - } - public String getFormat() { return format; } - public void setMaqlAst(final MaqlAst maqlAst) { - this.maqlAst = maqlAst; + public void setFormat(final String format) { + this.format = format; } public MaqlAst getMaqlAst() { return maqlAst; } + public void setMaqlAst(final MaqlAst maqlAst) { + this.maqlAst = maqlAst; + } + public Collection getFolders() { return folders; } diff --git a/src/main/java/com/gooddata/md/NestedAttribute.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/NestedAttribute.java similarity index 81% rename from src/main/java/com/gooddata/md/NestedAttribute.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/NestedAttribute.java index 05719f6b2..487844dcb 100644 --- a/src/main/java/com/gooddata/md/NestedAttribute.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/NestedAttribute.java @@ -1,12 +1,16 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md; +package com.gooddata.sdk.model.md; -import com.fasterxml.jackson.annotation.*; -import com.gooddata.util.GoodDataToStringBuilder; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.io.Serializable; import java.util.Collection; @@ -50,16 +54,6 @@ public DisplayForm getDefaultDisplayForm() { return getDisplayForms().iterator().next(); } - /** - * @return dimension URI string - * @deprecated use {@link #getDimensionUri()} instead - */ - @Deprecated - @JsonIgnore - public String getDimensionLink() { - return getDimensionUri(); - } - @JsonIgnore public String getDimensionUri() { return content.getDimensionUri(); @@ -129,31 +123,11 @@ public Collection getCompositeAttributePk() { return content.getCompositeAttributePk(); } - /** - * @return drill-down step display form URI string - * @deprecated use {@link #getDrillDownStepDisplayFormUri()} instead - */ - @Deprecated - @JsonIgnore - public String getDrillDownStepDisplayFormLink() { - return getDrillDownStepDisplayFormUri(); - } - @JsonIgnore public String getDrillDownStepDisplayFormUri() { return content.getDrillDownStepDisplayFormUri(); } - /** - * @return linked display form URI string - * @deprecated use {@link #getLinkedDisplayFormUri()} instead - */ - @Deprecated - @JsonIgnore - public String getLinkedDisplayFormLink() { - return getLinkedDisplayFormUri(); - } - @JsonIgnore public String getLinkedDisplayFormUri() { return content.getLinkedDisplayFormUri(); @@ -161,6 +135,7 @@ public String getLinkedDisplayFormUri() { /** * URIs of folders containing this object + * * @return collection of URIs or null */ @JsonIgnore @@ -240,16 +215,6 @@ public Collection getDisplayForms() { return displayForms; } - /** - * @return dimension URI string - * @deprecated use {@link #getDimensionUri()} instead - */ - @Deprecated - @JsonIgnore - public String getDimensionLink() { - return getDimensionUri(); - } - @JsonProperty("dimension") public String getDimensionUri() { return dimension; @@ -280,31 +245,11 @@ public Collection getCompositeAttributePk() { return compositeAttributePk; } - /** - * @return drill-down step display form URI string - * @deprecated use {@link #getDrillDownStepDisplayFormUri()} instead - */ - @Deprecated - @JsonIgnore - public String getDrillDownStepDisplayFormLink() { - return getDrillDownStepDisplayFormUri(); - } - @JsonProperty("drillDownStepAttributeDF") public String getDrillDownStepDisplayFormUri() { return drillDownStepAttributeDF; } - /** - * @return linked display form URI string - * @deprecated use {@link #getLinkedDisplayFormUri()} instead - */ - @Deprecated - @JsonIgnore - public String getLinkedDisplayFormLink() { - return getLinkedDisplayFormUri(); - } - @JsonProperty("linkAttributeDF") public String getLinkedDisplayFormUri() { return linkedDisplayFormUri; diff --git a/src/main/java/com/gooddata/md/Obj.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Obj.java similarity index 78% rename from src/main/java/com/gooddata/md/Obj.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Obj.java index 62f036f99..90bf5e414 100644 --- a/src/main/java/com/gooddata/md/Obj.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Obj.java @@ -1,17 +1,16 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md; +package com.gooddata.sdk.model.md; import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; -import com.gooddata.md.report.Report; -import com.gooddata.md.report.ReportDefinition; -import com.gooddata.md.visualization.VisualizationClass; -import com.gooddata.md.visualization.VisualizationObject; -import org.springframework.web.util.UriTemplate; +import com.gooddata.sdk.model.md.report.Report; +import com.gooddata.sdk.model.md.report.ReportDefinition; +import com.gooddata.sdk.model.md.visualization.VisualizationClass; +import com.gooddata.sdk.model.md.visualization.VisualizationObject; /** * First class metadata object - only dto objects, which have URI pointing to themselves should implement this. @@ -41,7 +40,6 @@ public interface Obj { String CREATE_URI = URI + "?createAndGet=true"; String CREATE_WITH_ID_URI = CREATE_URI + "&setIdentifier=true"; String OBJ_URI = URI + "/{objId}"; - UriTemplate OBJ_TEMPLATE = new UriTemplate(OBJ_URI); String getUri(); } diff --git a/src/main/java/com/gooddata/md/ProjectDashboard.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/ProjectDashboard.java similarity index 94% rename from src/main/java/com/gooddata/md/ProjectDashboard.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/ProjectDashboard.java index dcd3521d9..6db262a7e 100644 --- a/src/main/java/com/gooddata/md/ProjectDashboard.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/ProjectDashboard.java @@ -1,12 +1,9 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md; - -import static com.gooddata.util.Validate.notNull; -import static java.util.Arrays.asList; +package com.gooddata.sdk.model.md; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; @@ -15,13 +12,16 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.io.Serializable; import java.util.Collection; import java.util.Collections; import java.util.Objects; +import static com.gooddata.sdk.common.util.Validate.notNull; +import static java.util.Arrays.asList; + /** * Project Dashboard of GoodData project.
    * Deserialization only. This object is not complete representation of real 'projectDashboard' object. @@ -55,8 +55,7 @@ public Collection getTabs() { * If tab with such name doesn't exist, returns {@code null}. * * @param name tab name - * @return - *

      + * @return
        *
      • dashboard tab with the given name
      • *
      • {@code null} if tab doesn't exist
      • *
      diff --git a/src/main/java/com/gooddata/md/Query.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Query.java similarity index 94% rename from src/main/java/com/gooddata/md/Query.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Query.java index 5fa715c09..306757d3c 100644 --- a/src/main/java/com/gooddata/md/Query.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Query.java @@ -1,9 +1,9 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md; +package com.gooddata.sdk.model.md; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @@ -11,7 +11,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.util.Collection; diff --git a/src/main/java/com/gooddata/md/Queryable.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Queryable.java similarity index 75% rename from src/main/java/com/gooddata/md/Queryable.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Queryable.java index 058e7f7ab..aeb88f367 100644 --- a/src/main/java/com/gooddata/md/Queryable.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Queryable.java @@ -1,9 +1,9 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md; +package com.gooddata.sdk.model.md; /** * Marker interface for metadata objects which can be found using query resource (see MetadataService.find* methods). diff --git a/src/main/java/com/gooddata/md/ReportAttachment.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/ReportAttachment.java similarity index 89% rename from src/main/java/com/gooddata/md/ReportAttachment.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/ReportAttachment.java index 79c398a4d..acca59898 100644 --- a/src/main/java/com/gooddata/md/ReportAttachment.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/ReportAttachment.java @@ -1,14 +1,14 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md; +package com.gooddata.sdk.model.md; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import com.gooddata.export.ExportFormat; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.export.ExportFormat; import java.util.Arrays; import java.util.Collection; @@ -27,7 +27,7 @@ protected ReportAttachment( @JsonProperty("uri") String uri, @JsonProperty("exportOptions") Map exportOptions, @JsonProperty("formats") String... formats - ) { + ) { super(uri); this.exportOptions = exportOptions; this.formats = Arrays.asList(formats); @@ -38,9 +38,9 @@ protected ReportAttachment(String uri, Map exportOptions, Export } /** - * Options which modify default export behavior. Due to variety of - * export formats options only work for explicitly listed - * format types. + * Options which modify default export behavior. Due to variety of + * export formats options only work for explicitly listed + * format types. * *
        *
      • pageOrientation @@ -98,9 +98,13 @@ protected ReportAttachment(String uri, Map exportOptions, Export * * @return map of export options */ - public Map getExportOptions() { return exportOptions; } + public Map getExportOptions() { + return exportOptions; + } - public Collection getFormats() { return formats; } + public Collection getFormats() { + return formats; + } @Override public boolean equals(Object o) { diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Restriction.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Restriction.java new file mode 100644 index 000000000..9d6aa3972 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Restriction.java @@ -0,0 +1,88 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.md; + +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; + +import java.util.Objects; + +import static com.gooddata.sdk.common.util.Validate.notNull; + +/** + * Metadata query restriction. See static factory methods to get instance of desired restriction type. + */ +public class Restriction { + + private final Type type; + + private final String value; + + private Restriction(Type type, String value) { + this.type = notNull(type, "type"); + this.value = notNull(value, "value"); + } + + /** + * Construct a new instance with restriction type identifier and given value. + * + * @param value identifier you want to search for + * @return new restriction for identifier restriction + */ + public static Restriction identifier(String value) { + return new Restriction(Type.IDENTIFIER, value); + } + + /** + * Construct a new instance with restriction type title and given value. + * + * @param value title you want to search for + * @return new restriction for title restriction + */ + public static Restriction title(String value) { + return new Restriction(Type.TITLE, value); + } + + /** + * Construct a new instance with restriction type summary and given value. + * + * @param value summary you want to search for + * @return new restriction for summary restriction + */ + public static Restriction summary(String value) { + return new Restriction(Type.SUMMARY, value); + } + + public Type getType() { + return type; + } + + public String getValue() { + return value; + } + + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + final Restriction that = (Restriction) o; + return type == that.type && + value.equals(that.value); + } + + @Override + public int hashCode() { + return Objects.hash(type, value); + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } + + public enum Type { + IDENTIFIER, TITLE, SUMMARY + } +} diff --git a/src/main/java/com/gooddata/md/ScheduledMail.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/ScheduledMail.java similarity index 75% rename from src/main/java/com/gooddata/md/ScheduledMail.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/ScheduledMail.java index f5c712c63..9e03136e0 100644 --- a/src/main/java/com/gooddata/md/ScheduledMail.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/ScheduledMail.java @@ -1,21 +1,30 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md; - -import com.fasterxml.jackson.annotation.*; -import com.gooddata.export.ExportFormat; -import com.gooddata.md.report.ReportDefinition; -import com.gooddata.report.ReportExportFormat; -import com.gooddata.util.GoodDataToStringBuilder; -import org.joda.time.LocalDate; +package com.gooddata.sdk.model.md; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.export.ExportFormat; +import com.gooddata.sdk.model.md.report.ReportDefinition; import java.io.Serializable; -import java.util.*; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Set; -import static com.gooddata.util.Validate.notNull; +import static com.gooddata.sdk.common.util.Validate.notNull; /** * A scheduled mail MD object. It represents a schedule on mail-sending of @@ -53,7 +62,7 @@ private ScheduledMail(String title, String summary, Set tags, boolean de /** * Creates an almost empty instance of the object. It's up to the user's responsibility to call all the necessary setters. * - * @param title the title of the MD object + * @param title the title of the MD object * @param summary the summary of the MD object */ public ScheduledMail(String title, String summary) { @@ -65,16 +74,16 @@ public ScheduledMail(String title, String summary) { /** * Creates full, safe mail schedule object. * - * @param title the title of the MD object - * @param summary the summary of the MD object - * @param recurrency schedule in format defined in schedule - * @param startDate schedule starting date - * @param timeZone time zone of the starting date - * @param toAddresses collection of email addresses to send the mail to + * @param title the title of the MD object + * @param summary the summary of the MD object + * @param recurrency schedule in format defined in schedule + * @param startDate schedule starting date + * @param timeZone time zone of the starting date + * @param toAddresses collection of email addresses to send the mail to * @param bccAddresses collection of blind copy addresses to send the mail to - * @param subject the subject of the scheduled mail - * @param body the text body of the scheduled mail - * @param attachments reports and dashboards to send in the scheduled email + * @param subject the subject of the scheduled mail + * @param body the text body of the scheduled mail + * @param attachments reports and dashboards to send in the scheduled email */ public ScheduledMail(String title, String summary, String recurrency, LocalDate startDate, String timeZone, Collection toAddresses, Collection bccAddresses, String subject, String body, @@ -83,6 +92,109 @@ public ScheduledMail(String title, String summary, String recurrency, LocalDate bccAddresses, subject, body, attachments); } + @JsonIgnore + public ScheduledMailWhen getWhen() { + return content.getScheduledMailWhen(); + } + + @JsonIgnore + public Collection getToAddresses() { + return content.getToAddresses(); + } + + @JsonIgnore + public Collection getBccAddresses() { + return content.getBccAddresses(); + } + + @JsonIgnore + public String getSubject() { + return content.getSubject(); + } + + public ScheduledMail setSubject(String subject) { + this.content.setSubject(subject); + return this; + } + + @JsonIgnore + public String getBody() { + return content.getBody(); + } + + public ScheduledMail setBody(String body) { + this.content.setBody(body); + return this; + } + + @JsonIgnore + public Collection getAttachments() { + return content.getAttachments(); + } + + public ScheduledMail setAttachments(List attachments) { + this.content.setAttachments(attachments); + return this; + } + + public ScheduledMail setRecurrency(String recurrency) { + this.content.getScheduledMailWhen().setRecurrency(recurrency); + return this; + } + + public ScheduledMail setStartDate(LocalDate startDate) { + this.content.getScheduledMailWhen().setStartDate(startDate); + return this; + } + + public ScheduledMail setTimeZone(String timeZone) { + this.content.getScheduledMailWhen().setTimeZone(timeZone); + return this; + } + + public ScheduledMail setTo(Collection toAddresses) { + this.content.setToAddress(toAddresses); + return this; + } + + public ScheduledMail setBcc(Collection bccAddresses) { + this.content.setBccAddress(bccAddresses); + return this; + } + + public ScheduledMail addToAddress(String toAdd) { + this.content.getToAddresses().add(toAdd); + return this; + } + + public ScheduledMail addBccAddress(String bccAdd) { + this.content.getBccAddresses().add(bccAdd); + return this; + } + + public ScheduledMail addReportAttachment(ReportDefinition reportDefinition, Map exportOptions, String... formats) { + notNull(formats, "formats"); + ReportAttachment ra = new ReportAttachment(reportDefinition.getUri(), exportOptions, formats); + this.content.getAttachments().add(ra); + return this; + } + + public ScheduledMail addReportAttachment(ReportDefinition reportDefinition, Map exportOptions, ExportFormat... formats) { + return addReportAttachment(reportDefinition, exportOptions, ExportFormat.arrayToStringArray(formats)); + } + + public ScheduledMail addDashboardAttachment(String uri, Integer allTabs, String executionContext, String... tabs) { + notNull(tabs, "tabs"); + DashboardAttachment da = new DashboardAttachment(uri, allTabs, executionContext, tabs); + this.content.getAttachments().add(da); + return this; + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } + /** * Mail schedule MD object payload. */ @@ -133,146 +245,59 @@ public Content() { } @JsonIgnore - public ScheduledMailWhen getScheduledMailWhen() { return scheduledMailWhen; } - - @JsonIgnore - public Collection getToAddresses() { return toAddress; } - - @JsonIgnore - public Collection getBccAddresses() { return bccAddress; } - - public String getSubject() { return subject; } - - public String getBody() { return body; } - - public Collection getAttachments() { return attachments; } + public ScheduledMailWhen getScheduledMailWhen() { + return scheduledMailWhen; + } public void setScheduledMailWhen(ScheduledMailWhen scheduledMailWhen) { this.scheduledMailWhen = scheduledMailWhen; } - public void setToAddress(Collection toAddress) { - this.toAddress = toAddress; + @JsonIgnore + public Collection getToAddresses() { + return toAddress; } - public void setBccAddress(Collection bccAddress) { - this.bccAddress = bccAddress; + @JsonIgnore + public Collection getBccAddresses() { + return bccAddress; + } + + public String getSubject() { + return subject; } public void setSubject(String subject) { this.subject = subject; } + public String getBody() { + return body; + } + public void setBody(String body) { this.body = body; } + public Collection getAttachments() { + return attachments; + } + public void setAttachments(Collection attachments) { this.attachments = attachments; } + public void setToAddress(Collection toAddress) { + this.toAddress = toAddress; + } + + public void setBccAddress(Collection bccAddress) { + this.bccAddress = bccAddress; + } + @Override public String toString() { return GoodDataToStringBuilder.defaultToString(this); } } - - @JsonIgnore - public ScheduledMailWhen getWhen() { return content.getScheduledMailWhen(); } - - @JsonIgnore - public Collection getToAddresses() { return content.getToAddresses(); } - - @JsonIgnore - public Collection getBccAddresses() { return content.getBccAddresses(); } - - @JsonIgnore - public String getSubject() { return content.getSubject(); } - - @JsonIgnore - public String getBody() { return content.getBody(); } - - @JsonIgnore - public Collection getAttachments() { return content.getAttachments(); } - - public ScheduledMail setRecurrency(String recurrency) { - this.content.getScheduledMailWhen().setRecurrency(recurrency); - return this; - } - - public ScheduledMail setStartDate(LocalDate startDate) { - this.content.getScheduledMailWhen().setStartDate(startDate); - return this; - } - - public ScheduledMail setTimeZone(String timeZone) { - this.content.getScheduledMailWhen().setTimeZone(timeZone); - return this; - } - - public ScheduledMail setTo(Collection toAddresses) { - this.content.setToAddress(toAddresses); - return this; - } - - public ScheduledMail setBcc(Collection bccAddresses) { - this.content.setBccAddress(bccAddresses); - return this; - } - - public ScheduledMail setSubject(String subject) { - this.content.setSubject(subject); - return this; - } - - public ScheduledMail setBody(String body) { - this.content.setBody(body); - return this; - } - - public ScheduledMail setAttachments(List attachments) { - this.content.setAttachments(attachments); - return this; - } - - public ScheduledMail addToAddress(String toAdd) { - this.content.getToAddresses().add(toAdd); - return this; - } - - public ScheduledMail addBccAddress(String bccAdd) { - this.content.getBccAddresses().add(bccAdd); - return this; - } - - public ScheduledMail addReportAttachment(ReportDefinition reportDefinition, Map exportOptions, String... formats) { - notNull(formats, "formats"); - ReportAttachment ra = new ReportAttachment(reportDefinition.getUri(), exportOptions, formats); - this.content.getAttachments().add(ra); - return this; - } - - /** - * @deprecated use {@link #addReportAttachment(ReportDefinition, Map, ExportFormat...)} - */ - @Deprecated - public ScheduledMail addReportAttachment(ReportDefinition reportDefinition, Map exportOptions, ReportExportFormat... formats) { - return addReportAttachment(reportDefinition, exportOptions, ReportExportFormat.arrayToStringArray(formats)); - } - - public ScheduledMail addReportAttachment(ReportDefinition reportDefinition, Map exportOptions, ExportFormat... formats) { - return addReportAttachment(reportDefinition, exportOptions, ExportFormat.arrayToStringArray(formats)); - } - - public ScheduledMail addDashboardAttachment(String uri, Integer allTabs, String executionContext, String... tabs) { - notNull(tabs, "tabs"); - DashboardAttachment da = new DashboardAttachment(uri, allTabs, executionContext, tabs); - this.content.getAttachments().add(da); - return this; - } - - @Override - public String toString() { - return GoodDataToStringBuilder.defaultToString(this); - } } diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/ScheduledMailWhen.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/ScheduledMailWhen.java new file mode 100644 index 000000000..106c5e93b --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/ScheduledMailWhen.java @@ -0,0 +1,97 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.md; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.gooddata.sdk.common.util.GDLocalDate; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; + +import java.io.Serializable; +import java.time.LocalDate; + +/** + * Represents the start date and cron-like expression for {@link ScheduledMail} mail schedule. + */ +public class ScheduledMailWhen implements Serializable { + + private static final long serialVersionUID = 1203170008606357967L; + + /** + * Cron like recurrency pattern. Example: "0:0:0:1*12:0:0". + * For details, please see this comprehensive documentation. + */ + private String recurrency; + @GDLocalDate + @JsonInclude(JsonInclude.Include.NON_NULL) + private LocalDate startDate; + private String timeZone; + + @JsonCreator + protected ScheduledMailWhen(@JsonProperty("recurrency") String recurrency, + @JsonProperty("startDate") LocalDate startDate, + @JsonProperty("timeZone") String timeZone) { + this.recurrency = recurrency; + this.startDate = startDate; + this.timeZone = timeZone; + } + + public ScheduledMailWhen() { + } + + public String getRecurrency() { + return recurrency; + } + + public void setRecurrency(String recurrency) { + this.recurrency = recurrency; + } + + public LocalDate getStartDate() { + return startDate; + } + + public void setStartDate(LocalDate startDate) { + this.startDate = startDate; + } + + public String getTimeZone() { + return timeZone; + } + + public void setTimeZone(String timeZone) { + this.timeZone = timeZone; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + ScheduledMailWhen scheduledMailWhen = (ScheduledMailWhen) o; + + if (recurrency != null ? !recurrency.equals(scheduledMailWhen.recurrency) : scheduledMailWhen.recurrency != null) + return false; + if (startDate != null ? !startDate.equals(scheduledMailWhen.startDate) : scheduledMailWhen.startDate != null) + return false; + return !(timeZone != null ? !timeZone.equals(scheduledMailWhen.timeZone) : scheduledMailWhen.timeZone != null); + + } + + @Override + public int hashCode() { + int result = recurrency != null ? recurrency.hashCode() : 0; + result = 31 * result + (startDate != null ? startDate.hashCode() : 0); + result = 31 * result + (timeZone != null ? timeZone.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Service.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Service.java new file mode 100644 index 000000000..e5db880b5 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Service.java @@ -0,0 +1,49 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.md; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; + +import java.io.Serializable; + +/** + * Represents project/workspace metadata configuration. + */ +@JsonTypeName("service") +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +public class Service implements Serializable { + + public static final String TIMEZONE_URI = "/gdc/md/{projectId}/service/timezone"; + + private static final long serialVersionUID = -3382672258337809805L; + + private final String timezone; + + @JsonCreator + public Service(@JsonProperty("timezone") String timezone) { + this.timezone = timezone; + } + + /** + * @return string identifier of the timezone (see IANA/Olson tz database for possible values) + */ + public String getTimezone() { + return timezone; + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } +} diff --git a/src/main/java/com/gooddata/md/Table.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Table.java similarity index 91% rename from src/main/java/com/gooddata/md/Table.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Table.java index cf0811e69..514353859 100644 --- a/src/main/java/com/gooddata/md/Table.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Table.java @@ -1,16 +1,16 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md; +package com.gooddata.sdk.model.md; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.io.Serializable; import java.util.Collection; @@ -76,7 +76,7 @@ private static class Content implements Serializable { @JsonCreator private Content(@JsonProperty("tableDBName") String tableDBName, @JsonProperty("activeDataLoad") String activeDataLoad, - @JsonProperty("tableDataLoad") Collection tableDataLoads, @JsonProperty("weight") Integer weight) { + @JsonProperty("tableDataLoad") Collection tableDataLoads, @JsonProperty("weight") Integer weight) { this.tableDBName = tableDBName; this.activeDataLoad = activeDataLoad; this.tableDataLoads = tableDataLoads; diff --git a/src/main/java/com/gooddata/md/TableDataLoad.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/TableDataLoad.java similarity index 94% rename from src/main/java/com/gooddata/md/TableDataLoad.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/TableDataLoad.java index 824d17fa0..f5b9c22c5 100644 --- a/src/main/java/com/gooddata/md/TableDataLoad.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/TableDataLoad.java @@ -1,16 +1,16 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md; +package com.gooddata.sdk.model.md; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.io.Serializable; @@ -22,10 +22,9 @@ @JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) public class TableDataLoad extends AbstractObj implements Queryable { - private static final long serialVersionUID = -5209417147612785042L; public static final String TYPE_FULL = "full"; public static final String TYPE_INCREMENTAL = "incremental"; - + private static final long serialVersionUID = -5209417147612785042L; private final Content content; @JsonCreator diff --git a/src/main/java/com/gooddata/md/Updatable.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Updatable.java similarity index 75% rename from src/main/java/com/gooddata/md/Updatable.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Updatable.java index 59fd60e1c..13aa0f5c3 100644 --- a/src/main/java/com/gooddata/md/Updatable.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Updatable.java @@ -1,9 +1,9 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md; +package com.gooddata.sdk.model.md; /** * Marker interface for metadata objects which can be updated. (see {@link MetadataService#updateObj(Updatable)}). diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/UriToIdentifier.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/UriToIdentifier.java new file mode 100644 index 000000000..f97a97de7 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/UriToIdentifier.java @@ -0,0 +1,56 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.md; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; + +import java.util.Collection; + +import static com.gooddata.sdk.common.util.Validate.notNull; + +/** + * Structure with list of URIs to be expanded to list of symbolic names (identifiers). + * Serialization only. + *

        + * See also {@link IdentifierToUri}. + */ +public class UriToIdentifier { + + private final Collection uris; + + public UriToIdentifier(final Collection uris) { + notNull(uris, "uris"); + this.uris = uris; + } + + @JsonProperty("uriToIdentifier") + public Collection getUris() { + return uris; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + UriToIdentifier that = (UriToIdentifier) o; + + if (!uris.equals(that.uris)) return false; + + return true; + } + + @Override + public int hashCode() { + return uris.hashCode(); + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } +} diff --git a/src/main/java/com/gooddata/md/Usage.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Usage.java similarity index 76% rename from src/main/java/com/gooddata/md/Usage.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Usage.java index 90ae129a4..1a68c9746 100644 --- a/src/main/java/com/gooddata/md/Usage.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/Usage.java @@ -1,11 +1,11 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md; +package com.gooddata.sdk.model.md; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.util.Collection; @@ -20,10 +20,11 @@ public class Usage { /** * Constructs object. - * @param uri object URI + * + * @param uri object URI * @param usedBy using objects */ - Usage(final String uri, final Collection usedBy) { + public Usage(final String uri, final Collection usedBy) { this.uri = uri; this.usedBy = usedBy; } diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/UseMany.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/UseMany.java new file mode 100644 index 000000000..5dc8b3175 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/UseMany.java @@ -0,0 +1,40 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.md; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; + +import java.util.Collection; + +import static com.gooddata.sdk.common.util.Validate.notNull; + +/** + * UsedBy/Using batch result + */ +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +public class UseMany { + + private final Collection useMany; + + @JsonCreator + private UseMany(@JsonProperty("useMany") final Collection useMany) { + this.useMany = notNull(useMany, "useMany"); + } + + public Collection getUseMany() { + return useMany; + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } +} diff --git a/src/main/java/com/gooddata/md/UseManyEntries.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/UseManyEntries.java similarity index 85% rename from src/main/java/com/gooddata/md/UseManyEntries.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/UseManyEntries.java index 059c22b69..0ae541db6 100644 --- a/src/main/java/com/gooddata/md/UseManyEntries.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/UseManyEntries.java @@ -1,21 +1,21 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md; +package com.gooddata.sdk.model.md; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.util.Collection; @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(JsonInclude.Include.NON_NULL) -class UseManyEntries { +public class UseManyEntries { private final String uri; diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/dashboard/AnalyticalDashboard.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/dashboard/AnalyticalDashboard.java new file mode 100644 index 000000000..4ef5337f9 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/dashboard/AnalyticalDashboard.java @@ -0,0 +1,102 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ + +package com.gooddata.sdk.model.md.dashboard; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.gooddata.sdk.model.md.AbstractObj; +import com.gooddata.sdk.model.md.Meta; +import com.gooddata.sdk.model.md.Queryable; +import com.gooddata.sdk.model.md.Updatable; + +import java.io.Serializable; +import java.util.Collections; +import java.util.List; + +import static com.gooddata.sdk.common.util.Validate.notNull; + +/** + * Represents analytical dashboard configuration. + */ +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonTypeName("analyticalDashboard") +@JsonIgnoreProperties(ignoreUnknown = true) +public class AnalyticalDashboard extends AbstractObj implements Queryable, Updatable { + + private static final long serialVersionUID = -2217112261771452747L; + + private final Content content; + + /** + * Constructor. + * + * @param title dashboard title + * @param widgetUris URIs of widgets located on dashboard + * @param filtersContextUri URI of filters context applied to this dashboard (optional) + */ + public AnalyticalDashboard(final String title, final List widgetUris, final String filtersContextUri) { + this(new Meta(title), new Content(notNull(widgetUris, "widgetUris"), filtersContextUri)); + } + + @JsonCreator + private AnalyticalDashboard(@JsonProperty("meta") Meta meta, @JsonProperty("content") Content content) { + super(meta); + this.content = content; + } + + @JsonProperty + private Content getContent() { + return content; + } + + /** + * @return URIs of widgets contained in this dashboard + */ + @JsonIgnore + public List getWidgetUris() { + return Collections.unmodifiableList(getContent().getWidgets()); + } + + /** + * @return URI of filters context applied to this dashboard + */ + @JsonIgnore + public String getFiltersContextUri() { + return getContent().getFilterContext(); + } + + @JsonIgnoreProperties(ignoreUnknown = true) + private static class Content implements Serializable { + + private static final long serialVersionUID = 3492968666803382202L; + + private final List widgets; + private final String filterContext; + + @JsonCreator + private Content( + @JsonProperty("widgets") final List widgets, + @JsonProperty("filterContext") final String filterContext) { + this.widgets = widgets; + this.filterContext = filterContext; + } + + @JsonProperty + private List getWidgets() { + return widgets; + } + + @JsonProperty + private String getFilterContext() { + return filterContext; + } + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/dashboard/Kpi.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/dashboard/Kpi.java new file mode 100644 index 000000000..ff8427969 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/dashboard/Kpi.java @@ -0,0 +1,180 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ + +package com.gooddata.sdk.model.md.dashboard; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.gooddata.sdk.model.md.AbstractObj; +import com.gooddata.sdk.model.md.Meta; +import com.gooddata.sdk.model.md.Queryable; +import com.gooddata.sdk.model.md.Updatable; +import com.gooddata.sdk.model.md.dashboard.filter.FilterReference; + +import java.io.Serializable; +import java.util.Collections; +import java.util.List; + +import static com.gooddata.sdk.common.util.Validate.notEmpty; +import static com.gooddata.sdk.common.util.Validate.notNull; + +/** + * Represents KPI (key performance indicator) for analytical dashboard. + */ +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonTypeName("kpi") +@JsonIgnoreProperties(ignoreUnknown = true) +public class Kpi extends AbstractObj implements Queryable, Updatable { + + private static final long serialVersionUID = -7747260758488157192L; + + private static final String NONE_COMPARISON_TYPE = "none"; + + private final Content content; + + /** + * Creates new KPI for a given metric with some date filter and comparison + * + * @param title title of KPI + * @param metricUri URI of the KPI metric + * @param comparisonType KPI comparison type (e.g. {@code "lastYear"}) + * @param comparisonDirection KPI comparison direction (e.g. {@code "growIsGood"}) + * @param ignoreDashboardFilters list of filters which should be ignored for this KPI (can be empty) + * @param dateDatasetUri KPI date filter dataset URI (optional) + */ + public Kpi(final String title, final String metricUri, final String comparisonType, final String comparisonDirection, + final List ignoreDashboardFilters, final String dateDatasetUri) { + this(new Meta(title), new Content( + notEmpty(metricUri, "metricUri"), + notEmpty(comparisonType, "comparisonType"), + checkDirection(comparisonType, comparisonDirection), + null, + dateDatasetUri, + notNull(ignoreDashboardFilters, "ignoreDashboardFilters"))); + } + + @JsonCreator + private Kpi(@JsonProperty("meta") final Meta meta, @JsonProperty("content") final Content content) { + super(meta); + this.content = content; + } + + private static String checkDirection(final String comparisonType, final String comparisonDirection) { + if (NONE_COMPARISON_TYPE.equalsIgnoreCase(notEmpty(comparisonType, "comparisonType"))) { + return notEmpty(comparisonDirection, "comparisonDirection"); + } else { + return comparisonDirection; + } + } + + /** + * @return KPI metric URI string + */ + @JsonIgnore + public String getMetricUri() { + return getContent().getMetric(); + } + + /** + * @return KPI comparison type + */ + @JsonIgnore + public String getComparisonType() { + return getContent().getComparisonType(); + } + + /** + * @return KPI comparison direction + */ + @JsonIgnore + public String getComparisonDirection() { + return getContent().getComparisonDirection(); + } + + /** + * @return KPI date filter dataset URI + */ + @JsonIgnore + public String getDateDatasetUri() { + final String dateDatasetUri = getContent().getDateDataSet(); + return dateDatasetUri != null ? dateDatasetUri : getContent().getDateDimension(); + } + + /** + * @return list of filter references (containing URIs) of filters which should be ignored for this KPI + */ + @JsonIgnore + public List getIgnoreDashboardFilters() { + return Collections.unmodifiableList(getContent().getIgnoreDashboardFilters()); + } + + @JsonProperty + private Content getContent() { + return content; + } + + @JsonIgnoreProperties(ignoreUnknown = true) + @JsonInclude(JsonInclude.Include.NON_NULL) + private static class Content implements Serializable { + + private final String metric; + private final String comparisonType; + private final String comparisonDirection; + private final String dateDimension; + private final String dateDataset; + private final List ignoreDashboardFilters; + + @JsonCreator + private Content( + @JsonProperty("metric") final String metric, + @JsonProperty("comparisonType") final String comparisonType, + @JsonProperty("comparisonDirection") final String comparisonDirection, + @JsonProperty("dateDimension") final String dateDimension, + @JsonProperty("dateDataSet") final String dateDataset, + @JsonProperty("ignoreDashboardFilters") final List ignoreDashboardFilters) { + this.metric = metric; + this.comparisonType = comparisonType; + this.comparisonDirection = comparisonDirection; + this.dateDimension = dateDimension; + this.dateDataset = dateDataset; + this.ignoreDashboardFilters = ignoreDashboardFilters; + } + + public String getMetric() { + return metric; + } + + public String getComparisonType() { + return comparisonType; + } + + public String getComparisonDirection() { + return comparisonDirection; + } + + /** + * @return URI of the date dimension + * @deprecated if not null, {@link #getDateDataSet()} should be used instead + */ + @Deprecated + public String getDateDimension() { + return dateDimension; + } + + public String getDateDataSet() { + return dateDataset; + } + + public List getIgnoreDashboardFilters() { + return ignoreDashboardFilters; + } + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/dashboard/KpiAlert.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/dashboard/KpiAlert.java new file mode 100644 index 000000000..91a762dc5 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/dashboard/KpiAlert.java @@ -0,0 +1,184 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ + +package com.gooddata.sdk.model.md.dashboard; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.gooddata.sdk.model.md.AbstractObj; +import com.gooddata.sdk.model.md.Meta; +import com.gooddata.sdk.model.md.Queryable; +import com.gooddata.sdk.model.md.Updatable; + +import java.io.Serializable; + +import static com.gooddata.sdk.common.util.Validate.notEmpty; + +/** + * Represents KPI alert set for some KPI on analytical dashboard. + */ +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonTypeName("kpiAlert") +@JsonIgnoreProperties(ignoreUnknown = true) +public class KpiAlert extends AbstractObj implements Queryable, Updatable { + + private static final long serialVersionUID = 4771232690549128988L; + + private final Content content; + + /** + * Constructor. + * + * @param title KPI alert title + * @param kpiUri URI of the KPI for which the alert is defined + * @param dashboardUri URI of the KPI where the KPI alert is located + * @param threshold KPI alert threshold + * @param triggerCondition condition for triggering KPI alert + * @param filterContextUri URI of filter context used for computation of KPI alert (optional) + */ + public KpiAlert( + final String title, + final String kpiUri, + final String dashboardUri, + final double threshold, + final String triggerCondition, + final String filterContextUri) { + this(new Meta(title), new Content( + notEmpty(kpiUri, "kpiUri"), + notEmpty(dashboardUri, "dashboardUri"), + threshold, false, + notEmpty(triggerCondition, "triggerCondition"), + filterContextUri)); + } + + @JsonCreator + private KpiAlert(@JsonProperty("meta") final Meta meta, @JsonProperty("content") final Content content) { + super(meta); + this.content = content; + } + + @JsonProperty + private Content getContent() { + return content; + } + + /** + * @return if the KPI alert was already triggered + */ + @JsonIgnore + public boolean wasTriggered() { + return getContent().isTriggered(); + } + + /** + * @return KPI value threshold for triggering KPI alert + */ + @JsonIgnore + public double getThreshold() { + return getContent().getThreshold(); + } + + /** + * @return filters used for computation of KPI alert + */ + @JsonIgnore + public String getFilterContextUri() { + return getContent().getFilterContext(); + } + + /** + * @return condition for triggering KPI alert (e.g. {@code "above_threshold"}) + */ + @JsonIgnore + public String getTriggerCondition() { + return getContent().getWhenTriggered(); + } + + /** + * @return URI of the analytical dashboard where the alert is located + */ + @JsonIgnore + public String getDashboardUri() { + return getContent().getDashboard(); + } + + /** + * @return URI of the KPI for which is the alert configured + */ + @JsonIgnore + public String getKpiUri() { + return getContent().getKpi(); + } + + /** + * Creates new copy of KPI alert with a given triggered state changed. + * + * @param wasTriggered triggered state + * @return new KPI alert + */ + public KpiAlert withTriggeredState(final boolean wasTriggered) { + return new KpiAlert(meta, new Content(getKpiUri(), getDashboardUri(), getThreshold(), wasTriggered, getTriggerCondition(), + getFilterContextUri())); + } + + @JsonIgnoreProperties(ignoreUnknown = true) + private static class Content implements Serializable { + + private static final long serialVersionUID = 1L; + + private final boolean isTriggered; + private final double threshold; + private final String filterContext; + private final String whenTriggered; + private final String dashboard; + private final String kpi; + + @JsonCreator + private Content( + @JsonProperty("kpi") final String kpi, + @JsonProperty("dashboard") final String dashboard, + @JsonProperty("threshold") final double threshold, + @JsonProperty("isTriggered") final boolean isTriggered, + @JsonProperty("whenTriggered") final String whenTriggered, + @JsonProperty("filterContext") final String filterContext) { + this.isTriggered = isTriggered; + this.threshold = threshold; + this.filterContext = filterContext; + this.whenTriggered = whenTriggered; + this.dashboard = dashboard; + this.kpi = kpi; + } + + @JsonProperty("isTriggered") + public boolean isTriggered() { + return isTriggered; + } + + public double getThreshold() { + return threshold; + } + + public String getFilterContext() { + return filterContext; + } + + public String getWhenTriggered() { + return whenTriggered; + } + + public String getDashboard() { + return dashboard; + } + + public String getKpi() { + return kpi; + } + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/dashboard/filter/AttributeFilterReference.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/dashboard/filter/AttributeFilterReference.java new file mode 100644 index 000000000..b56af6159 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/dashboard/filter/AttributeFilterReference.java @@ -0,0 +1,47 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ + +package com.gooddata.sdk.model.md.dashboard.filter; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; + +import static com.gooddata.sdk.common.util.Validate.notEmpty; + +/** + * Reference for attribute filter for ignoring particular filter in {@link com.gooddata.sdk.model.md.dashboard.Kpi}. + * Is not standalone metadata object - must be part of {@link com.gooddata.sdk.model.md.dashboard.Kpi}. + */ +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonTypeName(AttributeFilterReference.NAME) +@JsonIgnoreProperties(ignoreUnknown = true) +public class AttributeFilterReference implements FilterReference { + + static final String NAME = "attributeFilterReference"; + private static final long serialVersionUID = -7882622280867466659L; + private final String displayFormUri; + + /** + * Constructor. + * + * @param displayFormUri display form URI of filter + */ + @JsonCreator + public AttributeFilterReference(@JsonProperty("displayForm") final String displayFormUri) { + this.displayFormUri = notEmpty(displayFormUri, "displayFormUri"); + } + + /** + * @return display form URI of the filter + */ + @JsonProperty("displayForm") + public String getDisplayFormUri() { + return displayFormUri; + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/dashboard/filter/DashboardAttributeFilter.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/dashboard/filter/DashboardAttributeFilter.java new file mode 100644 index 000000000..db70fc40c --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/dashboard/filter/DashboardAttributeFilter.java @@ -0,0 +1,86 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ + +package com.gooddata.sdk.model.md.dashboard.filter; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; + +import java.util.Collections; +import java.util.List; + +import static com.gooddata.sdk.common.util.Validate.notEmpty; + +/** + * Attribute filter located on analytical dashboard. + * Is not standalone metadata object - always must be part of {@link DashboardFilterContext}. + */ +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonTypeName(DashboardAttributeFilter.NAME) +@JsonIgnoreProperties(ignoreUnknown = true) +public class DashboardAttributeFilter implements DashboardFilter { + + static final String NAME = "attributeFilter"; + + private final String displayForm; + private final boolean negativeSelection; + private final List attributeElements; + + /** + * Constructor. + * + * @param displayForm display form of an attribute where this filter is applied + * @param negativeSelection if the negative selection of filter elements is applied + * @param attributeElementUris list of attribute element URIs applied in filter + */ + @JsonCreator + public DashboardAttributeFilter( + @JsonProperty("displayForm") final String displayForm, + @JsonProperty("negativeSelection") final boolean negativeSelection, + @JsonProperty("attributeElements") final List attributeElementUris) { + this.displayForm = notEmpty(displayForm, "displayForm"); + this.negativeSelection = negativeSelection; + this.attributeElements = notEmpty(attributeElementUris, "attributeElementUris"); + } + + /** + * @return display form of an attribute where this filter is applied + */ + public String getDisplayForm() { + return displayForm; + } + + /** + * @return if this filter is negative or positive selection of attribute elements contained in {@link #getAttributeElementUris()} + */ + public boolean isNegativeSelection() { + return negativeSelection; + } + + /** + * @return list of attribute element URI strings which should be included or excluded in filter + * @see #isNegativeSelection() + */ + @JsonIgnore + public List getAttributeElementUris() { + return Collections.unmodifiableList(getAttributeElements()); + } + + @JsonProperty + private List getAttributeElements() { + return attributeElements; + } + + @Override + public String toString() { + return GoodDataToStringBuilder.toString(this); + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/dashboard/filter/DashboardDateFilter.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/dashboard/filter/DashboardDateFilter.java new file mode 100644 index 000000000..7dcf10db1 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/dashboard/filter/DashboardDateFilter.java @@ -0,0 +1,147 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ + +package com.gooddata.sdk.model.md.dashboard.filter; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; + +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; + +import static com.gooddata.sdk.common.util.Validate.notEmpty; +import static com.gooddata.sdk.common.util.Validate.notNull; + +/** + * Date filter located on analytical dashboard. + * Is not standalone metadata object - always must be part of {@link DashboardFilterContext}. + */ +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonTypeName(DashboardDateFilter.NAME) +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +public class DashboardDateFilter implements DashboardFilter { + + public static final String RELATIVE_FILTER_TYPE = "relative"; + public static final String ABSOLUTE_FILTER_TYPE = "absolute"; + public static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ISO_LOCAL_DATE; + static final String NAME = "dateFilter"; + private static final String ABSOLUTE_DATE_FILTER_GRANULARITY = "GDC.time.date"; + private final String from; + private final String to; + private final String granularity; + private final String dataset; + private final String type; + + @JsonCreator + private DashboardDateFilter( + @JsonProperty("from") final String from, + @JsonProperty("to") final String to, + @JsonProperty("granularity") final String granularity, + @JsonProperty("dataSet") final String dataset, + @JsonProperty("type") final String type) { + this.from = from; + this.to = to; + this.granularity = granularity; + this.dataset = dataset; + this.type = type; + } + + /** + * Creates relative date filter with the given interval and granularity. + * + * @param from interval from + * @param to interval to + * @param granularity granularity (e.g. {@code GDC.time.year}) + * @param datasetUri date dataset URI (optional) + * @return created filter + */ + @JsonIgnore + public static DashboardDateFilter relativeDateFilter(final int from, final int to, final String granularity, final String datasetUri) { + return new DashboardDateFilter( + Integer.toString(from), + Integer.toString(to), + notEmpty(granularity, "granularity"), + datasetUri, + RELATIVE_FILTER_TYPE); + } + + /** + * Creates absolute date filter with the given interval + * + * @param from interval from + * @param to interval to + * @param datasetUri date dataset URI (optional) + * @return created filter + */ + @JsonIgnore + public static DashboardDateFilter absoluteDateFilter(final LocalDate from, final LocalDate to, final String datasetUri) { + return new DashboardDateFilter( + notNull(from, "from").format(DATE_FORMAT), + notNull(to, "to").format(DATE_FORMAT), + ABSOLUTE_DATE_FILTER_GRANULARITY, + datasetUri, + ABSOLUTE_FILTER_TYPE); + } + + /** + * Returns from value of date filter interval. Value represents in the case of: + *

          + *
        • relative date filter - integer value
        • + *
        • absolute date filter - date value with format {@code DD-MM-YYYY}
        • + *
        + * + * @return date filter from interval value + */ + public String getFrom() { + return from; + } + + /** + * Returns to value of date filter interval. Value represents in the case of: + *
          + *
        • relative date filter - integer value
        • + *
        • absolute date filter - date value with format {@code YYYY-DD-MM}
        • + *
        + * + * @return date filter from interval value + */ + public String getTo() { + return to; + } + + /** + * @return date interval granularity in the case of relative date filter + */ + public String getGranularity() { + return granularity; + } + + /** + * @return date dataset URI of this filter + */ + public String getDataSet() { + return dataset; + } + + /** + * @return date filter type, can be either relative or absolute + */ + public String getType() { + return type; + } + + @Override + public String toString() { + return GoodDataToStringBuilder.toString(this); + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/dashboard/filter/DashboardFilter.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/dashboard/filter/DashboardFilter.java new file mode 100644 index 000000000..ad08662b1 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/dashboard/filter/DashboardFilter.java @@ -0,0 +1,23 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ + +package com.gooddata.sdk.model.md.dashboard.filter; + +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; + +import java.io.Serializable; + +/** + * Parent interface for filter implementation inside {@link DashboardFilterContext}. + */ +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonSubTypes({ + @JsonSubTypes.Type(value = DashboardDateFilter.class, name = DashboardDateFilter.NAME), + @JsonSubTypes.Type(value = DashboardAttributeFilter.class, name = DashboardAttributeFilter.NAME) +}) +public interface DashboardFilter extends Serializable { +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/dashboard/filter/DashboardFilterContext.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/dashboard/filter/DashboardFilterContext.java new file mode 100644 index 000000000..e55ddd92c --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/dashboard/filter/DashboardFilterContext.java @@ -0,0 +1,93 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ + +package com.gooddata.sdk.model.md.dashboard.filter; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.md.AbstractObj; +import com.gooddata.sdk.model.md.Meta; +import com.gooddata.sdk.model.md.Queryable; +import com.gooddata.sdk.model.md.Updatable; + +import java.io.Serializable; +import java.util.Collections; +import java.util.List; + +import static com.gooddata.sdk.common.util.Validate.notNull; + +/** + * Class encapsulates list of filters on analytical dashboard. + * Currently can contain {@link DashboardDateFilter}s and {@link DashboardAttributeFilter}s. + */ +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonTypeName(DashboardFilterContext.NAME) +@JsonIgnoreProperties(ignoreUnknown = true) +public class DashboardFilterContext extends AbstractObj implements Updatable, Queryable { + + static final String NAME = "filterContext"; + private static final long serialVersionUID = -4572881756272497057L; + private final Content content; + + /** + * Constructs new dashboard filter context with given filters. + * + * @param filters list of dashboard filters (can be empty) + */ + public DashboardFilterContext(final List filters) { + this(new Meta(NAME), new Content(notNull(filters, "filters"))); + } + + @JsonCreator + private DashboardFilterContext(@JsonProperty("meta") final Meta meta, @JsonProperty("content") final Content content) { + super(meta); + this.content = content; + } + + /** + * @return all dashboard filters from this filter context + */ + @JsonIgnore + public List getFilters() { + return Collections.unmodifiableList(getContent().getFilters()); + } + + @JsonProperty + private Content getContent() { + return content; + } + + @Override + public String toString() { + return GoodDataToStringBuilder.toString(this); + } + + @JsonIgnoreProperties(ignoreUnknown = true) + private static class Content implements Serializable { + + private final List filters; + + @JsonCreator + private Content(@JsonProperty("filters") final List filters) { + this.filters = filters; + } + + @JsonProperty + private List getFilters() { + return filters; + } + + @Override + public String toString() { + return GoodDataToStringBuilder.toString(this); + } + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/dashboard/filter/DateFilterReference.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/dashboard/filter/DateFilterReference.java new file mode 100644 index 000000000..34520d7c3 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/dashboard/filter/DateFilterReference.java @@ -0,0 +1,47 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ + +package com.gooddata.sdk.model.md.dashboard.filter; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; + +import static com.gooddata.sdk.common.util.Validate.notEmpty; + +/** + * Reference for date filter for ignoring particular filter in {@link com.gooddata.sdk.model.md.dashboard.Kpi}. + * Is not standalone metadata object - must be part of {@link com.gooddata.sdk.model.md.dashboard.Kpi}. + */ +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonTypeName(DateFilterReference.NAME) +@JsonIgnoreProperties(ignoreUnknown = true) +public class DateFilterReference implements FilterReference { + + static final String NAME = "dateFilterReference"; + private static final long serialVersionUID = 6016252592161989340L; + private final String datasetUri; + + /** + * Constructor. + * + * @param datasetUri date dataset URI + */ + @JsonCreator + public DateFilterReference(@JsonProperty("dataSet") final String datasetUri) { + this.datasetUri = notEmpty(datasetUri, "datasetUri"); + } + + /** + * @return date dataset URI of the filter + */ + @JsonProperty("dataSet") + public String getDatasetUri() { + return datasetUri; + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/dashboard/filter/FilterReference.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/dashboard/filter/FilterReference.java new file mode 100644 index 000000000..c2693917f --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/dashboard/filter/FilterReference.java @@ -0,0 +1,23 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ + +package com.gooddata.sdk.model.md.dashboard.filter; + +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; + +import java.io.Serializable; + +/** + * Parent interface for ignored filter references inside {@link com.gooddata.sdk.model.md.dashboard.Kpi}. + */ +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonSubTypes({ + @JsonSubTypes.Type(value = DateFilterReference.class, name = DateFilterReference.NAME), + @JsonSubTypes.Type(value = AttributeFilterReference.class, name = AttributeFilterReference.NAME) +}) +public interface FilterReference extends Serializable { +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/maintenance/ExportProject.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/maintenance/ExportProject.java new file mode 100644 index 000000000..0128479e2 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/maintenance/ExportProject.java @@ -0,0 +1,85 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.md.maintenance; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.gooddata.sdk.common.util.BooleanStringSerializer; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; + +/** + * Complete project export configuration structure. + * Serialization only. + */ +@JsonTypeName("exportProject") +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonInclude(JsonInclude.Include.NON_NULL) +public class ExportProject { + + public static final String URI = "/gdc/md/{projectId}/maintenance/export"; + + private final boolean exportUsers; + private final boolean exportData; + private final boolean excludeSchedules; + private final boolean crossDataCenterExport; + private final String authorizedUsers; + + /** + * Creates new ExportProject with default settings. + * Sets exportUsers=true exportData=true, excludeSchedules=false, crossDataCenterExport=false and empty authorizedUsers. + */ + public ExportProject() { + this(true, true, false, false, null); + } + + /** + * Creates new ExportProject. + * + * @param exportUsers whether to add necessary data to be able to clone attribute properties + * @param exportData whether to add necessary data to be able to clone attribute properties + * @param excludeSchedules whether to add necessary data to be able to clone attribute properties + * @param crossDataCenterExport whether export should be usable in any Data Center + * @param authorizedUsers comma-separated list of email addresses of users authorized to import the project, surround email addresses with double quotes + */ + public ExportProject(final boolean exportUsers, final boolean exportData, final boolean excludeSchedules, final boolean crossDataCenterExport, final String authorizedUsers) { + this.exportUsers = exportUsers; + this.exportData = exportData; + this.excludeSchedules = excludeSchedules; + this.crossDataCenterExport = crossDataCenterExport; + this.authorizedUsers = authorizedUsers; + } + + @JsonSerialize(using = BooleanStringSerializer.class) + public boolean isExportUsers() { + return exportUsers; + } + + @JsonSerialize(using = BooleanStringSerializer.class) + public boolean isExportData() { + return exportData; + } + + @JsonSerialize(using = BooleanStringSerializer.class) + public boolean isExcludeSchedules() { + return excludeSchedules; + } + + @JsonSerialize(using = BooleanStringSerializer.class) + public boolean isCrossDataCenterExport() { + return crossDataCenterExport; + } + + public String getAuthorizedUsers() { + return authorizedUsers; + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/maintenance/ExportProjectArtifact.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/maintenance/ExportProjectArtifact.java new file mode 100644 index 000000000..2f756a50f --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/maintenance/ExportProjectArtifact.java @@ -0,0 +1,25 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.md.maintenance; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.gooddata.sdk.model.gdc.UriResponse; + +/** + * Complete project export result structure. + * For internal use only. + * Deserialization only. + */ +@JsonTypeName("exportArtifact") +public class ExportProjectArtifact extends PartialMdArtifact { + + @JsonCreator + public ExportProjectArtifact(@JsonProperty("status") UriResponse status, @JsonProperty("token") String token) { + super(status, token); + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/maintenance/ExportProjectToken.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/maintenance/ExportProjectToken.java new file mode 100644 index 000000000..3710b44d5 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/maintenance/ExportProjectToken.java @@ -0,0 +1,43 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.md.maintenance; + +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; + +import static com.gooddata.sdk.common.util.Validate.notEmpty; + +/** + * Complete project export token. Serves as configuration structure for import. + * Serialization only. + */ +@JsonTypeName("importProject") +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +public class ExportProjectToken { + + public static final String URI = "/gdc/md/{projectId}/maintenance/import"; + + private final String token; + + /** + * Creates new ExportProjectToken. + * + * @param token token identifying export of another project + */ + public ExportProjectToken(String token) { + this.token = notEmpty(token, "token"); + } + + public String getToken() { + return token; + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/maintenance/PartialMdArtifact.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/maintenance/PartialMdArtifact.java new file mode 100644 index 000000000..51338b6c2 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/maintenance/PartialMdArtifact.java @@ -0,0 +1,53 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.md.maintenance; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.gdc.UriResponse; + +/** + * Partial metadata export result structure. + * For internal use only. + */ +@JsonTypeName("partialMDArtifact") +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonInclude(JsonInclude.Include.NON_NULL) +public class PartialMdArtifact { + + private final UriResponse status; + private final String token; + + @JsonCreator + public PartialMdArtifact(@JsonProperty("status") UriResponse status, @JsonProperty("token") String token) { + this.status = status; + this.token = token; + } + + @JsonIgnore + public String getStatusUri() { + return getStatus().getUri(); + } + + public String getToken() { + return token; + } + + @JsonProperty("status") + private UriResponse getStatus() { + return status; + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } +} diff --git a/src/main/java/com/gooddata/md/maintenance/PartialMdExport.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/maintenance/PartialMdExport.java similarity index 81% rename from src/main/java/com/gooddata/md/maintenance/PartialMdExport.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/maintenance/PartialMdExport.java index f2a5bb744..4a65887f4 100644 --- a/src/main/java/com/gooddata/md/maintenance/PartialMdExport.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/maintenance/PartialMdExport.java @@ -1,22 +1,21 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md.maintenance; - -import static com.gooddata.util.Validate.notEmpty; -import static java.util.Arrays.asList; +package com.gooddata.sdk.model.md.maintenance; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.util.GoodDataToStringBuilder; -import org.springframework.web.util.UriTemplate; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.util.Collection; import java.util.HashSet; +import static com.gooddata.sdk.common.util.Validate.notEmpty; +import static java.util.Arrays.asList; + /** * Partial metadata export configuration structure. * Serialization only. @@ -27,7 +26,6 @@ public class PartialMdExport { public static final String URI = "/gdc/md/{projectId}/maintenance/partialmdexport"; - public static final UriTemplate TEMPLATE = new UriTemplate(URI); private final Collection uris; private final boolean crossDataCenterExport; @@ -57,8 +55,8 @@ public PartialMdExport(Collection mdObjectsUris) { * Creates new PartialMdExport. At least one uri should be given. * * @param exportAttributeProperties whether to add necessary data to be able to clone attribute properties - * @param crossDataCenterExport whether export should be usable in any Data Center - * @param mdObjectsUris list of uris to metadata objects which should be exported + * @param crossDataCenterExport whether export should be usable in any Data Center + * @param mdObjectsUris list of uris to metadata objects which should be exported */ public PartialMdExport(boolean exportAttributeProperties, boolean crossDataCenterExport, String... mdObjectsUris) { this(exportAttributeProperties, crossDataCenterExport, new HashSet<>(asList(mdObjectsUris))); @@ -68,8 +66,8 @@ public PartialMdExport(boolean exportAttributeProperties, boolean crossDataCente * Creates new PartialMdExport. At least one uri should be given. * * @param exportAttributeProperties whether to add necessary data to be able to clone attribute properties - * @param crossDataCenterExport whether export should be usable in any Data Center - * @param mdObjectsUris list of uris to metadata objects which should be exported + * @param crossDataCenterExport whether export should be usable in any Data Center + * @param mdObjectsUris list of uris to metadata objects which should be exported */ public PartialMdExport(boolean exportAttributeProperties, boolean crossDataCenterExport, Collection mdObjectsUris) { notEmpty(mdObjectsUris, "uris"); diff --git a/src/main/java/com/gooddata/md/maintenance/PartialMdExportToken.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/maintenance/PartialMdExportToken.java similarity index 87% rename from src/main/java/com/gooddata/md/maintenance/PartialMdExportToken.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/maintenance/PartialMdExportToken.java index 78cb7b444..9f267a6c9 100644 --- a/src/main/java/com/gooddata/md/maintenance/PartialMdExportToken.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/maintenance/PartialMdExportToken.java @@ -1,16 +1,15 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md.maintenance; - -import static com.gooddata.util.Validate.notEmpty; +package com.gooddata.sdk.model.md.maintenance; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.util.GoodDataToStringBuilder; -import org.springframework.web.util.UriTemplate; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; + +import static com.gooddata.sdk.common.util.Validate.notEmpty; /** * Partial metadata export token. Serves as configuration structure for import. @@ -21,7 +20,6 @@ public class PartialMdExportToken { public static final String URI = "/gdc/md/{projectId}/maintenance/partialmdimport"; - public static final UriTemplate TEMPLATE = new UriTemplate(URI); private final String token; private boolean overwriteNewer; @@ -53,10 +51,10 @@ public PartialMdExportToken(String token) { *
      • updateLDMObjects - default false
      • *
      * - * @param token token identifying metadata partially exported from another project + * @param token token identifying metadata partially exported from another project * @param importAttributeProperties see {@link #setImportAttributeProperties(boolean)} */ - PartialMdExportToken(String token, boolean importAttributeProperties) { + public PartialMdExportToken(String token, boolean importAttributeProperties) { this.token = notEmpty(token, "token"); setImportAttributeProperties(importAttributeProperties); setOverwriteNewer(true); @@ -71,14 +69,6 @@ public boolean isOverwriteNewer() { return overwriteNewer; } - public boolean isUpdateLDMObjects() { - return updateLDMObjects; - } - - public boolean isImportAttributeProperties() { - return importAttributeProperties; - } - /** * Sets the flag {@code overwriteNewer}. * If {@code true}, UDM/ADM objects are overwritten without checking modification time. @@ -89,6 +79,10 @@ public void setOverwriteNewer(boolean overwriteNewer) { this.overwriteNewer = overwriteNewer; } + public boolean isUpdateLDMObjects() { + return updateLDMObjects; + } + /** * Sets the flag {@code updateLDMObjects}. * If {@code true}, related LDM objects name, description and tags are overwritten @@ -99,6 +93,10 @@ public void setUpdateLDMObjects(boolean updateLDMObjects) { this.updateLDMObjects = updateLDMObjects; } + public boolean isImportAttributeProperties() { + return importAttributeProperties; + } + /** * Sets the flag {@code importAttributeProperties}. * If {@code true}, following attribute properties are cloned: diff --git a/src/main/java/com/gooddata/md/report/AttributeInGrid.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/report/AttributeInGrid.java similarity index 83% rename from src/main/java/com/gooddata/md/report/AttributeInGrid.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/report/AttributeInGrid.java index d6cc56c98..47a418433 100644 --- a/src/main/java/com/gooddata/md/report/AttributeInGrid.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/report/AttributeInGrid.java @@ -1,9 +1,9 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md.report; +package com.gooddata.sdk.model.md.report; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; @@ -12,16 +12,16 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.md.Attribute; -import com.gooddata.md.DisplayForm; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.md.Attribute; +import com.gooddata.sdk.model.md.DisplayForm; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; -import static com.gooddata.util.Validate.notNull; +import static com.gooddata.sdk.common.util.Validate.notNull; /** * Attribute in Grid @@ -45,19 +45,10 @@ public class AttributeInGrid implements GridElement, Serializable { this.totals = totals; } - /** - * Creates new instance from given uri with empty alias - * @param uri uri of displayForm of attribute to be in grid - * @deprecated because empty alias does not make much sense - */ - @Deprecated - public AttributeInGrid(String uri) { - this(uri, ""); - } - /** * Creates new instance. - * @param uri uri of displayForm of attribute to be in grid + * + * @param uri uri of displayForm of attribute to be in grid * @param alias alias used to label the attribute */ public AttributeInGrid(String uri, String alias) { @@ -66,8 +57,9 @@ public AttributeInGrid(String uri, String alias) { /** * Creates new instance. - * @param uri uri of displayForm of attribute to be in grid - * @param alias alias used to label the attribute + * + * @param uri uri of displayForm of attribute to be in grid + * @param alias alias used to label the attribute * @param totals totals for metrics used in grid - for each {@link MetricElement} in grid, there can be list * of totals. The totals are evaluated in given order. */ @@ -83,6 +75,7 @@ public AttributeInGrid(String uri, String alias, List> totals) { /** * Creates new AttributeInGrid using given DisplayForm's uri and it's title as alias. + * * @param displayForm displayForm to create AttributeInGrid from */ public AttributeInGrid(final DisplayForm displayForm) { @@ -91,8 +84,9 @@ public AttributeInGrid(final DisplayForm displayForm) { /** * Creates new AttributeInGrid using given DisplayForm's uri and given alias. + * * @param displayForm displayForm to create AttributeInGrid from - * @param alias alias used to label the attribute + * @param alias alias used to label the attribute */ public AttributeInGrid(final DisplayForm displayForm, final String alias) { this(notNull(notNull(displayForm, "displayForm").getUri(), "uri"), alias); @@ -100,6 +94,7 @@ public AttributeInGrid(final DisplayForm displayForm, final String alias) { /** * Creates new AttributeInGrid using given Attribute's default DisplayForm's uri and Attribute's title as alias. + * * @param attribute attribute to create AttributeInGrid from */ public AttributeInGrid(final Attribute attribute) { @@ -108,8 +103,9 @@ public AttributeInGrid(final Attribute attribute) { /** * Creates new AttributeInGrid using given Attribute's default DisplayForm's uri and given alias. + * * @param attribute attribute to create AttributeInGrid from - * @param alias alias used to label the attribute + * @param alias alias used to label the attribute */ public AttributeInGrid(final Attribute attribute, final String alias) { this(notNull(attribute, "attribute").getDefaultDisplayForm(), alias); @@ -117,7 +113,7 @@ public AttributeInGrid(final Attribute attribute, final String alias) { @JsonProperty("totals") public List> getStringTotals() { - return totals; + return totals; } @JsonIgnore diff --git a/src/main/java/com/gooddata/md/report/Filter.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/report/Filter.java similarity index 83% rename from src/main/java/com/gooddata/md/report/Filter.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/report/Filter.java index 40d92fd68..d66f42d46 100644 --- a/src/main/java/com/gooddata/md/report/Filter.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/report/Filter.java @@ -1,19 +1,19 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md.report; +package com.gooddata.sdk.model.md.report; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.io.Serializable; -import static com.gooddata.util.Validate.notEmpty; +import static com.gooddata.sdk.common.util.Validate.notEmpty; /** * Filter (in report definition) diff --git a/src/main/java/com/gooddata/md/report/Grid.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/report/Grid.java similarity index 83% rename from src/main/java/com/gooddata/md/report/Grid.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/report/Grid.java index 28e4d3dcf..b1da3b11a 100644 --- a/src/main/java/com/gooddata/md/report/Grid.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/report/Grid.java @@ -1,9 +1,9 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md.report; +package com.gooddata.sdk.model.md.report; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @@ -11,7 +11,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.io.Serializable; import java.util.Collection; @@ -36,19 +36,19 @@ public class Grid implements Serializable { /** * Creates new instance. - * @param columns report's definition columns - * @param rows report's definition rows - * @param metrics report's definition metrics - * @param sort report's sort definition - * @param columnWidths report columns' widths definition * + * @param columns report's definition columns + * @param rows report's definition rows + * @param metrics report's definition metrics + * @param sort report's sort definition + * @param columnWidths report columns' widths definition * @since 2.0.0 */ @JsonCreator public Grid(@JsonProperty("columns") @JsonDeserialize(contentUsing = GridElementDeserializer.class) - List columns, - @JsonProperty("rows") @JsonDeserialize(contentUsing = GridElementDeserializer.class) - List rows, + List columns, + @JsonProperty("rows") @JsonDeserialize(contentUsing = GridElementDeserializer.class) + List rows, @JsonProperty("metrics") List metrics, @JsonProperty("sort") Map> sort, @JsonProperty("columnWidths") Collection> columnWidths) { diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/report/GridElement.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/report/GridElement.java new file mode 100644 index 000000000..7fd1e3b2f --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/report/GridElement.java @@ -0,0 +1,14 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.md.report; + +/** + * Grid element + * (metricGroup | AttributeInGrid ... metricGroup can be maximally + * one time in rows or columns) + */ +public interface GridElement { +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/report/GridElementDeserializer.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/report/GridElementDeserializer.java new file mode 100644 index 000000000..ec4856d41 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/report/GridElementDeserializer.java @@ -0,0 +1,39 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.md.report; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; + +import java.io.IOException; + +import static com.gooddata.sdk.model.md.report.MetricGroup.METRIC_GROUP; + +/** + * Custom deserializer for {@link GridElement}'s implementations + */ +class GridElementDeserializer extends JsonDeserializer { + + @Override + public GridElement deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { + switch (jp.currentToken()) { + case VALUE_STRING: + final String textValue = ctxt.readValue(jp, String.class); + if (MetricGroup.equals(textValue)) { + return METRIC_GROUP; + } else { + return (GridElement) ctxt.handleWeirdStringValue(GridElement.class, textValue, + "Unknown string representation of GridElement: %s", textValue); + } + case START_OBJECT: + return ctxt.readValue(jp, AttributeInGrid.class); + default: + return (GridElement) ctxt.handleUnexpectedToken(GridElement.class, jp.currentToken(), jp, + "Unknown type of GridElement"); + } + } +} diff --git a/src/main/java/com/gooddata/md/report/GridElementSerializer.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/report/GridElementSerializer.java similarity index 90% rename from src/main/java/com/gooddata/md/report/GridElementSerializer.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/report/GridElementSerializer.java index a1b1c77a0..58276c1ab 100644 --- a/src/main/java/com/gooddata/md/report/GridElementSerializer.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/report/GridElementSerializer.java @@ -1,9 +1,9 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md.report; +package com.gooddata.sdk.model.md.report; import com.fasterxml.jackson.core.JsonGenerationException; import com.fasterxml.jackson.core.JsonGenerator; diff --git a/src/main/java/com/gooddata/md/report/GridReportDefinitionContent.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/report/GridReportDefinitionContent.java similarity index 93% rename from src/main/java/com/gooddata/md/report/GridReportDefinitionContent.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/report/GridReportDefinitionContent.java index ccb6c77f0..44a0998eb 100644 --- a/src/main/java/com/gooddata/md/report/GridReportDefinitionContent.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/report/GridReportDefinitionContent.java @@ -1,14 +1,14 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md.report; +package com.gooddata.sdk.model.md.report; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.gooddata.md.Meta; import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; +import com.gooddata.sdk.model.md.Meta; import java.util.Collection; import java.util.Collections; @@ -20,8 +20,8 @@ @JsonInclude(JsonInclude.Include.NON_NULL) public class GridReportDefinitionContent extends ReportDefinitionContent { - private static final long serialVersionUID = 1296467241365069724L; public static final String FORMAT = "grid"; + private static final long serialVersionUID = 1296467241365069724L; @JsonCreator private GridReportDefinitionContent( @@ -39,10 +39,6 @@ private GridReportDefinitionContent( this(grid, Collections.emptyList()); } - public String getFormat() { - return FORMAT; - } - public static ReportDefinition create(String title, List columns, List rows, List metrics) { return create(title, columns, rows, metrics, Collections.emptyList()); @@ -52,4 +48,8 @@ public static ReportDefinition create(String title, List List metrics, Collection filters) { return new ReportDefinition(new Meta(title), new GridReportDefinitionContent(new Grid(columns, rows, metrics), filters)); } + + public String getFormat() { + return FORMAT; + } } diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/report/MetricElement.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/report/MetricElement.java new file mode 100644 index 000000000..b2889f52f --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/report/MetricElement.java @@ -0,0 +1,83 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.md.report; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.md.Metric; + +import java.io.Serializable; + +import static com.gooddata.sdk.common.util.Validate.notNull; + +/** + * Metric used in {@link Grid} for report definition. + */ +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +public class MetricElement implements Serializable { + + private static final long serialVersionUID = 6199743301553304055L; + private final String uri; + private final String alias; + private final String format; + private final String drillAcrossStepAttributeDisplayFormUri; + + @JsonCreator + MetricElement(@JsonProperty("uri") final String uri, + @JsonProperty("alias") final String alias, + @JsonProperty("format") final String format, + @JsonProperty("drillAcrossStepAttributeDF") String drillAcrossStepAttributeDisplayFormUri) { + this.uri = uri; + this.alias = alias; + this.format = format; + this.drillAcrossStepAttributeDisplayFormUri = drillAcrossStepAttributeDisplayFormUri; + } + + /** + * Creates new instance using uri of given metric and alias. + * + * @param metric metric to create element from + * @param alias metric alias + */ + public MetricElement(final Metric metric, final String alias) { + this(notNull(notNull(metric, "metric").getUri(), "uri"), notNull(alias, "alias"), null, null); + } + + /** + * Creates new instance using uri of given metric and it's title as alias. + * + * @param metric metric to create element from + */ + public MetricElement(final Metric metric) { + this(metric, notNull(metric, "metric").getTitle()); + } + + public String getUri() { + return uri; + } + + public String getAlias() { + return alias; + } + + public String getFormat() { + return format; + } + + @JsonProperty("drillAcrossStepAttributeDF") + public String getDrillAcrossStepAttributeDisplayFormUri() { + return drillAcrossStepAttributeDisplayFormUri; + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } +} diff --git a/src/main/java/com/gooddata/md/report/MetricGroup.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/report/MetricGroup.java similarity index 92% rename from src/main/java/com/gooddata/md/report/MetricGroup.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/report/MetricGroup.java index 833956416..398f06b50 100644 --- a/src/main/java/com/gooddata/md/report/MetricGroup.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/report/MetricGroup.java @@ -1,9 +1,9 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md.report; +package com.gooddata.sdk.model.md.report; import java.io.Serializable; @@ -15,19 +15,13 @@ public final class MetricGroup implements GridElement, Serializable { private static final long serialVersionUID = -2971228185501817988L; private static final String JSON_VALUE = "metricGroup"; - - private final String value; - public static final MetricGroup METRIC_GROUP = new MetricGroup(JSON_VALUE); + private final String value; private MetricGroup(String value) { this.value = value; } - public String getValue() { - return value; - } - /** * @param string string to compare whether is metricGroup * @return true when the {@link #METRIC_GROUP}'s string value equals to the argument, false otherwise @@ -36,6 +30,10 @@ public static boolean equals(String string) { return METRIC_GROUP.getValue().equals(string); } + public String getValue() { + return value; + } + @Override public boolean equals(Object o) { return this == o; diff --git a/src/main/java/com/gooddata/md/report/OneNumberReportDefinitionContent.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/report/OneNumberReportDefinitionContent.java similarity index 95% rename from src/main/java/com/gooddata/md/report/OneNumberReportDefinitionContent.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/report/OneNumberReportDefinitionContent.java index 47d80bd58..543535218 100644 --- a/src/main/java/com/gooddata/md/report/OneNumberReportDefinitionContent.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/report/OneNumberReportDefinitionContent.java @@ -1,14 +1,14 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md.report; +package com.gooddata.sdk.model.md.report; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.gooddata.md.Meta; import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; +import com.gooddata.sdk.model.md.Meta; import java.io.Serializable; import java.util.Collection; @@ -21,9 +21,8 @@ @JsonInclude(JsonInclude.Include.NON_NULL) public class OneNumberReportDefinitionContent extends ReportDefinitionContent { - private static final long serialVersionUID = 5479509323034916986L; public static final String FORMAT = "oneNumber"; - + private static final long serialVersionUID = 5479509323034916986L; private final OneNumberVisualization oneNumber; @JsonCreator @@ -40,6 +39,17 @@ private OneNumberReportDefinitionContent(@JsonProperty("format") String format, oneNumber = new OneNumberVisualization(new OneNumberLabels(description)); } + public static ReportDefinition create(String title, List columns, List rows, + List metrics) { + return create(title, columns, rows, metrics, Collections.emptyList()); + } + + public static ReportDefinition create(String title, List columns, List rows, + List metrics, Collection filters) { + return new ReportDefinition(new Meta(title), new OneNumberReportDefinitionContent( + new Grid(columns, rows, metrics), title, filters)); + } + public String getFormat() { return FORMAT; } @@ -79,15 +89,4 @@ public String getDescription() { return description; } } - - public static ReportDefinition create(String title, List columns, List rows, - List metrics) { - return create(title, columns, rows, metrics, Collections.emptyList()); - } - - public static ReportDefinition create(String title, List columns, List rows, - List metrics, Collection filters) { - return new ReportDefinition(new Meta(title), new OneNumberReportDefinitionContent( - new Grid(columns, rows, metrics), title, filters)); - } } diff --git a/src/main/java/com/gooddata/md/report/Report.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/report/Report.java similarity index 84% rename from src/main/java/com/gooddata/md/report/Report.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/report/Report.java index a416ff154..a1b4ff81c 100644 --- a/src/main/java/com/gooddata/md/report/Report.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/report/Report.java @@ -1,26 +1,26 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md.report; +package com.gooddata.sdk.model.md.report; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.gooddata.md.AbstractObj; -import com.gooddata.md.Meta; -import com.gooddata.md.Queryable; -import com.gooddata.md.Updatable; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.md.AbstractObj; +import com.gooddata.sdk.model.md.Meta; +import com.gooddata.sdk.model.md.Queryable; +import com.gooddata.sdk.model.md.Updatable; import java.io.Serializable; +import java.util.Arrays; import java.util.Collection; -import static java.util.Arrays.asList; import static java.util.Collections.emptyList; /** @@ -44,12 +44,13 @@ private Report(@JsonProperty("meta") Meta meta, @JsonProperty("content") Content /** * Creates new report with given title and definitions - * @param title report title + * + * @param title report title * @param definitions report definitions */ public Report(String title, ReportDefinition... definitions) { // domains must be empty list to be included in serialized form properly - this(new Meta(title), new Content(asList(uris(definitions)), emptyList())); + this(new Meta(title), new Content(Arrays.asList(uris(definitions)), emptyList())); } @JsonIgnore diff --git a/src/main/java/com/gooddata/md/report/ReportDefinition.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/report/ReportDefinition.java similarity index 78% rename from src/main/java/com/gooddata/md/report/ReportDefinition.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/report/ReportDefinition.java index 0671f72ff..9ab2ed74c 100644 --- a/src/main/java/com/gooddata/md/report/ReportDefinition.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/report/ReportDefinition.java @@ -1,26 +1,26 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md.report; +package com.gooddata.sdk.model.md.report; -import static com.gooddata.util.Validate.notNullState; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.gooddata.md.AbstractObj; -import com.gooddata.md.Meta; -import com.gooddata.md.Queryable; -import com.gooddata.md.Updatable; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.md.AbstractObj; +import com.gooddata.sdk.model.md.Meta; +import com.gooddata.sdk.model.md.Queryable; +import com.gooddata.sdk.model.md.Updatable; import java.util.Map; +import static com.gooddata.sdk.common.util.Validate.notNullState; + /** * Report definition */ @@ -66,16 +66,6 @@ public Grid getGrid() { return content.getGrid(); } - /** - * @return explain URI string - * @deprecated use {@link #getExplainUri()} instead - */ - @Deprecated - @JsonIgnore - public String getExplainLink() { - return getExplainUri(); - } - @JsonIgnore public String getExplainUri() { return notNullState(links, "links").get(EXPLAIN_LINK); diff --git a/src/main/java/com/gooddata/md/report/ReportDefinitionContent.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/report/ReportDefinitionContent.java similarity index 91% rename from src/main/java/com/gooddata/md/report/ReportDefinitionContent.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/report/ReportDefinitionContent.java index 87cf8a341..4a993006f 100644 --- a/src/main/java/com/gooddata/md/report/ReportDefinitionContent.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/report/ReportDefinitionContent.java @@ -1,15 +1,15 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md.report; +package com.gooddata.sdk.model.md.report; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.io.Serializable; import java.util.Collection; diff --git a/src/main/java/com/gooddata/md/report/Total.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/report/Total.java similarity index 79% rename from src/main/java/com/gooddata/md/report/Total.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/report/Total.java index 9b70de36a..04ee28a92 100644 --- a/src/main/java/com/gooddata/md/report/Total.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/report/Total.java @@ -1,19 +1,20 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md.report; +package com.gooddata.sdk.model.md.report; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; -import org.springframework.util.StringUtils; import java.util.Arrays; import java.util.List; -import static com.gooddata.util.Validate.notNull; +import static com.gooddata.sdk.common.util.Validate.notNull; import static java.lang.String.format; +import static java.util.Arrays.stream; +import static java.util.stream.Collectors.joining; /** * Represents type of Total for {@link AttributeInGrid} @@ -26,12 +27,6 @@ public enum Total { NAT, MED; - @JsonValue - @Override - public String toString() { - return name().toLowerCase(); - } - @JsonCreator public static Total of(String total) { notNull(total, "total"); @@ -40,7 +35,7 @@ public static Total of(String total) { } catch (IllegalArgumentException e) { throw new UnsupportedOperationException( format("Unknown value for Grid's total: \"%s\", supported values are: [%s]", - total, StringUtils.arrayToCommaDelimitedString(Total.values())), + total, stream(Total.values()).map(Enum::name).collect(joining(","))), e); } } @@ -53,4 +48,10 @@ public static Total of(String total) { public static List orderedValues() { return Arrays.asList(SUM, MAX, MIN, AVG, MED, NAT); } + + @JsonValue + @Override + public String toString() { + return name().toLowerCase(); + } } diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/visualization/Bucket.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/visualization/Bucket.java new file mode 100644 index 000000000..0757f9fdd --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/visualization/Bucket.java @@ -0,0 +1,108 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.md.visualization; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.gooddata.sdk.model.executeafm.afm.LocallyIdentifiable; +import com.gooddata.sdk.model.executeafm.resultspec.TotalItem; + +import java.io.Serializable; +import java.util.List; +import java.util.Objects; + +/** + * Represents bucket within {@link VisualizationObject} + */ +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +public class Bucket implements Serializable, LocallyIdentifiable { + + private static final long serialVersionUID = -7718720886547680021L; + private final String localIdentifier; + private final List items; + private final List totals; + + /** + * Creates new instance of bucket without totals + * + * @param localIdentifier local identifier of bucket + * @param items list of {@link BucketItem}s for this bucket + */ + public Bucket(@JsonProperty("localIdentifier") final String localIdentifier, + @JsonProperty("items") final List items) { + this(localIdentifier, items, null); + } + + /** + * Creates new instance of bucket + * + * @param localIdentifier local identifier of bucket + * @param items list of {@link BucketItem}s for this bucket + * @param totals list of {@link TotalItem}s for this bucket + */ + @JsonCreator + public Bucket(@JsonProperty("localIdentifier") final String localIdentifier, + @JsonProperty("items") final List items, + @JsonProperty("totals") List totals) { + this.localIdentifier = localIdentifier; + this.items = items; + this.totals = totals; + } + + /** + * @return local identifier + */ + public String getLocalIdentifier() { + return localIdentifier; + } + + /** + * @return list of {@link BucketItem}s + */ + public List getItems() { + return items; + } + + /** + * @return list of defined {@link TotalItem}s + */ + public List getTotals() { + return totals; + } + + @JsonIgnore + VisualizationAttribute getOnlyAttribute() { + if (getItems() != null && getItems().size() == 1) { + final BucketItem item = getItems().iterator().next(); + if (item instanceof VisualizationAttribute) { + return (VisualizationAttribute) item; + } + } + + return null; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + Bucket bucket = (Bucket) o; + return Objects.equals(localIdentifier, bucket.localIdentifier) + && Objects.equals(items, bucket.items) + && Objects.equals(totals, bucket.totals); + } + + @Override + public int hashCode() { + return Objects.hash(localIdentifier, items, totals); + } +} diff --git a/src/main/java/com/gooddata/md/visualization/BucketItem.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/visualization/BucketItem.java similarity index 85% rename from src/main/java/com/gooddata/md/visualization/BucketItem.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/visualization/BucketItem.java index e4327474c..c61170c3c 100644 --- a/src/main/java/com/gooddata/md/visualization/BucketItem.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/visualization/BucketItem.java @@ -1,9 +1,9 @@ /* - * Copyright (C) 2018, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md.visualization; +package com.gooddata.sdk.model.md.visualization; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; @@ -20,5 +20,6 @@ }) @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(JsonInclude.Include.NON_NULL) -public interface BucketItem {} +public interface BucketItem { +} diff --git a/src/main/java/com/gooddata/md/visualization/CollectionType.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/visualization/CollectionType.java similarity index 79% rename from src/main/java/com/gooddata/md/visualization/CollectionType.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/visualization/CollectionType.java index d50f8dcb9..fc6d05502 100644 --- a/src/main/java/com/gooddata/md/visualization/CollectionType.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/visualization/CollectionType.java @@ -1,9 +1,9 @@ /* - * Copyright (C) 2018, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md.visualization; +package com.gooddata.sdk.model.md.visualization; /** * Represents type of collection that can be used as local identifier for {@link Bucket} diff --git a/src/main/java/com/gooddata/md/visualization/Measure.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/visualization/Measure.java similarity index 82% rename from src/main/java/com/gooddata/md/visualization/Measure.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/visualization/Measure.java index 3d28a93b0..0c396cd75 100644 --- a/src/main/java/com/gooddata/md/visualization/Measure.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/visualization/Measure.java @@ -1,16 +1,16 @@ /* - * Copyright (C) 2018, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md.visualization; +package com.gooddata.sdk.model.md.visualization; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import com.gooddata.executeafm.afm.MeasureDefinition; -import com.gooddata.executeafm.afm.MeasureItem; +import com.gooddata.sdk.model.executeafm.afm.MeasureDefinition; +import com.gooddata.sdk.model.executeafm.afm.MeasureItem; import java.util.Objects; @@ -20,14 +20,14 @@ @JsonInclude(JsonInclude.Include.NON_NULL) public class Measure extends MeasureItem implements BucketItem { - private static final long serialVersionUID = -6311373783004640731L; static final String NAME = "measure"; - + private static final long serialVersionUID = -6311373783004640731L; private String title; /** * Creates new instance of measure for use in {@link VisualizationObject} - * @param definition measure definition + * + * @param definition measure definition * @param localIdentifier local identifier */ public Measure(final MeasureDefinition definition, final String localIdentifier) { @@ -36,11 +36,12 @@ public Measure(final MeasureDefinition definition, final String localIdentifier) /** * Creates new instance of measure for use in {@link VisualizationObject} - * @param definition measure definition + * + * @param definition measure definition * @param localIdentifier local identifier - * @param alias alias for measure title - * @param title default name given to measure - * @param format format of measure to be computed + * @param alias alias for measure title + * @param title default name given to measure + * @param format format of measure to be computed */ @JsonCreator public Measure(@JsonProperty("definition") final MeasureDefinition definition, @@ -55,6 +56,7 @@ public Measure(@JsonProperty("definition") final MeasureDefinition definition, /** * @return true if measure definition has compute ratio set to true, false otherwise */ + @SuppressWarnings("deprecation") @JsonIgnore public boolean hasComputeRatio() { return getDefinition() instanceof VOSimpleMeasureDefinition && ((VOSimpleMeasureDefinition) getDefinition()).hasComputeRatio(); @@ -77,6 +79,7 @@ public void setTitle(String title) { /** * @return true if measure contains {@link VOPopMeasureDefinition}, false otherwise */ + @SuppressWarnings("deprecation") @JsonIgnore public boolean isPop() { return getDefinition() instanceof VOPopMeasureDefinition; diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/visualization/VOPopMeasureDefinition.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/visualization/VOPopMeasureDefinition.java new file mode 100644 index 000000000..63a53e4cd --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/visualization/VOPopMeasureDefinition.java @@ -0,0 +1,43 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.md.visualization; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonRootName; +import com.gooddata.sdk.model.executeafm.ObjQualifier; +import com.gooddata.sdk.model.executeafm.afm.PopMeasureDefinition; + +import static com.gooddata.sdk.model.md.visualization.VOPopMeasureDefinition.NAME; + +/** + * Period over Period measure definition to be used within {@link Measure} + * + * @deprecated identical with {@link PopMeasureDefinition}, see https://github.com/gooddata/gooddata-java/issues/581 + * Let's remove it once it's removed from API. + */ +@Deprecated +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonRootName(NAME) +public class VOPopMeasureDefinition extends PopMeasureDefinition { + + public static final String NAME = "popMeasureDefinition"; + private static final long serialVersionUID = -2727004914980057124L; + + /** + * Creates instance of Period over Period measure definition to be used in {@link VisualizationObject} + * + * @param measureIdentifier reference to local identifier of {@link VOSimpleMeasureDefinition} over which is PoP calculated + * @param popAttribute uri to attribute used for PoP + */ + @JsonCreator + public VOPopMeasureDefinition(@JsonProperty("measureIdentifier") final String measureIdentifier, + @JsonProperty("popAttribute") final ObjQualifier popAttribute) { + super(measureIdentifier, popAttribute); + } + +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/visualization/VOSimpleMeasureDefinition.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/visualization/VOSimpleMeasureDefinition.java new file mode 100644 index 000000000..3b117b507 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/visualization/VOSimpleMeasureDefinition.java @@ -0,0 +1,80 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.md.visualization; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonRootName; +import com.gooddata.sdk.model.executeafm.ObjQualifier; +import com.gooddata.sdk.model.executeafm.afm.Aggregation; +import com.gooddata.sdk.model.executeafm.afm.MeasureDefinition; +import com.gooddata.sdk.model.executeafm.afm.SimpleMeasureDefinition; +import com.gooddata.sdk.model.executeafm.afm.filter.FilterItem; + +import java.util.List; + +import static com.gooddata.sdk.model.md.visualization.VOSimpleMeasureDefinition.NAME; + +/** + * Simple measure definition to be used within {@link Measure} + * + * @deprecated identical with {@link MeasureDefinition}, see https://github.com/gooddata/gooddata-java/issues/581 + * Let's remove it once it's removed from API. + */ +@Deprecated +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonRootName(NAME) +public class VOSimpleMeasureDefinition extends SimpleMeasureDefinition { + + public static final String NAME = "measureDefinition"; + private static final long serialVersionUID = 8467311354259963694L; + + /** + * Creates instance of simple measure definition to be used in {@link VisualizationObject} + * + * @see SimpleMeasureDefinition#SimpleMeasureDefinition(ObjQualifier) + */ + public VOSimpleMeasureDefinition(ObjQualifier item) { + super(item); + } + + /** + * Creates instance of simple measure definition to be used in {@link VisualizationObject} + * + * @param item uri to measure + * @param aggregation used aggregation function + * @param computeRatio indicates if result should be calculated in percents + * @param filters filters by which measure is filtered + */ + @JsonCreator + public VOSimpleMeasureDefinition(@JsonProperty("item") final ObjQualifier item, + @JsonProperty("aggregation") final String aggregation, + @JsonProperty("computeRatio") final Boolean computeRatio, + @JsonProperty("filters") final List filters) { + super(item, aggregation, computeRatio, filters); + } + + /** + * Creates instance of simple measure definition to be used in {@link VisualizationObject} + * + * @see SimpleMeasureDefinition#SimpleMeasureDefinition(ObjQualifier, Aggregation, Boolean, List) + */ + public VOSimpleMeasureDefinition(ObjQualifier item, Aggregation aggregation, Boolean computeRatio, + List filters) { + super(item, aggregation, computeRatio, filters); + } + + /** + * Creates instance of simple measure definition to be used in {@link VisualizationObject} + * + * @see SimpleMeasureDefinition#SimpleMeasureDefinition(ObjQualifier, Aggregation, Boolean, FilterItem...) + */ + public VOSimpleMeasureDefinition(ObjQualifier item, Aggregation aggregation, Boolean computeRatio, + FilterItem... filters) { + super(item, aggregation, computeRatio, filters); + } +} diff --git a/src/main/java/com/gooddata/md/visualization/VisualizationAttribute.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/visualization/VisualizationAttribute.java similarity index 83% rename from src/main/java/com/gooddata/md/visualization/VisualizationAttribute.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/visualization/VisualizationAttribute.java index 4bebd96c4..d0b74a437 100644 --- a/src/main/java/com/gooddata/md/visualization/VisualizationAttribute.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/visualization/VisualizationAttribute.java @@ -1,15 +1,15 @@ /* - * Copyright (C) 2018, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md.visualization; +package com.gooddata.sdk.model.md.visualization; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import com.gooddata.executeafm.UriObjQualifier; -import com.gooddata.executeafm.afm.AttributeItem; +import com.gooddata.sdk.model.executeafm.UriObjQualifier; +import com.gooddata.sdk.model.executeafm.afm.AttributeItem; import java.util.Objects; @@ -19,13 +19,13 @@ @JsonInclude(JsonInclude.Include.NON_NULL) public class VisualizationAttribute extends AttributeItem implements BucketItem { - private static final long serialVersionUID = -5144496152695494774L; static final String NAME = "visualizationAttribute"; + private static final long serialVersionUID = -5144496152695494774L; /** * Creates new instance of visualization attribute for use in {@link Bucket} * - * @param displayForm display form of attribute + * @param displayForm display form of attribute * @param localIdentifier local identifier of attribute */ public VisualizationAttribute(final UriObjQualifier displayForm, final String localIdentifier) { @@ -35,9 +35,9 @@ public VisualizationAttribute(final UriObjQualifier displayForm, final String lo /** * Creates new instance of visualization attribute for use in {@link Bucket} * - * @param displayForm display form of attribute + * @param displayForm display form of attribute * @param localIdentifier local identifier of attribute - * @param alias alias of attribute + * @param alias alias of attribute */ @JsonCreator public VisualizationAttribute(@JsonProperty("displayForm") final UriObjQualifier displayForm, diff --git a/src/main/java/com/gooddata/md/visualization/VisualizationClass.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/visualization/VisualizationClass.java similarity index 85% rename from src/main/java/com/gooddata/md/visualization/VisualizationClass.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/visualization/VisualizationClass.java index 62b2121ec..497c37195 100644 --- a/src/main/java/com/gooddata/md/visualization/VisualizationClass.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/visualization/VisualizationClass.java @@ -1,9 +1,9 @@ /* - * Copyright (C) 2018, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md.visualization; +package com.gooddata.sdk.model.md.visualization; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; @@ -12,10 +12,10 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.md.AbstractObj; -import com.gooddata.md.Meta; -import com.gooddata.md.Queryable; -import com.gooddata.md.Updatable; +import com.gooddata.sdk.model.md.AbstractObj; +import com.gooddata.sdk.model.md.Meta; +import com.gooddata.sdk.model.md.Queryable; +import com.gooddata.sdk.model.md.Updatable; import java.io.Serializable; @@ -32,12 +32,11 @@ @JsonInclude(JsonInclude.Include.NON_NULL) public class VisualizationClass extends AbstractObj implements Queryable, Updatable { - private static final long serialVersionUID = -72785788784079208L; static final String NAME = "visualizationClass"; - + private static final long serialVersionUID = -72785788784079208L; private Content content; - private VisualizationClass(@JsonProperty("content") final Content content, @JsonProperty("meta") final Meta meta ) { + private VisualizationClass(@JsonProperty("content") final Content content, @JsonProperty("meta") final Meta meta) { super(meta); this.content = notNull(content); } @@ -92,7 +91,7 @@ public VisualizationType getVisualizationType() { String uriParts[] = getContent().getUrl().split(":"); if (uriParts.length > 0 && isLocal()) { - String derivedType = uriParts[uriParts.length-1]; + String derivedType = uriParts[uriParts.length - 1]; visualizationType = VisualizationType.of(derivedType); } @@ -105,7 +104,7 @@ private boolean isLocal() { return getContent().getChecksum().equals("local"); } - private Content getContent() { + private Content getContent() { return content; } @@ -118,10 +117,10 @@ private static class Content implements Serializable { @JsonCreator private Content(@JsonProperty("url") String url, - @JsonProperty("icon") String icon, - @JsonProperty("iconSelected") String iconSelected, - @JsonProperty("checksum") String checksum, - @JsonProperty("orderIndex") Float orderIndex) { + @JsonProperty("icon") String icon, + @JsonProperty("iconSelected") String iconSelected, + @JsonProperty("checksum") String checksum, + @JsonProperty("orderIndex") Float orderIndex) { this.url = notNull(url); this.icon = notNull(icon); this.iconSelected = notNull(iconSelected); diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/visualization/VisualizationConverter.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/visualization/VisualizationConverter.java new file mode 100644 index 000000000..b02e5b7aa --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/visualization/VisualizationConverter.java @@ -0,0 +1,476 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.md.visualization; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.gooddata.sdk.model.executeafm.Execution; +import com.gooddata.sdk.model.executeafm.afm.Afm; +import com.gooddata.sdk.model.executeafm.afm.AttributeItem; +import com.gooddata.sdk.model.executeafm.afm.MeasureItem; +import com.gooddata.sdk.model.executeafm.afm.NativeTotalItem; +import com.gooddata.sdk.model.executeafm.afm.SimpleMeasureDefinition; +import com.gooddata.sdk.model.executeafm.afm.filter.CompatibilityFilter; +import com.gooddata.sdk.model.executeafm.afm.filter.DateFilter; +import com.gooddata.sdk.model.executeafm.afm.filter.ExtendedFilter; +import com.gooddata.sdk.model.executeafm.afm.filter.FilterItem; +import com.gooddata.sdk.model.executeafm.afm.filter.MeasureValueFilter; +import com.gooddata.sdk.model.executeafm.afm.filter.NegativeAttributeFilter; +import com.gooddata.sdk.model.executeafm.afm.filter.PositiveAttributeFilter; +import com.gooddata.sdk.model.executeafm.afm.filter.RankingFilter; +import com.gooddata.sdk.model.executeafm.resultspec.Dimension; +import com.gooddata.sdk.model.executeafm.resultspec.ResultSpec; +import com.gooddata.sdk.model.executeafm.resultspec.SortItem; +import com.gooddata.sdk.model.executeafm.resultspec.TotalItem; +import com.gooddata.sdk.model.md.report.Total; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.function.Function; +import java.util.stream.Collectors; + +import static com.gooddata.sdk.common.util.Validate.isTrue; +import static com.gooddata.sdk.common.util.Validate.notNull; +import static com.gooddata.sdk.model.executeafm.resultspec.Dimension.MEASURE_GROUP; +import static java.util.stream.Collectors.toList; + +/** + * Helper class for converting {@link VisualizationObject} into {@link Execution} + */ +public abstract class VisualizationConverter { + private static final ObjectMapper MAPPER = new ObjectMapper(); + + /** + * Generate Execution from Visualization object. + *

      + * NOTE: totals are not included in this conversion + * + * @param visualizationObject which will be converted to {@link Execution} + * @param visualizationClassGetter {@link Function} for fetching VisualizationClass, + * which is necessary for correct generation of {@link ResultSpec} + * @return {@link Execution} object + * @see #convertToExecution(VisualizationObject, VisualizationClass) + */ + public static Execution convertToExecution(final VisualizationObject visualizationObject, + final Function visualizationClassGetter) { + notNull(visualizationObject, "visualizationObject"); + notNull(visualizationClassGetter, "visualizationClassGetter"); + return convertToExecution(visualizationObject, + visualizationClassGetter.apply(visualizationObject.getVisualizationClassUri())); + } + + /** + * Generate Execution from Visualization object. + *

      + * NOTE: totals are not included in this conversion + * + * @param visualizationObject which will be converted to {@link Execution} + * @param visualizationClass visualizationClass, which is necessary for correct generation of {@link ResultSpec} + * @return {@link Execution} object + * @see #convertToAfm(VisualizationObject) + * @see #convertToResultSpec(VisualizationObject, VisualizationClass) + */ + public static Execution convertToExecution(final VisualizationObject visualizationObject, + final VisualizationClass visualizationClass) { + notNull(visualizationObject, "visualizationObject"); + notNull(visualizationClass, "visualizationClass"); + ResultSpec resultSpec = convertToResultSpec(visualizationObject, visualizationClass); + Afm afm = convertToAfm(visualizationObject); + return new Execution(afm, resultSpec); + } + + /** + * Generate Execution from Visualization object with totals included. + * + * @param visualizationObject which will be converted to {@link Execution} + * @param visualizationClassGetter {@link Function} for fetching VisualizationClass, + * which is necessary for correct generation of {@link ResultSpec} + * @return {@link Execution} object + * @see #convertToExecutionWithTotals(VisualizationObject, VisualizationClass) + */ + public static Execution convertToExecutionWithTotals(final VisualizationObject visualizationObject, + final Function visualizationClassGetter) { + notNull(visualizationObject, "visualizationObject"); + notNull(visualizationClassGetter, "visualizationClassGetter"); + return convertToExecutionWithTotals(visualizationObject, + visualizationClassGetter.apply(visualizationObject.getVisualizationClassUri())); + } + + /** + * Generate Execution from Visualization object with totals included. + * + * @param visualizationObject which will be converted to {@link Execution} + * @param visualizationClass visualizationClass, which is necessary for correct generation of {@link ResultSpec} + * @return {@link Execution} object + * @see #convertToAfmWithNativeTotals(VisualizationObject) + * @see #convertToResultSpecWithTotals(VisualizationObject, VisualizationClass) + */ + public static Execution convertToExecutionWithTotals(final VisualizationObject visualizationObject, + final VisualizationClass visualizationClass) { + notNull(visualizationObject, "visualizationObject"); + notNull(visualizationClass, "visualizationClass"); + ResultSpec resultSpec = convertToResultSpecWithTotals(visualizationObject, visualizationClass); + Afm afm = convertToAfmWithNativeTotals(visualizationObject); + return new Execution(afm, resultSpec); + } + + /** + * Generate Afm from Visualization object. + *

      + * NOTE: native totals are not included in this conversion + * + * @param visualizationObject which will be converted to {@link Execution} + * @return {@link Afm} object + */ + public static Afm convertToAfm(final VisualizationObject visualizationObject) { + notNull(visualizationObject, "visualizationObject"); + final VisualizationObject visualizationObjectWithoutTotals = removeTotals(visualizationObject); + return convertToAfmWithNativeTotals(visualizationObjectWithoutTotals); + } + + /** + * Generate Afm from Visualization object with native totals included. + * + * @param visualizationObject which will be converted to {@link Execution} + * @return {@link Afm} object + */ + public static Afm convertToAfmWithNativeTotals(final VisualizationObject visualizationObject) { + notNull(visualizationObject, "visualizationObject"); + final List attributes = convertAttributes(visualizationObject.getAttributes()); + final List filters = convertFilters(visualizationObject.getFilters()); + final List measures = convertMeasures(visualizationObject.getMeasures()); + final List totals = convertNativeTotals(visualizationObject); + + return new Afm(attributes, filters, measures, totals); + } + + /** + * Generate ResultSpec from Visualization object. Currently {@link ResultSpec}'s {@link Dimension}s can be generated + * for table and four types of chart: bar, column, line and pie. + *

      + * NOTE: totals are not included in this conversion + * + * @param visualizationObject which will be converted to {@link Execution} + * @param visualizationClassGetter {@link Function} for fetching VisualizationClass, + * which is necessary for correct generation of {@link ResultSpec} + * @return {@link Execution} object + */ + public static ResultSpec convertToResultSpec(final VisualizationObject visualizationObject, + final Function visualizationClassGetter) { + notNull(visualizationObject, "visualizationObject"); + notNull(visualizationClassGetter, "visualizationClassGetter"); + return convertToResultSpec(visualizationObject, + visualizationClassGetter.apply(visualizationObject.getVisualizationClassUri())); + } + + /** + * Generate ResultSpec from Visualization object. Currently {@link ResultSpec}'s {@link Dimension}s can be generated + * for table and four types of chart: bar, column, line and pie. + *

      + * NOTE: totals are not included in this conversion + * + * @param visualizationObject which will be converted to {@link Execution} + * @param visualizationClass VisualizationClass, which is necessary for correct generation of {@link ResultSpec} + * @return {@link Execution} object + */ + public static ResultSpec convertToResultSpec(final VisualizationObject visualizationObject, + final VisualizationClass visualizationClass) { + notNull(visualizationObject, "visualizationObject"); + notNull(visualizationClass, "visualizationClass"); + final VisualizationObject visualizationObjectWithoutTotals = removeTotals(visualizationObject); + return convertToResultSpecWithTotals(visualizationObjectWithoutTotals, visualizationClass); + } + + /** + * Generate ResultSpec from Visualization object with totals included. Currently {@link ResultSpec}'s {@link Dimension}s + * can be generated for table and four types of chart: bar, column, line and pie. + * + * @param visualizationObject which will be converted to {@link Execution} + * @param visualizationClassGetter {@link Function} for fetching VisualizationClass, + * which is necessary for correct generation of {@link ResultSpec} + * @return {@link Execution} object + */ + public static ResultSpec convertToResultSpecWithTotals(final VisualizationObject visualizationObject, + final Function visualizationClassGetter) { + notNull(visualizationObject, "visualizationObject"); + notNull(visualizationClassGetter, "visualizationClassGetter"); + return convertToResultSpecWithTotals(visualizationObject, + visualizationClassGetter.apply(visualizationObject.getVisualizationClassUri())); + } + + /** + * Generate ResultSpec from Visualization object with totals included. Currently {@link ResultSpec}'s {@link Dimension}s + * can be generated for table and four types of chart: bar, column, line and pie. + * + * @param visualizationObject which will be converted to {@link Execution} + * @param visualizationClass VisualizationClass, which is necessary for correct generation of {@link ResultSpec} + * @return {@link Execution} object + */ + public static ResultSpec convertToResultSpecWithTotals(final VisualizationObject visualizationObject, + final VisualizationClass visualizationClass) { + notNull(visualizationObject, "visualizationObject"); + notNull(visualizationClass, "visualizationClass"); + isTrue(visualizationObject.getVisualizationClassUri().equals(visualizationClass.getUri()), + "visualizationClass URI does not match the URI within visualizationObject, " + + "you're trying to create ResultSpec for incompatible objects"); + List sorts = getSorting(visualizationObject); + List dimensions = getDimensions(visualizationObject, visualizationClass.getVisualizationType()); + return new ResultSpec(dimensions, sorts); + } + + static List getSorting(final VisualizationObject visualizationObject) { + try { + List sorts = parseSorting(visualizationObject.getProperties()); + if (sorts != null) { + return sorts; + } + } catch (Exception ignored) { + } + + return null; + } + + static List parseSorting(final String properties) throws Exception { + JsonNode jsonProperties = parseProperties(properties); + JsonNode nodeSortItems = jsonProperties.get("sortItems"); + TypeReference> mapType = new TypeReference>() { + }; + return MAPPER.convertValue(nodeSortItems, mapType); + } + + /** + * Creates a new {@link VisualizationObject} derived from the original one, with all "totals" removed from its buckets. + * This is to ensure backward compatibility in cases where totals were not previously handled. + * + * @param visualizationObject original {@link VisualizationObject} + * @return a new VisualizationObject derived from the original but without any totals in the buckets. + */ + private static VisualizationObject removeTotals(final VisualizationObject visualizationObject) { + final List bucketsWithoutTotals = visualizationObject.getBuckets().stream() + // create buckets without totals + .map(bucket -> new Bucket(bucket.getLocalIdentifier(), bucket.getItems())) + .collect(toList()); + return visualizationObject.withBuckets(bucketsWithoutTotals); + } + + private static List getDimensions(final VisualizationObject visualizationObject, + final VisualizationType visualizationType) { + switch (visualizationType) { + case COLUMN: + case BAR: + return getDimensionsForStacked(visualizationObject, CollectionType.STACK, CollectionType.VIEW); + case LINE: + return getDimensionsForStacked(visualizationObject, CollectionType.SEGMENT, CollectionType.TREND); + case PIE: + return getDimensionsForPie(visualizationObject); + default: + return getDimensionsForTable(visualizationObject); + } + } + + private static List getDimensionsForPie(final VisualizationObject visualizationObject) { + VisualizationAttribute attribute = visualizationObject.getView(); + + List dimensions = new ArrayList<>(); + + if (visualizationObject.hasMeasures()) { + dimensions.add(new Dimension(MEASURE_GROUP)); + } + + if (attribute != null) { + dimensions.add(new Dimension(attribute.getLocalIdentifier())); + } + + return dimensions; + } + + private static List getDimensionsForStacked(final VisualizationObject visualizationObject, + final CollectionType stackBy, + final CollectionType viewBy) { + VisualizationAttribute stack = visualizationObject.getAttributeFromCollection(stackBy); + VisualizationAttribute view = visualizationObject.getAttributeFromCollection(viewBy); + + List dimensions = new ArrayList<>(); + + if (stack != null) { + dimensions.add(new Dimension(stack.getLocalIdentifier())); + + List dimensionItems = new ArrayList<>(); + + if (view != null) { + dimensionItems.add(view.getLocalIdentifier()); + } + + if (visualizationObject.hasMeasures()) { + dimensionItems.add(MEASURE_GROUP); + } + + if (!dimensionItems.isEmpty()) { + dimensions.add(new Dimension(dimensionItems)); + } + } else { + if (visualizationObject.hasMeasures()) { + dimensions.add(new Dimension(MEASURE_GROUP)); + } + + if (view != null) { + dimensions.add(new Dimension(view.getLocalIdentifier())); + } + } + + return dimensions; + } + + private static List getDimensionsForTable(final VisualizationObject visualizationObject) { + List dimensions = new ArrayList<>(); + + List attributes = visualizationObject.getAttributes(); + List totals = visualizationObject.getTotals(); + + if (!attributes.isEmpty()) { + final Dimension attributeDimension = new Dimension(attributes.stream() + .map(VisualizationAttribute::getLocalIdentifier) + .collect(toList())); + if (!totals.isEmpty()) { + attributeDimension.setTotals(new HashSet<>(totals)); + } + dimensions.add(attributeDimension); + } else { + dimensions.add(new Dimension(new ArrayList<>())); + } + + if (visualizationObject.hasMeasures()) { + dimensions.add(new Dimension(MEASURE_GROUP)); + } + + return dimensions; + } + + private static JsonNode parseProperties(final String properties) throws Exception { + return MAPPER.readValue(properties, JsonNode.class); + } + + private static List convertAttributes(final List attributes) { + return attributes.stream() + .map(AttributeItem.class::cast) + .collect(toList()); + } + + private static List convertFilters(final List filters) { + if (filters == null) { + return new ArrayList<>(); + } + + List validFilters = removeIrrelevantFilters(filters); + return getCompatibilityFilters(validFilters); + } + + private static List convertMeasures(final List measures) { + return measures.stream() + .map(VisualizationConverter::removeFormat) + .map(VisualizationConverter::getAfmMeasure) + .map(VisualizationConverter::convertMeasureFilters) + .collect(toList()); + } + + private static Measure removeFormat(final Measure measure) { + if (measure.hasComputeRatio()) { + measure.setFormat(""); + } + + return measure; + } + + private static MeasureItem getAfmMeasure(final Measure measure) { + String alias = measure.getAlias(); + String usedTitle = alias; + if (alias == null || alias.isEmpty()) { + if (measure.getTitle() != null) { + usedTitle = measure.getTitle(); + } + } + return new MeasureItem(measure.getDefinition(), measure.getLocalIdentifier(), usedTitle, measure.getFormat()); + } + + private static MeasureItem convertMeasureFilters(final MeasureItem measure) { + if (measure.getDefinition() instanceof SimpleMeasureDefinition) { + List filters = ((SimpleMeasureDefinition) measure.getDefinition()).getFilters(); + + List validFilters; + if (filters == null) { + validFilters = new ArrayList<>(); + } else { + validFilters = removeIrrelevantFilters(filters); + } + + ((SimpleMeasureDefinition) measure.getDefinition()).setFilters(validFilters); + } + + return measure; + } + + private static List getCompatibilityFilters(final List filters) { + return filters.stream() + .map(CompatibilityFilter.class::cast) + .collect(toList()); + } + + private static List removeIrrelevantFilters(final List filters) { + return filters.stream() + .filter(f -> { + if (f instanceof DateFilter) { + return !((DateFilter) f).isAllTimeSelected(); + } else if (f instanceof MeasureValueFilter) { + return ((MeasureValueFilter) f).getCondition() != null; + } else if (f instanceof NegativeAttributeFilter) { + return !((NegativeAttributeFilter) f).isAllSelected(); + } else return f instanceof PositiveAttributeFilter || f instanceof RankingFilter; + + }) + .collect(Collectors.toList()); + } + + private static List convertNativeTotals(final VisualizationObject visualizationObject) { + final List attributeBuckets = getAttributeBuckets(visualizationObject); + final List attributeIds = getIdsFromAttributeBuckets(attributeBuckets); + return attributeBuckets.stream() + .filter(bucket -> bucket.getTotals() != null) + .flatMap(bucket -> bucket.getTotals().stream()) + .filter(totalItem -> isNativeTotal(totalItem) && attributeIds.contains(totalItem.getAttributeIdentifier())) + .map(totalItem -> convertToNativeTotalItem(totalItem, attributeIds)) + .collect(toList()); + } + + private static NativeTotalItem convertToNativeTotalItem(TotalItem totalItem, List attributeIds) { + final int attributeIdx = attributeIds.indexOf(totalItem.getAttributeIdentifier()); + return new NativeTotalItem( + totalItem.getMeasureIdentifier(), + new ArrayList<>(attributeIds.subList(0, attributeIdx)) + ); + } + + private static List getAttributeBuckets(final VisualizationObject visualizationObject) { + return visualizationObject.getBuckets().stream() + .filter(bucket -> bucket.getItems().stream().allMatch(AttributeItem.class::isInstance)) + .collect(toList()); + } + + private static List getIdsFromAttributeBuckets(final List attributeBuckets) { + return attributeBuckets.stream() + .flatMap(bucket -> + bucket.getItems().stream() + .map(AttributeItem.class::cast) + .map(AttributeItem::getLocalIdentifier) + ) + .collect(toList()); + } + + private static boolean isNativeTotal(TotalItem totalItem) { + return totalItem.getType() != null && Total.NAT.name().equals(totalItem.getType().toUpperCase()); + } +} diff --git a/src/main/java/com/gooddata/md/visualization/VisualizationObject.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/visualization/VisualizationObject.java similarity index 79% rename from src/main/java/com/gooddata/md/visualization/VisualizationObject.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/visualization/VisualizationObject.java index f07517a63..dea99a829 100644 --- a/src/main/java/com/gooddata/md/visualization/VisualizationObject.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/visualization/VisualizationObject.java @@ -1,9 +1,9 @@ /* - * Copyright (C) 2018, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.md.visualization; +package com.gooddata.sdk.model.md.visualization; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; @@ -12,32 +12,34 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import static com.fasterxml.jackson.annotation.JsonTypeInfo.As.WRAPPER_OBJECT; -import static com.fasterxml.jackson.annotation.JsonTypeInfo.Id.NAME; -import static com.gooddata.md.visualization.CollectionType.*; -import static java.util.Collections.emptyList; -import static java.util.stream.Collectors.toList; -import static org.apache.commons.lang3.Validate.notEmpty; -import static org.apache.commons.lang3.Validate.notNull; - -import com.gooddata.executeafm.UriObjQualifier; -import com.gooddata.executeafm.afm.Afm; -import com.gooddata.executeafm.afm.FilterItem; -import com.gooddata.executeafm.Execution; -import com.gooddata.executeafm.resultspec.ResultSpec; -import com.gooddata.md.AbstractObj; -import com.gooddata.md.Meta; -import com.gooddata.md.Queryable; -import com.gooddata.md.Updatable; +import com.gooddata.sdk.model.executeafm.Execution; +import com.gooddata.sdk.model.executeafm.UriObjQualifier; +import com.gooddata.sdk.model.executeafm.afm.Afm; +import com.gooddata.sdk.model.executeafm.afm.filter.ExtendedFilter; +import com.gooddata.sdk.model.executeafm.resultspec.ResultSpec; +import com.gooddata.sdk.model.executeafm.resultspec.TotalItem; +import com.gooddata.sdk.model.md.AbstractObj; +import com.gooddata.sdk.model.md.Meta; +import com.gooddata.sdk.model.md.Obj; +import com.gooddata.sdk.model.md.Queryable; +import com.gooddata.sdk.model.md.Updatable; import java.io.Serializable; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.Function; +import static com.fasterxml.jackson.annotation.JsonTypeInfo.As.WRAPPER_OBJECT; +import static com.fasterxml.jackson.annotation.JsonTypeInfo.Id.NAME; +import static java.util.Collections.emptyList; +import static java.util.stream.Collectors.toList; +import static org.apache.commons.lang3.Validate.notEmpty; +import static org.apache.commons.lang3.Validate.notNull; + /** - * Complete information about new visualization object that can be stored as MD object (see {@link com.gooddata.md.Obj}) + * Complete information about new visualization object that can be stored as MD object (see {@link Obj}) * to md server. *

      * The visualization object is part of new GD UI visualizations situated in AD and KPI dashboards. @@ -56,7 +58,7 @@ public class VisualizationObject extends AbstractObj implements Queryable, Updat /** * Constructor. * - * @param title title of visualization object + * @param title title of visualization object * @param visualizationClassUri uri to the {@link VisualizationClass} */ public VisualizationObject(final String title, final String visualizationClassUri) { @@ -77,8 +79,17 @@ public List getMeasures() { return content.getMeasures(); } + /** + * @return all totals from all buckets in visualization object + */ + @JsonIgnore + public List getTotals() { + return content.getTotals(); + } + /** * Get measure by local identifier or null if not found + * * @param localIdentifier of measure * @return measure or null */ @@ -93,6 +104,7 @@ public Measure getMeasure(final String localIdentifier) { /** * @return all measures from all buckets whose measure definition is instance of {@link VOSimpleMeasureDefinition} */ + @SuppressWarnings("deprecation") @JsonIgnore public List getSimpleMeasures() { return getMeasures().stream() @@ -119,6 +131,7 @@ public VisualizationAttribute getAttribute(final String localIdentifier) { /** * Returns attribute from collection bucket, if and only if bucket contains exactly one item of type * {@link VisualizationAttribute}, null otherwise + * * @param type of collection which we want to get, stored as local identifier in each bucket * @return attribute from collection bucket */ @@ -146,6 +159,7 @@ public boolean hasDerivedMeasure() { /** * Method to get uri to requested local identifier from reference items + * * @param id of item * @return uri of requested item */ @@ -164,7 +178,7 @@ public String getItemById(String id) { */ @JsonIgnore public VisualizationAttribute getStack() { - return getAttributeFromCollection(STACK); + return getAttributeFromCollection(CollectionType.STACK); } /** @@ -172,7 +186,7 @@ public VisualizationAttribute getStack() { */ @JsonIgnore public VisualizationAttribute getView() { - return getAttributeFromCollection(VIEW); + return getAttributeFromCollection(CollectionType.VIEW); } /** @@ -180,7 +194,7 @@ public VisualizationAttribute getView() { */ @JsonIgnore public VisualizationAttribute getSegment() { - return getAttributeFromCollection(SEGMENT); + return getAttributeFromCollection(CollectionType.SEGMENT); } /** @@ -188,7 +202,7 @@ public VisualizationAttribute getSegment() { */ @JsonIgnore public VisualizationAttribute getTrend() { - return getAttributeFromCollection(TREND); + return getAttributeFromCollection(CollectionType.TREND); } /** @@ -215,19 +229,27 @@ public void setBuckets(List buckets) { content.setBuckets(buckets); } + /** + * @return a new copy of this {@link VisualizationObject} with the specified buckets + */ + @JsonIgnore + public VisualizationObject withBuckets(List buckets) { + return new VisualizationObject(content.withBuckets(buckets), meta); + } + /** * @return filters from visualization object */ @JsonIgnore - public List getFilters() { + public List getFilters() { return content.getFilters(); } /** - * @param filters replacing previsous visualization object's filters + * @param filters replacing previous visualization object's filters */ @JsonIgnore - public void setFilters(List filters) { + public void setFilters(List filters) { content.setFilters(filters); } @@ -264,7 +286,7 @@ public void setReferenceItems(Map referenceItems) { } /** - * @return uri to visualizaton class wrapped as {@link UriObjQualifier} + * @return uri to visualization class wrapped as {@link UriObjQualifier} */ @JsonIgnore public UriObjQualifier getVisualizationClass() { @@ -326,7 +348,7 @@ private static class Content implements Serializable { private static final long serialVersionUID = 2895359822118041504L; private UriObjQualifier visualizationClass; private List buckets; - private List filters; + private List filters; private String properties; private Map referenceItems; @@ -336,10 +358,10 @@ private Content(final String visualizationClassUri, final List buckets) @JsonCreator private Content(@JsonProperty("visualizationClass") final UriObjQualifier visualizationClass, - @JsonProperty("buckets") final List buckets, - @JsonProperty("filters") final List filters, - @JsonProperty("properties") final String properties, - @JsonProperty("references") final Map referenceItems) { + @JsonProperty("buckets") final List buckets, + @JsonProperty("filters") final List filters, + @JsonProperty("properties") final String properties, + @JsonProperty("references") final Map referenceItems) { this.visualizationClass = notNull(visualizationClass); this.buckets = notNull(buckets); @@ -352,6 +374,10 @@ public List getBuckets() { return buckets; } + public void setBuckets(List buckets) { + this.buckets = buckets; + } + @JsonIgnore public List getAttributes() { return buckets.stream() @@ -361,26 +387,6 @@ public List getAttributes() { .collect(toList()); } - public void setVisualizationClass(UriObjQualifier visualizationClass) { - this.visualizationClass = visualizationClass; - } - - public void setBuckets(List buckets) { - this.buckets = buckets; - } - - public void setFilters(List filters) { - this.filters = filters; - } - - public void setProperties(String properties) { - this.properties = properties; - } - - public void setReferenceItems(Map referenceItems) { - this.referenceItems = referenceItems; - } - @JsonIgnore public List getMeasures() { return buckets.stream() @@ -390,12 +396,20 @@ public List getMeasures() { .collect(toList()); } + @JsonIgnore + public List getTotals() { + return buckets.stream() + .filter(bucket -> bucket.getTotals() != null) + .flatMap(bucket -> bucket.getTotals().stream()) + .collect(toList()); + } + @JsonIgnore public String getVisualizationClassUri() { return visualizationClass.getUri(); } - public List getFilters() { + public List getFilters() { if (filters == null) { return new ArrayList<>(); } @@ -403,17 +417,47 @@ public List getFilters() { return filters; } + public void setFilters(List filters) { + this.filters = filters; + } + public String getProperties() { return properties; } + public void setProperties(String properties) { + this.properties = properties; + } + public UriObjQualifier getVisualizationClass() { return visualizationClass; } + public void setVisualizationClass(UriObjQualifier visualizationClass) { + this.visualizationClass = visualizationClass; + } + @JsonProperty("references") public Map getReferenceItems() { return referenceItems; } + + public void setReferenceItems(Map referenceItems) { + this.referenceItems = referenceItems; + } + + /** + * @return a new copy of this {@link Content} with the specified buckets + */ + @JsonIgnore + public Content withBuckets(List buckets) { + return new Content( + visualizationClass, + buckets, + filters != null ? new ArrayList<>(filters) : null, + properties, + referenceItems != null ? new HashMap<>(referenceItems) : null + ); + } } } diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/visualization/VisualizationType.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/visualization/VisualizationType.java new file mode 100644 index 000000000..c9d9794ee --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/md/visualization/VisualizationType.java @@ -0,0 +1,33 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.md.visualization; + +import static com.gooddata.sdk.common.util.Validate.notNull; +import static java.lang.String.format; +import static java.util.Arrays.stream; +import static java.util.stream.Collectors.joining; + +/** + * Represents supported types of currently used visualizations + */ +public enum VisualizationType { + TABLE, + LINE, + COLUMN, + BAR, + PIE; + + public static VisualizationType of(final String type) { + try { + return VisualizationType.valueOf(notNull(type, "type").toUpperCase()); + } catch (IllegalArgumentException e) { + throw new UnsupportedOperationException( + format("Unknown visualization type: \"%s\", supported types are: [%s]", + type, stream(VisualizationType.values()).map(Enum::name).collect(joining(","))), + e); + } + } +} diff --git a/src/main/java/com/gooddata/notification/Channel.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/notification/Channel.java similarity index 77% rename from src/main/java/com/gooddata/notification/Channel.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/notification/Channel.java index 9a7b37aec..73c98949d 100644 --- a/src/main/java/com/gooddata/notification/Channel.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/notification/Channel.java @@ -1,22 +1,21 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.notification; - -import static com.gooddata.util.Validate.notEmpty; -import static com.gooddata.util.Validate.notNull; +package com.gooddata.sdk.model.notification; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.account.Account; -import com.gooddata.md.Meta; -import com.gooddata.util.GoodDataToStringBuilder; -import org.springframework.web.util.UriTemplate; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.account.Account; +import com.gooddata.sdk.model.md.Meta; + +import static com.gooddata.sdk.common.util.Validate.notEmpty; +import static com.gooddata.sdk.common.util.Validate.notNull; /** * Notification channel @@ -27,7 +26,6 @@ public class Channel { public static final String URI = Account.URI + "/channelConfigurations"; - public static final UriTemplate URI_TEMPLATE = new UriTemplate(URI); private final Configuration configuration; private final Meta meta; diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/notification/Configuration.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/notification/Configuration.java new file mode 100644 index 000000000..e470fa1c1 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/notification/Configuration.java @@ -0,0 +1,20 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.notification; + +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; + +/** + * Interface for configurations of channel + */ +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, + include = JsonTypeInfo.As.WRAPPER_OBJECT) +@JsonSubTypes({ + @JsonSubTypes.Type(value = EmailConfiguration.class, name = "emailConfiguration"), +}) +public interface Configuration { +} diff --git a/src/main/java/com/gooddata/notification/EmailConfiguration.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/notification/EmailConfiguration.java similarity index 82% rename from src/main/java/com/gooddata/notification/EmailConfiguration.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/notification/EmailConfiguration.java index 387f918df..3828c2e9a 100644 --- a/src/main/java/com/gooddata/notification/EmailConfiguration.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/notification/EmailConfiguration.java @@ -1,18 +1,18 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.notification; - -import static com.gooddata.util.Validate.notEmpty; +package com.gooddata.sdk.model.notification; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; + +import static com.gooddata.sdk.common.util.Validate.notEmpty; /** * Email configuration of channel diff --git a/src/main/java/com/gooddata/notification/MessageTemplate.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/notification/MessageTemplate.java similarity index 83% rename from src/main/java/com/gooddata/notification/MessageTemplate.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/notification/MessageTemplate.java index 13755a576..b7141cb1b 100644 --- a/src/main/java/com/gooddata/notification/MessageTemplate.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/notification/MessageTemplate.java @@ -1,18 +1,18 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.notification; - -import static com.gooddata.util.Validate.notEmpty; +package com.gooddata.sdk.model.notification; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; + +import static com.gooddata.sdk.common.util.Validate.notEmpty; /** * Template of notification message diff --git a/src/main/java/com/gooddata/notification/ProjectEvent.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/notification/ProjectEvent.java similarity index 84% rename from src/main/java/com/gooddata/notification/ProjectEvent.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/notification/ProjectEvent.java index cc2173a3e..2cad800a0 100644 --- a/src/main/java/com/gooddata/notification/ProjectEvent.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/notification/ProjectEvent.java @@ -1,26 +1,24 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.notification; - -import static com.gooddata.util.Validate.notEmpty; -import static com.gooddata.util.Validate.notNull; +package com.gooddata.sdk.model.notification; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; - -import com.gooddata.util.GoodDataToStringBuilder; -import org.springframework.web.util.UriTemplate; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.util.HashMap; import java.util.Map; +import static com.gooddata.sdk.common.util.Validate.notEmpty; +import static com.gooddata.sdk.common.util.Validate.notNull; + /** * Project event. - * + *

      * Serialization only. */ @JsonTypeName("projectEvent") @@ -28,7 +26,6 @@ public class ProjectEvent { public static final String URI = "/gdc/projects/{projectId}/notifications/events"; - public static final UriTemplate TEMPLATE = new UriTemplate(URI); private final String type; private final Map parameters; @@ -46,7 +43,8 @@ public ProjectEvent(final String type, final Map parameters) { /** * Set the parameter with given key and value, overwriting the preceding value of the same key (if any). - * @param key parameter key + * + * @param key parameter key * @param value parameter value */ public void setParameter(final String key, final String value) { diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/notification/Subscription.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/notification/Subscription.java new file mode 100644 index 000000000..456b08a4b --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/notification/Subscription.java @@ -0,0 +1,132 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.notification; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.md.Meta; + +import java.util.List; +import java.util.stream.Collectors; + +import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL; +import static org.apache.commons.lang3.Validate.notEmpty; +import static org.apache.commons.lang3.Validate.notNull; + +/** + * Subscription for notifications + */ +@JsonTypeName("subscription") +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(NON_NULL) +public class Subscription { + + public static final String URI = "/gdc/projects/{project}/users/{user}/subscriptions"; + + private final List triggers; + private final TriggerCondition condition; + private final MessageTemplate messageTemplate; + private final MessageTemplate subjectTemplate; + private final List channels; + private final Meta meta; + + + /** + * Creates Subscription + * + * @param triggers triggers of subscription + * @param channels list of {@link Channel} + * @param condition condition under which this subscription activates + * @param messageTemplate of message + * @param title name of subscription + */ + public Subscription(final List triggers, + final List channels, + final TriggerCondition condition, + final MessageTemplate messageTemplate, + final String title) { + this(triggers, channels, condition, messageTemplate, null, title); + } + + /** + * Creates Subscription + * + * @param triggers triggers of subscription + * @param channels list of {@link Channel} + * @param condition condition under which this subscription activates + * @param messageTemplate of message + * @param subjectTemplate of message + * @param title name of subscription + */ + public Subscription(final List triggers, + final List channels, + final TriggerCondition condition, + final MessageTemplate messageTemplate, + final MessageTemplate subjectTemplate, + final String title) { + this(notNull(triggers, "triggers"), + notNull(condition, "condition"), + notNull(messageTemplate, "messageTemplate"), + subjectTemplate, + notNull(channels, "channels").stream().map(e -> e.getMeta().getUri()).collect(Collectors.toList()), + new Meta( + notEmpty(title, "title") + ) + ); + } + + @JsonCreator + Subscription(@JsonProperty("triggers") final List triggers, + @JsonProperty("condition") final TriggerCondition condition, + @JsonProperty("message") final MessageTemplate messageTemplate, + @JsonProperty("subject") final MessageTemplate subjectTemplate, + @JsonProperty("channels") final List channels, + @JsonProperty("meta") final Meta meta) { + this.triggers = triggers; + this.condition = condition; + this.messageTemplate = messageTemplate; + this.subjectTemplate = subjectTemplate; + this.channels = channels; + this.meta = meta; + } + + public List getTriggers() { + return triggers; + } + + public TriggerCondition getCondition() { + return condition; + } + + @JsonProperty("message") + public MessageTemplate getTemplate() { + return messageTemplate; + } + + @JsonProperty("subject") + public MessageTemplate getSubjectTemplate() { + return subjectTemplate; + } + + public List getChannels() { + return channels; + } + + public Meta getMeta() { + return meta; + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } +} diff --git a/src/main/java/com/gooddata/notification/TimerEvent.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/notification/TimerEvent.java similarity index 83% rename from src/main/java/com/gooddata/notification/TimerEvent.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/notification/TimerEvent.java index 4498ca08c..3c42b9eee 100644 --- a/src/main/java/com/gooddata/notification/TimerEvent.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/notification/TimerEvent.java @@ -1,18 +1,18 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.notification; - -import static com.gooddata.util.Validate.notEmpty; +package com.gooddata.sdk.model.notification; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; + +import static com.gooddata.sdk.common.util.Validate.notEmpty; /** * Time based trigger diff --git a/src/main/java/com/gooddata/notification/Trigger.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/notification/Trigger.java similarity index 82% rename from src/main/java/com/gooddata/notification/Trigger.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/notification/Trigger.java index d575d5850..42da4afd4 100644 --- a/src/main/java/com/gooddata/notification/Trigger.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/notification/Trigger.java @@ -1,9 +1,9 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.notification; +package com.gooddata.sdk.model.notification; import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; diff --git a/src/main/java/com/gooddata/notification/TriggerCondition.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/notification/TriggerCondition.java similarity index 85% rename from src/main/java/com/gooddata/notification/TriggerCondition.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/notification/TriggerCondition.java index cb83f53db..5bfe26932 100644 --- a/src/main/java/com/gooddata/notification/TriggerCondition.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/notification/TriggerCondition.java @@ -1,11 +1,9 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.notification; - -import static com.gooddata.util.Validate.notEmpty; +package com.gooddata.sdk.model.notification; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @@ -13,6 +11,8 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; +import static com.gooddata.sdk.common.util.Validate.notEmpty; + /** * Condition of trigger */ diff --git a/src/main/java/com/gooddata/project/CreatedInvitations.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/CreatedInvitations.java similarity index 93% rename from src/main/java/com/gooddata/project/CreatedInvitations.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/CreatedInvitations.java index 0ab708ca5..aa2f7e613 100644 --- a/src/main/java/com/gooddata/project/CreatedInvitations.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/CreatedInvitations.java @@ -1,16 +1,16 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.project; +package com.gooddata.sdk.model.project; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.util.Collections; import java.util.List; @@ -38,6 +38,7 @@ private CreatedInvitations(@JsonProperty("uri") List invitationUris, /** * List of successful invitations + * * @return list of URIs (never null) */ public List getInvitationUris() { @@ -46,6 +47,7 @@ public List getInvitationUris() { /** * List of emails which can't be invited to the project because their users belongs to a different domain + * * @return list of emails (never null) */ public List getDomainMismatchEmails() { @@ -54,6 +56,7 @@ public List getDomainMismatchEmails() { /** * List of emails which can't be invited to the project because they are already members of the project + * * @return list of emails (never null) */ public List getAlreadyInProjectEmails() { diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/Environment.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/Environment.java new file mode 100644 index 000000000..a30b12a5c --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/Environment.java @@ -0,0 +1,25 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.project; + +/** + * Optional property for project or warehouse create, the property is ignored during update. + * Default value is {@link #PRODUCTION} which is also environment for all currently existing projects or warehouses. + */ +public enum Environment { + /** + * Default value, projects or warehouses are backed-up and archived. + */ + PRODUCTION, + /** + * no meaning yet and behavior is the same as for {@link #PRODUCTION} projects or warehouses. + */ + DEVELOPMENT, + /** + * 'TESTING' projects or warehouses are not backed-up and archived. + */ + TESTING +} diff --git a/src/main/java/com/gooddata/project/Invitation.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/Invitation.java similarity index 89% rename from src/main/java/com/gooddata/project/Invitation.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/Invitation.java index db09ef0e5..d496ba39c 100644 --- a/src/main/java/com/gooddata/project/Invitation.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/Invitation.java @@ -1,9 +1,9 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.project; +package com.gooddata.sdk.model.project; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @@ -11,10 +11,10 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.md.Meta; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.md.Meta; -import static com.gooddata.util.Validate.notEmpty; +import static com.gooddata.sdk.common.util.Validate.notEmpty; /** * Project invitation diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/Invitations.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/Invitations.java new file mode 100644 index 000000000..d53621f37 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/Invitations.java @@ -0,0 +1,40 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.project; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; + +import java.util.List; + +import static java.util.Arrays.asList; + +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +public class Invitations { + + /** + * @see Project#getInvitationsUri() + */ + public static final String URI = Project.URI + "/invitations"; + + private final List invitations; + + public Invitations(Invitation... invitations) { + this.invitations = asList(invitations); + } + + public List getInvitations() { + return invitations; + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } + +} diff --git a/src/main/java/com/gooddata/project/Project.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/Project.java similarity index 77% rename from src/main/java/com/gooddata/project/Project.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/Project.java index 38afb9c52..65e870ef0 100644 --- a/src/main/java/com/gooddata/project/Project.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/Project.java @@ -1,31 +1,31 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.project; +package com.gooddata.sdk.model.project; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.gooddata.md.Meta; -import com.gooddata.util.BooleanDeserializer; -import com.gooddata.util.GDDateTimeDeserializer; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.gooddata.util.GoodDataToStringBuilder; -import org.joda.time.DateTime; -import org.springframework.web.util.UriTemplate; +import com.gooddata.sdk.common.util.BooleanDeserializer; +import com.gooddata.sdk.common.util.GDZonedDateTimeDeserializer; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.md.Meta; +import com.gooddata.sdk.model.util.UriHelper; +import java.time.ZonedDateTime; import java.util.HashSet; import java.util.Set; -import static com.gooddata.util.Validate.notEmpty; -import static com.gooddata.util.Validate.notNull; -import static com.gooddata.util.Validate.notNullState; +import static com.gooddata.sdk.common.util.Validate.notEmpty; +import static com.gooddata.sdk.common.util.Validate.notNull; +import static com.gooddata.sdk.common.util.Validate.notNullState; import static java.util.Arrays.asList; /** @@ -37,9 +37,7 @@ @JsonInclude(JsonInclude.Include.NON_NULL) public class Project { - public static final String PROJECTS_URI = "/gdc/account/profile/{id}/projects"; public static final String URI = Projects.URI + "/{id}"; - public static final UriTemplate TEMPLATE = new UriTemplate(URI); private static final Set PREPARING_STATES = new HashSet<>(asList("PREPARING", "PREPARED", "LOADING")); @JsonProperty("content") @@ -75,7 +73,7 @@ public void setProjectTemplate(String uri) { @JsonIgnore public String getId() { - return TEMPLATE.match(getUri()).get("id"); + return UriHelper.getLastUriPart(getUri()); } @JsonIgnore @@ -93,6 +91,16 @@ public String getDriver() { return content.getDriver(); } + public void setDriver(String driver) { + notEmpty(driver, "driver"); + content.setDriver(driver); + } + + public void setDriver(ProjectDriver driver) { + notNull(driver, "driver"); + setDriver(driver.getValue()); + } + @JsonIgnore public String getGuidedNavigation() { return content.getGuidedNavigation(); @@ -129,12 +137,12 @@ public String getContributor() { } @JsonIgnore - public DateTime getCreated() { + public ZonedDateTime getCreated() { return meta.getCreated(); } @JsonIgnore - public DateTime getUpdated() { + public ZonedDateTime getUpdated() { return meta.getUpdated(); } @@ -143,241 +151,85 @@ public String getUri() { return notNullState(links, "links").getSelf(); } - /** - * @return users URI string - * @deprecated use {@link #getUsersUri()} instead - */ - @Deprecated - @JsonIgnore - public String getUsersLink() { - return getUsersUri(); - } - @JsonIgnore public String getUsersUri() { return notNullState(links, "links").getUsers(); } - /** - * @return roles URI string - * @deprecated use {@link #getRolesUri()} instead - */ - @Deprecated - @JsonIgnore - public String getRolesLink() { - return getRolesUri(); - } - @JsonIgnore public String getRolesUri() { return notNullState(links, "links").getRoles(); } - /** - * @return groups URI string - * @deprecated use {@link #getGroupsUri()} instead - */ - @Deprecated - @JsonIgnore - public String getGroupsLink() { - return getGroupsUri(); - } - @JsonIgnore public String getGroupsUri() { return notNullState(links, "links").getGroups(); } - /** - * @return invitations URI string - * @deprecated use {@link #getInvitationsUri()} instead - */ - @Deprecated - @JsonIgnore - public String getInvitationsLink() { - return getInvitationsUri(); - } - @JsonIgnore public String getInvitationsUri() { return notNullState(links, "links").getInvitations(); } - /** - * @return LDM URI string - * @deprecated use {@link #getLdmUri()} instead - */ - @Deprecated - @JsonIgnore - public String getLdmLink() { - return getLdmUri(); - } - @JsonIgnore public String getLdmUri() { return links.getLdm(); } - /** - * @return LDM thumbnail URI string - * @deprecated use {@link #getLdmThumbnailUri()} instead - */ - @Deprecated - @JsonIgnore - public String getLdmThumbnailLink() { - return getLdmThumbnailUri(); - } - @JsonIgnore public String getLdmThumbnailUri() { return notNullState(links, "links").getLdmThumbnail(); } - /** - * @return metadata URI string - * @deprecated use {@link #getMetadataUri()} instead - */ - @Deprecated - @JsonIgnore - public String getMetadataLink() { - return getMetadataUri(); - } - @JsonIgnore public String getMetadataUri() { return notNullState(links, "links").getMetadata(); } - /** - * @return public artifacts URI string - * @deprecated use {@link #getPublicArtifactsUri()} instead - */ - @Deprecated - @JsonIgnore - public String getPublicArtifactsLink() { - return getPublicArtifactsUri(); - } - @JsonIgnore public String getPublicArtifactsUri() { return notNullState(links, "links").getPublicArtifacts(); } - /** - * @return templates URI string - * @deprecated use {@link #getTemplatesUri()} instead - */ - @Deprecated - @JsonIgnore - public String getTemplatesLink() { - return getTemplatesUri(); - } - @JsonIgnore public String getTemplatesUri() { return notNullState(links, "links").getTemplates(); } - /** - * @return connectors URI string - * @deprecated use {@link #getConnectorsUri()} instead - */ - @Deprecated - @JsonIgnore - public String getConnectorsLink() { - return getConnectorsUri(); - } - @JsonIgnore public String getConnectorsUri() { return notNullState(links, "links").getConnectors(); } - /** - * @return data load URI string - * @deprecated use {@link #getDataLoadUri()} instead - */ - @Deprecated - @JsonIgnore - public String getDataLoadLink() { - return getDataLoadUri(); - } - @JsonIgnore public String getDataLoadUri() { return notNullState(links, "links").getDataLoad(); } - /** - * @return schedules URI string - * @deprecated use {@link #getSchedulesUri()} instead - */ - @Deprecated - @JsonIgnore - public String getSchedulesLink() { - return getSchedulesUri(); - } - @JsonIgnore public String getSchedulesUri() { return notNullState(links, "links").getSchedules(); } - /** - * @return execute URI string - * @deprecated use {@link #getExecuteUri()} instead - */ - @Deprecated - @JsonIgnore - public String getExecuteLink() { - return getExecuteUri(); - } - @JsonIgnore public String getExecuteUri() { return notNullState(links, "links").getExecute(); } /** - * @return event stores URI string - * @deprecated use {@link #getEventStoresUri()} instead + * @deprecated This service has been removed from platform long time ago. */ - @Deprecated - @JsonIgnore - public String getEventStoresLink() { - return getEventStoresUri(); - } - @JsonIgnore + @Deprecated public String getEventStoresUri() { return notNullState(links, "links").getEventStores(); } - /** - * @return clear caches URI string - * @deprecated use {@link #getClearCachesUri()} instead - */ - @Deprecated - @JsonIgnore - public String getClearCachesLink() { - return getClearCachesUri(); - } - @JsonIgnore public String getClearCachesUri() { return notNullState(links, "links").getClearCaches(); } - /** - * @return uploads URI string - * @deprecated use {@link #getUploadsUri()} instead - */ - @Deprecated - @JsonIgnore - public String getUploadsLink() { - return getUploadsUri(); - } - @JsonIgnore public String getUploadsUri() { return notNullState(links, "links").getUploads(); @@ -393,16 +245,6 @@ public boolean isEnabled() { return "ENABLED".equals(getState()); } - public void setDriver(String driver) { - notEmpty(driver, "driver"); - content.setDriver(driver); - } - - public void setDriver(ProjectDriver driver) { - notNull(driver, "driver"); - setDriver(driver.getValue()); - } - @JsonIgnore public String getEnvironment() { return content.getEnvironment(); @@ -434,13 +276,10 @@ private static class ProjectContent { @JsonProperty("authorizationToken") private final String authorizationToken; - - @JsonProperty("driver") - private String driver; - @JsonProperty("guidedNavigation") private final String guidedNavigation; - + @JsonProperty("driver") + private String driver; @JsonIgnore private String cluster; @@ -488,6 +327,10 @@ public String getDriver() { return driver; } + public void setDriver(String driver) { + this.driver = driver; + } + public String getGuidedNavigation() { return guidedNavigation; } @@ -500,10 +343,6 @@ public String getIsPublic() { return isPublic; } - public void setDriver(String driver) { - this.driver = driver; - } - public String getEnvironment() { return environment; } @@ -631,6 +470,10 @@ public String getExecute() { return execute; } + /** + * @deprecated This service has been removed from platform long time ago. + */ + @Deprecated public String getEventStores() { return eventStores; } @@ -651,8 +494,8 @@ private static class ProjectMeta extends Meta { @JsonCreator private ProjectMeta(@JsonProperty("author") String author, @JsonProperty("contributor") String contributor, - @JsonProperty("created") @JsonDeserialize(using = GDDateTimeDeserializer.class) DateTime created, - @JsonProperty("updated") @JsonDeserialize(using = GDDateTimeDeserializer.class) DateTime updated, + @JsonProperty("created") @JsonDeserialize(using = GDZonedDateTimeDeserializer.class) ZonedDateTime created, + @JsonProperty("updated") @JsonDeserialize(using = GDZonedDateTimeDeserializer.class) ZonedDateTime updated, @JsonProperty("summary") String summary, @JsonProperty("title") String title, @JsonProperty("category") String category, diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/ProjectDriver.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/ProjectDriver.java new file mode 100644 index 000000000..cea08b357 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/ProjectDriver.java @@ -0,0 +1,24 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.project; + +import static com.gooddata.sdk.common.util.Validate.notEmpty; + +public enum ProjectDriver { + POSTGRES("Pg"), + VERTICA("vertica"); + + private final String value; + + ProjectDriver(String value) { + notEmpty(value, "value"); + this.value = value; + } + + public String getValue() { + return value; + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/ProjectEnvironment.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/ProjectEnvironment.java new file mode 100644 index 000000000..f12a4ec4c --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/ProjectEnvironment.java @@ -0,0 +1,26 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.project; + +/** + * Optional property for project create, the property is ignored during project update. + * Default value is {@link #PRODUCTION} which is also environment for all currently existing projects.

      + * Preffer {@link Environment} if possible. + */ +public enum ProjectEnvironment { + /** + * Default value, projects are backed-up and archived. + */ + PRODUCTION, + /** + * no meaning yet and behavior is the same as for {@link #PRODUCTION} projects + */ + DEVELOPMENT, + /** + * 'TESTING' projects are not backed-up and archived. + */ + TESTING +} diff --git a/src/main/java/com/gooddata/project/ProjectTemplate.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/ProjectTemplate.java similarity index 89% rename from src/main/java/com/gooddata/project/ProjectTemplate.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/ProjectTemplate.java index dc316083b..c1b877d09 100644 --- a/src/main/java/com/gooddata/project/ProjectTemplate.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/ProjectTemplate.java @@ -1,15 +1,15 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.project; +package com.gooddata.sdk.model.project; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; /** * Project template. diff --git a/src/main/java/com/gooddata/project/ProjectTemplates.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/ProjectTemplates.java similarity index 84% rename from src/main/java/com/gooddata/project/ProjectTemplates.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/ProjectTemplates.java index 4ff21115a..5a85c1932 100644 --- a/src/main/java/com/gooddata/project/ProjectTemplates.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/ProjectTemplates.java @@ -1,15 +1,15 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.project; +package com.gooddata.sdk.model.project; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.util.Collection; @@ -19,7 +19,7 @@ */ @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(JsonInclude.Include.NON_NULL) -class ProjectTemplates { +public class ProjectTemplates { private final Collection templatesInfo; diff --git a/src/main/java/com/gooddata/project/ProjectUsersUpdateResult.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/ProjectUsersUpdateResult.java similarity index 91% rename from src/main/java/com/gooddata/project/ProjectUsersUpdateResult.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/ProjectUsersUpdateResult.java index 44c589cbb..a3ff57711 100644 --- a/src/main/java/com/gooddata/project/ProjectUsersUpdateResult.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/ProjectUsersUpdateResult.java @@ -1,9 +1,9 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.project; +package com.gooddata.sdk.model.project; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @@ -21,7 +21,7 @@ @JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(JsonInclude.Include.NON_NULL) -class ProjectUsersUpdateResult { +public class ProjectUsersUpdateResult { private final List successful; private final List failed; diff --git a/src/main/java/com/gooddata/project/ProjectValidationResult.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/ProjectValidationResult.java similarity index 95% rename from src/main/java/com/gooddata/project/ProjectValidationResult.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/ProjectValidationResult.java index 6e7d18b7c..a7bb18a28 100644 --- a/src/main/java/com/gooddata/project/ProjectValidationResult.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/ProjectValidationResult.java @@ -1,14 +1,14 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.project; +package com.gooddata.sdk.model.project; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.util.List; @@ -19,14 +19,12 @@ @JsonIgnoreProperties(ignoreUnknown = true) public class ProjectValidationResult { + private static final String LEVEL_WARNING = "WARN"; + private static final String LEVEL_ERROR = "ERROR"; private final String category; private final String level; private final String message; private final List params; - - private static final String LEVEL_WARNING = "WARN"; - private static final String LEVEL_ERROR = "ERROR"; - private ProjectValidationType validation; @JsonCreator diff --git a/src/main/java/com/gooddata/project/ProjectValidationResultGdcTimeElParam.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/ProjectValidationResultGdcTimeElParam.java similarity index 78% rename from src/main/java/com/gooddata/project/ProjectValidationResultGdcTimeElParam.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/ProjectValidationResultGdcTimeElParam.java index 49ead2703..a9e8056ee 100644 --- a/src/main/java/com/gooddata/project/ProjectValidationResultGdcTimeElParam.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/ProjectValidationResultGdcTimeElParam.java @@ -1,18 +1,17 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.project; +package com.gooddata.sdk.model.project; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.util.List; -import java.util.Objects; @JsonTypeName("gdctime_el") @JsonIgnoreProperties(ignoreUnknown = true) @@ -33,15 +32,6 @@ public List getIds() { return ids; } - /** - * @return list of values - * @deprecated for backward compatibility only. Do not use this method, it always returns null. - */ - @Deprecated - public List getVals() { - return null; - } - @Override public boolean equals(final Object o) { if (this == o) return true; diff --git a/src/main/java/com/gooddata/project/ProjectValidationResultItem.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/ProjectValidationResultItem.java similarity index 90% rename from src/main/java/com/gooddata/project/ProjectValidationResultItem.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/ProjectValidationResultItem.java index 551347d4e..82410caa6 100644 --- a/src/main/java/com/gooddata/project/ProjectValidationResultItem.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/ProjectValidationResultItem.java @@ -1,14 +1,14 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.project; +package com.gooddata.sdk.model.project; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.util.List; diff --git a/src/main/java/com/gooddata/project/ProjectValidationResultObjectParam.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/ProjectValidationResultObjectParam.java similarity index 92% rename from src/main/java/com/gooddata/project/ProjectValidationResultObjectParam.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/ProjectValidationResultObjectParam.java index b1175c619..aca9cb899 100644 --- a/src/main/java/com/gooddata/project/ProjectValidationResultObjectParam.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/ProjectValidationResultObjectParam.java @@ -1,15 +1,15 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.project; +package com.gooddata.sdk.model.project; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; @JsonTypeName("object") @JsonIgnoreProperties(ignoreUnknown = true) diff --git a/src/main/java/com/gooddata/project/ProjectValidationResultParam.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/ProjectValidationResultParam.java similarity index 90% rename from src/main/java/com/gooddata/project/ProjectValidationResultParam.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/ProjectValidationResultParam.java index df2d81aa8..cd8dc6a38 100644 --- a/src/main/java/com/gooddata/project/ProjectValidationResultParam.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/ProjectValidationResultParam.java @@ -1,9 +1,9 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.project; +package com.gooddata.sdk.model.project; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonSubTypes; diff --git a/src/main/java/com/gooddata/project/ProjectValidationResultSliElParam.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/ProjectValidationResultSliElParam.java similarity index 89% rename from src/main/java/com/gooddata/project/ProjectValidationResultSliElParam.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/ProjectValidationResultSliElParam.java index 81e382dc9..9849fa8fc 100644 --- a/src/main/java/com/gooddata/project/ProjectValidationResultSliElParam.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/ProjectValidationResultSliElParam.java @@ -1,22 +1,22 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.project; - -import static java.lang.String.format; +package com.gooddata.sdk.model.project; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import static java.lang.String.format; + @JsonTypeName("sli_el") @JsonIgnoreProperties(ignoreUnknown = true) public class ProjectValidationResultSliElParam extends ProjectValidationResultParam { @@ -43,7 +43,6 @@ public List getIds() { /** * @return list of values. Values have only informative character and are connected to IDs. - * * @see #getIds() */ public List getVals() { @@ -58,14 +57,13 @@ public List getVals() { *

    • ID and it's corresponding value are on the same index.
    • *
    * - * @see #getIds() - * @see #getVals() - * * @return {@code null} when ids are {@code null} or map of tuples * @throws IllegalStateException
      - *
    • when ids are not {@code null} and vals are {@code null}
    • - *
    • when sizes of ids and vals lists are not equal
    • - *
    + *
  • when ids are not {@code null} and vals are {@code null}
  • + *
  • when sizes of ids and vals lists are not equal
  • + * + * @see #getIds() + * @see #getVals() */ public Map asMap() { if (ids == null) { diff --git a/src/main/java/com/gooddata/project/ProjectValidationResultStringParam.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/ProjectValidationResultStringParam.java similarity index 90% rename from src/main/java/com/gooddata/project/ProjectValidationResultStringParam.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/ProjectValidationResultStringParam.java index e5b06f3b6..7be9c85cb 100644 --- a/src/main/java/com/gooddata/project/ProjectValidationResultStringParam.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/ProjectValidationResultStringParam.java @@ -1,14 +1,14 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.project; +package com.gooddata.sdk.model.project; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; @JsonTypeName("common") @JsonIgnoreProperties(ignoreUnknown = true) diff --git a/src/main/java/com/gooddata/project/ProjectValidationResults.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/ProjectValidationResults.java similarity index 92% rename from src/main/java/com/gooddata/project/ProjectValidationResults.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/ProjectValidationResults.java index 433ab3147..ce8515b56 100644 --- a/src/main/java/com/gooddata/project/ProjectValidationResults.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/ProjectValidationResults.java @@ -1,25 +1,25 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.project; +package com.gooddata.sdk.model.project; -import com.gooddata.util.BooleanDeserializer; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.BooleanDeserializer; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.util.LinkedList; import java.util.List; /** * Results of project validation. - * + *

    * Deserialization only. */ @JsonTypeName("projectValidateResult") @@ -57,6 +57,7 @@ private ProjectValidationResults(@JsonProperty("error_found") @JsonDeserialize(u /** * True if validation found some error + * * @return true in case of validation error, false otherwise */ public boolean isError() { @@ -65,6 +66,7 @@ public boolean isError() { /** * True in case some part of validation crashed (not executed at all) + * * @return true if validation crashed, false otherwise */ public boolean isFatalError() { @@ -73,6 +75,7 @@ public boolean isFatalError() { /** * True if some warning was found during validation. + * * @return true if some warning was found during validation, false otherwise */ public boolean isWarning() { @@ -81,15 +84,17 @@ public boolean isWarning() { /** * True if no warning or error is in the validation results. + * * @return true if no warning or error is in the validation results, false otherwise */ public boolean isValid() { - return ! (error || fatalError || warning); + return !(error || fatalError || warning); } /** * Get validation results, describing output of all validations executed. * Can return empty list, in case the validation had no error or warning (is valid)- + * * @return validation results list */ public List getResults() { diff --git a/src/main/java/com/gooddata/project/ProjectValidationType.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/ProjectValidationType.java similarity index 92% rename from src/main/java/com/gooddata/project/ProjectValidationType.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/ProjectValidationType.java index 9e7e686fb..45c2e94aa 100644 --- a/src/main/java/com/gooddata/project/ProjectValidationType.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/ProjectValidationType.java @@ -1,21 +1,19 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.project; +package com.gooddata.sdk.model.project; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; /** * Represents project validation type. */ public class ProjectValidationType { - private final String value; - public static final ProjectValidationType PDM_VS_DWH = new ProjectValidationType("pdm::pdm_vs_dwh"); public static final ProjectValidationType METRIC_FILTER = new ProjectValidationType("metric_filter"); public static final ProjectValidationType PDM_TRANSITIVITY = new ProjectValidationType("pdm::transitivity"); @@ -23,6 +21,7 @@ public class ProjectValidationType { public static final ProjectValidationType INVALID_OBJECTS = new ProjectValidationType("invalid_objects"); public static final ProjectValidationType PDM_ELEM = new ProjectValidationType("pdm::elem_validation"); public static final ProjectValidationType PDM_PK_FK_CONSISTENCY = new ProjectValidationType("pdm::pk_fk_consistency"); + private final String value; @JsonCreator public ProjectValidationType(String value) { diff --git a/src/main/java/com/gooddata/project/ProjectValidations.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/ProjectValidations.java similarity index 80% rename from src/main/java/com/gooddata/project/ProjectValidations.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/ProjectValidations.java index 7b7aa8a2f..e9c2e5ecc 100644 --- a/src/main/java/com/gooddata/project/ProjectValidations.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/ProjectValidations.java @@ -1,15 +1,15 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.project; +package com.gooddata.sdk.model.project; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.util.HashSet; import java.util.Set; @@ -22,7 +22,7 @@ */ @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(JsonInclude.Include.NON_NULL) -class ProjectValidations { +public class ProjectValidations { public static final String URI = "/gdc/md/{projectId}/validate"; @@ -33,7 +33,7 @@ class ProjectValidations { } @JsonCreator - ProjectValidations(@JsonProperty("availableValidations") final Set validations) { + public ProjectValidations(@JsonProperty("availableValidations") final Set validations) { this.validations = validations; } diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/Projects.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/Projects.java new file mode 100644 index 000000000..f0dec6442 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/Projects.java @@ -0,0 +1,70 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.project; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.gooddata.sdk.common.collections.Page; +import com.gooddata.sdk.common.collections.PageDeserializer; +import com.gooddata.sdk.common.collections.Paging; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; + +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import static com.gooddata.sdk.model.project.Projects.ROOT_NODE; + +/** + * Collection of GoodData projects being returned from API. + */ +@JsonDeserialize(using = Projects.Deserializer.class) +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonTypeName(ROOT_NODE) +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +public class Projects extends Page { + + public static final String URI = "/gdc/projects"; + public static final String LIST_PROJECTS_URI = "/gdc/account/profile/{id}/projects"; + + static final String ROOT_NODE = "projects"; + + public Projects(List items, Paging paging) { + super(items, paging); + } + + /** + * @return the list of current page items only + * @deprecated use {@link Page#getPageItems()} or other methods from {@link Page}. + * Deprecated since version 3.0.0. Will be removed in one of future versions. + */ + @Deprecated + public Collection getProjects() { + return getPageItems(); + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } + + static class Deserializer extends PageDeserializer { + + protected Deserializer() { + super(Project.class); + } + + @Override + protected Projects createPage(final List items, final Paging paging, final Map links) { + return new Projects(items, paging); + } + } + +} diff --git a/src/main/java/com/gooddata/project/Role.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/Role.java similarity index 89% rename from src/main/java/com/gooddata/project/Role.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/Role.java index 99164ed74..b10e3639a 100644 --- a/src/main/java/com/gooddata/project/Role.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/Role.java @@ -1,24 +1,23 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.project; +package com.gooddata.sdk.model.project; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.gooddata.md.Meta; -import com.gooddata.util.BooleanDeserializer; -import com.gooddata.util.BooleanStringSerializer; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.gooddata.util.GoodDataToStringBuilder; -import org.springframework.web.util.UriTemplate; +import com.gooddata.sdk.common.util.BooleanDeserializer; +import com.gooddata.sdk.common.util.BooleanStringSerializer; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.md.Meta; import java.util.Collections; import java.util.HashMap; @@ -36,7 +35,6 @@ @JsonInclude(JsonInclude.Include.NON_NULL) public class Role { public static final String URI = "/gdc/projects/{projectId}/roles/{roleId}"; - public static final UriTemplate TEMPLATE = new UriTemplate(URI); private static final String SELF_LINK = "self"; @@ -93,20 +91,20 @@ public String getIdentifier() { return meta.getIdentifier(); } + @JsonIgnore + public String getUri() { + return links.get(SELF_LINK); + } + /** * Allows service to set self link as it is not provided by REST API. *

    * NOTE: This is intentionally left package-private. */ - void setUri(final String uri) { + public void setUri(final String uri) { links.put(SELF_LINK, uri); } - @JsonIgnore - public String getUri() { - return links.get(SELF_LINK); - } - @Override public boolean equals(final Object o) { if (this == o) return true; diff --git a/src/main/java/com/gooddata/project/Roles.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/Roles.java similarity index 76% rename from src/main/java/com/gooddata/project/Roles.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/Roles.java index 28629dcd1..03b4aeda4 100644 --- a/src/main/java/com/gooddata/project/Roles.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/Roles.java @@ -1,17 +1,16 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.project; +package com.gooddata.sdk.model.project; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.util.GoodDataToStringBuilder; -import org.springframework.web.util.UriTemplate; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.util.Set; @@ -21,9 +20,8 @@ @JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) @JsonTypeName("projectRoles") @JsonIgnoreProperties(ignoreUnknown = true) -class Roles { +public class Roles { public static final String URI = "/gdc/projects/{projectId}/roles"; - public static final UriTemplate TEMPLATE = new UriTemplate(URI); private final Set roles; @@ -32,7 +30,7 @@ class Roles { this.roles = roles; } - Set getRoles() { + public Set getRoles() { return roles; } diff --git a/src/main/java/com/gooddata/project/User.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/User.java similarity index 93% rename from src/main/java/com/gooddata/project/User.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/User.java index 9b028659a..d94da7aa0 100644 --- a/src/main/java/com/gooddata/project/User.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/User.java @@ -1,20 +1,19 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.project; +package com.gooddata.sdk.model.project; -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.account.Account; -import com.gooddata.util.GoodDataToStringBuilder; -import org.springframework.web.util.UriTemplate; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; +import com.gooddata.sdk.model.account.Account; import java.util.Arrays; import java.util.List; @@ -22,6 +21,7 @@ /** * User in project + * * @see Account */ @JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) @@ -31,7 +31,6 @@ public class User { public static final String URI = "/gdc/projects/{projectId}/users/{userId}"; - public static final UriTemplate TEMPLATE = new UriTemplate(URI); @JsonProperty private UserContent content; @@ -45,7 +44,7 @@ public class User { this.links = links; } - User(final Account account, + public User(final Account account, final Role... userRoles) { final List userRoleUris = Arrays.asList(userRoles).stream().map(e -> e.getUri()).collect(Collectors.toList()); @@ -63,6 +62,10 @@ public String getStatus() { return content.getStatus(); } + public void setStatus(final String status) { + this.content.status = status; + } + @JsonIgnore public String getLastName() { return content.getLastName(); @@ -92,10 +95,6 @@ public Links getLinks() { return links; } - public void setStatus(final String status) { - this.content.status = status; - } - @Override public String toString() { return GoodDataToStringBuilder.defaultToString(this); diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/Users.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/Users.java new file mode 100644 index 000000000..43c33ab88 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/Users.java @@ -0,0 +1,42 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.project; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeInfo.Id; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.gooddata.sdk.common.collections.Page; +import com.gooddata.sdk.common.collections.Paging; + +import java.util.List; + +import static com.gooddata.sdk.model.project.Users.ROOT_NODE; +import static java.util.Arrays.asList; + +/** + * List of users. + */ +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = Id.NONE) +@JsonTypeName(ROOT_NODE) +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonDeserialize(using = UsersDeserializer.class) +@JsonSerialize(using = UsersSerializer.class) +public class Users extends Page { + public static final String URI = "/gdc/projects/{projectId}/users"; + + static final String ROOT_NODE = "users"; + + Users(final List items, final Paging paging) { + super(items, paging); + } + + public Users(final User... users) { + this(asList(users), null); + } +} diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/UsersDeserializer.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/UsersDeserializer.java new file mode 100644 index 000000000..a30318c9d --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/UsersDeserializer.java @@ -0,0 +1,24 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.project; + +import com.gooddata.sdk.common.collections.PageDeserializer; +import com.gooddata.sdk.common.collections.Paging; + +import java.util.List; +import java.util.Map; + +class UsersDeserializer extends PageDeserializer { + + protected UsersDeserializer() { + super(User.class, Users.ROOT_NODE); + } + + @Override + protected Users createPage(final List items, final Paging paging, final Map links) { + return new Users(items, paging); + } +} diff --git a/src/main/java/com/gooddata/project/UsersSerializer.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/UsersSerializer.java similarity index 79% rename from src/main/java/com/gooddata/project/UsersSerializer.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/UsersSerializer.java index cde681587..5eb007cf8 100644 --- a/src/main/java/com/gooddata/project/UsersSerializer.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/UsersSerializer.java @@ -1,13 +1,12 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.project; +package com.gooddata.sdk.model.project; import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.ObjectCodec; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; @@ -20,13 +19,13 @@ class UsersSerializer extends JsonSerializer { @Override - public void serialize(final Users users, final JsonGenerator jgen, final SerializerProvider serializerProvider) throws IOException, JsonProcessingException { + public void serialize(final Users users, final JsonGenerator jgen, final SerializerProvider serializerProvider) throws IOException { jgen.writeStartObject(); jgen.writeFieldName(Users.ROOT_NODE); jgen.writeStartArray(); final ObjectCodec codec = jgen.getCodec(); - for (Object item: users) { + for (Object item : users.getPageItems()) { codec.writeValue(jgen, item); } jgen.writeEndArray(); diff --git a/src/main/java/com/gooddata/model/DiffRequest.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/model/DiffRequest.java similarity index 87% rename from src/main/java/com/gooddata/model/DiffRequest.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/model/DiffRequest.java index 0a87125f0..230ada541 100644 --- a/src/main/java/com/gooddata/model/DiffRequest.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/model/DiffRequest.java @@ -1,9 +1,9 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.model; +package com.gooddata.sdk.model.project.model; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; @@ -11,9 +11,9 @@ import com.fasterxml.jackson.annotation.JsonRawValue; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; -import static com.gooddata.util.Validate.notNull; +import static com.gooddata.sdk.common.util.Validate.notNull; /** * A request to perform diff between current project model and given targetModel. @@ -40,6 +40,7 @@ public DiffRequest(String targetModel) { /** * Returns desired target state of project model + * * @return desired target state of project model */ public String getTargetModel() { diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/model/MaqlDdl.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/model/MaqlDdl.java new file mode 100644 index 000000000..dcd4a6342 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/model/MaqlDdl.java @@ -0,0 +1,22 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.project.model; + +import com.gooddata.sdk.model.gdc.AbstractMaql; + +/** + * MAQL DDL statement. + * Serialization only. + */ +public class MaqlDdl extends AbstractMaql { + + public static final String URI = "/gdc/md/{project}/ldm/manage2"; + + public MaqlDdl(final String maql) { + super(maql); + } + +} diff --git a/src/main/java/com/gooddata/model/MaqlDdlLinks.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/model/MaqlDdlLinks.java similarity index 75% rename from src/main/java/com/gooddata/model/MaqlDdlLinks.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/model/MaqlDdlLinks.java index a1fe493c4..4cd3c7caf 100644 --- a/src/main/java/com/gooddata/model/MaqlDdlLinks.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/model/MaqlDdlLinks.java @@ -1,15 +1,15 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.model; +package com.gooddata.sdk.model.project.model; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.gooddata.gdc.LinkEntries; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; +import com.gooddata.sdk.model.gdc.LinkEntries; import java.util.List; @@ -19,6 +19,7 @@ */ @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(JsonInclude.Include.NON_NULL) +public class MaqlDdlLinks extends LinkEntries { private static final String TASKS_STATUS = "tasks-status"; @@ -28,15 +29,6 @@ private MaqlDdlLinks(@JsonProperty("entries") List entries) { super(entries); } - /** - * @return status URI string - * @deprecated use {@link #getStatusUri()} instead - */ - @Deprecated - public String getStatusLink() { - return getStatusUri(); - } - public String getStatusUri() { for (LinkEntry linkEntry : getEntries()) { if (TASKS_STATUS.equals(linkEntry.getCategory())) { diff --git a/src/main/java/com/gooddata/model/ModelDiff.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/model/ModelDiff.java similarity index 96% rename from src/main/java/com/gooddata/model/ModelDiff.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/model/ModelDiff.java index 79e17c7ca..9f8d2601f 100644 --- a/src/main/java/com/gooddata/model/ModelDiff.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/project/model/ModelDiff.java @@ -1,16 +1,16 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.model; +package com.gooddata.sdk.model.project.model; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.sdk.common.util.GoodDataToStringBuilder; import java.util.Collections; import java.util.List; @@ -113,7 +113,7 @@ public String toString() { @JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) @JsonTypeName("updateScript") @JsonIgnoreProperties(ignoreUnknown = true) - static class UpdateScript { + public static class UpdateScript { private final List maqlChunks; private final Boolean preserveData; @@ -124,7 +124,7 @@ static class UpdateScript { * * @param preserveData true if data should be preserved, false if they should be truncated * @param cascadeDrops true if related objects should be also dropped, false if not - * @param maqlChunks MAQL strings + * @param maqlChunks MAQL strings */ @JsonCreator UpdateScript(@JsonProperty("preserveData") Boolean preserveData, @@ -140,7 +140,7 @@ static class UpdateScript { * * @param preserveData true if data should be preserved, false if they should be truncated * @param cascadeDrops true if related objects should be also dropped, false if not - * @param maqlChunks MAQL strings + * @param maqlChunks MAQL strings */ UpdateScript(boolean preserveData, boolean cascadeDrops, String... maqlChunks) { this(preserveData, cascadeDrops, asList(maqlChunks)); diff --git a/src/main/java/com/gooddata/projecttemplate/Template.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/projecttemplate/Template.java similarity index 89% rename from src/main/java/com/gooddata/projecttemplate/Template.java rename to gooddata-java-model/src/main/java/com/gooddata/sdk/model/projecttemplate/Template.java index e0ed00164..87ac0b942 100644 --- a/src/main/java/com/gooddata/projecttemplate/Template.java +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/projecttemplate/Template.java @@ -1,9 +1,9 @@ /* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * (C) 2025 GoodData Corporation. * This source code is licensed under the BSD-style license found in the * LICENSE.txt file in the root directory of this source tree. */ -package com.gooddata.projecttemplate; +package com.gooddata.sdk.model.projecttemplate; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @@ -11,7 +11,7 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.gooddata.util.BooleanDeserializer; +import com.gooddata.sdk.common.util.BooleanDeserializer; import java.util.List; import java.util.Objects; @@ -19,7 +19,12 @@ /** * Represents one project template. * Deserialization only. + * + * @deprecated The project templates are deprecated and stopped working on May 15, 2019. + * See https://support.gooddata.com/hc/en-us/articles/360016126334-April-4-2019 + * Deprecated since version 3.0.1. Will be removed in one of future versions. */ +@Deprecated @JsonTypeName("projectTemplate") @JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) @JsonIgnoreProperties(ignoreUnknown = true) @@ -34,8 +39,8 @@ public class Template { @JsonCreator private Template(@JsonProperty("link") String uri, @JsonProperty("urn") String urn, @JsonProperty("version") String version, - @JsonProperty("hidden") @JsonDeserialize(using = BooleanDeserializer.class) Boolean hidden, - @JsonProperty("content") Content content, @JsonProperty("meta") Meta meta) { + @JsonProperty("hidden") @JsonDeserialize(using = BooleanDeserializer.class) Boolean hidden, + @JsonProperty("content") Content content, @JsonProperty("meta") Meta meta) { this.uri = uri; this.urn = urn; this.version = version; diff --git a/gooddata-java-model/src/main/java/com/gooddata/sdk/model/projecttemplate/Templates.java b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/projecttemplate/Templates.java new file mode 100644 index 000000000..a23116889 --- /dev/null +++ b/gooddata-java-model/src/main/java/com/gooddata/sdk/model/projecttemplate/Templates.java @@ -0,0 +1,37 @@ +/* + * (C) 2025 GoodData Corporation. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.sdk.model.projecttemplate; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.List; + +/** + * Wrapper for list of project templates. + * Deserialization only. + * + * @deprecated The project templates are deprecated and stopped working on May 15, 2019. + * See https://support.gooddata.com/hc/en-us/articles/360016126334-April-4-2019 + * Deprecated since version 3.0.1. Will be removed in one of future versions. + */ +@Deprecated +@JsonIgnoreProperties(ignoreUnknown = true) +public class Templates { + + public static final String URI = "/projectTemplates"; + private final List