diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..c27c9cc --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,29 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + test: + name: Test (Java ${{ matrix.java-version }}) + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + java-version: ["11", "17", "21"] + + steps: + - uses: actions/checkout@v4 + + - name: Set up JDK ${{ matrix.java-version }} + uses: actions/setup-java@v4 + with: + java-version: ${{ matrix.java-version }} + distribution: "temurin" + cache: "maven" + + - name: Build and test with Maven + run: mvn -B package --no-transfer-progress --file pom.xml diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml deleted file mode 100644 index 159c41c..0000000 --- a/.github/workflows/maven.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: Java CI with Maven - -on: - push: - branches: [ "main" ] - pull_request: - branches: [ "main" ] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Set up JDK 11 - uses: actions/setup-java@v3 - with: - java-version: '11' - distribution: 'temurin' - cache: maven - - name: Test - run: mvn test diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 85067f9..84a1a75 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -3,25 +3,33 @@ name: Publish to Maven Central on: push: tags: - - 'v*' + - "v*" jobs: - build: + publish: + name: Publish to Maven Central runs-on: ubuntu-latest + steps: - uses: actions/checkout@v4 + - name: Set up JDK 11 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: - java-version: '11' - distribution: 'temurin' - cache: maven - - name: Build and Deploy + java-version: "11" + distribution: "temurin" + cache: "maven" + + - name: Import GPG signing key env: - OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }} - OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} run: | - echo $GPG_PRIVATE_KEY | base64 --decode | gpg --import --batch --yes --pinentry-mode loopback --passphrase "$GPG_SIGNING_PASSPHRASE" - mvn clean deploy -P release --settings .github/settings.xml + echo "$GPG_PRIVATE_KEY" | base64 --decode | gpg --import --batch --yes --pinentry-mode loopback --passphrase "$GPG_PASSPHRASE" + + - name: Build, test and deploy + env: + OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }} + OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} + GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} + run: mvn -B clean deploy --no-transfer-progress --settings .github/settings.xml diff --git a/.gitignore b/.gitignore index b425f09..cf5010c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,35 +1,28 @@ +# Build output target/ -!.mvn/wrapper/maven-wrapper.jar +build/ !**/src/main/**/target/ !**/src/test/**/target/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +# Dependencies +!.mvn/wrapper/maven-wrapper.jar -### IntelliJ IDEA ### +# Environment +.env + +# IDE .idea/ -*.iws +.vscode/ *.iml +*.iws *.ipr - -### Eclipse ### -.apt_generated .classpath -.factorypath .project -.settings -.springBeans -.sts4-cache - -### NetBeans ### -/nbproject/private/ -/nbbuild/ -/dist/ -/nbdist/ -/.nb-gradle/ -build/ -!**/src/main/**/build/ -!**/src/test/**/build/ - -### VS Code ### -.vscode/ +.settings/ +.factorypath +.apt_generated -### Mac OS ### -.DS_Store \ No newline at end of file +# OS +.DS_Store diff --git a/.openapi-generator-ignore b/.openapi-generator-ignore new file mode 100644 index 0000000..546eb45 --- /dev/null +++ b/.openapi-generator-ignore @@ -0,0 +1,20 @@ +src/main/java/com/regexsolver/api/exceptions/** +**/test/ +pom.xml +.gitignore +git_push.sh +.travis.yml +.gitlab-ci.yml +.github/ +api/ +docs/ +test/ +README.md +build.gradle +settings.gradle +gradlew +gradlew.bat +gradle/ +gradle.properties +build.sbt +**/*.xml diff --git a/.openapi-generator/FILES b/.openapi-generator/FILES new file mode 100644 index 0000000..776575b --- /dev/null +++ b/.openapi-generator/FILES @@ -0,0 +1,52 @@ +src/main/java/com/regexsolver/api/generated/ApiClient.java +src/main/java/com/regexsolver/api/generated/ApiException.java +src/main/java/com/regexsolver/api/generated/ApiResponse.java +src/main/java/com/regexsolver/api/generated/Configuration.java +src/main/java/com/regexsolver/api/generated/JSON.java +src/main/java/com/regexsolver/api/generated/Pair.java +src/main/java/com/regexsolver/api/generated/RFC3339DateFormat.java +src/main/java/com/regexsolver/api/generated/RFC3339InstantDeserializer.java +src/main/java/com/regexsolver/api/generated/RFC3339JavaTimeModule.java +src/main/java/com/regexsolver/api/generated/ServerConfiguration.java +src/main/java/com/regexsolver/api/generated/ServerVariable.java +src/main/java/com/regexsolver/api/generated/api/AccountApi.java +src/main/java/com/regexsolver/api/generated/api/AnalyzeApi.java +src/main/java/com/regexsolver/api/generated/api/ComputeApi.java +src/main/java/com/regexsolver/api/generated/api/GenerateApi.java +src/main/java/com/regexsolver/api/generated/model/AbstractOpenApiSchema.java +src/main/java/com/regexsolver/api/generated/model/AccountLimitsDto.java +src/main/java/com/regexsolver/api/generated/model/BooleanDto.java +src/main/java/com/regexsolver/api/generated/model/Cardinality200ResponseDto.java +src/main/java/com/regexsolver/api/generated/model/CardinalityBigIntegerDto.java +src/main/java/com/regexsolver/api/generated/model/CardinalityDto.java +src/main/java/com/regexsolver/api/generated/model/CardinalityInfiniteDto.java +src/main/java/com/regexsolver/api/generated/model/CardinalityIntegerDto.java +src/main/java/com/regexsolver/api/generated/model/Concat200ResponseDto.java +src/main/java/com/regexsolver/api/generated/model/Dot200ResponseDto.java +src/main/java/com/regexsolver/api/generated/model/Empty200ResponseDto.java +src/main/java/com/regexsolver/api/generated/model/ErrorResponse400Dto.java +src/main/java/com/regexsolver/api/generated/model/ErrorResponse401Dto.java +src/main/java/com/regexsolver/api/generated/model/ErrorResponse403Dto.java +src/main/java/com/regexsolver/api/generated/model/ErrorResponseDto.java +src/main/java/com/regexsolver/api/generated/model/ExecutionOptionsDto.java +src/main/java/com/regexsolver/api/generated/model/FairResponseOptionsDto.java +src/main/java/com/regexsolver/api/generated/model/GenerateStringsCharacterOrderDto.java +src/main/java/com/regexsolver/api/generated/model/GenerateStringsPathOrderDto.java +src/main/java/com/regexsolver/api/generated/model/GenerateStringsRequestDto.java +src/main/java/com/regexsolver/api/generated/model/GenerateStringsResponseDto.java +src/main/java/com/regexsolver/api/generated/model/Length200ResponseDto.java +src/main/java/com/regexsolver/api/generated/model/LengthDto.java +src/main/java/com/regexsolver/api/generated/model/Limits200ResponseDto.java +src/main/java/com/regexsolver/api/generated/model/MultiTermsRequestDto.java +src/main/java/com/regexsolver/api/generated/model/RepeatRequestDto.java +src/main/java/com/regexsolver/api/generated/model/RequestOptionsDto.java +src/main/java/com/regexsolver/api/generated/model/ResponseOptionsDto.java +src/main/java/com/regexsolver/api/generated/model/StringDto.java +src/main/java/com/regexsolver/api/generated/model/Strings200ResponseDto.java +src/main/java/com/regexsolver/api/generated/model/StringsDto.java +src/main/java/com/regexsolver/api/generated/model/TermDto.java +src/main/java/com/regexsolver/api/generated/model/TermFairDto.java +src/main/java/com/regexsolver/api/generated/model/TermFairMetadataDto.java +src/main/java/com/regexsolver/api/generated/model/TermRegexDto.java +src/main/java/com/regexsolver/api/generated/model/TermRequestDto.java +src/main/java/com/regexsolver/api/generated/model/TwoTermsRequestDto.java diff --git a/.openapi-generator/VERSION b/.openapi-generator/VERSION new file mode 100644 index 0000000..a29ba3d --- /dev/null +++ b/.openapi-generator/VERSION @@ -0,0 +1 @@ +7.21.0 diff --git a/README.md b/README.md index c9fb093..24e9b05 100644 --- a/README.md +++ b/README.md @@ -1,223 +1,192 @@ # RegexSolver Java API Client - [Homepage](https://regexsolver.com) | [Online Demo](https://regexsolver.com/demo) | [Documentation](https://docs.regexsolver.com) | [Developer Console](https://console.regexsolver.com) -This repository contains the source code of the Java library for [RegexSolver](https://regexsolver.com) API. - -RegexSolver is a powerful regular expression manipulation toolkit, that gives you the power to manipulate regex as if -they were sets. +**RegexSolver** is a powerful toolkit for building, combining, and analyzing regular expressions. It is designed for constraint solvers, test generators, and other systems that need advanced regex operations. ## Installation -### Requirements - -- Java >=11 - ### Maven ```xml com.regexsolver.api RegexSolver - 1.0.2 + 1.1.0 ``` ### Gradle ```groovy -implementation "com.regexsolver.api:RegexSolver:1.0.2" +implementation "com.regexsolver.api:RegexSolver:1.1.0" ``` -## Usage +Requirements: **Java >= 11** -In order to use the library you need to generate an API Token on -our [Developer Console](https://console.regexsolver.com/). +## Quick Start + +1. Create an API token in the [Developer Console](https://console.regexsolver.com/). +2. Initialize the client and start working with terms. + +### Synchronous Usage + +The synchronous client provides a simple, blocking API. ```java -import com.regexsolver.api.RegexSolver; +import com.regexsolver.api.RegexSolverClient; import com.regexsolver.api.Term; -import com.regexsolver.api.exception.ApiError; - -import java.io.IOException; public class Main { - public static void main(String[] args) throws IOException, ApiError { - RegexSolver.initialize("YOUR TOKEN HERE"); + public static void main(String[] args) { + RegexSolverClient client = RegexSolverClient.builder() + .apiToken("REGEXSOLVER_API_TOKEN") + .build(); Term term1 = Term.regex("(abc|de|fg){2,}"); Term term2 = Term.regex("de.*"); - Term term3 = Term.regex(".*abc"); - Term term4 = Term.regex(".+(abc|de).+"); - - Term result = term1.intersection(term2, term3) - .subtraction(term4); - - System.out.println(result); + Term intersection = client.intersection(term1, term2); + String pattern = client.getPattern(intersection); + System.out.println(pattern); // de(abc|de|fg)+ } } ``` -## Features - -- [Intersection](#intersection) -- [Union](#union) -- [Subtraction / Difference](#subtraction--difference) -- [Equivalence](#equivalence) -- [Subset](#subset) -- [Details](#details) -- [Generate Strings](#generate-strings) - -### Intersection +### Asynchronous Usage -#### Request - -Compute the intersection of the provided terms and return the resulting term. - -The maximum number of terms is currently limited to 10. +For non-blocking applications, use the asynchronous client. ```java -Term.Regex term1 = Term.regex("(abc|de){2}"); -Term.Regex term2 = Term.regex("de.*"); -Term.Regex term3 = Term.regex(".*abc"); - -Term result = term1.intersection(term2, term3); -System.out.println(result); -``` - -#### Response - -``` -regex=deabc -``` - -### Union - -Compute the union of the provided terms and return the resulting term. - -The maximum number of terms is currently limited to 10. +import com.regexsolver.api.AsyncRegexSolverClient; +import com.regexsolver.api.Term; +import java.util.concurrent.CompletableFuture; -#### Request +public class Main { + public static void main(String[] args) { + AsyncRegexSolverClient client = AsyncRegexSolverClient.builder() + .apiToken("REGEXSOLVER_API_TOKEN") + .build(); -```java -Term.Regex term1 = Term.regex("abc"); -Term.Regex term2 = Term.regex("de"); -Term.Regex term3 = Term.regex("fghi"); + Term term1 = Term.regex("(abc|de|fg){2,}"); + Term term2 = Term.regex("de.*"); -Term result = term1.union(term2, term3); -System.out.println(result); + client.intersection(term1, term2) + .thenCompose(client::getPattern) + .thenAccept(System.out::println); // de(abc|de|fg)+ + } +} ``` -#### Response +## Key Concepts & Limitations -``` -regex=(abc|de|fghi) -``` +RegexSolver supports a subset of regular expressions that adhere to the principles of regular languages. Here are the key characteristics and limitations of the regular expressions supported by RegexSolver: +- **Anchored Expressions:** All regular expressions in RegexSolver are anchored. This means that the expressions are treated as if they start and end at the boundaries of the input text. For example, the expression `abc` will match the string "abc" but not "xabc" or "abcx". +- **Lookahead/Lookbehind:** RegexSolver does not support lookahead (`(?=...)`) or lookbehind (`(?<=...)`) assertions. Using them returns an error. +- **Pure Regular Expressions:** RegexSolver focuses on pure regular expressions as defined in regular language theory. This means features that extend beyond regular languages, such as backreferences (`\1`, `\2`, etc.), are not supported. Any use of backreference would return an error. +- **Greedy/Ungreedy Quantifiers:** The concept of ungreedy (`*?`, `+?`, `??`) quantifiers is not supported. All quantifiers are treated as greedy. For example, `a*` or `a*?` will match the longest possible sequence of "a"s. +- **Line Feed and Dot:** RegexSolver handles all characters the same way. The dot `.` matches any Unicode character including line feed (`\n`). +- **Empty Regular Expressions:** The empty language (matches no string) is represented by constructs like `[]` (empty character class). This is distinct from the empty string. -### Subtraction / Difference +## Response Formats -Compute the first term minus the second and return the resulting term. +The API can handle terms in two formats: +- `regex`: a regular expression pattern +- `fair`: FAIR (Fast Automaton Internal Representation), a stable, signed format used internally by the engine -#### Request +By default, the engine returns whatever the operation produces, with no extra conversion. Override with `OperationOptions`, accepted by the operations that return a term: ```java -Term.Regex term1 = Term.regex("(abc|de)"); -Term.Regex term2 = Term.regex("de"); - -Term result = term1.subtraction(term2); -System.out.println(result); -``` - -#### Response - -``` -regex=abc -``` +import com.regexsolver.api.ResponseFormat; +import com.regexsolver.api.OperationOptions; -### Equivalence +Term term1 = Term.regex("abcde"); +Term term2 = Term.regex("de"); -Analyze if the two provided terms are equivalent. +Term result1 = client.union(term1, term2, new OperationOptions().responseFormat(ResponseFormat.REGEX)); +System.out.println(result1); // regex=(abc)?de -#### Request - -```java -Term.Regex term1 = Term.regex("(abc|de)"); -Term.Fair term2 = Term.regex("(abc|de)*"); - -boolean result = term1.isEquivalentTo(term2); -System.out.println(result); +Term result2 = client.union(term1, term2, new OperationOptions().responseFormat(ResponseFormat.FAIR)); +System.out.println(result2); // fair=... ``` -#### Response - -``` -false -``` +If the format does not matter, omit `responseFormat` or set it to `ResponseFormat.ANY`. -### Subset +Regardless of the format, you can always call `getPattern()` to obtain the regex pattern of a term. -Analyze if the second term is a subset of the first. +## Bounding execution time -#### Request +Set a server-side compute timeout in milliseconds with `executionTimeout` in `OperationOptions`: ```java -Term.Regex term1 = Term.regex("de"); -Term.Regex term2 = Term.regex("(abc|de)"); - -boolean result = term1.isSubsetOf(term2); -System.out.println(result); +import com.regexsolver.api.exceptions.TimeoutExceededException; +import com.regexsolver.api.OperationOptions; + +// Limit the server-side compute time to 100 ms +try { + Term term1 = Term.regex(".*ab.*c(de|fg).*dab.*c(de|fg).*ab.*c(de|fg).*dab.*c"); + Term term2 = Term.regex(".*abc.*"); + + Term res = client.difference(term1, term2, new OperationOptions().executionTimeout(100)); +} catch (TimeoutExceededException error) { + System.out.println(error.getMessage()); // The operation took too much time. +} ``` -#### Response +Timeout is best effort. The exact time is not guaranteed. -``` -true -``` - -### Details +## API Overview -Compute the details of the provided term. +`RegexSolverClient` and `AsyncRegexSolverClient` expose the following methods. Every method accepts an optional `OperationOptions` as its last parameter (`responseFormat`, `deterministic`, `executionTimeout`). An option that does not apply to an operation is ignored: analyze operations and `determinize()` only honour `executionTimeout`; the response format is not theirs to choose. `generateStrings()` additionally accepts a `GenerateStringsOptions` carrying its ordering, seed, length and charset options. -The computed details are: +### Analyze -- **Cardinality:** the number of possible values. -- **Length:** the minimum and maximum length of possible values. -- **Empty:** true if is an empty set (does not contain any value), false otherwise. -- **Total:** true if is a total set (contains all values), false otherwise. +| Method | Return | Description | +| -------- | ------- | ------- | +| `client.equivalent(term1, term2, options?)` | `boolean` | `true` if `term1` and `term2` accept exactly the same language. | +| `client.getCardinality(term, options?)` | `Cardinality` | Returns the number of possible matched strings. | +| `client.getDot(term, options?)` | `String` | Returns a Graphviz DOT representation of the automaton. | +| `client.getLength(term, options?)` | `Length` | Returns the minimum and maximum length of matched strings. | +| `client.getPattern(term, options?)` | `String` | Returns a regular expression pattern for the term. | +| `client.isEmpty(term, options?)` | `boolean` | `true` if the term matches no string. | +| `client.isEmptyString(term, options?)` | `boolean` | `true` if the term matches only the empty string. | +| `client.isTotal(term, options?)` | `boolean` | `true` if the term matches all possible strings. | +| `client.isDeterministic(term, options?)` | `boolean` | `true` if the term's automaton is deterministic. Only a deterministic FAIR guarantees consistent string ordering across paginated `generateStrings()` calls; call `determinize()` first if this is `false`. | +| `client.subset(subset, superset, options?)` | `boolean` | `true` if every string matched by `subset` is also matched by `superset`. | -#### Request +*Note: For `AsyncRegexSolverClient`, these methods return `CompletableFuture`.* -```java -Term.Regex term = Term.regex("(abc|de)"); +### Compute -Details details = term.getDetails(); -System.out.println(details); -``` +| Method | Return | Description | +| -------- | ------- | ------- | +| `client.complement(term, options?)` | `Term` | Computes the complement of the given term. | +| `client.concat(term1, term2, ..., options?)` | `Term` | Concatenates multiple terms in order. | +| `client.determinize(term, options?)` | `Term` | Computes a deterministic FAIR for the given term, suitable for consistent pagination with `generateStrings()`. | +| `client.difference(base, excluded, options?)` | `Term` | Computes the difference `base - excluded`. | +| `client.intersection(term1, term2, ..., options?)` | `Term` | Computes the intersection of the given terms. | +| `client.repeat(term, min, max, options?)` | `Term` | Computes the repetition of the term between `min` and `max` times. | +| `client.union(term1, term2, ..., options?)` | `Term` | Computes the union of the given terms. | -#### Response +*Note: For `AsyncRegexSolverClient`, these methods return `CompletableFuture`.* -``` -Details[cardinality=Integer(2), length=Length[minimum=2, maximum=3], empty=false, total=false] -``` +### Generate -### Generate Strings +| Method | Return | Description | +| -------- | ------- | ------- | +| `client.generateStrings(term, limit, offset, options?)` | `List` | Generates up to `limit` unique strings matched by `term`, skipping the first `offset` strings. Pass a `GenerateStringsOptions` to control `pathOrder`, `characterOrder`, `seed`, `minLength`, `maxLength` and `charset`. | -Generate the given number of strings that can be matched by the provided term. +*Note: For `AsyncRegexSolverClient`, this method returns `CompletableFuture>`.* -The maximum number of strings to generate is currently limited to 200. +## Cross-Language Support -#### Request +If you want to use this library with other programming languages, we provide: +- [regexsolver-js](https://github.com/RegexSolver/regexsolver-js) +- [regexsolver-python](https://github.com/RegexSolver/regexsolver-python) -```java -Term.Regex term = Term.regex("(abc|de){2}"); +For more information about how to use the wrappers, you can refer to our [guide](https://docs.regexsolver.com/getting-started.html). -List strings = term.generateStrings(3); -System.out.println(strings); -``` +You can also take a look at [regexsolver](https://github.com/RegexSolver/regexsolver) which contains the source code of the engine. -#### Response +## License -``` -[abcde, dede, deabc] -``` +This project is licensed under the MIT License. diff --git a/generate-api.sh b/generate-api.sh new file mode 100755 index 0000000..0afec82 --- /dev/null +++ b/generate-api.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +SPEC_FILE="../m-lab/shared/openapi.yaml" +OUT_DIR="./" + +echo "Running openapi-generator-cli..." +openapi-generator-cli generate \ + -i "$SPEC_FILE" \ + -g java \ + -o "$OUT_DIR" \ + --model-name-suffix Dto \ + --additional-properties=library=native \ + --additional-properties=invokerPackage=com.regexsolver.api.generated \ + --additional-properties=apiPackage=com.regexsolver.api.generated.api \ + --additional-properties=modelPackage=com.regexsolver.api.generated.model \ + --additional-properties=asyncNative=true \ + --additional-properties=useRuntimeException=true \ + --additional-properties=openApiNullable=false \ + --additional-properties=useJakartaEe=true + +echo "API Generation Complete." diff --git a/openapitools.json b/openapitools.json new file mode 100644 index 0000000..91d9c43 --- /dev/null +++ b/openapitools.json @@ -0,0 +1,7 @@ +{ + "$schema": "./node_modules/@openapitools/openapi-generator-cli/config.schema.json", + "spaces": 2, + "generator-cli": { + "version": "7.21.0" + } +} diff --git a/pom.xml b/pom.xml index 4f04249..2130650 100644 --- a/pom.xml +++ b/pom.xml @@ -1,12 +1,14 @@ - - + + 4.0.0 com.regexsolver.api RegexSolver - 1.0.2 + 1.1.0 https://regexsolver.com @@ -17,8 +19,7 @@ https://github.com/RegexSolver/regexsolver-java - RegexSolver allows you to manipulate regular expressions as sets, enabling operations such as intersection, - union, and subtraction. + RegexSolver is a powerful toolkit for building, combining, and analyzing regular expressions. @@ -38,34 +39,103 @@ 11 11 UTF-8 + + 2.21.1 + 2.21 + 2.1.1 + 5.10.2 + 3.2.5 + 5.20.0 + 3.25.3 - com.squareup.retrofit2 - retrofit - 2.11.0 + jakarta.annotation + jakarta.annotation-api + ${jakarta.annotation.version} + + + + com.fasterxml.jackson.core + jackson-core + ${jackson.version} + + + + com.fasterxml.jackson.core + jackson-annotations + ${jackson.annotations.version} + + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + ${jackson.version} + + + + org.openapitools + jackson-databind-nullable + 0.2.9 + + + + org.junit.jupiter + junit-jupiter-api + ${junit.version} + test + - com.squareup.retrofit2 - converter-jackson - 2.11.0 + org.junit.jupiter + junit-jupiter-engine + ${junit.version} + test + - junit - junit - 4.13.2 + org.mockito + mockito-core + ${mockito.version} test - com.squareup.okhttp3 - mockwebserver - 3.14.9 + org.mockito + mockito-junit-jupiter + ${mockito.version} + test + + + + org.assertj + assertj-core + ${assertj.version} test + + + org.apache.maven.plugins + maven-compiler-plugin + 3.13.0 + + 11 + + + + org.apache.maven.plugins + maven-surefire-plugin + ${surefire.version} + org.apache.maven.plugins maven-source-plugin @@ -84,9 +154,7 @@ maven-javadoc-plugin 3.7.0 - - **/ResponseContent.java - + 11 @@ -100,7 +168,7 @@ org.apache.maven.plugins maven-gpg-plugin - 1.5 + 3.2.4 sign-artifacts @@ -128,4 +196,4 @@ - \ No newline at end of file + diff --git a/src/main/java/com/regexsolver/api/AccountLimits.java b/src/main/java/com/regexsolver/api/AccountLimits.java new file mode 100644 index 0000000..5e56eb7 --- /dev/null +++ b/src/main/java/com/regexsolver/api/AccountLimits.java @@ -0,0 +1,107 @@ +package com.regexsolver.api; + +import com.regexsolver.api.generated.model.AccountLimitsDto; +import java.util.Objects; + +/** + * The plan limits currently applying to the account. + */ +public final class AccountLimits { + + private final long maxRequestsCount; + private final long maxRequestsRate; + private final long maxTermsCount; + private final long maxTimeout; + private final long maxStatesCount; + + AccountLimits( + long maxRequestsCount, + long maxRequestsRate, + long maxTermsCount, + long maxTimeout, + long maxStatesCount + ) { + this.maxRequestsCount = maxRequestsCount; + this.maxRequestsRate = maxRequestsRate; + this.maxTermsCount = maxTermsCount; + this.maxTimeout = maxTimeout; + this.maxStatesCount = maxStatesCount; + } + + static AccountLimits fromDto(AccountLimitsDto dto) { + return new AccountLimits( + dto.getMaxRequestsCount(), + dto.getMaxRequestsRate(), + dto.getMaxTermsCount(), + dto.getMaxTimeout(), + dto.getMaxStatesCount() + ); + } + + /** @return Maximum number of requests allowed per billing period. */ + public long getMaxRequestsCount() { + return maxRequestsCount; + } + + /** @return Maximum number of requests allowed per second. 0 means no rate limit is enforced. */ + public long getMaxRequestsRate() { + return maxRequestsRate; + } + + /** @return Maximum number of terms accepted in a single request. */ + public long getMaxTermsCount() { + return maxTermsCount; + } + + /** @return Maximum execution timeout per request, in milliseconds. */ + public long getMaxTimeout() { + return maxTimeout; + } + + /** @return Maximum number of automaton states an operation may build. */ + public long getMaxStatesCount() { + return maxStatesCount; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof AccountLimits)) return false; + AccountLimits that = (AccountLimits) o; + return ( + maxRequestsCount == that.maxRequestsCount && + maxRequestsRate == that.maxRequestsRate && + maxTermsCount == that.maxTermsCount && + maxTimeout == that.maxTimeout && + maxStatesCount == that.maxStatesCount + ); + } + + @Override + public int hashCode() { + return Objects.hash( + maxRequestsCount, + maxRequestsRate, + maxTermsCount, + maxTimeout, + maxStatesCount + ); + } + + @Override + public String toString() { + return ( + "" + ); + } +} diff --git a/src/main/java/com/regexsolver/api/AsyncRegexSolverClient.java b/src/main/java/com/regexsolver/api/AsyncRegexSolverClient.java new file mode 100644 index 0000000..b60f3fa --- /dev/null +++ b/src/main/java/com/regexsolver/api/AsyncRegexSolverClient.java @@ -0,0 +1,1269 @@ +package com.regexsolver.api; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.regexsolver.api.exceptions.*; +import com.regexsolver.api.generated.ApiClient; +import com.regexsolver.api.generated.ApiException; +import com.regexsolver.api.generated.api.AccountApi; +import com.regexsolver.api.generated.api.AnalyzeApi; +import com.regexsolver.api.generated.api.ComputeApi; +import com.regexsolver.api.generated.api.GenerateApi; +import com.regexsolver.api.generated.model.*; +import java.net.http.HttpHeaders; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; +import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +/** + * The Asynchronous Client for RegexSolver. + * + * Provides non-blocking access to all RegexSolver API endpoints. + */ +public final class AsyncRegexSolverClient { + + private static final String VERSION = "1.1.0"; + + // Retry policy for 429 responses: retry as long as the total wait stays + // within the budget, adding full jitter on top of `Retry-After` so + // concurrent waiters do not re-collide as a single burst. The values are + // shared across all the official clients — change them together. + private static final long RETRY_BUDGET_MS = 300_000; + private static final double JITTER_BASE_S = 0.25; + private static final double JITTER_CAP_S = 2.0; + private static final double DEFAULT_RETRY_AFTER_S = 1.0; + + private final String apiToken; + private final String baseUrl; + private final RateLimiter rateLimiter; + private final AccountApi accountApi; + private final AnalyzeApi analyzeApi; + private final ComputeApi computeApi; + private final GenerateApi generateApi; + private final ObjectMapper objectMapper; + private final boolean autoBatch; + private final Integer maxTermsPerRequest; + private final AtomicReference> limitsFuture = + new AtomicReference<>(); + private volatile Integer serverMaxTerms; + + private AsyncRegexSolverClient(Builder builder) { + this.apiToken = builder.apiToken; + this.baseUrl = builder.baseUrl; + this.rateLimiter = RateLimiter.getInstance(this.apiToken); + this.autoBatch = builder.autoBatch; + this.maxTermsPerRequest = builder.maxTermsPerRequest; + + ApiClient apiClient = new ApiClient(); + apiClient.updateBaseUri(this.baseUrl); + apiClient.setRequestInterceptor(requestBuilder -> { + requestBuilder.header( + "User-Agent", + "RegexSolver Java / " + VERSION + ); + requestBuilder.header("Authorization", "Bearer " + this.apiToken); + }); + + this.accountApi = new AccountApi(apiClient); + this.analyzeApi = new AnalyzeApi(apiClient); + this.computeApi = new ComputeApi(apiClient); + this.generateApi = new GenerateApi(apiClient); + this.objectMapper = apiClient.getObjectMapper(); + } + + public static Builder builder() { + return new Builder(); + } + + public static final class Builder { + + private String apiToken; + private String baseUrl = "https://api.regexsolver.com/v1"; + private boolean autoBatch = true; + private Integer maxTermsPerRequest; + + public Builder apiToken(String apiToken) { + this.apiToken = apiToken; + return this; + } + + public Builder baseUrl(String baseUrl) { + this.baseUrl = baseUrl; + return this; + } + + /** + * When true (the default), calls to concat/intersection/union + * carrying more terms than the account's per-request limit are + * transparently split into several requests and folded back into one + * result. Each constituent request counts against the monthly quota. + * + * @param autoBatch whether to enable auto-batching + * @return this builder + */ + public Builder autoBatch(boolean autoBatch) { + this.autoBatch = autoBatch; + return this; + } + + /** + * Upper bound (>= 2) on the number of terms sent in a single + * request, overriding the limit fetched from the API when smaller. + * + * @param maxTermsPerRequest the cap, or null to use the account limit + * @return this builder + */ + public Builder maxTermsPerRequest(Integer maxTermsPerRequest) { + this.maxTermsPerRequest = maxTermsPerRequest; + return this; + } + + public AsyncRegexSolverClient build() { + if (apiToken == null || apiToken.isEmpty()) { + throw new IllegalArgumentException("apiToken is required"); + } + if (maxTermsPerRequest != null && maxTermsPerRequest < 2) { + throw new IllegalArgumentException( + "maxTermsPerRequest must be at least 2" + ); + } + return new AsyncRegexSolverClient(this); + } + } + + // --- INTERNAL HELPERS --- + + private RequestOptionsDto buildOptions(OperationOptions options) { + RequestOptionsDto dto = new RequestOptionsDto().schemaVersion(1); + if (options != null) { + options + .getExecutionTimeout() + .ifPresent(timeout -> + dto.execution(new ExecutionOptionsDto().timeout(timeout)) + ); + + Optional responseFormat = options.getResponseFormat(); + Optional deterministic = options.getDeterministic(); + + if (deterministic.isPresent() && responseFormat.isPresent()) { + if (responseFormat.get() != ResponseFormat.FAIR) { + throw new IllegalArgumentException( + "deterministic can only be used with responseFormat=ResponseFormat.FAIR, got " + + responseFormat.get() + ); + } + } + + if (responseFormat.isPresent() || deterministic.isPresent()) { + ResponseOptionsDto responseOptions = new ResponseOptionsDto(); + responseFormat.ifPresent(format -> responseOptions.format(format.toDto())); + deterministic.ifPresent(value -> { + responseOptions.fair(new FairResponseOptionsDto().deterministic(value)); + if (responseFormat.isEmpty()) { + responseOptions.format(ResponseFormat.FAIR.toDto()); + } + }); + dto.response(responseOptions); + } + } + return dto; + } + + private CompletableFuture executeWithRetry( + Supplier> apiCall + ) { + return executeWithRetry(apiCall, 0, null); + } + + private CompletableFuture executeWithRetry( + Supplier> apiCall, + int attempt, + Long firstFailureAtMillis + ) { + CompletableFuture gate = rateLimiter.waitIfNecessary(); + if (attempt > 0) { + long jitterMillis = (long) (ThreadLocalRandom.current().nextDouble() * + Math.min(JITTER_BASE_S * Math.pow(2, attempt), JITTER_CAP_S) * + 1000); + gate = gate.thenCompose(v -> + CompletableFuture.runAsync( + () -> {}, + CompletableFuture.delayedExecutor( + Math.max(jitterMillis, 1), + java.util.concurrent.TimeUnit.MILLISECONDS + ) + ) + ); + } + return exceptionallyCompose( + gate.thenCompose(v -> apiCall.get()), + ex -> { + Throwable cause = ex.getCause() != null ? ex.getCause() : ex; + if (cause instanceof ApiException) { + ApiException apiEx = (ApiException) cause; + if (apiEx.getCode() == 429) { + double retryAfter = DEFAULT_RETRY_AFTER_S; + HttpHeaders headers = apiEx.getResponseHeaders(); + if (headers != null) { + try { + retryAfter = headers + .firstValue("Retry-After") + .map(Double::parseDouble) + .orElse(DEFAULT_RETRY_AFTER_S); + } catch (NumberFormatException ignored) {} + } + long now = System.currentTimeMillis(); + long firstFailureAt = firstFailureAtMillis != null + ? firstFailureAtMillis + : now; + if ( + now - + firstFailureAt + + (long) (retryAfter * 1000) <= + RETRY_BUDGET_MS + ) { + rateLimiter.trigger(retryAfter); + return executeWithRetry( + apiCall, + attempt + 1, + firstFailureAt + ); + } + } + throw mapException(apiEx); + } + if ( + cause instanceof RuntimeException + ) throw (RuntimeException) cause; + throw new RuntimeException(cause); + } + ); + } + + /** + * `CompletableFuture.exceptionallyCompose` equivalent; that method is + * only available from Java 12 onwards and this SDK targets Java 11. + */ + private static CompletableFuture exceptionallyCompose( + CompletableFuture future, + Function> fallback + ) { + CompletableFuture> composed = future.handle( + (value, ex) -> + ex == null + ? CompletableFuture.completedFuture(value) + : fallback.apply(ex) + ); + return composed.thenCompose(stage -> stage); + } + + private RegexSolverException mapException(ApiException ex) { + int code = ex.getCode(); + String body = ex.getResponseBody(); + String message = ex.getMessage(); + String errorCode = "UnknownError"; + + try { + ErrorResponseDto errorResponse = objectMapper.readValue( + body, + ErrorResponseDto.class + ); + if (errorResponse.getError() != null) message = + errorResponse.getError(); + if (errorResponse.getErrorCode() != null) errorCode = + errorResponse.getErrorCode(); + } catch (Exception ignored) {} + + switch (code) { + case 400: + if ( + "InvalidJson".equals(errorCode) + ) return new InvalidJsonException( + message, + code, + errorCode, + body + ); + if ( + "TooManyTerms".equals(errorCode) + ) return new TooManyTermsException( + message, + code, + errorCode, + body + ); + if ( + "TooFewTerms".equals(errorCode) + ) return new TooFewTermsException( + message, + code, + errorCode, + body + ); + if ( + "TimeoutTooLarge".equals(errorCode) + ) return new TimeoutTooLargeException( + message, + code, + errorCode, + body + ); + if ( + "TimeoutExceeded".equals(errorCode) + ) return new TimeoutExceededException( + message, + code, + errorCode, + body + ); + if ( + "InvalidNumberOfStringsToGenerate".equals(errorCode) + ) return new InvalidNumberOfStringsToGenerateException( + message, + code, + errorCode, + body + ); + if ( + "AutomatonTooManyStates".equals(errorCode) + ) return new AutomatonTooManyStatesException( + message, + code, + errorCode, + body + ); + if ( + "RegexSyntaxError".equals(errorCode) + ) return new RegexSyntaxException( + message, + code, + errorCode, + body + ); + if ( + "FairSyntaxError".equals(errorCode) + ) return new FairSyntaxException( + message, + code, + errorCode, + body + ); + return new BadRequestException(message, code, errorCode, body); + case 401: + if ( + "MissingOrMalformedToken".equals(errorCode) + ) return new MissingOrMalformedTokenException( + message, + code, + errorCode, + body + ); + if ( + "InvalidToken".equals(errorCode) + ) return new InvalidTokenException( + message, + code, + errorCode, + body + ); + return new UnauthorizedException( + message, + code, + errorCode, + body + ); + case 403: + if ( + "QuotaExceeded".equals(errorCode) + ) return new QuotaExceededException( + message, + code, + errorCode, + body + ); + return new ForbiddenException(message, code, errorCode, body); + case 404: + return new NotFoundException(message, code, errorCode, body); + case 429: + return new TooManyRequestsException( + "Max retries exceeded for 429 Too Many Requests.", + code, + errorCode, + body + ); + case 500: + return new InternalServerException( + message, + code, + errorCode, + body + ); + default: + return new com.regexsolver.api.exceptions.ApiException( + message, + code, + errorCode, + body + ); + } + } + + // --- ACCOUNT OPERATIONS --- + + /** + * Fetches the plan limits applying to the account asynchronously. + * + * The call never consumes request quota (it is only rate-limited) and the + * result is cached on the client, so calling it again is free. The cached + * maxTermsCount also drives auto-batching. + * + * @return A CompletableFuture containing the five plan limits. + */ + public CompletableFuture getAccountLimits() { + CompletableFuture existing = limitsFuture.get(); + if (existing != null) { + return existing; + } + CompletableFuture created = executeWithRetry(() -> + accountApi.limits() + ).thenApply(resp -> { + AccountLimits limits = AccountLimits.fromDto(resp.getData()); + serverMaxTerms = (int) Math.min( + limits.getMaxTermsCount(), + Integer.MAX_VALUE + ); + return limits; + }); + if (!limitsFuture.compareAndSet(null, created)) { + return limitsFuture.get(); + } + created.whenComplete((limits, error) -> { + if (error != null) { + // Cleared on failure so a later call can retry the fetch. + limitsFuture.compareAndSet(created, null); + } + }); + return created; + } + + // --- AUTO-BATCHING --- + + /** The largest term count to send in one request, when known. */ + private Integer effectiveMaxTerms() { + Integer serverMax = serverMaxTerms; + if (maxTermsPerRequest != null) { + return serverMax != null + ? Math.min(maxTermsPerRequest, serverMax) + : maxTermsPerRequest; + } + return serverMax; + } + + /** + * Run an n-ary operation (concat/intersection/union), transparently + * splitting the terms into several requests when they exceed the + * account's terms-per-request limit (auto-batching). + */ + private CompletableFuture runNary( + List terms, + OperationOptions options, + Function> op + ) { + Integer maxTerms = autoBatch ? effectiveMaxTerms() : null; + if (maxTerms != null && terms.size() > maxTerms) { + return fold(op, terms, options, maxTerms); + } + boolean limitWasKnown = maxTerms != null; + return exceptionallyCompose( + naryCall(op, terms, options, true), + ex -> { + Throwable cause = ex.getCause() != null ? ex.getCause() : ex; + if ( + !autoBatch || + limitWasKnown || + !(cause instanceof TooManyTermsException) + ) { + return CompletableFuture.failedFuture(cause); + } + return getAccountLimits() + .handle((limits, fetchError) -> + // A failed fetch falls back to surfacing the original + // TooManyTerms, never worse than without batching. + fetchError != null ? null : effectiveMaxTerms() + ) + .thenCompose(newMax -> { + if ( + newMax == null || + newMax < 2 || + terms.size() <= newMax + ) { + return CompletableFuture.failedFuture(cause); + } + return fold(op, terms, options, newMax); + }); + } + ); + } + + private CompletableFuture naryCall( + Function> op, + List batch, + OperationOptions options, + boolean isFinal + ) { + // Intermediate results are fed straight back into the next request, + // so only the final call carries the caller's response options; + // executionTimeout bounds every constituent request. + OperationOptions effective = isFinal + ? options + : intermediateOptions(options); + MultiTermsRequestDto request = new MultiTermsRequestDto() + .terms(batch.stream().map(Term::toDto).collect(Collectors.toList())) + .options(buildOptions(effective)); + return op.apply(request).thenApply(Term::fromDto); + } + + private static OperationOptions intermediateOptions( + OperationOptions options + ) { + if (options == null) { + return null; + } + return options + .getExecutionTimeout() + .map(timeout -> OperationOptions.builder().executionTimeout(timeout)) + .orElse(null); + } + + /** + * Left fold: combine the first {@code maxTerms} terms, then keep feeding + * the accumulated result back with the next {@code maxTerms - 1} terms. + * Left-associative, so concat order is preserved; union and intersection + * are commutative and unaffected. + */ + private CompletableFuture fold( + Function> op, + List terms, + OperationOptions options, + int maxTerms + ) { + CompletableFuture acc = naryCall( + op, + terms.subList(0, maxTerms), + options, + false + ); + int index = maxTerms; + while (index < terms.size()) { + int end = Math.min(index + maxTerms - 1, terms.size()); + final List chunk = terms.subList(index, end); + final boolean isFinal = end >= terms.size(); + acc = acc.thenCompose(accTerm -> { + List batch = new ArrayList<>(); + batch.add(accTerm); + batch.addAll(chunk); + return naryCall(op, batch, options, isFinal); + }); + index = end; + } + return acc; + } + + // --- ANALYZE OPERATIONS --- + + /** + * Computes how many unique strings the term matches asynchronously. + * + * @param term The term to analyze. + * @return A CompletableFuture containing a Cardinality object representing either an exact Integer, a BigInteger, or Infinite cardinality. + */ + public CompletableFuture getCardinality(Term term) { + return getCardinality(term, (OperationOptions) null); + } + + /** + * Computes how many unique strings the term matches asynchronously. + * + * @param term The term to analyze. + * @param options Options for the operation. + * @return A CompletableFuture containing a Cardinality object representing either an exact Integer, a BigInteger, or Infinite cardinality. + */ + public CompletableFuture getCardinality( + Term term, + OperationOptions options + ) { + if (term.getCachedCardinality() != null) { + return CompletableFuture.completedFuture( + term.getCachedCardinality() + ); + } + TermRequestDto request = new TermRequestDto() + .term(term.toDto()) + .options(buildOptions(options)); + return executeWithRetry(() -> + analyzeApi.cardinality(request) + ).thenApply(resp -> { + Cardinality card = Cardinality.fromDto(resp.getData()); + term.setCachedCardinality(card); + return card; + }); + } + + /** + * Computes the minimum and maximum length of strings matched by the term asynchronously. + * + * @param term The term to analyze. + * @return A CompletableFuture containing a Length object with `min` and `max` integers. Limits are null if unbounded or undefined. + */ + public CompletableFuture getLength(Term term) { + return getLength(term, (OperationOptions) null); + } + + /** + * Computes the minimum and maximum length of strings matched by the term asynchronously. + * + * @param term The term to analyze. + * @param options Options for the operation. + * @return A CompletableFuture containing a Length object with `min` and `max` integers. Limits are null if unbounded or undefined. + */ + public CompletableFuture getLength( + Term term, + OperationOptions options + ) { + if (term.getCachedLength() != null) { + return CompletableFuture.completedFuture(term.getCachedLength()); + } + TermRequestDto request = new TermRequestDto() + .term(term.toDto()) + .options(buildOptions(options)); + return executeWithRetry(() -> analyzeApi.length(request)).thenApply( + resp -> { + Length len = Length.fromDto(resp.getData()); + term.setCachedLength(len); + return len; + } + ); + } + + /** + * Checks if the term matches no strings at all asynchronously. + * + * @param term The term to analyze. + * @return A CompletableFuture containing true if the language is completely empty, false otherwise. + */ + public CompletableFuture isEmpty(Term term) { + return isEmpty(term, (OperationOptions) null); + } + + /** + * Checks if the term matches no strings at all asynchronously. + * + * @param term The term to analyze. + * @param options Options for the operation. + * @return A CompletableFuture containing true if the language is completely empty, false otherwise. + */ + public CompletableFuture isEmpty( + Term term, + OperationOptions options + ) { + if (term.getCachedEmpty() != null) { + return CompletableFuture.completedFuture(term.getCachedEmpty()); + } + TermRequestDto request = new TermRequestDto() + .term(term.toDto()) + .options(buildOptions(options)); + return executeWithRetry(() -> analyzeApi.empty(request)).thenApply( + resp -> { + boolean val = resp.getData().getValue(); + term.setCachedEmpty(val); + if (val) { + term.setCachedCardinality(new Cardinality.Integer(0)); + term.setCachedLength(new Length(null, null)); + } + return val; + } + ); + } + + /** + * Checks if the term matches only the empty string asynchronously. + * + * @param term The term to analyze. + * @return A CompletableFuture containing true if the term strictly matches the empty string ("") and nothing else. + */ + public CompletableFuture isEmptyString(Term term) { + return isEmptyString(term, (OperationOptions) null); + } + + /** + * Checks if the term matches only the empty string asynchronously. + * + * @param term The term to analyze. + * @param options Options for the operation. + * @return A CompletableFuture containing true if the term strictly matches the empty string ("") and nothing else. + */ + public CompletableFuture isEmptyString( + Term term, + OperationOptions options + ) { + if (term.getCachedEmptyString() != null) { + return CompletableFuture.completedFuture( + term.getCachedEmptyString() + ); + } + TermRequestDto request = new TermRequestDto() + .term(term.toDto()) + .options(buildOptions(options)); + return executeWithRetry(() -> + analyzeApi.emptyString(request) + ).thenApply(resp -> { + boolean val = resp.getData().getValue(); + term.setCachedEmptyString(val); + + if (val) { + term.setCachedCardinality(new Cardinality.Integer(1)); + term.setCachedLength(new Length(0, 0)); + } + return val; + }); + } + + /** + * Checks if the term matches all possible strings asynchronously. + * + * @param term The term to analyze. + * @return A CompletableFuture containing true if the term matches every possible string. + */ + public CompletableFuture isTotal(Term term) { + return isTotal(term, (OperationOptions) null); + } + + /** + * Checks if the term matches all possible strings asynchronously. + * + * @param term The term to analyze. + * @param options Options for the operation. + * @return A CompletableFuture containing true if the term matches every possible string. + */ + public CompletableFuture isTotal( + Term term, + OperationOptions options + ) { + if (term.getCachedTotal() != null) { + return CompletableFuture.completedFuture(term.getCachedTotal()); + } + TermRequestDto request = new TermRequestDto() + .term(term.toDto()) + .options(buildOptions(options)); + return executeWithRetry(() -> analyzeApi.total(request)).thenApply( + resp -> { + boolean val = resp.getData().getValue(); + term.setCachedTotal(val); + + if (val) { + term.setCachedCardinality(new Cardinality.Infinite()); + term.setCachedLength(new Length(0, null)); + } + return val; + } + ); + } + + /** + * Checks if the term's automaton is deterministic asynchronously. + * Only a deterministic FAIR guarantees consistent string ordering across paginated generateStrings() calls; call determinize() first if this is false. + * + * @param term The term to analyze. + * @return A CompletableFuture containing true if the term's automaton is deterministic. + */ + public CompletableFuture isDeterministic(Term term) { + return isDeterministic(term, (OperationOptions) null); + } + + /** + * Checks if the term's automaton is deterministic asynchronously. + * Only a deterministic FAIR guarantees consistent string ordering across paginated generateStrings() calls; call determinize() first if this is false. + * + * @param term The term to analyze. + * @param options Options for the operation. + * @return A CompletableFuture containing true if the term's automaton is deterministic. + */ + public CompletableFuture isDeterministic( + Term term, + OperationOptions options + ) { + if (!(term instanceof Term.FairTerm)) { + return CompletableFuture.completedFuture(false); + } + Term.FairTerm fairTerm = (Term.FairTerm) term; + Optional cached = fairTerm.getCachedDeterministic(); + if (cached.isPresent()) { + return CompletableFuture.completedFuture(cached.get()); + } + TermRequestDto request = new TermRequestDto() + .term(term.toDto()) + .options(buildOptions(options)); + return executeWithRetry(() -> analyzeApi.deterministic(request)).thenApply( + resp -> { + boolean val = resp.getData().getValue(); + fairTerm.setCachedDeterministic(Optional.of(val)); + return val; + } + ); + } + + /** + * Returns a regular expression pattern that represents the term asynchronously. + * + * @param term The term to extract the pattern from. + * @return A CompletableFuture containing a valid regular expression string representing the language. + */ + public CompletableFuture getPattern(Term term) { + return getPattern(term, (OperationOptions) null); + } + + /** + * Returns a regular expression pattern that represents the term asynchronously. + * + * @param term The term to extract the pattern from. + * @param options Options for the operation. + * @return A CompletableFuture containing a valid regular expression string representing the language. + */ + public CompletableFuture getPattern( + Term term, + OperationOptions options + ) { + if (term.getCachedPattern() != null) { + return CompletableFuture.completedFuture(term.getCachedPattern()); + } + TermRequestDto request = new TermRequestDto() + .term(term.toDto()) + .options(buildOptions(options)); + return executeWithRetry(() -> + analyzeApi.pattern(request) + ).thenApply(resp -> { + String val = resp.getData().getValue(); + term.setCachedPattern(val); + return val; + }); + } + + /** + * Builds a Graphviz DOT representation of the term's automaton asynchronously. + * + * @param term The term to visualize. + * @return A CompletableFuture containing the raw DOT syntax for Graphviz compilation. + */ + public CompletableFuture getDot(Term term) { + return getDot(term, (OperationOptions) null); + } + + /** + * Builds a Graphviz DOT representation of the term's automaton asynchronously. + * + * @param term The term to visualize. + * @param options Options for the operation. + * @return A CompletableFuture containing the raw DOT syntax for Graphviz compilation. + */ + public CompletableFuture getDot( + Term term, + OperationOptions options + ) { + if (term.getCachedDot() != null) { + return CompletableFuture.completedFuture(term.getCachedDot()); + } + TermRequestDto request = new TermRequestDto() + .term(term.toDto()) + .options(buildOptions(options)); + return executeWithRetry(() -> analyzeApi.dot(request)).thenApply( + resp -> { + String val = resp.getData().getValue(); + term.setCachedDot(val); + return val; + } + ); + } + + /** + * Checks if the two terms accept exactly the same language asynchronously. + * + * @param term1 The first term. + * @param term2 The second term to compare against. + * @return A CompletableFuture containing true if they are entirely equivalent, false otherwise. + */ + public CompletableFuture equivalent(Term term1, Term term2) { + return equivalent(term1, term2, (OperationOptions) null); + } + + /** + * Checks if the two terms accept exactly the same language asynchronously. + * + * @param term1 The first term. + * @param term2 The second term to compare against. + * @param options Options for the operation. + * @return A CompletableFuture containing true if they are entirely equivalent, false otherwise. + */ + public CompletableFuture equivalent( + Term term1, + Term term2, + OperationOptions options + ) { + TwoTermsRequestDto request = new TwoTermsRequestDto() + .addTermsItem(term1.toDto()) + .addTermsItem(term2.toDto()) + .options(buildOptions(options)); + return executeWithRetry(() -> analyzeApi.equivalent(request)).thenApply( + resp -> resp.getData().getValue() + ); + } + + /** + * Checks if the first term's language is a subset of the second term's language asynchronously. + * + * @param subset The term to test as the subset. + * @param superset The term representing the entire set space. + * @return A CompletableFuture containing true if every string matched by subset is also matched by superset. + */ + public CompletableFuture subset(Term subset, Term superset) { + return subset(subset, superset, (OperationOptions) null); + } + + /** + * Checks if the first term's language is a subset of the second term's language asynchronously. + * + * @param subset The term to test as the subset. + * @param superset The term representing the entire set space. + * @param options Options for the operation. + * @return A CompletableFuture containing true if every string matched by subset is also matched by superset. + */ + public CompletableFuture subset( + Term subset, + Term superset, + OperationOptions options + ) { + TwoTermsRequestDto request = new TwoTermsRequestDto() + .addTermsItem(subset.toDto()) + .addTermsItem(superset.toDto()) + .options(buildOptions(options)); + return executeWithRetry(() -> analyzeApi.subset(request)).thenApply( + resp -> resp.getData().getValue() + ); + } + + // --- COMPUTE OPERATIONS --- + + /** + * Concatenates the given terms sequentially asynchronously. + * + * @param terms Variadic terms to concatenate in order. + * @return A CompletableFuture containing a newly computed concatenated term. + */ + public CompletableFuture concat(Term... terms) { + return concat(Arrays.asList(terms)); + } + + /** + * Concatenates the given terms sequentially asynchronously. + * + * @param terms A dynamic list of terms to concatenate in order. + * @return A CompletableFuture containing a newly computed concatenated term. + */ + public CompletableFuture concat(List terms) { + return concat(terms, (OperationOptions) null); + } + + /** + * Concatenates the given terms sequentially asynchronously. + * + * @param terms A dynamic list of terms to concatenate in order. + * @param options Options for the operation. + * @return A CompletableFuture containing a newly computed concatenated term. + */ + public CompletableFuture concat( + List terms, + OperationOptions options + ) { + return runNary(terms, options, request -> + executeWithRetry(() -> computeApi.concat(request)).thenApply( + Concat200ResponseDto::getData + ) + ); + } + + /** + * Computes the intersection of the given terms asynchronously. + * + * @param terms Variadic terms to intersect. + * @return A CompletableFuture containing a term representing only strings matched by ALL provided terms. + */ + public CompletableFuture intersection(Term... terms) { + return intersection(Arrays.asList(terms)); + } + + /** + * Computes the intersection of the given terms asynchronously. + * + * @param terms A dynamic list of terms to intersect. + * @return A CompletableFuture containing a term representing only strings matched by ALL provided terms. + */ + public CompletableFuture intersection(List terms) { + return intersection(terms, (OperationOptions) null); + } + + /** + * Computes the intersection of the given terms asynchronously. + * + * @param terms A dynamic list of terms to intersect. + * @param options Options for the operation. + * @return A CompletableFuture containing a term representing only strings matched by ALL provided terms. + */ + public CompletableFuture intersection( + List terms, + OperationOptions options + ) { + return runNary(terms, options, request -> + executeWithRetry(() -> computeApi.intersection(request)).thenApply( + Concat200ResponseDto::getData + ) + ); + } + + /** + * Computes the union of the given terms asynchronously. + * + * @param terms Variadic terms to combine. + * @return A CompletableFuture containing a term representing strings matched by ANY of the provided terms. + */ + public CompletableFuture union(Term... terms) { + return union(Arrays.asList(terms)); + } + + /** + * Computes the union of the given terms asynchronously. + * + * @param terms A dynamic list of terms to combine. + * @return A CompletableFuture containing a term representing strings matched by ANY of the provided terms. + */ + public CompletableFuture union(List terms) { + return union(terms, (OperationOptions) null); + } + + /** + * Computes the union of the given terms asynchronously. + * + * @param terms A dynamic list of terms to combine. + * @param options Options for the operation. + * @return A CompletableFuture containing a term representing strings matched by ANY of the provided terms. + */ + public CompletableFuture union( + List terms, + OperationOptions options + ) { + return runNary(terms, options, request -> + executeWithRetry(() -> computeApi.union(request)).thenApply( + Concat200ResponseDto::getData + ) + ); + } + + /** + * Computes the difference between the two provided terms asynchronously. + * + * @param base The base language term to subtract from. + * @param excluded The term whose language should be removed from the base. + * @return A CompletableFuture containing a computed difference term. + */ + public CompletableFuture difference(Term base, Term excluded) { + return difference(base, excluded, (OperationOptions) null); + } + + /** + * Computes the difference between the two provided terms asynchronously. + * + * @param base The base language term to subtract from. + * @param excluded The term whose language should be removed from the base. + * @param options Options for the operation. + * @return A CompletableFuture containing a computed difference term. + */ + public CompletableFuture difference( + Term base, + Term excluded, + OperationOptions options + ) { + TwoTermsRequestDto request = new TwoTermsRequestDto() + .addTermsItem(base.toDto()) + .addTermsItem(excluded.toDto()) + .options(buildOptions(options)); + return executeWithRetry(() -> computeApi.difference(request)).thenApply( + resp -> Term.fromDto(resp.getData()) + ); + } + + /** + * Computes the complement of the given term asynchronously. + * + * @param term The term to complement. + * @return A CompletableFuture containing the complemented term. + */ + public CompletableFuture complement(Term term) { + return complement(term, (OperationOptions) null); + } + + /** + * Computes the complement of the given term asynchronously. + * + * @param term The term to complement. + * @param options Options for the operation. + * @return A CompletableFuture containing the complemented term. + */ + public CompletableFuture complement( + Term term, + OperationOptions options + ) { + TermRequestDto request = new TermRequestDto() + .term(term.toDto()) + .options(buildOptions(options)); + return executeWithRetry(() -> computeApi.complement(request)).thenApply( + resp -> Term.fromDto(resp.getData()) + ); + } + + /** + * Repeats a term between a minimum and maximum number of times asynchronously. + * + * @param term The term to repeat. + * @param min The inclusive lower bound of repetitions. + * @param max The inclusive upper bound. If null, repetitions are unbounded. + * @return A CompletableFuture containing a computed repeated term. + */ + public CompletableFuture repeat(Term term, int min, Integer max) { + return repeat(term, min, max, (OperationOptions) null); + } + + /** + * Repeats a term between a minimum and maximum number of times asynchronously. + * + * @param term The term to repeat. + * @param min The inclusive lower bound of repetitions. + * @param max The inclusive upper bound. If null, repetitions are unbounded. + * @param options Options for the operation. + * @return A CompletableFuture containing a computed repeated term. + */ + public CompletableFuture repeat( + Term term, + int min, + Integer max, + OperationOptions options + ) { + RepeatRequestDto request = new RepeatRequestDto() + .term(term.toDto()) + .min(min) + .max(max) + .options(buildOptions(options)); + return executeWithRetry(() -> computeApi.repeat(request)).thenApply( + resp -> Term.fromDto(resp.getData()) + ); + } + + /** + * Computes a deterministic FAIR automaton from the given term asynchronously. + * A deterministic FAIR guarantees consistent string ordering across paginated + * generateStrings() calls. Use this when isDeterministic() is false + * before calling generateStrings() with an offset. + * + * @param term The term to determinize. + * @return A CompletableFuture containing a deterministic FAIR. + */ + public CompletableFuture determinize(Term term) { + return determinize(term, (OperationOptions) null); + } + + /** + * Computes a deterministic FAIR automaton from the given term asynchronously. + * A deterministic FAIR guarantees consistent string ordering across paginated + * generateStrings() calls. Use this when isDeterministic() is false + * before calling generateStrings() with an offset. + * + * @param term The term to determinize. + * @param options Options for the operation. + * @return A CompletableFuture containing a deterministic FAIR. + */ + public CompletableFuture determinize( + Term term, + OperationOptions options + ) { + TermRequestDto request = new TermRequestDto() + .term(term.toDto()) + .options(buildOptions(options)); + return executeWithRetry(() -> computeApi.determinize(request)).thenApply( + resp -> Term.fromDto(resp.getData()) + ); + } + + // --- GENERATE OPERATIONS --- + + /** + * Generates up to {@code limit} distinct strings matched by the term, skipping the first {@code offset} strings asynchronously. + * + * @param term The term to sample generated strings from. + * @param limit The maximum number of unique strings to return. + * @param offset Number of matched strings to skip before starting to collect the results. Used for pagination. + * @return A CompletableFuture containing a list of strings that match the term. + */ + public CompletableFuture> generateStrings( + Term term, + int limit, + int offset + ) { + return generateStrings(term, limit, offset, (OperationOptions) null); + } + + /** + * Generates up to {@code limit} distinct strings matched by the term, skipping the first {@code offset} strings asynchronously. + * + * @param term The term to sample generated strings from. + * @param limit The maximum number of unique strings to return. + * @param offset Number of matched strings to skip before starting to collect the results. Used for pagination. + * @param options Options for the operation. Pass a {@link GenerateStringsOptions} + * to control ordering, seed, length bounds and charset. + * @return A CompletableFuture containing a list of strings that match the term. + */ + public CompletableFuture> generateStrings( + Term term, + int limit, + int offset, + OperationOptions options + ) { + GenerateStringsRequestDto request = new GenerateStringsRequestDto() + .term(term.toDto()) + .limit(limit) + .offset(offset) + .options(buildOptions(options)); + + if (options instanceof GenerateStringsOptions) { + GenerateStringsOptions generateOptions = + (GenerateStringsOptions) options; + generateOptions + .getPathOrder() + .ifPresent(value -> request.pathOrder(value.toDto())); + generateOptions + .getCharacterOrder() + .ifPresent(value -> request.characterOrder(value.toDto())); + generateOptions.getSeed().ifPresent(request::seed); + generateOptions.getMinLength().ifPresent(request::minLength); + generateOptions.getMaxLength().ifPresent(request::maxLength); + generateOptions.getCharset().ifPresent(request::charset); + } + + return executeWithRetry(() -> generateApi.strings(request)).thenApply( + resp -> resp.getData().getStrings().getValue() + ); + } +} diff --git a/src/main/java/com/regexsolver/api/Cardinality.java b/src/main/java/com/regexsolver/api/Cardinality.java new file mode 100644 index 0000000..3dcb979 --- /dev/null +++ b/src/main/java/com/regexsolver/api/Cardinality.java @@ -0,0 +1,147 @@ +package com.regexsolver.api; + +import com.regexsolver.api.generated.model.CardinalityBigIntegerDto; +import com.regexsolver.api.generated.model.CardinalityDto; +import com.regexsolver.api.generated.model.CardinalityIntegerDto; +import java.util.Objects; +import java.util.Optional; + +/** Base class representing the number of unique strings matched by a term. */ +public abstract class Cardinality extends TermPropertiesMixin { + + private Cardinality() {} + + static Cardinality fromDto(CardinalityDto card) { + Object inst = card.getActualInstance(); + if (inst instanceof CardinalityIntegerDto) { + return new Cardinality.Integer( + ((CardinalityIntegerDto) inst).getValue() + ); + } else if (inst instanceof CardinalityBigIntegerDto) { + return new Cardinality.BigInteger(); + } else { + return new Cardinality.Infinite(); + } + } + + /** Indicates that the set of matched strings is finite and exactly calculable. */ + public static final class Integer extends Cardinality { + + private final long value; + + /** + * @param value The exact count of uniquely matched strings. + */ + public Integer(long value) { + this.value = value; + } + + public long getValue() { + return value; + } + + @Override + public Optional isEmpty() { + return Optional.of(value == 0); + } + + @Override + public Optional isEmptyString() { + if (this.value == 1) { + return Optional.empty(); + } + return Optional.of(false); + } + + @Override + public Optional isTotal() { + return Optional.of(false); + } + + @Override + public String toString() { + return String.format("", this.value); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Integer integer = (Integer) o; + return value == integer.value; + } + + @Override + public int hashCode() { + return Objects.hash(value); + } + } + + /** Indicates that the set of matched strings is finite but too large to be returned as a standard integer. */ + public static final class BigInteger extends Cardinality { + + @Override + public Optional isEmpty() { + return Optional.of(false); + } + + @Override + public Optional isEmptyString() { + return Optional.of(false); + } + + @Override + public Optional isTotal() { + return Optional.of(false); + } + + @Override + public String toString() { + return ""; + } + + @Override + public boolean equals(Object o) { + return o instanceof BigInteger; + } + + @Override + public int hashCode() { + return 0; + } + } + + /** Indicates that the set of matched strings is infinite. */ + public static final class Infinite extends Cardinality { + + @Override + public Optional isEmpty() { + return Optional.of(false); + } + + @Override + public Optional isEmptyString() { + return Optional.of(false); + } + + @Override + public Optional isTotal() { + return Optional.empty(); + } + + @Override + public String toString() { + return ""; + } + + @Override + public boolean equals(Object o) { + return o instanceof Infinite; + } + + @Override + public int hashCode() { + return 0; + } + } +} diff --git a/src/main/java/com/regexsolver/api/CharacterOrder.java b/src/main/java/com/regexsolver/api/CharacterOrder.java new file mode 100644 index 0000000..c4c4051 --- /dev/null +++ b/src/main/java/com/regexsolver/api/CharacterOrder.java @@ -0,0 +1,34 @@ +package com.regexsolver.api; + +import com.regexsolver.api.generated.model.GenerateStringsCharacterOrderDto; + +/** + * Order in which the strings within each path are produced when generating + * strings. Orthogonal to {@link PathOrder}: it does not change what + * can be generated, only which strings are reached first. + */ +public enum CharacterOrder { + /** + * Expand each position from the low end of its character range first — a + * stable order returning the smallest witnesses of a path first. + */ + ASCENDING, + /** + * A permutation drawn from the seed, so the strings look like real + * inputs. Random in look only — generation stays reproducible. + */ + SHUFFLED; + + GenerateStringsCharacterOrderDto toDto() { + switch (this) { + case ASCENDING: + return GenerateStringsCharacterOrderDto.ASCENDING; + case SHUFFLED: + return GenerateStringsCharacterOrderDto.SHUFFLED; + default: + throw new IllegalArgumentException( + String.format("Unsupported CharacterOrder %s.", this) + ); + } + } +} diff --git a/src/main/java/com/regexsolver/api/GenerateStringsOptions.java b/src/main/java/com/regexsolver/api/GenerateStringsOptions.java new file mode 100644 index 0000000..1d058ad --- /dev/null +++ b/src/main/java/com/regexsolver/api/GenerateStringsOptions.java @@ -0,0 +1,125 @@ +package com.regexsolver.api; + +import java.util.Optional; + +/** + * Options for generateStrings(), extending {@link OperationOptions} so it is + * accepted wherever an options object is. + */ +public final class GenerateStringsOptions extends OperationOptions { + + private PathOrder pathOrder; + private CharacterOrder characterOrder; + private Long seed; + private Integer minLength; + private Integer maxLength; + private String charset; + + public GenerateStringsOptions() {} + + public static GenerateStringsOptions builder() { + return new GenerateStringsOptions(); + } + + @Override + public GenerateStringsOptions executionTimeout(Integer timeout) { + super.executionTimeout(timeout); + return this; + } + + /** + * Order in which the paths (shapes) of the language are scheduled. + * Defaults to {@link PathOrder#SWEEP}. + * + * @param pathOrder the path order + * @return these options + */ + public GenerateStringsOptions pathOrder(PathOrder pathOrder) { + this.pathOrder = pathOrder; + return this; + } + + /** + * Order in which the strings within each path are produced. Defaults to + * {@link CharacterOrder#ASCENDING}. + * + * @param characterOrder the character order + * @return these options + */ + public GenerateStringsOptions characterOrder(CharacterOrder characterOrder) { + this.characterOrder = characterOrder; + return this; + } + + /** + * Seed behind the shuffled modes. The default seed is fixed, so two calls + * sharing a seed generate the same strings and {@code offset} pages + * through them consistently. + * + * @param seed the seed + * @return these options + */ + public GenerateStringsOptions seed(Long seed) { + this.seed = seed; + return this; + } + + /** + * Shortest string to generate. Shorter strings are left out of the + * enumeration entirely, {@code offset} never counting them. + * + * @param minLength the minimum length + * @return these options + */ + public GenerateStringsOptions minLength(Integer minLength) { + this.minLength = minLength; + return this; + } + + /** + * Longest string to generate. + * + * @param maxLength the maximum length + * @return these options + */ + public GenerateStringsOptions maxLength(Integer maxLength) { + this.maxLength = maxLength; + return this; + } + + /** + * Restricts generation to the given characters, e.g. {@code [a-z]}. Paths + * requiring a character outside it are dropped. + * + * @param charset the allowed characters + * @return these options + */ + public GenerateStringsOptions charset(String charset) { + this.charset = charset; + return this; + } + + public Optional getPathOrder() { + return Optional.ofNullable(pathOrder); + } + + public Optional getCharacterOrder() { + return Optional.ofNullable(characterOrder); + } + + public Optional getSeed() { + return Optional.ofNullable(seed); + } + + public Optional getMinLength() { + return Optional.ofNullable(minLength); + } + + public Optional getMaxLength() { + return Optional.ofNullable(maxLength); + } + + public Optional getCharset() { + return Optional.ofNullable(charset); + } +} diff --git a/src/main/java/com/regexsolver/api/Length.java b/src/main/java/com/regexsolver/api/Length.java new file mode 100644 index 0000000..4c13b2d --- /dev/null +++ b/src/main/java/com/regexsolver/api/Length.java @@ -0,0 +1,82 @@ +package com.regexsolver.api; + +import com.regexsolver.api.generated.model.LengthDto; +import java.util.Objects; +import java.util.Optional; + +/** + * Represents the minimum and maximum lengths of any string matched by the term. + */ +public final class Length extends TermPropertiesMixin { + + private final Integer min; + private final Integer max; + + public Length(Integer min, Integer max) { + this.min = min; + this.max = max; + } + + static Length fromDto(LengthDto len) { + return new Length(len.getMin(), len.getMax()); + } + + /** @return The shortest possible matched string length, or {@link java.util.Optional#empty()} if the language is empty. */ + public Optional getMin() { + return Optional.ofNullable(min); + } + + /** @return The longest possible matched string length, or {@link java.util.Optional#empty()} if the length is unbounded. */ + public Optional getMax() { + return Optional.ofNullable(max); + } + + @Override + public Optional isEmpty() { + return Optional.of(this.min == null && this.max == null); + } + + @Override + public Optional isEmptyString() { + // min/max are null for the empty language and max is null when the length + // is unbounded, so these comparisons must not unbox. + return Optional.of(isZero(this.min) && isZero(this.max)); + } + + @Override + public Optional isTotal() { + if (!isZero(this.min) || this.max != null) { + return Optional.of(false); + } else { + return Optional.empty(); + } + } + + private static boolean isZero(Integer value) { + return value != null && value.intValue() == 0; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Length length = (Length) o; + return ( + Objects.equals(min, length.min) && Objects.equals(max, length.max) + ); + } + + @Override + public int hashCode() { + return Objects.hash(min, max); + } + + @Override + public String toString() { + return String.format( + "", + min == null ? "null" : min, + max == null ? "null" : max + ); + } +} diff --git a/src/main/java/com/regexsolver/api/OperationOptions.java b/src/main/java/com/regexsolver/api/OperationOptions.java new file mode 100644 index 0000000..6f44003 --- /dev/null +++ b/src/main/java/com/regexsolver/api/OperationOptions.java @@ -0,0 +1,78 @@ +package com.regexsolver.api; + +import java.util.Optional; + +/** + * Options for RegexSolver operations. + * + *

Not every option is relevant to every operation: an option is ignored by any operation + * it does not apply to. For instance the options describing the returned term have no effect + * on an operation that does not return one. + */ +public class OperationOptions { + + private Integer executionTimeout; + private ResponseFormat responseFormat; + private Boolean deterministic; + + public OperationOptions() {} + + public OperationOptions( + Integer executionTimeout, + ResponseFormat responseFormat + ) { + this.executionTimeout = executionTimeout; + this.responseFormat = responseFormat; + } + + public static OperationOptions builder() { + return new OperationOptions(); + } + + /** + * Maximum time, in milliseconds, the engine may spend on the operation before aborting it. + * + * @param timeout the timeout in milliseconds + * @return these options + */ + public OperationOptions executionTimeout(Integer timeout) { + this.executionTimeout = timeout; + return this; + } + + /** + * Format of the term returned by the operation. + * + * @param format the requested response format + * @return these options + */ + public OperationOptions responseFormat(ResponseFormat format) { + this.responseFormat = format; + return this; + } + + /** + * When true, guarantees the returned FAIR encodes a deterministic automaton. + * Only valid with responseFormat = ResponseFormat.FAIR or when responseFormat is + * unset (in which case it defaults to ResponseFormat.FAIR). Throws otherwise. + * + * @param deterministic whether the returned FAIR must be deterministic + * @return these options + */ + public OperationOptions deterministic(Boolean deterministic) { + this.deterministic = deterministic; + return this; + } + + public Optional getExecutionTimeout() { + return Optional.ofNullable(executionTimeout); + } + + public Optional getResponseFormat() { + return Optional.ofNullable(responseFormat); + } + + public Optional getDeterministic() { + return Optional.ofNullable(deterministic); + } +} diff --git a/src/main/java/com/regexsolver/api/PathOrder.java b/src/main/java/com/regexsolver/api/PathOrder.java new file mode 100644 index 0000000..ca88a81 --- /dev/null +++ b/src/main/java/com/regexsolver/api/PathOrder.java @@ -0,0 +1,41 @@ +package com.regexsolver.api; + +import com.regexsolver.api.generated.model.GenerateStringsPathOrderDto; + +/** + * Order in which the paths of the language are scheduled when generating + * strings — the shapes the term allows, as opposed to the characters + * filling them. + */ +public enum PathOrder { + /** + * Expand one path in full, shortest first, before moving to the next one. + * The cheapest way to page through a whole language. + */ + SWEEP, + /** + * Cover every path once before any path yields a second string. Best + * suited to deriving test cases. + */ + INTERLEAVE, + /** + * Interleave with same-length paths visited in an order drawn from the + * seed. + */ + SHUFFLED; + + GenerateStringsPathOrderDto toDto() { + switch (this) { + case SWEEP: + return GenerateStringsPathOrderDto.SWEEP; + case INTERLEAVE: + return GenerateStringsPathOrderDto.INTERLEAVE; + case SHUFFLED: + return GenerateStringsPathOrderDto.SHUFFLED; + default: + throw new IllegalArgumentException( + String.format("Unsupported PathOrder %s.", this) + ); + } + } +} diff --git a/src/main/java/com/regexsolver/api/RateLimiter.java b/src/main/java/com/regexsolver/api/RateLimiter.java new file mode 100644 index 0000000..a40ff63 --- /dev/null +++ b/src/main/java/com/regexsolver/api/RateLimiter.java @@ -0,0 +1,55 @@ +package com.regexsolver.api; + +import java.time.Duration; +import java.time.Instant; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; + +/** + * Global rate limiter shared by apiToken. + * + * Holds a single deadline. {@code trigger} keeps the later of the current and + * the new deadline; {@code waitIfNecessary} schedules a non-blocking delay + * (no thread is ever parked) and re-checks the deadline after every wake, so + * a deadline extended by a concurrent 429 is honored. + */ +class RateLimiter { + + private static final ConcurrentHashMap INSTANCES = + new ConcurrentHashMap<>(); + + private final AtomicReference retryAfter = new AtomicReference<>( + Instant.MIN + ); + + private RateLimiter() {} + + public static RateLimiter getInstance(String apiToken) { + return INSTANCES.computeIfAbsent(apiToken, k -> new RateLimiter()); + } + + public CompletableFuture waitIfNecessary() { + Instant now = Instant.now(); + Instant retryAt = retryAfter.get(); + + if (!retryAt.isAfter(now)) { + return CompletableFuture.completedFuture(null); + } + long delay = Math.max(Duration.between(now, retryAt).toMillis(), 1); + return CompletableFuture.runAsync( + () -> {}, + CompletableFuture.delayedExecutor(delay, TimeUnit.MILLISECONDS) + ).thenCompose(v -> waitIfNecessary()); + } + + public void trigger(double seconds) { + Instant nextRetry = Instant.now().plus( + Duration.ofMillis((long) (seconds * 1000)) + ); + retryAfter.updateAndGet(current -> + nextRetry.isAfter(current) ? nextRetry : current + ); + } +} diff --git a/src/main/java/com/regexsolver/api/RegexSolver.java b/src/main/java/com/regexsolver/api/RegexSolver.java deleted file mode 100644 index 97e2ea7..0000000 --- a/src/main/java/com/regexsolver/api/RegexSolver.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.regexsolver.api; - -public final class RegexSolver { - public static void initialize(String token) { - RegexSolverApiWrapper.initialize(token); - } - - public static void initialize(String token, String baseUrl) { - RegexSolverApiWrapper.initialize(token, baseUrl); - } -} diff --git a/src/main/java/com/regexsolver/api/RegexSolverApiWrapper.java b/src/main/java/com/regexsolver/api/RegexSolverApiWrapper.java deleted file mode 100644 index 6f1f050..0000000 --- a/src/main/java/com/regexsolver/api/RegexSolverApiWrapper.java +++ /dev/null @@ -1,164 +0,0 @@ -package com.regexsolver.api; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.regexsolver.api.Request.GenerateStringsRequest; -import com.regexsolver.api.Request.MultiTermsRequest; -import com.regexsolver.api.Response.BooleanResponse; -import com.regexsolver.api.Response.StringsResponse; -import com.regexsolver.api.dto.Details; -import com.regexsolver.api.exception.ApiError; -import com.regexsolver.api.exception.MissingAPITokenException; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.ResponseBody; -import retrofit2.Call; -import retrofit2.Response; -import retrofit2.Retrofit; -import retrofit2.converter.jackson.JacksonConverterFactory; -import retrofit2.http.Body; -import retrofit2.http.POST; - -import java.io.IOException; -import java.util.List; -import java.util.Objects; - -final class RegexSolverApiWrapper { - private static final RegexSolverApiWrapper INSTANCE = new RegexSolverApiWrapper(); - - private final static String DEFAULT_BASE_URL = "https://api.regexsolver.com/"; - - private final static String USER_AGENT = "RegexSolver Java / 1.0.2"; - - private RegexApi api; - - public static RegexSolverApiWrapper getInstance() { - return INSTANCE; - } - - private RegexSolverApiWrapper() { - initializeInternal(null, DEFAULT_BASE_URL); - } - - static void initialize(String token) { - getInstance().initializeInternal(token, DEFAULT_BASE_URL); - } - - static void initialize(String token, String baseUrl) { - getInstance().initializeInternal(token, baseUrl); - } - - private void initializeInternal(String token, String baseUrl) { - Retrofit retrofit = new Retrofit.Builder() - .client(new OkHttpClient.Builder().addInterceptor(chain -> { - if (token == null) { - throw new MissingAPITokenException(); - } - Request newRequest = chain.request().newBuilder() - .addHeader("User-Agent", USER_AGENT) - .addHeader("Authorization", "Bearer " + token) - .build(); - return chain.proceed(newRequest); - }).build()) - .baseUrl(baseUrl) - .addConverterFactory(JacksonConverterFactory.create()) - .build(); - - api = retrofit.create(RegexApi.class); - } - - public Term computeIntersection(MultiTermsRequest multiTermsRequest) throws ApiError, IOException { - Response response = api.computeIntersection(multiTermsRequest).execute(); - if (response.isSuccessful()) { - return response.body(); - } else { - throw getApiError(response); - } - } - - public Term computeUnion(MultiTermsRequest multiTermsRequest) throws ApiError, IOException { - Response response = api.computeUnion(multiTermsRequest).execute(); - if (response.isSuccessful()) { - return response.body(); - } else { - throw getApiError(response); - } - } - - public Term computeSubtraction(MultiTermsRequest multiTermsRequest) throws ApiError, IOException { - Response response = api.computeSubtraction(multiTermsRequest).execute(); - if (response.isSuccessful()) { - return response.body(); - } else { - throw getApiError(response); - } - } - - public Details getDetails(Term term) throws ApiError, IOException { - Response

response = api.getDetails(term).execute(); - if (response.isSuccessful()) { - return response.body(); - } else { - throw getApiError(response); - } - } - - public boolean equivalence(MultiTermsRequest multiTermsRequest) throws ApiError, IOException { - Response response = api.equivalence(multiTermsRequest).execute(); - if (response.isSuccessful()) { - return response.body().value(); - } else { - throw getApiError(response); - } - } - - public boolean subset(MultiTermsRequest multiTermsRequest) throws ApiError, IOException { - Response response = api.subset(multiTermsRequest).execute(); - if (response.isSuccessful()) { - return response.body().value(); - } else { - throw getApiError(response); - } - } - - public List generateStrings(Term term, int count) throws ApiError, IOException { - GenerateStringsRequest generateStringsRequest = new GenerateStringsRequest(term, count); - Response response = api.generateStrings(generateStringsRequest).execute(); - if (response.isSuccessful()) { - return response.body().value(); - } else { - throw getApiError(response); - } - } - - private static ApiError getApiError(Response response) throws IOException { - assert !response.isSuccessful(); - try (ResponseBody errorBody = response.errorBody()) { - String json = Objects.requireNonNull(errorBody).string(); - ObjectMapper mapper = new ObjectMapper(); - return mapper.readValue(json, ApiError.class); - } - } - - private interface RegexApi { - @POST("api/compute/intersection") - Call computeIntersection(@Body MultiTermsRequest multiTermsRequest); - - @POST("api/compute/union") - Call computeUnion(@Body MultiTermsRequest multiTermsRequest); - - @POST("api/compute/subtraction") - Call computeSubtraction(@Body MultiTermsRequest multiTermsRequest); - - @POST("api/analyze/details") - Call
getDetails(@Body Term term); - - @POST("api/analyze/equivalence") - Call equivalence(@Body MultiTermsRequest multiTermsRequest); - - @POST("api/analyze/subset") - Call subset(@Body MultiTermsRequest multiTermsRequest); - - @POST("api/generate/strings") - Call generateStrings(@Body GenerateStringsRequest request); - } -} diff --git a/src/main/java/com/regexsolver/api/RegexSolverClient.java b/src/main/java/com/regexsolver/api/RegexSolverClient.java new file mode 100644 index 0000000..145cf2f --- /dev/null +++ b/src/main/java/com/regexsolver/api/RegexSolverClient.java @@ -0,0 +1,714 @@ +package com.regexsolver.api; + +import java.util.List; + +/** + * The Synchronous Client for RegexSolver. + * + * Provides blocking access to all RegexSolver API endpoints. + */ +public final class RegexSolverClient { + + private final AsyncRegexSolverClient asyncClient; + + private RegexSolverClient(Builder builder) { + this.asyncClient = builder.asyncBuilder.build(); + } + + public static Builder builder() { + return new Builder(); + } + + public static final class Builder { + + private final AsyncRegexSolverClient.Builder asyncBuilder = + AsyncRegexSolverClient.builder(); + + public Builder apiToken(String apiToken) { + asyncBuilder.apiToken(apiToken); + return this; + } + + public Builder baseUrl(String baseUrl) { + asyncBuilder.baseUrl(baseUrl); + return this; + } + + /** + * When true (the default), calls to concat/intersection/union + * carrying more terms than the account's per-request limit are + * transparently split into several requests and folded back into one + * result. Each constituent request counts against the monthly quota. + * + * @param autoBatch whether to enable auto-batching + * @return this builder + */ + public Builder autoBatch(boolean autoBatch) { + asyncBuilder.autoBatch(autoBatch); + return this; + } + + /** + * Upper bound (>= 2) on the number of terms sent in a single + * request, overriding the limit fetched from the API when smaller. + * + * @param maxTermsPerRequest the cap, or null to use the account limit + * @return this builder + */ + public Builder maxTermsPerRequest(Integer maxTermsPerRequest) { + asyncBuilder.maxTermsPerRequest(maxTermsPerRequest); + return this; + } + + public RegexSolverClient build() { + return new RegexSolverClient(this); + } + } + + // --- ACCOUNT OPERATIONS --- + + /** + * Fetches the plan limits applying to the account. + * + * The call never consumes request quota (it is only rate-limited) and the + * result is cached on the client, so calling it again is free. The cached + * maxTermsCount also drives auto-batching. + * + * @return The five plan limits. + */ + public AccountLimits getAccountLimits() { + try { + return asyncClient.getAccountLimits().join(); + } catch (java.util.concurrent.CompletionException e) { + if (e.getCause() instanceof RuntimeException) { + throw (RuntimeException) e.getCause(); + } + + throw e; + } + } + + // --- ANALYZE OPERATIONS --- + + /** + * Computes how many unique strings the term matches. + * + * @param term The term to analyze. + * @return Cardinality object representing either an exact Integer, a BigInteger, or Infinite cardinality. + */ + public Cardinality getCardinality(Term term) { + return getCardinality(term, (OperationOptions) null); + } + + /** + * Computes how many unique strings the term matches. + * + * @param term The term to analyze. + * @param options Options for the operation. + * @return Cardinality object representing either an exact Integer, a BigInteger, or Infinite cardinality. + */ + public Cardinality getCardinality(Term term, OperationOptions options) { + try { + return asyncClient.getCardinality(term, options).join(); + } catch (java.util.concurrent.CompletionException e) { + if (e.getCause() instanceof RuntimeException) { + throw (RuntimeException) e.getCause(); + } + + throw e; + } + } + + /** + * Computes the minimum and maximum length of strings matched by the term. + * + * @param term The term to analyze. + * @return Length object with `min` and `max` integers. Limits are null if unbounded or undefined. + */ + public Length getLength(Term term) { + return getLength(term, (OperationOptions) null); + } + + /** + * Computes the minimum and maximum length of strings matched by the term. + * + * @param term The term to analyze. + * @param options Options for the operation. + * @return Length object with `min` and `max` integers. Limits are null if unbounded or undefined. + */ + public Length getLength(Term term, OperationOptions options) { + try { + return asyncClient.getLength(term, options).join(); + } catch (java.util.concurrent.CompletionException e) { + if (e.getCause() instanceof RuntimeException) { + throw (RuntimeException) e.getCause(); + } + + throw e; + } + } + + /** + * Checks if the term matches no strings at all. + * + * @param term The term to analyze. + * @return true if the language is completely empty, false otherwise. + */ + public boolean isEmpty(Term term) { + return isEmpty(term, (OperationOptions) null); + } + + /** + * Checks if the term matches no strings at all. + * + * @param term The term to analyze. + * @param options Options for the operation. + * @return true if the language is completely empty, false otherwise. + */ + public boolean isEmpty(Term term, OperationOptions options) { + try { + return asyncClient.isEmpty(term, options).join(); + } catch (java.util.concurrent.CompletionException e) { + if (e.getCause() instanceof RuntimeException) { + throw (RuntimeException) e.getCause(); + } + + throw e; + } + } + + /** + * Checks if the term matches only the empty string. + * + * @param term The term to analyze. + * @return true if the term strictly matches the empty string ("") and nothing else. + */ + public boolean isEmptyString(Term term) { + return isEmptyString(term, (OperationOptions) null); + } + + /** + * Checks if the term matches only the empty string. + * + * @param term The term to analyze. + * @param options Options for the operation. + * @return true if the term strictly matches the empty string ("") and nothing else. + */ + public boolean isEmptyString(Term term, OperationOptions options) { + try { + return asyncClient.isEmptyString(term, options).join(); + } catch (java.util.concurrent.CompletionException e) { + if (e.getCause() instanceof RuntimeException) { + throw (RuntimeException) e.getCause(); + } + + throw e; + } + } + + /** + * Checks if the term matches all possible strings. + * + * @param term The term to analyze. + * @return true if the term matches every possible string. + */ + public boolean isTotal(Term term) { + return isTotal(term, (OperationOptions) null); + } + + /** + * Checks if the term matches all possible strings. + * + * @param term The term to analyze. + * @param options Options for the operation. + * @return true if the term matches every possible string. + */ + public boolean isTotal(Term term, OperationOptions options) { + try { + return asyncClient.isTotal(term, options).join(); + } catch (java.util.concurrent.CompletionException e) { + if (e.getCause() instanceof RuntimeException) { + throw (RuntimeException) e.getCause(); + } + + throw e; + } + } + + /** + * Checks if the term's automaton is deterministic. + * Only a deterministic FAIR guarantees consistent string ordering across paginated generateStrings() calls; call determinize() first if this is false. + * + * @param term The term to analyze. + * @return true if the term's automaton is deterministic. + */ + public boolean isDeterministic(Term term) { + return isDeterministic(term, (OperationOptions) null); + } + + /** + * Checks if the term's automaton is deterministic. + * Only a deterministic FAIR guarantees consistent string ordering across paginated generateStrings() calls; call determinize() first if this is false. + * + * @param term The term to analyze. + * @param options Options for the operation. + * @return true if the term's automaton is deterministic. + */ + public boolean isDeterministic(Term term, OperationOptions options) { + try { + return asyncClient.isDeterministic(term, options).join(); + } catch (java.util.concurrent.CompletionException e) { + if (e.getCause() instanceof RuntimeException) { + throw (RuntimeException) e.getCause(); + } + + throw e; + } + } + + /** + * Returns a regular expression pattern that represents the term. + * + * @param term The term to extract the pattern from. + * @return A valid regular expression string representing the language. + */ + public String getPattern(Term term) { + return getPattern(term, (OperationOptions) null); + } + + /** + * Returns a regular expression pattern that represents the term. + * + * @param term The term to extract the pattern from. + * @param options Options for the operation. + * @return A valid regular expression string representing the language. + */ + public String getPattern(Term term, OperationOptions options) { + try { + return asyncClient.getPattern(term, options).join(); + } catch (java.util.concurrent.CompletionException e) { + if (e.getCause() instanceof RuntimeException) { + throw (RuntimeException) e.getCause(); + } + + throw e; + } + } + + /** + * Builds a Graphviz DOT representation of the term's automaton. + * + * @param term The term to visualize. + * @return The raw DOT syntax for Graphviz compilation. + */ + public String getDot(Term term) { + return getDot(term, (OperationOptions) null); + } + + /** + * Builds a Graphviz DOT representation of the term's automaton. + * + * @param term The term to visualize. + * @param options Options for the operation. + * @return The raw DOT syntax for Graphviz compilation. + */ + public String getDot(Term term, OperationOptions options) { + try { + return asyncClient.getDot(term, options).join(); + } catch (java.util.concurrent.CompletionException e) { + if (e.getCause() instanceof RuntimeException) { + throw (RuntimeException) e.getCause(); + } + + throw e; + } + } + + /** + * Checks if the two terms accept exactly the same language. + * + * @param term1 The first term. + * @param term2 The second term to compare against. + * @return true if they are entirely equivalent, false otherwise. + */ + public boolean equivalent(Term term1, Term term2) { + return equivalent(term1, term2, (OperationOptions) null); + } + + /** + * Checks if the two terms accept exactly the same language. + * + * @param term1 The first term. + * @param term2 The second term to compare against. + * @param options Options for the operation. + * @return true if they are entirely equivalent, false otherwise. + */ + public boolean equivalent( + Term term1, + Term term2, + OperationOptions options + ) { + try { + return asyncClient.equivalent(term1, term2, options).join(); + } catch (java.util.concurrent.CompletionException e) { + if (e.getCause() instanceof RuntimeException) { + throw (RuntimeException) e.getCause(); + } + + throw e; + } + } + + /** + * Checks if the first term's language is a subset of the second term's language. + * + * @param subset The term to test as the subset. + * @param superset The term representing the entire set space. + * @return true if every string matched by subset is also matched by superset. + */ + public boolean subset(Term subset, Term superset) { + return subset(subset, superset, (OperationOptions) null); + } + + /** + * Checks if the first term's language is a subset of the second term's language. + * + * @param subset The term to test as the subset. + * @param superset The term representing the entire set space. + * @param options Options for the operation. + * @return true if every string matched by subset is also matched by superset. + */ + public boolean subset( + Term subset, + Term superset, + OperationOptions options + ) { + try { + return asyncClient.subset(subset, superset, options).join(); + } catch (java.util.concurrent.CompletionException e) { + if (e.getCause() instanceof RuntimeException) { + throw (RuntimeException) e.getCause(); + } + + throw e; + } + } + + // --- COMPUTE OPERATIONS --- + + /** + * Concatenates the given terms sequentially. + * + * @param terms Variadic terms to concatenate in order. + * @return A newly computed concatenated term. + */ + public Term concat(Term... terms) { + try { + return asyncClient.concat(terms).join(); + } catch (java.util.concurrent.CompletionException e) { + if (e.getCause() instanceof RuntimeException) { + throw (RuntimeException) e.getCause(); + } + + throw e; + } + } + + /** + * Concatenates the given terms sequentially. + * + * @param terms A list of terms to concatenate in order. + * @return A newly computed concatenated term. + */ + public Term concat(List terms) { + return concat(terms, (OperationOptions) null); + } + + /** + * Concatenates the given terms sequentially, allowing for options specification. + * + * @param terms A list of terms to concatenate in order. + * @param options Options for the operation. + * @return A newly computed concatenated term. + */ + public Term concat(List terms, OperationOptions options) { + try { + return asyncClient.concat(terms, options).join(); + } catch (java.util.concurrent.CompletionException e) { + if (e.getCause() instanceof RuntimeException) { + throw (RuntimeException) e.getCause(); + } + + throw e; + } + } + + /** + * Computes the intersection of the given terms. + * + * @param terms Variadic terms to intersect. + * @return A term representing only strings matched by ALL provided terms. + */ + public Term intersection(Term... terms) { + try { + return asyncClient.intersection(terms).join(); + } catch (java.util.concurrent.CompletionException e) { + if (e.getCause() instanceof RuntimeException) { + throw (RuntimeException) e.getCause(); + } + + throw e; + } + } + + /** + * Computes the intersection of the given terms. + * + * @param terms A list of terms to intersect. + * @return A term representing only strings matched by ALL provided terms. + */ + public Term intersection(List terms) { + return intersection(terms, (OperationOptions) null); + } + + /** + * Computes the intersection of the given terms, allowing for options specification. + * + * @param terms A list of terms to intersect. + * @param options Options for the operation. + * @return A term representing only strings matched by ALL provided terms. + */ + public Term intersection(List terms, OperationOptions options) { + try { + return asyncClient.intersection(terms, options).join(); + } catch (java.util.concurrent.CompletionException e) { + if (e.getCause() instanceof RuntimeException) { + throw (RuntimeException) e.getCause(); + } + + throw e; + } + } + + /** + * Computes the union of the given terms. + * + * @param terms Variadic terms to combine. + * @return A term representing strings matched by ANY of the provided terms. + */ + public Term union(Term... terms) { + try { + return asyncClient.union(terms).join(); + } catch (java.util.concurrent.CompletionException e) { + if (e.getCause() instanceof RuntimeException) { + throw (RuntimeException) e.getCause(); + } + + throw e; + } + } + + /** + * Computes the union of the given terms. + * + * @param terms A list of terms to combine. + * @return A term representing strings matched by ANY of the provided terms. + */ + public Term union(List terms) { + return union(terms, (OperationOptions) null); + } + + /** + * Computes the union of the given terms, allowing for options specification. + * + * @param terms A list of terms to combine. + * @param options Options for the operation. + * @return A term representing strings matched by ANY of the provided terms. + */ + public Term union(List terms, OperationOptions options) { + try { + return asyncClient.union(terms, options).join(); + } catch (java.util.concurrent.CompletionException e) { + if (e.getCause() instanceof RuntimeException) { + throw (RuntimeException) e.getCause(); + } + + throw e; + } + } + + /** + * Computes the difference between the two provided terms. + * + * @param base The base language term to subtract from. + * @param excluded The term whose language should be removed from the base. + * @return A computed difference term. + */ + public Term difference(Term base, Term excluded) { + return difference(base, excluded, (OperationOptions) null); + } + + /** + * Computes the difference between the two provided terms. + * + * @param base The base language term to subtract from. + * @param excluded The term whose language should be removed from the base. + * @param options Options for the operation. + * @return A computed difference term. + */ + public Term difference(Term base, Term excluded, OperationOptions options) { + try { + return asyncClient.difference(base, excluded, options).join(); + } catch (java.util.concurrent.CompletionException e) { + if (e.getCause() instanceof RuntimeException) { + throw (RuntimeException) e.getCause(); + } + + throw e; + } + } + + /** + * Computes the complement of the given term. + * + * @param term The term to complement. + * @return The complemented term. + */ + public Term complement(Term term) { + return complement(term, (OperationOptions) null); + } + + /** + * Computes the complement of the given term. + * + * @param term The term to complement. + * @param options Options for the operation. + * @return The complemented term. + */ + public Term complement(Term term, OperationOptions options) { + try { + return asyncClient.complement(term, options).join(); + } catch (java.util.concurrent.CompletionException e) { + if (e.getCause() instanceof RuntimeException) { + throw (RuntimeException) e.getCause(); + } + + throw e; + } + } + + /** + * Repeats a term between a minimum and maximum number of times. + * + * @param term The term to repeat. + * @param min The inclusive lower bound of repetitions. + * @param max The inclusive upper bound. If null, repetitions are unbounded. + * @return A computed repeated term. + */ + public Term repeat(Term term, int min, Integer max) { + return repeat(term, min, max, (OperationOptions) null); + } + + /** + * Repeats a term between a minimum and maximum number of times. + * + * @param term The term to repeat. + * @param min The inclusive lower bound of repetitions. + * @param max The inclusive upper bound. If null, repetitions are unbounded. + * @param options Options for the operation. + * @return A computed repeated term. + */ + public Term repeat( + Term term, + int min, + Integer max, + OperationOptions options + ) { + try { + return asyncClient.repeat(term, min, max, options).join(); + } catch (java.util.concurrent.CompletionException e) { + if (e.getCause() instanceof RuntimeException) { + throw (RuntimeException) e.getCause(); + } + + throw e; + } + } + + /** + * Computes a deterministic FAIR automaton from the given term. + * A deterministic FAIR guarantees consistent string ordering across paginated + * generateStrings() calls. Use this when isDeterministic() is false + * before calling generateStrings() with an offset. + * + * @param term The term to determinize. + * @return A deterministic FAIR. + */ + public Term determinize(Term term) { + return determinize(term, (OperationOptions) null); + } + + /** + * Computes a deterministic FAIR automaton from the given term. + * A deterministic FAIR guarantees consistent string ordering across paginated + * generateStrings() calls. Use this when isDeterministic() is false + * before calling generateStrings() with an offset. + * + * @param term The term to determinize. + * @param options Options for the operation. + * @return A deterministic FAIR. + */ + public Term determinize(Term term, OperationOptions options) { + try { + return asyncClient.determinize(term, options).join(); + } catch (java.util.concurrent.CompletionException e) { + if (e.getCause() instanceof RuntimeException) { + throw (RuntimeException) e.getCause(); + } + + throw e; + } + } + + // --- GENERATE OPERATIONS --- + + /** + * Generates up to {@code limit} distinct strings matched by the term, skipping the first {@code offset} strings. + * + * @param term The term to sample generated strings from. + * @param limit The maximum number of unique strings to return. + * @param offset Number of matched strings to skip before starting to collect the results. Used for pagination. + * @return A list of strings that match the term. + */ + public List generateStrings(Term term, int limit, int offset) { + return generateStrings(term, limit, offset, (OperationOptions) null); + } + + /** + * Generates up to {@code limit} distinct strings matched by the term, skipping the first {@code offset} strings. + * + * @param term The term to sample generated strings from. + * @param limit The maximum number of unique strings to return. + * @param offset Number of matched strings to skip before starting to collect the results. Used for pagination. + * @param options Options for the operation. + * @return A list of strings that match the term. + */ + public List generateStrings( + Term term, + int limit, + int offset, + OperationOptions options + ) { + try { + return asyncClient + .generateStrings(term, limit, offset, options) + .join(); + } catch (java.util.concurrent.CompletionException e) { + if (e.getCause() instanceof RuntimeException) { + throw (RuntimeException) e.getCause(); + } + + throw e; + } + } +} diff --git a/src/main/java/com/regexsolver/api/Request.java b/src/main/java/com/regexsolver/api/Request.java deleted file mode 100644 index cdd3a71..0000000 --- a/src/main/java/com/regexsolver/api/Request.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.regexsolver.api; - -import com.fasterxml.jackson.annotation.JsonProperty; - -import java.util.List; - -final class Request { - - public static final class MultiTermsRequest { - private final List terms; - - public MultiTermsRequest(@JsonProperty("terms") List terms) { - this.terms = terms; - } - - public List getTerms() { - return terms; - } - } - - public static final class GenerateStringsRequest { - private final Term term; - private final int count; - - public GenerateStringsRequest( - @JsonProperty("term") Term term, - @JsonProperty("count") int count - ) { - this.term = term; - this.count = count; - } - - public Term getTerm() { - return term; - } - - public int getCount() { - return count; - } - } -} diff --git a/src/main/java/com/regexsolver/api/Response.java b/src/main/java/com/regexsolver/api/Response.java deleted file mode 100644 index 5675052..0000000 --- a/src/main/java/com/regexsolver/api/Response.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.regexsolver.api; - -import com.fasterxml.jackson.annotation.JsonProperty; - -import java.util.List; - -final class Response { - public static final class BooleanResponse implements ResponseContent { - private final boolean value; - - public BooleanResponse(@JsonProperty("value") boolean value) { - this.value = value; - } - - public boolean value() { - return value; - } - } - - public static final class StringsResponse implements ResponseContent { - private final List value; - - public StringsResponse(@JsonProperty("value") List value) { - this.value = value; - } - - public List value() { - return value; - } - } -} diff --git a/src/main/java/com/regexsolver/api/ResponseContent.java b/src/main/java/com/regexsolver/api/ResponseContent.java deleted file mode 100644 index a7ff289..0000000 --- a/src/main/java/com/regexsolver/api/ResponseContent.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.regexsolver.api; - -import com.fasterxml.jackson.annotation.JsonSubTypes; -import com.fasterxml.jackson.annotation.JsonTypeInfo; -import com.regexsolver.api.Response.BooleanResponse; -import com.regexsolver.api.Response.StringsResponse; -import com.regexsolver.api.dto.Details; - -@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type") -@JsonSubTypes({ - @JsonSubTypes.Type(value = Term.Fair.class, name = "fair"), - @JsonSubTypes.Type(value = Term.Regex.class, name = "regex"), - @JsonSubTypes.Type(value = Details.class, name = "details"), - @JsonSubTypes.Type(value = StringsResponse.class, name = "strings"), - @JsonSubTypes.Type(value = BooleanResponse.class, name = "boolean"), -}) -public interface ResponseContent { -} diff --git a/src/main/java/com/regexsolver/api/ResponseFormat.java b/src/main/java/com/regexsolver/api/ResponseFormat.java new file mode 100644 index 0000000..5e189d5 --- /dev/null +++ b/src/main/java/com/regexsolver/api/ResponseFormat.java @@ -0,0 +1,27 @@ +package com.regexsolver.api; + +import com.regexsolver.api.generated.model.ResponseOptionsDto.FormatEnum; + +/** + * Used in compute operations to specify the format of the result. + */ +public enum ResponseFormat { + ANY, + REGEX, + FAIR; + + FormatEnum toDto() { + switch (this) { + case ANY: + return FormatEnum.ANY; + case REGEX: + return FormatEnum.REGEX; + case FAIR: + return FormatEnum.FAIR; + default: + throw new IllegalArgumentException( + String.format("Unsupported ResponseFormat %s.", this) + ); + } + } +} diff --git a/src/main/java/com/regexsolver/api/Term.java b/src/main/java/com/regexsolver/api/Term.java index 3673670..d8de403 100644 --- a/src/main/java/com/regexsolver/api/Term.java +++ b/src/main/java/com/regexsolver/api/Term.java @@ -1,217 +1,180 @@ package com.regexsolver.api; -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.regexsolver.api.Request.MultiTermsRequest; -import com.regexsolver.api.dto.Details; -import com.regexsolver.api.exception.ApiError; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; +import com.regexsolver.api.generated.model.TermDto; +import com.regexsolver.api.generated.model.TermFairDto; +import com.regexsolver.api.generated.model.TermFairMetadataDto; +import com.regexsolver.api.generated.model.TermRegexDto; import java.util.Objects; import java.util.Optional; +import java.util.regex.Pattern; /** - * This abstract class represents a term on which it is possible to perform operations. + * Represents a mathematical term (Regex or FAIR) on which operations can be performed. */ -public abstract class Term implements ResponseContent { - @JsonIgnore - private final static String REGEX_PREFIX = "regex"; - @JsonIgnore - private final static String FAIR_PREFIX = "fair"; - @JsonIgnore - private final static String UNKNOWN_PREFIX = "unknown"; +public abstract class Term { + + /** How the engine renders a language that matches no string at all. */ + private static final String EMPTY_LANGUAGE_PATTERN = "[]"; private final String value; - @JsonIgnore - private transient String serialized = null; + // Shared Cache (Internal) + private Cardinality cardinality; + private Length length; + private Boolean empty; + private Boolean emptyString; + private Boolean total; + protected String pattern; + private String dot; - @JsonIgnore - private transient Details details; + private Pattern compiledRegex; - /** - * Create a new instance. - * - * @param value The value of the term. - */ protected Term(String value) { this.value = value; } - /** - * Create a new instance of {@link Term.Regex}. - * - * @param regex The regular expression pattern. - * @return The created instance. - */ - public static Term.Regex regex(String regex) { - return new Term.Regex(regex); + public abstract Optional getPattern(); + + public abstract Optional getFair(); + + abstract TermDto toDto(); + + public static Term regex(String pattern) { + return new RegexTerm(pattern); } - /** - * Create a new instance of {@link Term.Fair}. - * - * @param fair The FAIR. - * @return The created instance. - */ - public static Term.Fair fair(String fair) { - return new Term.Fair(fair); + public static Term fair(String payload) { + return new FairTerm(payload, Optional.empty()); } - String getValue() { + // --- Shared Behavior --- + + public String getValue() { return value; } + void setPropertiesMixin(TermPropertiesMixin propertiesMixin) { + propertiesMixin.isEmpty().ifPresent(this::setCachedEmpty); + propertiesMixin.isEmptyString().ifPresent(this::setCachedEmptyString); + propertiesMixin.isTotal().ifPresent(this::setCachedTotal); + } + /** - * Get the details of this term. - * Cache the result to avoid calling the API again if this method is called multiple times. - * - * @return The details of this term. - * @throws IOException In case of issues requesting the API server. - * @throws ApiError In case of error returned by the API. + * Client-side matching implementation. + * @param str The string to test against the term. + * @return True if matches, false if not. Throws if pattern is not set. */ - @JsonIgnore - public Details getDetails() throws IOException, ApiError { - if (details != null) { - return details; + public boolean matches(String str) { + Optional patternOpt = getPattern(); + if (patternOpt.isEmpty()) { + throw new IllegalStateException( + "The regex pattern of this term is not defined yet, call getPattern() on the client to set it." + ); + } + + // The engine renders the empty language as "[]", which java.util.regex + // rejects. By definition it matches nothing. + if (EMPTY_LANGUAGE_PATTERN.equals(patternOpt.get())) { + return false; } - details = RegexSolverApiWrapper.getInstance().getDetails(this); - return details; + + if (compiledRegex == null) { + compiledRegex = Pattern.compile(patternOpt.get(), Pattern.DOTALL); + } + + return compiledRegex.matcher(str).matches(); } - /** - * Generate the given number of unique strings matched by this term. - * - * @param count The number of unique strings to generate. - * @return A list of unique strings matched by this term. - * @throws IOException In case of issues requesting the API server. - * @throws ApiError In case of error returned by the API. - */ - @JsonIgnore - public List generateStrings(int count) throws IOException, ApiError { - return RegexSolverApiWrapper.getInstance().generateStrings(this, count); + public abstract String serialize(); + + public static Optional deserialize(String serialized) { + if (serialized == null || !serialized.contains("=")) { + return Optional.empty(); + } + + int index = serialized.indexOf("="); + String typeStr = serialized.substring(0, index); + String val = serialized.substring(index + 1); + + if ("regex".equalsIgnoreCase(typeStr)) { + return Optional.of(regex(val)); + } else if ("fair".equalsIgnoreCase(typeStr)) { + return Optional.of(fair(val)); + } + return Optional.empty(); } - @JsonIgnore - private List getArgs(Term... terms) { - ArrayList args = new ArrayList<>(); - args.add(this); - args.addAll(List.of(terms)); - return args; + static Term fromDto(TermDto dto) { + Object instance = dto.getActualInstance(); + if (instance instanceof TermRegexDto) { + return Term.regex(((TermRegexDto) instance).getValue()); + } + TermFairDto fairDto = (TermFairDto) instance; + // Keep metadata.deterministic so isDeterministic() does not need a second + // round trip for a FAIR the server already told us about. + Optional deterministic = Optional.ofNullable(fairDto.getMetadata()) + .map(TermFairMetadataDto::getDeterministic); + return new FairTerm(fairDto.getValue(), deterministic); } - /** - * Compute the intersection with the given terms and return the resulting term. - * - * @param terms The terms to compute an intersection with. - * @return The resulting term - * @throws IOException In case of issues requesting the API server. - * @throws ApiError In case of error returned by the API. - */ - @JsonIgnore - public Term intersection(Term... terms) throws IOException, ApiError { - return RegexSolverApiWrapper.getInstance() - .computeIntersection(new MultiTermsRequest(getArgs(terms))); + // --- Shared Getters/Setters --- + + Cardinality getCachedCardinality() { + return cardinality; } - /** - * Compute the union with the given terms and return the resulting term. - * - * @param terms The terms to compute a union with. - * @return The resulting term - * @throws IOException In case of issues requesting the API server. - * @throws ApiError In case of error returned by the API. - */ - @JsonIgnore - public Term union(Term... terms) throws IOException, ApiError { - return RegexSolverApiWrapper.getInstance() - .computeUnion(new MultiTermsRequest(getArgs(terms))); + void setCachedCardinality(Cardinality cardinality) { + setPropertiesMixin(cardinality); + this.cardinality = cardinality; } - /** - * Compute the subtraction with the given term and return the resulting term. - * - * @param term The term to subtract. - * @return The resulting term - * @throws IOException In case of issues requesting the API server. - * @throws ApiError In case of error returned by the API. - */ - @JsonIgnore - public Term subtraction(Term term) throws IOException, ApiError { - return RegexSolverApiWrapper.getInstance() - .computeSubtraction(new MultiTermsRequest(getArgs(term))); + Length getCachedLength() { + return length; } - /** - * Check equivalence with the given term. - * - * @param term The term to check equivalence with. - * @return true if the terms are equivalent, false otherwise. - * @throws IOException In case of issues requesting the API server. - * @throws ApiError In case of error returned by the API. - */ - @JsonIgnore - public boolean isEquivalentTo(Term term) throws IOException, ApiError { - return RegexSolverApiWrapper.getInstance() - .equivalence(new MultiTermsRequest(getArgs(term))); + void setCachedLength(Length length) { + setPropertiesMixin(length); + this.length = length; } - /** - * Check if is a subset of the given term. - * - * @param term The term to check if is the superset of this. - * @return true if this is a subset, false otherwise. - * @throws IOException In case of issues requesting the API server. - * @throws ApiError In case of error returned by the API. - */ - @JsonIgnore - public boolean isSubsetOf(Term term) throws IOException, ApiError { - return RegexSolverApiWrapper.getInstance() - .subset(new MultiTermsRequest(getArgs(term))); + Boolean getCachedEmpty() { + return empty; } - /** - * Generate a string representation that can be parsed by {@link #deserialize(String)}. - * - * @return A string representation of this term. - */ - public String serialize() { - if (serialized != null) { - return serialized; - } - String prefix; - if (this instanceof Regex) { - prefix = REGEX_PREFIX; - } else if (this instanceof Fair) { - prefix = FAIR_PREFIX; - } else { - prefix = UNKNOWN_PREFIX; - } - serialized = String.format("%s=%s", prefix, value); - return serialized; + void setCachedEmpty(Boolean empty) { + this.empty = empty; } - /** - * Parse a string representation of a {@link Term} produced by {@link #serialize()}. - * - * @param string A string representation produced by {@link #serialize()}. - * @return The parsed term, or empty if the method was not able to parse. - */ - @JsonIgnore - public static Optional deserialize(String string) { - if (string == null) { - return Optional.empty(); - } + Boolean getCachedEmptyString() { + return emptyString; + } - if (string.startsWith(REGEX_PREFIX)) { - return Optional.of(regex(string.substring(REGEX_PREFIX.length() + 1))); - } else if (string.startsWith(FAIR_PREFIX)) { - return Optional.of(fair(string.substring(FAIR_PREFIX.length() + 1))); - } else { - return Optional.empty(); - } + void setCachedEmptyString(Boolean emptyString) { + this.emptyString = emptyString; + } + + Boolean getCachedTotal() { + return total; + } + + void setCachedTotal(Boolean total) { + this.total = total; + } + + void setCachedPattern(String pattern) { + this.pattern = pattern; + } + + String getCachedPattern() { + return this.pattern; + } + + String getCachedDot() { + return dot; + } + + void setCachedDot(String dot) { + this.dot = dot; } @Override @@ -219,12 +182,12 @@ public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Term term = (Term) o; - return Objects.equals(term.serialize(), serialize()); + return Objects.equals(serialize(), term.serialize()); } @Override public int hashCode() { - return Objects.hash(serialize()); + return serialize().hashCode(); } @Override @@ -232,58 +195,82 @@ public String toString() { return serialize(); } - /** - * This term represents a Fast Automaton Internal Representation (FAIR). - *

- * You can learn more about FAIR in our documentation. - *

- */ - public static final class Fair extends Term { - /** - * Create a new instance. - * - * @param fair The FAIR. - */ - public Fair(@JsonProperty("value") String fair) { - super(fair); + public static final class RegexTerm extends Term { + + RegexTerm(String value) { + super(value); } - /** - * Return the Fast Automaton Internal Representation (FAIR). - * - * @return The FAIR. - */ - @JsonProperty("value") - public String getFair() { - return getValue(); + @Override + public Optional getPattern() { + return Optional.of(getValue()); + } + + @Override + public Optional getFair() { + return Optional.empty(); + } + + @Override + TermDto toDto() { + return new TermDto( + new TermRegexDto() + .type(TermRegexDto.TypeEnum.REGEX) + .value(getValue()) + ); + } + + @Override + public String serialize() { + return "regex=" + getValue(); } } + public static final class FairTerm extends Term { - /** - * This term represents a regular expression. - *

- * You can learn more about regular expression in our documentation - *

- */ - public static final class Regex extends Term { - /** - * Create a new instance. - * - * @param regex The regular expression pattern. - */ - public Regex(@JsonProperty("value") String regex) { - super(regex); + private Optional deterministic = Optional.empty(); + + FairTerm(String value, Optional deterministic) { + super(value); + this.deterministic = deterministic; } /** - * Return the regular expression pattern. + * Whether this FAIR encodes a deterministic automaton, or + * {@link java.util.Optional#empty()} if it is not known yet. * - * @return The regular expression pattern. + * @return the cached determinism flag, if known */ - @JsonProperty("value") - public String getPattern() { - return getValue(); + public Optional getCachedDeterministic() { + return this.deterministic; + } + + void setCachedDeterministic(Optional deterministic) { + this.deterministic = deterministic; + } + + @Override + public Optional getPattern() { + return Optional.ofNullable(this.pattern); + } + + @Override + public Optional getFair() { + return Optional.of(getValue()); + } + + @Override + TermDto toDto() { + return new TermDto( + new TermFairDto() + .type(TermFairDto.TypeEnum.FAIR) + .value(getValue()) + ); + } + + @Override + public String serialize() { + return "fair=" + getValue(); } } } diff --git a/src/main/java/com/regexsolver/api/TermPropertiesMixin.java b/src/main/java/com/regexsolver/api/TermPropertiesMixin.java new file mode 100644 index 0000000..a3db3cd --- /dev/null +++ b/src/main/java/com/regexsolver/api/TermPropertiesMixin.java @@ -0,0 +1,41 @@ +package com.regexsolver.api; + +import java.util.Optional; + +/** + * A mixin providing default property inference for Term analytics. + * + * Returns {@code Optional.empty()} when a property cannot be strictly inferred from the current data alone. + */ +abstract class TermPropertiesMixin { + + /** + * Infers whether the term matches no strings at all. + * + * @return An {@code Optional} containing {@code true} if it definitely matches no strings, + * {@code false} if it matches at least one, or {@code Optional.empty()} if it cannot be inferred. + */ + public Optional isEmpty() { + return Optional.empty(); + } + + /** + * Infers whether the term matches strictly the empty string (""). + * + * @return An {@code Optional} containing {@code true} if it definitely matches only the empty string, + * {@code false} if it matches other strings, or {@code Optional.empty()} if it cannot be inferred. + */ + public Optional isEmptyString() { + return Optional.empty(); + } + + /** + * Infers whether the term matches all possible strings. + * + * @return An {@code Optional} containing {@code true} if it definitely matches all strings, + * {@code false} if it misses at least one string, or {@code Optional.empty()} if it cannot be inferred. + */ + public Optional isTotal() { + return Optional.empty(); + } +} diff --git a/src/main/java/com/regexsolver/api/dto/Cardinality.java b/src/main/java/com/regexsolver/api/dto/Cardinality.java deleted file mode 100644 index f62261b..0000000 --- a/src/main/java/com/regexsolver/api/dto/Cardinality.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.regexsolver.api.dto; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonSubTypes; -import com.fasterxml.jackson.annotation.JsonTypeInfo; - -/** - * Abstract class that represent the number of possible values. - */ -@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type") -@JsonSubTypes({ - @JsonSubTypes.Type(value = Cardinality.BigInteger.class, name = "BigInteger"), - @JsonSubTypes.Type(value = Cardinality.Infinite.class, name = "Infinite"), - @JsonSubTypes.Type(value = Cardinality.Integer.class, name = "Integer") -}) -public abstract class Cardinality { - /** - * @return true if it has a finite number of values, false otherwise. - */ - public abstract boolean isFinite(); - - public abstract String toString(); - - /** - * An infinite number of possible values. - */ - public static final class Infinite extends Cardinality { - @Override - public boolean isFinite() { - return false; - } - - @Override - public String toString() { - return "Infinite"; - } - } - - /** - * A finite number of possible values, but the number is too big to be computed. - */ - public static final class BigInteger extends Cardinality { - @Override - public boolean isFinite() { - return true; - } - - @Override - public String toString() { - return "BigInteger"; - } - } - - /** - * A finite number of possible values, available in {@link #getCount()}. - */ - public static final class Integer extends Cardinality { - private final long count; - - /** - * Create a new instance. - * - * @param count The number of possible values. - */ - public Integer(@JsonProperty("value") long count) { - this.count = count; - } - - @Override - public boolean isFinite() { - return false; - } - - /** - * @return The number of possible values. - */ - public long getCount() { - return count; - } - - @Override - public String toString() { - return String.format("Integer(%s)", count); - } - } -} diff --git a/src/main/java/com/regexsolver/api/dto/Details.java b/src/main/java/com/regexsolver/api/dto/Details.java deleted file mode 100644 index 0d78d67..0000000 --- a/src/main/java/com/regexsolver/api/dto/Details.java +++ /dev/null @@ -1,88 +0,0 @@ -package com.regexsolver.api.dto; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.regexsolver.api.ResponseContent; -import com.regexsolver.api.Term; - -import java.util.Objects; - -/** - * Contains details about the requested {@link Term}. - */ -public final class Details implements ResponseContent { - private final Cardinality cardinality; - private final Length length; - private final boolean empty; - private final boolean total; - - /** - * @param cardinality the number of possible values. - * @param length the minimum and maximum length of possible values. - * @param empty true if is an empty set (does not contain any value), false otherwise. - * @param total true if is a total set (contains all values), false otherwise. - */ - public Details( - @JsonProperty("cardinality") Cardinality cardinality, - @JsonProperty("length") Length length, - @JsonProperty("empty") boolean empty, - @JsonProperty("total") boolean total - ) { - this.cardinality = cardinality; - this.length = length; - this.empty = empty; - this.total = total; - } - - /** - * @return The number of possible values. - */ - public Cardinality getCardinality() { - return cardinality; - } - - /** - * @return The minimum and maximum length of possible values. - */ - public Length getLength() { - return length; - } - - /** - * @return true if is an empty set (does not contain any value), false otherwise. - */ - public boolean isEmpty() { - return empty; - } - - /** - * @return true if is a total set (contains all values), false otherwise. - */ - public boolean isTotal() { - return total; - } - - @Override - public boolean equals(Object obj) { - if (obj == this) return true; - if (obj == null || obj.getClass() != this.getClass()) return false; - var that = (Details) obj; - return Objects.equals(this.cardinality, that.cardinality) && - Objects.equals(this.length, that.length) && - this.empty == that.empty && - this.total == that.total; - } - - @Override - public int hashCode() { - return Objects.hash(cardinality, length, empty, total); - } - - @Override - public String toString() { - return "Details[" + - "cardinality=" + cardinality + ", " + - "length=" + length + ", " + - "empty=" + empty + ", " + - "total=" + total + ']'; - } -} diff --git a/src/main/java/com/regexsolver/api/dto/Length.java b/src/main/java/com/regexsolver/api/dto/Length.java deleted file mode 100644 index 3e1200f..0000000 --- a/src/main/java/com/regexsolver/api/dto/Length.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.regexsolver.api.dto; - -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -import java.io.IOException; -import java.util.Objects; -import java.util.OptionalLong; - -/** - * Contains the minimum and maximum length of possible values. - */ -@JsonDeserialize(using = Length.LengthDeserializer.class) -public final class Length { - private final Long minimum; - private final Long maximum; - - /** - * @param minimum the minimum length of possible values, empty if is an empty set. - * @param maximum the maximum length of possible values, empty if the maximum length is infinite or if is an empty set. - */ - Length(Long minimum, Long maximum) { - this.minimum = minimum; - this.maximum = maximum; - } - - /** - * @return The minimum length of possible values, empty if is an empty set. - */ - public OptionalLong getMinimum() { - if (minimum == null) { - return OptionalLong.empty(); - } - return OptionalLong.of(minimum); - } - - /** - * @return The maximum length of possible values, empty if the maximum length is infinite or if is an empty set. - */ - public OptionalLong getMaximum() { - if (maximum == null) { - return OptionalLong.empty(); - } - return OptionalLong.of(maximum); - } - - @Override - public boolean equals(Object obj) { - if (obj == this) return true; - if (obj == null || obj.getClass() != this.getClass()) return false; - var that = (Length) obj; - return Objects.equals(this.minimum, that.minimum) && - Objects.equals(this.maximum, that.maximum); - } - - @Override - public int hashCode() { - return Objects.hash(minimum, maximum); - } - - @Override - public String toString() { - return "Length[" + - "minimum=" + minimum + ", " + - "maximum=" + maximum + ']'; - } - - static class LengthDeserializer extends JsonDeserializer { - @Override - public Length deserialize(JsonParser jp, DeserializationContext ctx) - throws IOException { - Long[] lengthArray = jp.readValueAs(Long[].class); - if (lengthArray != null && lengthArray.length == 2) { - return new Length( - lengthArray[0], - lengthArray[1] - ); - } else { - throw new IOException("Invalid length array."); - } - } - } -} \ No newline at end of file diff --git a/src/main/java/com/regexsolver/api/dto/package-info.java b/src/main/java/com/regexsolver/api/dto/package-info.java deleted file mode 100644 index e518844..0000000 --- a/src/main/java/com/regexsolver/api/dto/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Contains simple objects. - */ -package com.regexsolver.api.dto; \ No newline at end of file diff --git a/src/main/java/com/regexsolver/api/exception/ApiError.java b/src/main/java/com/regexsolver/api/exception/ApiError.java deleted file mode 100644 index b18d74c..0000000 --- a/src/main/java/com/regexsolver/api/exception/ApiError.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.regexsolver.api.exception; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; - -/** - * Thrown when the API returns an error. - */ -@JsonIgnoreProperties(ignoreUnknown = true) -public class ApiError extends Exception { - /** - * Create a new instance. - * - * @param message The error message returned by the API. - */ - public ApiError(@JsonProperty("message") String message) { - super(String.format("The API returned the following error: %s", message)); - } -} diff --git a/src/main/java/com/regexsolver/api/exception/MissingAPITokenException.java b/src/main/java/com/regexsolver/api/exception/MissingAPITokenException.java deleted file mode 100644 index ddac5ec..0000000 --- a/src/main/java/com/regexsolver/api/exception/MissingAPITokenException.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.regexsolver.api.exception; - -/** - * Thrown if the API token has not been set as environment variable. - */ -public class MissingAPITokenException extends RuntimeException { - /** - * The API token has not been set, call RegexSolverApiWrapper.initialize(\"YOUR_TOKEN\"); to set it. - * To generate a token go to RegexSolver Console. - */ - public MissingAPITokenException() { - super("The API token has not been set, call RegexSolverApiWrapper.initialize(\"YOUR_TOKEN\") to set it.\n" + - "To generate a token go to https://console.regexsolver.com/."); - } -} diff --git a/src/main/java/com/regexsolver/api/exception/package-info.java b/src/main/java/com/regexsolver/api/exception/package-info.java deleted file mode 100644 index bc21fdf..0000000 --- a/src/main/java/com/regexsolver/api/exception/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Contains exceptions that can be thrown while using the library. - */ -package com.regexsolver.api.exception; \ No newline at end of file diff --git a/src/main/java/com/regexsolver/api/exceptions/ApiException.java b/src/main/java/com/regexsolver/api/exceptions/ApiException.java new file mode 100644 index 0000000..1bc2f8b --- /dev/null +++ b/src/main/java/com/regexsolver/api/exceptions/ApiException.java @@ -0,0 +1,33 @@ +package com.regexsolver.api.exceptions; + +/** Base exception raised when the RegexSolver API returns an error response. */ +public class ApiException extends RegexSolverException { + + private final int statusCode; + private final String errorCode; + private final String body; + + public ApiException( + String message, + int statusCode, + String errorCode, + String body + ) { + super(message); + this.statusCode = statusCode; + this.errorCode = errorCode; + this.body = body; + } + + public int getStatusCode() { + return statusCode; + } + + public String getErrorCode() { + return errorCode; + } + + public String getBody() { + return body; + } +} diff --git a/src/main/java/com/regexsolver/api/exceptions/AutomatonTooManyStatesException.java b/src/main/java/com/regexsolver/api/exceptions/AutomatonTooManyStatesException.java new file mode 100644 index 0000000..97d0dc0 --- /dev/null +++ b/src/main/java/com/regexsolver/api/exceptions/AutomatonTooManyStatesException.java @@ -0,0 +1,10 @@ +package com.regexsolver.api.exceptions; + +/** + * Raised when the NFA/DFA exceeds the maximum allowed number of states for your current plan. + */ +public class AutomatonTooManyStatesException extends BadRequestException { + public AutomatonTooManyStatesException(String message, int statusCode, String errorCode, String body) { + super(message, statusCode, errorCode, body); + } +} diff --git a/src/main/java/com/regexsolver/api/exceptions/BadRequestException.java b/src/main/java/com/regexsolver/api/exceptions/BadRequestException.java new file mode 100644 index 0000000..969c03c --- /dev/null +++ b/src/main/java/com/regexsolver/api/exceptions/BadRequestException.java @@ -0,0 +1,14 @@ +package com.regexsolver.api.exceptions; + +/** Raised when the API returns a 400 Bad Request error. */ +public class BadRequestException extends ApiException { + + public BadRequestException( + String message, + int statusCode, + String errorCode, + String body + ) { + super(message, statusCode, errorCode, body); + } +} diff --git a/src/main/java/com/regexsolver/api/exceptions/FairSyntaxException.java b/src/main/java/com/regexsolver/api/exceptions/FairSyntaxException.java new file mode 100644 index 0000000..ebfdf8c --- /dev/null +++ b/src/main/java/com/regexsolver/api/exceptions/FairSyntaxException.java @@ -0,0 +1,10 @@ +package com.regexsolver.api.exceptions; + +/** + * Raised when the provided FAIR value is malformed or cannot be decoded. + */ +public class FairSyntaxException extends BadRequestException { + public FairSyntaxException(String message, int statusCode, String errorCode, String body) { + super(message, statusCode, errorCode, body); + } +} diff --git a/src/main/java/com/regexsolver/api/exceptions/ForbiddenException.java b/src/main/java/com/regexsolver/api/exceptions/ForbiddenException.java new file mode 100644 index 0000000..f4bee72 --- /dev/null +++ b/src/main/java/com/regexsolver/api/exceptions/ForbiddenException.java @@ -0,0 +1,14 @@ +package com.regexsolver.api.exceptions; + +/** Raised when the API returns a 403 Forbidden error. */ +public class ForbiddenException extends ApiException { + + public ForbiddenException( + String message, + int statusCode, + String errorCode, + String body + ) { + super(message, statusCode, errorCode, body); + } +} diff --git a/src/main/java/com/regexsolver/api/exceptions/InternalServerException.java b/src/main/java/com/regexsolver/api/exceptions/InternalServerException.java new file mode 100644 index 0000000..0f292f7 --- /dev/null +++ b/src/main/java/com/regexsolver/api/exceptions/InternalServerException.java @@ -0,0 +1,17 @@ +package com.regexsolver.api.exceptions; + +/** + * Raised when the API returns a 500 Internal Server Error. + * Indicates an unexpected failure or panic on the RegexSolver compute servers. + */ +public class InternalServerException extends ApiException { + + public InternalServerException( + String message, + int statusCode, + String errorCode, + String body + ) { + super(message, statusCode, errorCode, body); + } +} diff --git a/src/main/java/com/regexsolver/api/exceptions/InvalidJsonException.java b/src/main/java/com/regexsolver/api/exceptions/InvalidJsonException.java new file mode 100644 index 0000000..e86994e --- /dev/null +++ b/src/main/java/com/regexsolver/api/exceptions/InvalidJsonException.java @@ -0,0 +1,14 @@ +package com.regexsolver.api.exceptions; + +/** Raised when the provided JSON is invalid or cannot be parsed. */ +public class InvalidJsonException extends BadRequestException { + + public InvalidJsonException( + String message, + int statusCode, + String errorCode, + String body + ) { + super(message, statusCode, errorCode, body); + } +} diff --git a/src/main/java/com/regexsolver/api/exceptions/InvalidNumberOfStringsToGenerateException.java b/src/main/java/com/regexsolver/api/exceptions/InvalidNumberOfStringsToGenerateException.java new file mode 100644 index 0000000..e138a63 --- /dev/null +++ b/src/main/java/com/regexsolver/api/exceptions/InvalidNumberOfStringsToGenerateException.java @@ -0,0 +1,16 @@ +package com.regexsolver.api.exceptions; + +/** Raised when the requested number of strings to generate is below the minimum or exceeds the maximum allowed. */ +public class InvalidNumberOfStringsToGenerateException + extends BadRequestException +{ + + public InvalidNumberOfStringsToGenerateException( + String message, + int statusCode, + String errorCode, + String body + ) { + super(message, statusCode, errorCode, body); + } +} diff --git a/src/main/java/com/regexsolver/api/exceptions/InvalidTokenException.java b/src/main/java/com/regexsolver/api/exceptions/InvalidTokenException.java new file mode 100644 index 0000000..eb5d31b --- /dev/null +++ b/src/main/java/com/regexsolver/api/exceptions/InvalidTokenException.java @@ -0,0 +1,14 @@ +package com.regexsolver.api.exceptions; + +/** Raised when the provided authentication token is invalid. */ +public class InvalidTokenException extends UnauthorizedException { + + public InvalidTokenException( + String message, + int statusCode, + String errorCode, + String body + ) { + super(message, statusCode, errorCode, body); + } +} diff --git a/src/main/java/com/regexsolver/api/exceptions/MissingOrMalformedTokenException.java b/src/main/java/com/regexsolver/api/exceptions/MissingOrMalformedTokenException.java new file mode 100644 index 0000000..cff1b35 --- /dev/null +++ b/src/main/java/com/regexsolver/api/exceptions/MissingOrMalformedTokenException.java @@ -0,0 +1,14 @@ +package com.regexsolver.api.exceptions; + +/** Raised when the provided authentication token is missing or malformed. */ +public class MissingOrMalformedTokenException extends UnauthorizedException { + + public MissingOrMalformedTokenException( + String message, + int statusCode, + String errorCode, + String body + ) { + super(message, statusCode, errorCode, body); + } +} diff --git a/src/main/java/com/regexsolver/api/exceptions/NotFoundException.java b/src/main/java/com/regexsolver/api/exceptions/NotFoundException.java new file mode 100644 index 0000000..1fd8d4e --- /dev/null +++ b/src/main/java/com/regexsolver/api/exceptions/NotFoundException.java @@ -0,0 +1,16 @@ +package com.regexsolver.api.exceptions; + +/** Raised when the API returns a 404 Not Found error. + * Indicates that the requested API endpoint or resource does not exist. + */ +public class NotFoundException extends ApiException { + + public NotFoundException( + String message, + int statusCode, + String errorCode, + String body + ) { + super(message, statusCode, errorCode, body); + } +} diff --git a/src/main/java/com/regexsolver/api/exceptions/QuotaExceededException.java b/src/main/java/com/regexsolver/api/exceptions/QuotaExceededException.java new file mode 100644 index 0000000..cdb8157 --- /dev/null +++ b/src/main/java/com/regexsolver/api/exceptions/QuotaExceededException.java @@ -0,0 +1,14 @@ +package com.regexsolver.api.exceptions; + +/** Raised when your account's monthly compute quota has been exceeded. */ +public class QuotaExceededException extends ForbiddenException { + + public QuotaExceededException( + String message, + int statusCode, + String errorCode, + String body + ) { + super(message, statusCode, errorCode, body); + } +} diff --git a/src/main/java/com/regexsolver/api/exceptions/RegexSolverException.java b/src/main/java/com/regexsolver/api/exceptions/RegexSolverException.java new file mode 100644 index 0000000..531fa0c --- /dev/null +++ b/src/main/java/com/regexsolver/api/exceptions/RegexSolverException.java @@ -0,0 +1,11 @@ +package com.regexsolver.api.exceptions; + +/** + * Base exception for all RegexSolver errors. + */ +public class RegexSolverException extends RuntimeException { + + public RegexSolverException(String message) { + super(message); + } +} diff --git a/src/main/java/com/regexsolver/api/exceptions/RegexSyntaxException.java b/src/main/java/com/regexsolver/api/exceptions/RegexSyntaxException.java new file mode 100644 index 0000000..5b63e64 --- /dev/null +++ b/src/main/java/com/regexsolver/api/exceptions/RegexSyntaxException.java @@ -0,0 +1,10 @@ +package com.regexsolver.api.exceptions; + +/** + * Raised when the provided regular expression has invalid syntax. + */ +public class RegexSyntaxException extends BadRequestException { + public RegexSyntaxException(String message, int statusCode, String errorCode, String body) { + super(message, statusCode, errorCode, body); + } +} diff --git a/src/main/java/com/regexsolver/api/exceptions/TimeoutExceededException.java b/src/main/java/com/regexsolver/api/exceptions/TimeoutExceededException.java new file mode 100644 index 0000000..2fed7de --- /dev/null +++ b/src/main/java/com/regexsolver/api/exceptions/TimeoutExceededException.java @@ -0,0 +1,14 @@ +package com.regexsolver.api.exceptions; + +/** Raised when the execution of the request exceeds the provided `execution_timeout` or the maximum allowed for your current plan. */ +public class TimeoutExceededException extends BadRequestException { + + public TimeoutExceededException( + String message, + int statusCode, + String errorCode, + String body + ) { + super(message, statusCode, errorCode, body); + } +} diff --git a/src/main/java/com/regexsolver/api/exceptions/TimeoutTooLargeException.java b/src/main/java/com/regexsolver/api/exceptions/TimeoutTooLargeException.java new file mode 100644 index 0000000..dff3d3d --- /dev/null +++ b/src/main/java/com/regexsolver/api/exceptions/TimeoutTooLargeException.java @@ -0,0 +1,14 @@ +package com.regexsolver.api.exceptions; + +/** Raised when the requested `execution_timeout` exceeds the maximum allowed for your current plan. */ +public class TimeoutTooLargeException extends BadRequestException { + + public TimeoutTooLargeException( + String message, + int statusCode, + String errorCode, + String body + ) { + super(message, statusCode, errorCode, body); + } +} diff --git a/src/main/java/com/regexsolver/api/exceptions/TooFewTermsException.java b/src/main/java/com/regexsolver/api/exceptions/TooFewTermsException.java new file mode 100644 index 0000000..be05235 --- /dev/null +++ b/src/main/java/com/regexsolver/api/exceptions/TooFewTermsException.java @@ -0,0 +1,14 @@ +package com.regexsolver.api.exceptions; + +/** Raised when fewer terms are provided than the operation requires. */ +public class TooFewTermsException extends BadRequestException { + + public TooFewTermsException( + String message, + int statusCode, + String errorCode, + String body + ) { + super(message, statusCode, errorCode, body); + } +} diff --git a/src/main/java/com/regexsolver/api/exceptions/TooManyRequestsException.java b/src/main/java/com/regexsolver/api/exceptions/TooManyRequestsException.java new file mode 100644 index 0000000..47b1904 --- /dev/null +++ b/src/main/java/com/regexsolver/api/exceptions/TooManyRequestsException.java @@ -0,0 +1,17 @@ +package com.regexsolver.api.exceptions; + +/** + * Raised when the API returns a 429 Too Many Requests error and max retries are exceeded. + * Indicates that your requests-per-second (req/s) rate limit has been exceeded. + */ +public class TooManyRequestsException extends ApiException { + + public TooManyRequestsException( + String message, + int statusCode, + String errorCode, + String body + ) { + super(message, statusCode, errorCode, body); + } +} diff --git a/src/main/java/com/regexsolver/api/exceptions/TooManyTermsException.java b/src/main/java/com/regexsolver/api/exceptions/TooManyTermsException.java new file mode 100644 index 0000000..21ac3f6 --- /dev/null +++ b/src/main/java/com/regexsolver/api/exceptions/TooManyTermsException.java @@ -0,0 +1,14 @@ +package com.regexsolver.api.exceptions; + +/** Raised when the number of terms provided exceeds the maximum allowed. */ +public class TooManyTermsException extends BadRequestException { + + public TooManyTermsException( + String message, + int statusCode, + String errorCode, + String body + ) { + super(message, statusCode, errorCode, body); + } +} diff --git a/src/main/java/com/regexsolver/api/exceptions/UnauthorizedException.java b/src/main/java/com/regexsolver/api/exceptions/UnauthorizedException.java new file mode 100644 index 0000000..73e5d9d --- /dev/null +++ b/src/main/java/com/regexsolver/api/exceptions/UnauthorizedException.java @@ -0,0 +1,14 @@ +package com.regexsolver.api.exceptions; + +/** Raised when the API returns a 401 Unauthorized error. */ +public class UnauthorizedException extends ApiException { + + public UnauthorizedException( + String message, + int statusCode, + String errorCode, + String body + ) { + super(message, statusCode, errorCode, body); + } +} diff --git a/src/main/java/com/regexsolver/api/exceptions/package-info.java b/src/main/java/com/regexsolver/api/exceptions/package-info.java new file mode 100644 index 0000000..612475e --- /dev/null +++ b/src/main/java/com/regexsolver/api/exceptions/package-info.java @@ -0,0 +1,4 @@ +/** + * Exception classes for the RegexSolver Java client. + */ +package com.regexsolver.api.exceptions; diff --git a/src/main/java/com/regexsolver/api/generated/ApiClient.java b/src/main/java/com/regexsolver/api/generated/ApiClient.java new file mode 100644 index 0000000..e36d17b --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/ApiClient.java @@ -0,0 +1,486 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +package com.regexsolver.api.generated; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; + +import java.io.InputStream; +import java.io.IOException; +import java.net.URI; +import java.net.URLEncoder; +import java.net.http.HttpClient; +import java.net.http.HttpConnectTimeoutException; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.time.Duration; +import java.time.OffsetDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.StringJoiner; +import java.util.function.Consumer; +import java.util.Optional; +import java.util.zip.GZIPInputStream; +import java.util.stream.Collectors; + +import static java.nio.charset.StandardCharsets.UTF_8; + +/** + * Configuration and utility class for API clients. + * + *

This class can be constructed and modified, then used to instantiate the + * various API classes. The API classes use the settings in this class to + * configure themselves, but otherwise do not store a link to this class.

+ * + *

This class is mutable and not synchronized, so it is not thread-safe. + * The API classes generated from this are immutable and thread-safe.

+ * + *

The setter methods of this class return the current object to facilitate + * a fluent style of configuration.

+ */ +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class ApiClient { + + protected HttpClient.Builder builder; + protected ObjectMapper mapper; + protected String scheme; + protected String host; + protected int port; + protected String basePath; + protected Consumer interceptor; + protected Consumer> responseInterceptor; + protected Consumer> asyncResponseInterceptor; + protected Duration readTimeout; + protected Duration connectTimeout; + + public static String valueToString(Object value) { + if (value == null) { + return ""; + } + if (value instanceof OffsetDateTime) { + return ((OffsetDateTime) value).format(DateTimeFormatter.ISO_OFFSET_DATE_TIME); + } + return value.toString(); + } + + /** + * URL encode a string in the UTF-8 encoding. + * + * @param s String to encode. + * @return URL-encoded representation of the input string. + */ + public static String urlEncode(String s) { + return URLEncoder.encode(s, UTF_8).replaceAll("\\+", "%20"); + } + + /** + * Convert a URL query name/value parameter to a list of encoded {@link Pair} + * objects. + * + *

The value can be null, in which case an empty list is returned.

+ * + * @param name The query name parameter. + * @param value The query value, which may not be a collection but may be + * null. + * @return A singleton list of the {@link Pair} objects representing the input + * parameters, which is encoded for use in a URL. If the value is null, an + * empty list is returned. + */ + public static List parameterToPairs(String name, Object value) { + if (name == null || name.isEmpty() || value == null) { + return Collections.emptyList(); + } + return Collections.singletonList(new Pair(urlEncode(name), urlEncode(valueToString(value)))); + } + + /** + * Convert a URL query name/collection parameter to a list of encoded + * {@link Pair} objects. + * + * @param collectionFormat The swagger collectionFormat string (csv, tsv, etc). + * @param name The query name parameter. + * @param values A collection of values for the given query name, which may be + * null. + * @return A list of {@link Pair} objects representing the input parameters, + * which is encoded for use in a URL. If the values collection is null, an + * empty list is returned. + */ + public static List parameterToPairs( + String collectionFormat, String name, Collection values) { + if (name == null || name.isEmpty() || values == null || values.isEmpty()) { + return Collections.emptyList(); + } + + // get the collection format (default: csv) + String format = collectionFormat == null || collectionFormat.isEmpty() ? "csv" : collectionFormat; + + // create the params based on the collection format + if ("multi".equals(format)) { + return values.stream() + .map(value -> new Pair(urlEncode(name), urlEncode(valueToString(value)))) + .collect(Collectors.toList()); + } + + String delimiter; + switch(format) { + case "csv": + delimiter = urlEncode(","); + break; + case "ssv": + delimiter = urlEncode(" "); + break; + case "tsv": + delimiter = urlEncode("\t"); + break; + case "pipes": + delimiter = urlEncode("|"); + break; + default: + throw new IllegalArgumentException("Illegal collection format: " + collectionFormat); + } + + StringJoiner joiner = new StringJoiner(delimiter); + for (Object value : values) { + joiner.add(urlEncode(valueToString(value))); + } + + return Collections.singletonList(new Pair(urlEncode(name), joiner.toString())); + } + + /** + * Create an instance of ApiClient. + */ + public ApiClient() { + this.builder = createDefaultHttpClientBuilder(); + this.mapper = createDefaultObjectMapper(); + updateBaseUri("https://api.regexsolver.com/v1"); + interceptor = null; + readTimeout = null; + connectTimeout = null; + responseInterceptor = null; + asyncResponseInterceptor = null; + } + + /** + * Create an instance of ApiClient. + * + * @param builder Http client builder. + * @param mapper Object mapper. + * @param baseUri Base URI + */ + public ApiClient(HttpClient.Builder builder, ObjectMapper mapper, String baseUri) { + this.builder = builder; + this.mapper = mapper; + updateBaseUri(baseUri != null ? baseUri : "https://api.regexsolver.com/v1"); + interceptor = null; + readTimeout = null; + connectTimeout = null; + responseInterceptor = null; + asyncResponseInterceptor = null; + } + + public static ObjectMapper createDefaultObjectMapper() { + ObjectMapper mapper = new ObjectMapper(); + mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + mapper.configure(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE, false); + mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + mapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING); + mapper.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING); + mapper.disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE); + mapper.registerModule(new JavaTimeModule()); + mapper.registerModule(new RFC3339JavaTimeModule()); + return mapper; + } + + protected final String getDefaultBaseUri() { + return basePath; + } + + public static HttpClient.Builder createDefaultHttpClientBuilder() { + return HttpClient.newBuilder(); + } + + public final void updateBaseUri(String baseUri) { + URI uri = URI.create(baseUri); + scheme = uri.getScheme(); + host = uri.getHost(); + port = uri.getPort(); + basePath = uri.getRawPath(); + } + + /** + * Set a custom {@link HttpClient.Builder} object to use when creating the + * {@link HttpClient} that is used by the API client. + * + * @param builder Custom client builder. + * @return This object. + */ + public ApiClient setHttpClientBuilder(HttpClient.Builder builder) { + this.builder = builder; + return this; + } + + /** + * Get an {@link HttpClient} based on the current {@link HttpClient.Builder}. + * + *

The returned object is immutable and thread-safe.

+ * + * @return The HTTP client. + */ + public HttpClient getHttpClient() { + return builder.build(); + } + + /** + * Set a custom {@link ObjectMapper} to serialize and deserialize the request + * and response bodies. + * + * @param mapper Custom object mapper. + * @return This object. + */ + public ApiClient setObjectMapper(ObjectMapper mapper) { + this.mapper = mapper; + return this; + } + + /** + * Get a copy of the current {@link ObjectMapper}. + * + * @return A copy of the current object mapper. + */ + public ObjectMapper getObjectMapper() { + return mapper.copy(); + } + + /** + * Set a custom host name for the target service. + * + * @param host The host name of the target service. + * @return This object. + */ + public ApiClient setHost(String host) { + this.host = host; + return this; + } + + /** + * Set a custom port number for the target service. + * + * @param port The port of the target service. Set this to -1 to reset the + * value to the default for the scheme. + * @return This object. + */ + public ApiClient setPort(int port) { + this.port = port; + return this; + } + + /** + * Set a custom base path for the target service, for example '/v2'. + * + * @param basePath The base path against which the rest of the path is + * resolved. + * @return This object. + */ + public ApiClient setBasePath(String basePath) { + this.basePath = basePath; + return this; + } + + /** + * Get the base URI to resolve the endpoint paths against. + * + * @return The complete base URI that the rest of the API parameters are + * resolved against. + */ + public String getBaseUri() { + return scheme + "://" + host + (port == -1 ? "" : ":" + port) + basePath; + } + + /** + * Set a custom scheme for the target service, for example 'https'. + * + * @param scheme The scheme of the target service + * @return This object. + */ + public ApiClient setScheme(String scheme){ + this.scheme = scheme; + return this; + } + + /** + * Set a custom request interceptor. + * + *

A request interceptor is a mechanism for altering each request before it + * is sent. After the request has been fully configured but not yet built, the + * request builder is passed into this function for further modification, + * after which it is sent out.

+ * + *

This is useful for altering the requests in a custom manner, such as + * adding headers. It could also be used for logging and monitoring.

+ * + * @param interceptor A function invoked before creating each request. A value + * of null resets the interceptor to a no-op. + * @return This object. + */ + public ApiClient setRequestInterceptor(Consumer interceptor) { + this.interceptor = interceptor; + return this; + } + + /** + * Get the custom interceptor. + * + * @return The custom interceptor that was set, or null if there isn't any. + */ + public Consumer getRequestInterceptor() { + return interceptor; + } + + /** + * Set a custom response interceptor. + * + *

This is useful for logging, monitoring or extraction of header variables

+ * + * @param interceptor A function invoked before creating each request. A value + * of null resets the interceptor to a no-op. + * @return This object. + */ + public ApiClient setResponseInterceptor(Consumer> interceptor) { + this.responseInterceptor = interceptor; + return this; + } + + /** + * Get the custom response interceptor. + * + * @return The custom interceptor that was set, or null if there isn't any. + */ + public Consumer> getResponseInterceptor() { + return responseInterceptor; + } + + /** + * Set a custom async response interceptor. Use this interceptor when asyncNative is set to 'true'. + * + *

This is useful for logging, monitoring or extraction of header variables

+ * + * @param interceptor A function invoked before creating each request. A value + * of null resets the interceptor to a no-op. + * @return This object. + */ + public ApiClient setAsyncResponseInterceptor(Consumer> interceptor) { + this.asyncResponseInterceptor = interceptor; + return this; + } + + /** + * Get the custom async response interceptor. Use this interceptor when asyncNative is set to 'true'. + * + * @return The custom interceptor that was set, or null if there isn't any. + */ + public Consumer> getAsyncResponseInterceptor() { + return asyncResponseInterceptor; + } + + /** + * Set the read timeout for the http client. + * + *

This is the value used by default for each request, though it can be + * overridden on a per-request basis with a request interceptor.

+ * + * @param readTimeout The read timeout used by default by the http client. + * Setting this value to null resets the timeout to an + * effectively infinite value. + * @return This object. + */ + public ApiClient setReadTimeout(Duration readTimeout) { + this.readTimeout = readTimeout; + return this; + } + + /** + * Get the read timeout that was set. + * + * @return The read timeout, or null if no timeout was set. Null represents + * an infinite wait time. + */ + public Duration getReadTimeout() { + return readTimeout; + } + /** + * Sets the connect timeout (in milliseconds) for the http client. + * + *

In the case where a new connection needs to be established, if + * the connection cannot be established within the given {@code + * duration}, then {@link HttpClient#send(HttpRequest,BodyHandler) + * HttpClient::send} throws an {@link HttpConnectTimeoutException}, or + * {@link HttpClient#sendAsync(HttpRequest,BodyHandler) + * HttpClient::sendAsync} completes exceptionally with an + * {@code HttpConnectTimeoutException}. If a new connection does not + * need to be established, for example if a connection can be reused + * from a previous request, then this timeout duration has no effect. + * + * @param connectTimeout connection timeout in milliseconds + * + * @return This object. + */ + public ApiClient setConnectTimeout(Duration connectTimeout) { + this.connectTimeout = connectTimeout; + this.builder.connectTimeout(connectTimeout); + return this; + } + + /** + * Get connection timeout (in milliseconds). + * + * @return Timeout in milliseconds + */ + public Duration getConnectTimeout() { + return connectTimeout; + } + + /** + * Returns the response body InputStream, transparently decoding gzip-compressed + * payloads when the server sets {@code Content-Encoding: gzip}. + * + * @param response HTTP response whose body should be consumed + * @return Original or decompressed InputStream for the response body + * @throws IOException if the response body cannot be accessed or wrapping fails + */ + public static InputStream getResponseBody(HttpResponse response) throws IOException { + if (response == null) { + return null; + } + InputStream body = response.body(); + if (body == null) { + return null; + } + Optional encoding = response.headers().firstValue("Content-Encoding"); + if (encoding.isPresent()) { + for (String token : encoding.get().split(",")) { + if ("gzip".equalsIgnoreCase(token.trim())) { + return new GZIPInputStream(body, 8192); + } + } + } + return body; + } + +} diff --git a/src/main/java/com/regexsolver/api/generated/ApiException.java b/src/main/java/com/regexsolver/api/generated/ApiException.java new file mode 100644 index 0000000..ce86146 --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/ApiException.java @@ -0,0 +1,92 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.regexsolver.api.generated; + +import java.net.http.HttpHeaders; + +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class ApiException extends RuntimeException { + private static final long serialVersionUID = 1L; + + private int code = 0; + private HttpHeaders responseHeaders = null; + private String responseBody = null; + + public ApiException() {} + + public ApiException(Throwable throwable) { + super(throwable); + } + + public ApiException(String message) { + super(message); + } + + public ApiException(String message, Throwable throwable, int code, HttpHeaders responseHeaders, String responseBody) { + super(message, throwable); + this.code = code; + this.responseHeaders = responseHeaders; + this.responseBody = responseBody; + } + + public ApiException(String message, int code, HttpHeaders responseHeaders, String responseBody) { + this(message, (Throwable) null, code, responseHeaders, responseBody); + } + + public ApiException(String message, Throwable throwable, int code, HttpHeaders responseHeaders) { + this(message, throwable, code, responseHeaders, null); + } + + public ApiException(int code, HttpHeaders responseHeaders, String responseBody) { + this((String) null, (Throwable) null, code, responseHeaders, responseBody); + } + + public ApiException(int code, String message) { + super(message); + this.code = code; + } + + public ApiException(int code, String message, HttpHeaders responseHeaders, String responseBody) { + this(code, message); + this.responseHeaders = responseHeaders; + this.responseBody = responseBody; + } + + /** + * Get the HTTP status code. + * + * @return HTTP status code + */ + public int getCode() { + return code; + } + + /** + * Get the HTTP response headers. + * + * @return Headers as an HttpHeaders object + */ + public HttpHeaders getResponseHeaders() { + return responseHeaders; + } + + /** + * Get the HTTP response body. + * + * @return Response body in the form of string + */ + public String getResponseBody() { + return responseBody; + } +} diff --git a/src/main/java/com/regexsolver/api/generated/ApiResponse.java b/src/main/java/com/regexsolver/api/generated/ApiResponse.java new file mode 100644 index 0000000..435f51e --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/ApiResponse.java @@ -0,0 +1,60 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.regexsolver.api.generated; + +import java.util.List; +import java.util.Map; + +/** + * API response returned by API call. + * + * @param The type of data that is deserialized from response body + */ +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class ApiResponse { + final private int statusCode; + final private Map> headers; + final private T data; + + /** + * @param statusCode The status code of HTTP response + * @param headers The headers of HTTP response + */ + public ApiResponse(int statusCode, Map> headers) { + this(statusCode, headers, null); + } + + /** + * @param statusCode The status code of HTTP response + * @param headers The headers of HTTP response + * @param data The object deserialized from response bod + */ + public ApiResponse(int statusCode, Map> headers, T data) { + this.statusCode = statusCode; + this.headers = headers; + this.data = data; + } + + public int getStatusCode() { + return statusCode; + } + + public Map> getHeaders() { + return headers; + } + + public T getData() { + return data; + } +} diff --git a/src/main/java/com/regexsolver/api/generated/Configuration.java b/src/main/java/com/regexsolver/api/generated/Configuration.java new file mode 100644 index 0000000..47d3997 --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/Configuration.java @@ -0,0 +1,63 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.regexsolver.api.generated; + +import java.util.Objects; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Supplier; + +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class Configuration { + public static final String VERSION = "1.1.0"; + + private static final AtomicReference defaultApiClient = new AtomicReference<>(); + private static volatile Supplier apiClientFactory = ApiClient::new; + + /** + * Get the default API client, which would be used when creating API instances without providing an API client. + * + * @return Default API client + */ + public static ApiClient getDefaultApiClient() { + ApiClient client = defaultApiClient.get(); + if (client == null) { + client = defaultApiClient.updateAndGet(val -> { + if (val != null) { // changed by another thread + return val; + } + return apiClientFactory.get(); + }); + } + return client; + } + + /** + * Set the default API client, which would be used when creating API instances without providing an API client. + * + * @param apiClient API client + */ + public static void setDefaultApiClient(ApiClient apiClient) { + defaultApiClient.set(apiClient); + } + + /** + * set the callback used to create new ApiClient objects + */ + public static void setApiClientFactory(Supplier factory) { + apiClientFactory = Objects.requireNonNull(factory); + } + + private Configuration() { + } +} \ No newline at end of file diff --git a/src/main/java/com/regexsolver/api/generated/JSON.java b/src/main/java/com/regexsolver/api/generated/JSON.java new file mode 100644 index 0000000..87e6757 --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/JSON.java @@ -0,0 +1,261 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.regexsolver.api.generated; + +import com.fasterxml.jackson.annotation.*; +import com.fasterxml.jackson.databind.*; +import com.fasterxml.jackson.databind.json.JsonMapper; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.regexsolver.api.generated.model.*; + +import java.text.DateFormat; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class JSON { + private ObjectMapper mapper; + + public JSON() { + mapper = JsonMapper.builder() + .serializationInclusion(JsonInclude.Include.NON_NULL) + .disable(MapperFeature.ALLOW_COERCION_OF_SCALARS) + .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) + .enable(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE) + .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) + .enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING) + .enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING) + .defaultDateFormat(new RFC3339DateFormat()) + .addModule(new JavaTimeModule()) + .build(); + } + + /** + * Set the date format for JSON (de)serialization with Date properties. + * + * @param dateFormat Date format + */ + public void setDateFormat(DateFormat dateFormat) { + mapper.setDateFormat(dateFormat); + } + + /** + * Get the object mapper + * + * @return object mapper + */ + public ObjectMapper getMapper() { return mapper; } + + /** + * Returns the target model class that should be used to deserialize the input data. + * The discriminator mappings are used to determine the target model class. + * + * @param node The input data. + * @param modelClass The class that contains the discriminator mappings. + * + * @return the target model class. + */ + public static Class getClassForElement(JsonNode node, Class modelClass) { + ClassDiscriminatorMapping cdm = modelDiscriminators.get(modelClass); + if (cdm != null) { + return cdm.getClassForElement(node, new HashSet>()); + } + return null; + } + + /** + * Helper class to register the discriminator mappings. + */ + @jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") + private static class ClassDiscriminatorMapping { + // The model class name. + Class modelClass; + // The name of the discriminator property. + String discriminatorName; + // The discriminator mappings for a model class. + Map> discriminatorMappings; + + // Constructs a new class discriminator. + ClassDiscriminatorMapping(Class cls, String propertyName, Map> mappings) { + modelClass = cls; + discriminatorName = propertyName; + discriminatorMappings = new HashMap>(); + if (mappings != null) { + discriminatorMappings.putAll(mappings); + } + } + + // Return the name of the discriminator property for this model class. + String getDiscriminatorPropertyName() { + return discriminatorName; + } + + // Return the discriminator value or null if the discriminator is not + // present in the payload. + String getDiscriminatorValue(JsonNode node) { + // Determine the value of the discriminator property in the input data. + if (discriminatorName != null) { + // Get the value of the discriminator property, if present in the input payload. + node = node.get(discriminatorName); + if (node != null && node.isValueNode()) { + String discrValue = node.asText(); + if (discrValue != null) { + return discrValue; + } + } + } + return null; + } + + /** + * Returns the target model class that should be used to deserialize the input data. + * This function can be invoked for anyOf/oneOf composed models with discriminator mappings. + * The discriminator mappings are used to determine the target model class. + * + * @param node The input data. + * @param visitedClasses The set of classes that have already been visited. + * + * @return the target model class. + */ + Class getClassForElement(JsonNode node, Set> visitedClasses) { + if (visitedClasses.contains(modelClass)) { + // Class has already been visited. + return null; + } + // Determine the value of the discriminator property in the input data. + String discrValue = getDiscriminatorValue(node); + if (discrValue == null) { + return null; + } + Class cls = discriminatorMappings.get(discrValue); + // It may not be sufficient to return this cls directly because that target class + // may itself be a composed schema, possibly with its own discriminator. + visitedClasses.add(modelClass); + for (Class childClass : discriminatorMappings.values()) { + ClassDiscriminatorMapping childCdm = modelDiscriminators.get(childClass); + if (childCdm == null) { + continue; + } + if (!discriminatorName.equals(childCdm.discriminatorName)) { + discrValue = getDiscriminatorValue(node); + if (discrValue == null) { + continue; + } + } + if (childCdm != null) { + // Recursively traverse the discriminator mappings. + Class childDiscr = childCdm.getClassForElement(node, visitedClasses); + if (childDiscr != null) { + return childDiscr; + } + } + } + return cls; + } + } + + /** + * Returns true if inst is an instance of modelClass in the OpenAPI model hierarchy. + * + * The Java class hierarchy is not implemented the same way as the OpenAPI model hierarchy, + * so it's not possible to use the instanceof keyword. + * + * @param modelClass A OpenAPI model class. + * @param inst The instance object. + * @param visitedClasses The set of classes that have already been visited. + * + * @return true if inst is an instance of modelClass in the OpenAPI model hierarchy. + */ + public static boolean isInstanceOf(Class modelClass, Object inst, Set> visitedClasses) { + if (modelClass.isInstance(inst)) { + // This handles the 'allOf' use case with single parent inheritance. + return true; + } + if (visitedClasses.contains(modelClass)) { + // This is to prevent infinite recursion when the composed schemas have + // a circular dependency. + return false; + } + visitedClasses.add(modelClass); + + // Traverse the oneOf/anyOf composed schemas. + Map> descendants = modelDescendants.get(modelClass); + if (descendants != null) { + for (Class childType : descendants.values()) { + if (isInstanceOf(childType, inst, visitedClasses)) { + return true; + } + } + } + return false; + } + + /** + * A map of discriminators for all model classes. + */ + private static Map, ClassDiscriminatorMapping> modelDiscriminators = new HashMap<>(); + + /** + * A map of oneOf/anyOf descendants for each model class. + */ + private static Map, Map>> modelDescendants = new HashMap<>(); + + /** + * Register a model class discriminator. + * + * @param modelClass the model class + * @param discriminatorPropertyName the name of the discriminator property + * @param mappings a map with the discriminator mappings. + */ + public static void registerDiscriminator(Class modelClass, String discriminatorPropertyName, Map> mappings) { + ClassDiscriminatorMapping m = new ClassDiscriminatorMapping(modelClass, discriminatorPropertyName, mappings); + modelDiscriminators.put(modelClass, m); + } + + /** + * Register the oneOf/anyOf descendants of the modelClass. + * + * @param modelClass the model class + * @param descendants a map of oneOf/anyOf descendants. + */ + public static void registerDescendants(Class modelClass, Map> descendants) { + modelDescendants.put(modelClass, descendants); + } + + private static JSON json; + + static { + json = new JSON(); + } + + /** + * Get the default JSON instance. + * + * @return the default JSON instance + */ + public static JSON getDefault() { + return json; + } + + /** + * Set the default JSON instance. + * + * @param json JSON instance to be used + */ + public static void setDefault(JSON json) { + JSON.json = json; + } +} diff --git a/src/main/java/com/regexsolver/api/generated/Pair.java b/src/main/java/com/regexsolver/api/generated/Pair.java new file mode 100644 index 0000000..021d2db --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/Pair.java @@ -0,0 +1,37 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.regexsolver.api.generated; + +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class Pair { + private final String name; + private final String value; + + public Pair(String name, String value) { + this.name = isValidString(name) ? name : ""; + this.value = isValidString(value) ? value : ""; + } + + public String getName() { + return this.name; + } + + public String getValue() { + return this.value; + } + + private static boolean isValidString(String arg) { + return arg != null; + } +} diff --git a/src/main/java/com/regexsolver/api/generated/RFC3339DateFormat.java b/src/main/java/com/regexsolver/api/generated/RFC3339DateFormat.java new file mode 100644 index 0000000..ad89cfe --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/RFC3339DateFormat.java @@ -0,0 +1,57 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +package com.regexsolver.api.generated; + +import java.text.DateFormat; +import java.text.FieldPosition; +import java.text.ParsePosition; +import java.util.Date; +import java.text.DecimalFormat; +import java.util.GregorianCalendar; +import java.util.TimeZone; +import com.fasterxml.jackson.databind.util.StdDateFormat; + +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class RFC3339DateFormat extends DateFormat { + private static final long serialVersionUID = 1L; + private static final TimeZone TIMEZONE_Z = TimeZone.getTimeZone("UTC"); + + private final StdDateFormat fmt = new StdDateFormat() + .withTimeZone(TIMEZONE_Z) + .withColonInTimeZone(true); + + public RFC3339DateFormat() { + this.calendar = new GregorianCalendar(); + this.numberFormat = new DecimalFormat(); + } + + @Override + public Date parse(String source) { + return parse(source, new ParsePosition(0)); + } + + @Override + public Date parse(String source, ParsePosition pos) { + return fmt.parse(source, pos); + } + + @Override + public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) { + return fmt.format(date, toAppendTo, fieldPosition); + } + + @Override + public Object clone() { + return super.clone(); + } +} diff --git a/src/main/java/com/regexsolver/api/generated/RFC3339InstantDeserializer.java b/src/main/java/com/regexsolver/api/generated/RFC3339InstantDeserializer.java new file mode 100644 index 0000000..7b9f9ce --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/RFC3339InstantDeserializer.java @@ -0,0 +1,100 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +package com.regexsolver.api.generated; + +import java.io.IOException; +import java.time.Instant; +import java.time.OffsetDateTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.time.temporal.Temporal; +import java.time.temporal.TemporalAccessor; +import java.util.function.BiFunction; +import java.util.function.Function; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeFeature; +import com.fasterxml.jackson.datatype.jsr310.deser.InstantDeserializer; + +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class RFC3339InstantDeserializer extends InstantDeserializer { + private static final long serialVersionUID = 1L; + private final static boolean DEFAULT_NORMALIZE_ZONE_ID = JavaTimeFeature.NORMALIZE_DESERIALIZED_ZONE_ID.enabledByDefault(); + private final static boolean DEFAULT_ALWAYS_ALLOW_STRINGIFIED_DATE_TIMESTAMPS + = JavaTimeFeature.ALWAYS_ALLOW_STRINGIFIED_DATE_TIMESTAMPS.enabledByDefault(); + + public static final RFC3339InstantDeserializer INSTANT = new RFC3339InstantDeserializer<>( + Instant.class, DateTimeFormatter.ISO_INSTANT, + Instant::from, + a -> Instant.ofEpochMilli( a.value ), + a -> Instant.ofEpochSecond( a.integer, a.fraction ), + null, + true, // yes, replace zero offset with Z + DEFAULT_NORMALIZE_ZONE_ID, + DEFAULT_ALWAYS_ALLOW_STRINGIFIED_DATE_TIMESTAMPS + ); + + public static final RFC3339InstantDeserializer OFFSET_DATE_TIME = new RFC3339InstantDeserializer<>( + OffsetDateTime.class, DateTimeFormatter.ISO_OFFSET_DATE_TIME, + OffsetDateTime::from, + a -> OffsetDateTime.ofInstant( Instant.ofEpochMilli( a.value ), a.zoneId ), + a -> OffsetDateTime.ofInstant( Instant.ofEpochSecond( a.integer, a.fraction ), a.zoneId ), + (d, z) -> ( d.isEqual( OffsetDateTime.MIN ) || d.isEqual( OffsetDateTime.MAX ) ? + d : + d.withOffsetSameInstant( z.getRules().getOffset( d.toLocalDateTime() ) ) ), + true, // yes, replace zero offset with Z + DEFAULT_NORMALIZE_ZONE_ID, + DEFAULT_ALWAYS_ALLOW_STRINGIFIED_DATE_TIMESTAMPS + ); + + public static final RFC3339InstantDeserializer ZONED_DATE_TIME = new RFC3339InstantDeserializer<>( + ZonedDateTime.class, DateTimeFormatter.ISO_ZONED_DATE_TIME, + ZonedDateTime::from, + a -> ZonedDateTime.ofInstant( Instant.ofEpochMilli( a.value ), a.zoneId ), + a -> ZonedDateTime.ofInstant( Instant.ofEpochSecond( a.integer, a.fraction ), a.zoneId ), + ZonedDateTime::withZoneSameInstant, + false, // keep zero offset and Z separate since zones explicitly supported + DEFAULT_NORMALIZE_ZONE_ID, + DEFAULT_ALWAYS_ALLOW_STRINGIFIED_DATE_TIMESTAMPS + ); + + protected RFC3339InstantDeserializer( + Class supportedType, + DateTimeFormatter formatter, + Function parsedToValue, + Function fromMilliseconds, + Function fromNanoseconds, + BiFunction adjust, + boolean replaceZeroOffsetAsZ, + boolean normalizeZoneId, + boolean readNumericStringsAsTimestamp) { + super( + supportedType, + formatter, + parsedToValue, + fromMilliseconds, + fromNanoseconds, + adjust, + replaceZeroOffsetAsZ, + normalizeZoneId, + readNumericStringsAsTimestamp + ); + } + + @Override + protected T _fromString(JsonParser p, DeserializationContext ctxt, String string0) throws IOException { + return super._fromString(p, ctxt, string0.replace( ' ', 'T' )); + } +} \ No newline at end of file diff --git a/src/main/java/com/regexsolver/api/generated/RFC3339JavaTimeModule.java b/src/main/java/com/regexsolver/api/generated/RFC3339JavaTimeModule.java new file mode 100644 index 0000000..aa14b1e --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/RFC3339JavaTimeModule.java @@ -0,0 +1,39 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +package com.regexsolver.api.generated; + +import java.time.Instant; +import java.time.OffsetDateTime; +import java.time.ZonedDateTime; + +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.databind.Module.SetupContext; + +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class RFC3339JavaTimeModule extends SimpleModule { + private static final long serialVersionUID = 1L; + + public RFC3339JavaTimeModule() { + super("RFC3339JavaTimeModule"); + } + + @Override + public void setupModule(SetupContext context) { + super.setupModule(context); + + addDeserializer(Instant.class, RFC3339InstantDeserializer.INSTANT); + addDeserializer(OffsetDateTime.class, RFC3339InstantDeserializer.OFFSET_DATE_TIME); + addDeserializer(ZonedDateTime.class, RFC3339InstantDeserializer.ZONED_DATE_TIME); + } + +} diff --git a/src/main/java/com/regexsolver/api/generated/ServerConfiguration.java b/src/main/java/com/regexsolver/api/generated/ServerConfiguration.java new file mode 100644 index 0000000..86872b4 --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/ServerConfiguration.java @@ -0,0 +1,72 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.regexsolver.api.generated; + +import java.util.Map; + +/** + * Representing a Server configuration. + */ +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class ServerConfiguration { + public String URL; + public String description; + public Map variables; + + /** + * @param URL A URL to the target host. + * @param description A description of the host designated by the URL. + * @param variables A map between a variable name and its value. The value is used for substitution in the server's URL template. + */ + public ServerConfiguration(String URL, String description, Map variables) { + this.URL = URL; + this.description = description; + this.variables = variables; + } + + /** + * Format URL template using given variables. + * + * @param variables A map between a variable name and its value. + * @return Formatted URL. + */ + public String URL(Map variables) { + String url = this.URL; + + // go through variables and replace placeholders + for (Map.Entry variable: this.variables.entrySet()) { + String name = variable.getKey(); + ServerVariable serverVariable = variable.getValue(); + String value = serverVariable.defaultValue; + + if (variables != null && variables.containsKey(name)) { + value = variables.get(name); + if (serverVariable.enumValues.size() > 0 && !serverVariable.enumValues.contains(value)) { + throw new IllegalArgumentException("The variable " + name + " in the server URL has invalid value " + value + "."); + } + } + url = url.replace("{" + name + "}", value); + } + return url; + } + + /** + * Format URL template using default server variables. + * + * @return Formatted URL. + */ + public String URL() { + return URL(null); + } +} diff --git a/src/main/java/com/regexsolver/api/generated/ServerVariable.java b/src/main/java/com/regexsolver/api/generated/ServerVariable.java new file mode 100644 index 0000000..43b8681 --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/ServerVariable.java @@ -0,0 +1,37 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.regexsolver.api.generated; + +import java.util.HashSet; + +/** + * Representing a Server Variable for server URL template substitution. + */ +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class ServerVariable { + public String description; + public String defaultValue; + public HashSet enumValues = null; + + /** + * @param description A description for the server variable. + * @param defaultValue The default value to use for substitution. + * @param enumValues An enumeration of string values to be used if the substitution options are from a limited set. + */ + public ServerVariable(String description, String defaultValue, HashSet enumValues) { + this.description = description; + this.defaultValue = defaultValue; + this.enumValues = enumValues; + } +} diff --git a/src/main/java/com/regexsolver/api/generated/api/AccountApi.java b/src/main/java/com/regexsolver/api/generated/api/AccountApi.java new file mode 100644 index 0000000..e396454 --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/api/AccountApi.java @@ -0,0 +1,288 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +package com.regexsolver.api.generated.api; + +import com.regexsolver.api.generated.ApiClient; +import com.regexsolver.api.generated.ApiException; +import com.regexsolver.api.generated.ApiResponse; +import com.regexsolver.api.generated.Configuration; +import com.regexsolver.api.generated.Pair; + +import com.regexsolver.api.generated.model.ErrorResponse401Dto; +import com.regexsolver.api.generated.model.ErrorResponseDto; +import com.regexsolver.api.generated.model.Limits200ResponseDto; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.InputStream; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.net.http.HttpRequest; +import java.nio.channels.Channels; +import java.nio.channels.Pipe; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.time.Duration; + +import java.util.ArrayList; +import java.util.StringJoiner; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Consumer; + +import java.util.concurrent.CompletableFuture; + +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class AccountApi { + /** + * Utility class for extending HttpRequest.Builder functionality. + */ + private static class HttpRequestBuilderExtensions { + /** + * Adds additional headers to the provided HttpRequest.Builder. Useful for adding method/endpoint specific headers. + * + * @param builder the HttpRequest.Builder to which headers will be added + * @param headers a map of header names and values to add; may be null + * @return the same HttpRequest.Builder instance with the additional headers set + */ + static HttpRequest.Builder withAdditionalHeaders(HttpRequest.Builder builder, Map headers) { + if (headers != null) { + for (Map.Entry entry : headers.entrySet()) { + builder.header(entry.getKey(), entry.getValue()); + } + } + return builder; + } + } + private final HttpClient memberVarHttpClient; + private final ObjectMapper memberVarObjectMapper; + private final String memberVarBaseUri; + private final Consumer memberVarInterceptor; + private final Duration memberVarReadTimeout; + private final Consumer> memberVarResponseInterceptor; + private final Consumer> memberVarAsyncResponseInterceptor; + + public AccountApi() { + this(Configuration.getDefaultApiClient()); + } + + public AccountApi(ApiClient apiClient) { + memberVarHttpClient = apiClient.getHttpClient(); + memberVarObjectMapper = apiClient.getObjectMapper(); + memberVarBaseUri = apiClient.getBaseUri(); + memberVarInterceptor = apiClient.getRequestInterceptor(); + memberVarReadTimeout = apiClient.getReadTimeout(); + memberVarResponseInterceptor = apiClient.getResponseInterceptor(); + memberVarAsyncResponseInterceptor = apiClient.getAsyncResponseInterceptor(); + } + + + private ApiException getApiException(String operationId, HttpResponse response) { + try { + InputStream responseBody = ApiClient.getResponseBody(response); + String body = null; + if (responseBody != null) { + body = new String(responseBody.readAllBytes()); + responseBody.close(); + } + String message = formatExceptionMessage(operationId, response.statusCode(), body); + return new ApiException(response.statusCode(), message, response.headers(), body); + } catch (IOException e) { + return new ApiException(e); + } + } + + private String formatExceptionMessage(String operationId, int statusCode, String body) { + if (body == null || body.isEmpty()) { + body = "[no body]"; + } + return operationId + " call failed with: " + statusCode + " - " + body; + } + + /** + * Download file from the given response. + * + * @param response Response + * @return File + * @throws ApiException If fail to read file content from response and write to disk + */ + public File downloadFileFromResponse(HttpResponse response, InputStream responseBody) throws ApiException { + if (responseBody == null) { + throw new ApiException(new IOException("Response body is empty")); + } + try { + File file = prepareDownloadFile(response); + java.nio.file.Files.copy(responseBody, file.toPath(), java.nio.file.StandardCopyOption.REPLACE_EXISTING); + return file; + } catch (IOException e) { + throw new ApiException(e); + } + } + + /** + *

Prepare the file for download from the response.

+ * + * @param response a {@link java.net.http.HttpResponse} object. + * @return a {@link java.io.File} object. + * @throws java.io.IOException if any. + */ + private File prepareDownloadFile(HttpResponse response) throws IOException { + String filename = null; + java.util.Optional contentDisposition = response.headers().firstValue("Content-Disposition"); + if (contentDisposition.isPresent() && !"".equals(contentDisposition.get())) { + // Get filename from the Content-Disposition header. + java.util.regex.Pattern pattern = java.util.regex.Pattern.compile("filename=['\"]?([^'\"\\s]+)['\"]?"); + java.util.regex.Matcher matcher = pattern.matcher(contentDisposition.get()); + if (matcher.find()) + filename = matcher.group(1); + } + File file = null; + if (filename != null) { + java.nio.file.Path tempDir = java.nio.file.Files.createTempDirectory("swagger-gen-native"); + java.nio.file.Path filePath = java.nio.file.Files.createFile(tempDir.resolve(filename)); + file = filePath.toFile(); + tempDir.toFile().deleteOnExit(); // best effort cleanup + file.deleteOnExit(); // best effort cleanup + } else { + file = java.nio.file.Files.createTempFile("download-", "").toFile(); + file.deleteOnExit(); // best effort cleanup + } + return file; + } + + /** + * Limits + * Return the plan limits applying to the account. + * @return CompletableFuture<Limits200ResponseDto> + * @throws ApiException if fails to make API call + */ + public CompletableFuture limits() throws ApiException { + return limits(null); + } + + /** + * Limits + * Return the plan limits applying to the account. + * @param headers Optional headers to include in the request + * @return CompletableFuture<Limits200ResponseDto> + * @throws ApiException if fails to make API call + */ + public CompletableFuture limits(Map headers) throws ApiException { + try { + return limitsWithHttpInfo(headers) + .thenApply(ApiResponse::getData); + } + catch (ApiException e) { + return CompletableFuture.failedFuture(e); + } + } + + /** + * Limits + * Return the plan limits applying to the account. + * @return CompletableFuture<ApiResponse<Limits200ResponseDto>> + * @throws ApiException if fails to make API call + */ + public CompletableFuture> limitsWithHttpInfo() throws ApiException { + return limitsWithHttpInfo(null); + } + + /** + * Limits + * Return the plan limits applying to the account. + * @param headers Optional headers to include in the request + * @return CompletableFuture<ApiResponse<Limits200ResponseDto>> + * @throws ApiException if fails to make API call + */ + public CompletableFuture> limitsWithHttpInfo(Map headers) throws ApiException { + try { + HttpRequest.Builder localVarRequestBuilder = limitsRequestBuilder(headers); + return memberVarHttpClient.sendAsync( + localVarRequestBuilder.build(), + HttpResponse.BodyHandlers.ofInputStream()).thenComposeAsync(localVarResponse -> { + if (memberVarAsyncResponseInterceptor != null) { + memberVarAsyncResponseInterceptor.accept(localVarResponse); + } + if (localVarResponse.statusCode()/ 100 != 2) { + return CompletableFuture.failedFuture(getApiException("limits", localVarResponse)); + } + try { + InputStream localVarResponseBody = ApiClient.getResponseBody(localVarResponse); + try { + if (localVarResponseBody == null) { + return CompletableFuture.completedFuture( + new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + null + ) + ); + } + + + String responseBody = new String(localVarResponseBody.readAllBytes()); + Limits200ResponseDto responseValue = responseBody.isBlank()? null: memberVarObjectMapper.readValue(responseBody, new TypeReference() {}); + + return CompletableFuture.completedFuture( + new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + responseValue + ) + ); + } finally { + if (localVarResponseBody != null) { + localVarResponseBody.close(); + } + } + } catch (IOException e) { + return CompletableFuture.failedFuture(new ApiException(e)); + } + } + ); + } + catch (ApiException e) { + return CompletableFuture.failedFuture(e); + } + } + + private HttpRequest.Builder limitsRequestBuilder(Map headers) throws ApiException { + + HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); + + String localVarPath = "/account/limits"; + + localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); + + localVarRequestBuilder.header("Accept", "application/json"); + + localVarRequestBuilder.method("GET", HttpRequest.BodyPublishers.noBody()); + if (memberVarReadTimeout != null) { + localVarRequestBuilder.timeout(memberVarReadTimeout); + } + // Add custom headers if provided + localVarRequestBuilder = HttpRequestBuilderExtensions.withAdditionalHeaders(localVarRequestBuilder, headers); + if (memberVarInterceptor != null) { + memberVarInterceptor.accept(localVarRequestBuilder); + } + return localVarRequestBuilder; + } + +} diff --git a/src/main/java/com/regexsolver/api/generated/api/AnalyzeApi.java b/src/main/java/com/regexsolver/api/generated/api/AnalyzeApi.java new file mode 100644 index 0000000..ee7f989 --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/api/AnalyzeApi.java @@ -0,0 +1,1497 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +package com.regexsolver.api.generated.api; + +import com.regexsolver.api.generated.ApiClient; +import com.regexsolver.api.generated.ApiException; +import com.regexsolver.api.generated.ApiResponse; +import com.regexsolver.api.generated.Configuration; +import com.regexsolver.api.generated.Pair; + +import com.regexsolver.api.generated.model.Cardinality200ResponseDto; +import com.regexsolver.api.generated.model.Dot200ResponseDto; +import com.regexsolver.api.generated.model.Empty200ResponseDto; +import com.regexsolver.api.generated.model.ErrorResponse400Dto; +import com.regexsolver.api.generated.model.ErrorResponse401Dto; +import com.regexsolver.api.generated.model.ErrorResponse403Dto; +import com.regexsolver.api.generated.model.ErrorResponseDto; +import com.regexsolver.api.generated.model.Length200ResponseDto; +import com.regexsolver.api.generated.model.TermRequestDto; +import com.regexsolver.api.generated.model.TwoTermsRequestDto; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.InputStream; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.net.http.HttpRequest; +import java.nio.channels.Channels; +import java.nio.channels.Pipe; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.time.Duration; + +import java.util.ArrayList; +import java.util.StringJoiner; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Consumer; + +import java.util.concurrent.CompletableFuture; + +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class AnalyzeApi { + /** + * Utility class for extending HttpRequest.Builder functionality. + */ + private static class HttpRequestBuilderExtensions { + /** + * Adds additional headers to the provided HttpRequest.Builder. Useful for adding method/endpoint specific headers. + * + * @param builder the HttpRequest.Builder to which headers will be added + * @param headers a map of header names and values to add; may be null + * @return the same HttpRequest.Builder instance with the additional headers set + */ + static HttpRequest.Builder withAdditionalHeaders(HttpRequest.Builder builder, Map headers) { + if (headers != null) { + for (Map.Entry entry : headers.entrySet()) { + builder.header(entry.getKey(), entry.getValue()); + } + } + return builder; + } + } + private final HttpClient memberVarHttpClient; + private final ObjectMapper memberVarObjectMapper; + private final String memberVarBaseUri; + private final Consumer memberVarInterceptor; + private final Duration memberVarReadTimeout; + private final Consumer> memberVarResponseInterceptor; + private final Consumer> memberVarAsyncResponseInterceptor; + + public AnalyzeApi() { + this(Configuration.getDefaultApiClient()); + } + + public AnalyzeApi(ApiClient apiClient) { + memberVarHttpClient = apiClient.getHttpClient(); + memberVarObjectMapper = apiClient.getObjectMapper(); + memberVarBaseUri = apiClient.getBaseUri(); + memberVarInterceptor = apiClient.getRequestInterceptor(); + memberVarReadTimeout = apiClient.getReadTimeout(); + memberVarResponseInterceptor = apiClient.getResponseInterceptor(); + memberVarAsyncResponseInterceptor = apiClient.getAsyncResponseInterceptor(); + } + + + private ApiException getApiException(String operationId, HttpResponse response) { + try { + InputStream responseBody = ApiClient.getResponseBody(response); + String body = null; + if (responseBody != null) { + body = new String(responseBody.readAllBytes()); + responseBody.close(); + } + String message = formatExceptionMessage(operationId, response.statusCode(), body); + return new ApiException(response.statusCode(), message, response.headers(), body); + } catch (IOException e) { + return new ApiException(e); + } + } + + private String formatExceptionMessage(String operationId, int statusCode, String body) { + if (body == null || body.isEmpty()) { + body = "[no body]"; + } + return operationId + " call failed with: " + statusCode + " - " + body; + } + + /** + * Download file from the given response. + * + * @param response Response + * @return File + * @throws ApiException If fail to read file content from response and write to disk + */ + public File downloadFileFromResponse(HttpResponse response, InputStream responseBody) throws ApiException { + if (responseBody == null) { + throw new ApiException(new IOException("Response body is empty")); + } + try { + File file = prepareDownloadFile(response); + java.nio.file.Files.copy(responseBody, file.toPath(), java.nio.file.StandardCopyOption.REPLACE_EXISTING); + return file; + } catch (IOException e) { + throw new ApiException(e); + } + } + + /** + *

Prepare the file for download from the response.

+ * + * @param response a {@link java.net.http.HttpResponse} object. + * @return a {@link java.io.File} object. + * @throws java.io.IOException if any. + */ + private File prepareDownloadFile(HttpResponse response) throws IOException { + String filename = null; + java.util.Optional contentDisposition = response.headers().firstValue("Content-Disposition"); + if (contentDisposition.isPresent() && !"".equals(contentDisposition.get())) { + // Get filename from the Content-Disposition header. + java.util.regex.Pattern pattern = java.util.regex.Pattern.compile("filename=['\"]?([^'\"\\s]+)['\"]?"); + java.util.regex.Matcher matcher = pattern.matcher(contentDisposition.get()); + if (matcher.find()) + filename = matcher.group(1); + } + File file = null; + if (filename != null) { + java.nio.file.Path tempDir = java.nio.file.Files.createTempDirectory("swagger-gen-native"); + java.nio.file.Path filePath = java.nio.file.Files.createFile(tempDir.resolve(filename)); + file = filePath.toFile(); + tempDir.toFile().deleteOnExit(); // best effort cleanup + file.deleteOnExit(); // best effort cleanup + } else { + file = java.nio.file.Files.createTempFile("download-", "").toFile(); + file.deleteOnExit(); // best effort cleanup + } + return file; + } + + /** + * Cardinality + * Compute how many strings the term matches. + * @param termRequestDto (required) + * @return CompletableFuture<Cardinality200ResponseDto> + * @throws ApiException if fails to make API call + */ + public CompletableFuture cardinality(@jakarta.annotation.Nonnull TermRequestDto termRequestDto) throws ApiException { + return cardinality(termRequestDto, null); + } + + /** + * Cardinality + * Compute how many strings the term matches. + * @param termRequestDto (required) + * @param headers Optional headers to include in the request + * @return CompletableFuture<Cardinality200ResponseDto> + * @throws ApiException if fails to make API call + */ + public CompletableFuture cardinality(@jakarta.annotation.Nonnull TermRequestDto termRequestDto, Map headers) throws ApiException { + try { + return cardinalityWithHttpInfo(termRequestDto, headers) + .thenApply(ApiResponse::getData); + } + catch (ApiException e) { + return CompletableFuture.failedFuture(e); + } + } + + /** + * Cardinality + * Compute how many strings the term matches. + * @param termRequestDto (required) + * @return CompletableFuture<ApiResponse<Cardinality200ResponseDto>> + * @throws ApiException if fails to make API call + */ + public CompletableFuture> cardinalityWithHttpInfo(@jakarta.annotation.Nonnull TermRequestDto termRequestDto) throws ApiException { + return cardinalityWithHttpInfo(termRequestDto, null); + } + + /** + * Cardinality + * Compute how many strings the term matches. + * @param termRequestDto (required) + * @param headers Optional headers to include in the request + * @return CompletableFuture<ApiResponse<Cardinality200ResponseDto>> + * @throws ApiException if fails to make API call + */ + public CompletableFuture> cardinalityWithHttpInfo(@jakarta.annotation.Nonnull TermRequestDto termRequestDto, Map headers) throws ApiException { + try { + HttpRequest.Builder localVarRequestBuilder = cardinalityRequestBuilder(termRequestDto, headers); + return memberVarHttpClient.sendAsync( + localVarRequestBuilder.build(), + HttpResponse.BodyHandlers.ofInputStream()).thenComposeAsync(localVarResponse -> { + if (memberVarAsyncResponseInterceptor != null) { + memberVarAsyncResponseInterceptor.accept(localVarResponse); + } + if (localVarResponse.statusCode()/ 100 != 2) { + return CompletableFuture.failedFuture(getApiException("cardinality", localVarResponse)); + } + try { + InputStream localVarResponseBody = ApiClient.getResponseBody(localVarResponse); + try { + if (localVarResponseBody == null) { + return CompletableFuture.completedFuture( + new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + null + ) + ); + } + + + String responseBody = new String(localVarResponseBody.readAllBytes()); + Cardinality200ResponseDto responseValue = responseBody.isBlank()? null: memberVarObjectMapper.readValue(responseBody, new TypeReference() {}); + + return CompletableFuture.completedFuture( + new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + responseValue + ) + ); + } finally { + if (localVarResponseBody != null) { + localVarResponseBody.close(); + } + } + } catch (IOException e) { + return CompletableFuture.failedFuture(new ApiException(e)); + } + } + ); + } + catch (ApiException e) { + return CompletableFuture.failedFuture(e); + } + } + + private HttpRequest.Builder cardinalityRequestBuilder(@jakarta.annotation.Nonnull TermRequestDto termRequestDto, Map headers) throws ApiException { + // verify the required parameter 'termRequestDto' is set + if (termRequestDto == null) { + throw new ApiException(400, "Missing the required parameter 'termRequestDto' when calling cardinality"); + } + + HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); + + String localVarPath = "/analyze/cardinality"; + + localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); + + localVarRequestBuilder.header("Content-Type", "application/json"); + localVarRequestBuilder.header("Accept", "application/json"); + + try { + byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(termRequestDto); + localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); + } catch (IOException e) { + throw new ApiException(e); + } + if (memberVarReadTimeout != null) { + localVarRequestBuilder.timeout(memberVarReadTimeout); + } + // Add custom headers if provided + localVarRequestBuilder = HttpRequestBuilderExtensions.withAdditionalHeaders(localVarRequestBuilder, headers); + if (memberVarInterceptor != null) { + memberVarInterceptor.accept(localVarRequestBuilder); + } + return localVarRequestBuilder; + } + + /** + * Deterministic + * Check if the term's automaton is deterministic. Only a deterministic FAIR guarantees consistent string ordering across paginated /generate/strings requests; call /compute/determinize first if this is false. + * @param termRequestDto (required) + * @return CompletableFuture<Empty200ResponseDto> + * @throws ApiException if fails to make API call + */ + public CompletableFuture deterministic(@jakarta.annotation.Nonnull TermRequestDto termRequestDto) throws ApiException { + return deterministic(termRequestDto, null); + } + + /** + * Deterministic + * Check if the term's automaton is deterministic. Only a deterministic FAIR guarantees consistent string ordering across paginated /generate/strings requests; call /compute/determinize first if this is false. + * @param termRequestDto (required) + * @param headers Optional headers to include in the request + * @return CompletableFuture<Empty200ResponseDto> + * @throws ApiException if fails to make API call + */ + public CompletableFuture deterministic(@jakarta.annotation.Nonnull TermRequestDto termRequestDto, Map headers) throws ApiException { + try { + return deterministicWithHttpInfo(termRequestDto, headers) + .thenApply(ApiResponse::getData); + } + catch (ApiException e) { + return CompletableFuture.failedFuture(e); + } + } + + /** + * Deterministic + * Check if the term's automaton is deterministic. Only a deterministic FAIR guarantees consistent string ordering across paginated /generate/strings requests; call /compute/determinize first if this is false. + * @param termRequestDto (required) + * @return CompletableFuture<ApiResponse<Empty200ResponseDto>> + * @throws ApiException if fails to make API call + */ + public CompletableFuture> deterministicWithHttpInfo(@jakarta.annotation.Nonnull TermRequestDto termRequestDto) throws ApiException { + return deterministicWithHttpInfo(termRequestDto, null); + } + + /** + * Deterministic + * Check if the term's automaton is deterministic. Only a deterministic FAIR guarantees consistent string ordering across paginated /generate/strings requests; call /compute/determinize first if this is false. + * @param termRequestDto (required) + * @param headers Optional headers to include in the request + * @return CompletableFuture<ApiResponse<Empty200ResponseDto>> + * @throws ApiException if fails to make API call + */ + public CompletableFuture> deterministicWithHttpInfo(@jakarta.annotation.Nonnull TermRequestDto termRequestDto, Map headers) throws ApiException { + try { + HttpRequest.Builder localVarRequestBuilder = deterministicRequestBuilder(termRequestDto, headers); + return memberVarHttpClient.sendAsync( + localVarRequestBuilder.build(), + HttpResponse.BodyHandlers.ofInputStream()).thenComposeAsync(localVarResponse -> { + if (memberVarAsyncResponseInterceptor != null) { + memberVarAsyncResponseInterceptor.accept(localVarResponse); + } + if (localVarResponse.statusCode()/ 100 != 2) { + return CompletableFuture.failedFuture(getApiException("deterministic", localVarResponse)); + } + try { + InputStream localVarResponseBody = ApiClient.getResponseBody(localVarResponse); + try { + if (localVarResponseBody == null) { + return CompletableFuture.completedFuture( + new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + null + ) + ); + } + + + String responseBody = new String(localVarResponseBody.readAllBytes()); + Empty200ResponseDto responseValue = responseBody.isBlank()? null: memberVarObjectMapper.readValue(responseBody, new TypeReference() {}); + + return CompletableFuture.completedFuture( + new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + responseValue + ) + ); + } finally { + if (localVarResponseBody != null) { + localVarResponseBody.close(); + } + } + } catch (IOException e) { + return CompletableFuture.failedFuture(new ApiException(e)); + } + } + ); + } + catch (ApiException e) { + return CompletableFuture.failedFuture(e); + } + } + + private HttpRequest.Builder deterministicRequestBuilder(@jakarta.annotation.Nonnull TermRequestDto termRequestDto, Map headers) throws ApiException { + // verify the required parameter 'termRequestDto' is set + if (termRequestDto == null) { + throw new ApiException(400, "Missing the required parameter 'termRequestDto' when calling deterministic"); + } + + HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); + + String localVarPath = "/analyze/deterministic"; + + localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); + + localVarRequestBuilder.header("Content-Type", "application/json"); + localVarRequestBuilder.header("Accept", "application/json"); + + try { + byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(termRequestDto); + localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); + } catch (IOException e) { + throw new ApiException(e); + } + if (memberVarReadTimeout != null) { + localVarRequestBuilder.timeout(memberVarReadTimeout); + } + // Add custom headers if provided + localVarRequestBuilder = HttpRequestBuilderExtensions.withAdditionalHeaders(localVarRequestBuilder, headers); + if (memberVarInterceptor != null) { + memberVarInterceptor.accept(localVarRequestBuilder); + } + return localVarRequestBuilder; + } + + /** + * Graphviz DOT + * Build a Graphviz DOT representation of the term's automaton. + * @param termRequestDto (required) + * @return CompletableFuture<Dot200ResponseDto> + * @throws ApiException if fails to make API call + */ + public CompletableFuture dot(@jakarta.annotation.Nonnull TermRequestDto termRequestDto) throws ApiException { + return dot(termRequestDto, null); + } + + /** + * Graphviz DOT + * Build a Graphviz DOT representation of the term's automaton. + * @param termRequestDto (required) + * @param headers Optional headers to include in the request + * @return CompletableFuture<Dot200ResponseDto> + * @throws ApiException if fails to make API call + */ + public CompletableFuture dot(@jakarta.annotation.Nonnull TermRequestDto termRequestDto, Map headers) throws ApiException { + try { + return dotWithHttpInfo(termRequestDto, headers) + .thenApply(ApiResponse::getData); + } + catch (ApiException e) { + return CompletableFuture.failedFuture(e); + } + } + + /** + * Graphviz DOT + * Build a Graphviz DOT representation of the term's automaton. + * @param termRequestDto (required) + * @return CompletableFuture<ApiResponse<Dot200ResponseDto>> + * @throws ApiException if fails to make API call + */ + public CompletableFuture> dotWithHttpInfo(@jakarta.annotation.Nonnull TermRequestDto termRequestDto) throws ApiException { + return dotWithHttpInfo(termRequestDto, null); + } + + /** + * Graphviz DOT + * Build a Graphviz DOT representation of the term's automaton. + * @param termRequestDto (required) + * @param headers Optional headers to include in the request + * @return CompletableFuture<ApiResponse<Dot200ResponseDto>> + * @throws ApiException if fails to make API call + */ + public CompletableFuture> dotWithHttpInfo(@jakarta.annotation.Nonnull TermRequestDto termRequestDto, Map headers) throws ApiException { + try { + HttpRequest.Builder localVarRequestBuilder = dotRequestBuilder(termRequestDto, headers); + return memberVarHttpClient.sendAsync( + localVarRequestBuilder.build(), + HttpResponse.BodyHandlers.ofInputStream()).thenComposeAsync(localVarResponse -> { + if (memberVarAsyncResponseInterceptor != null) { + memberVarAsyncResponseInterceptor.accept(localVarResponse); + } + if (localVarResponse.statusCode()/ 100 != 2) { + return CompletableFuture.failedFuture(getApiException("dot", localVarResponse)); + } + try { + InputStream localVarResponseBody = ApiClient.getResponseBody(localVarResponse); + try { + if (localVarResponseBody == null) { + return CompletableFuture.completedFuture( + new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + null + ) + ); + } + + + String responseBody = new String(localVarResponseBody.readAllBytes()); + Dot200ResponseDto responseValue = responseBody.isBlank()? null: memberVarObjectMapper.readValue(responseBody, new TypeReference() {}); + + return CompletableFuture.completedFuture( + new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + responseValue + ) + ); + } finally { + if (localVarResponseBody != null) { + localVarResponseBody.close(); + } + } + } catch (IOException e) { + return CompletableFuture.failedFuture(new ApiException(e)); + } + } + ); + } + catch (ApiException e) { + return CompletableFuture.failedFuture(e); + } + } + + private HttpRequest.Builder dotRequestBuilder(@jakarta.annotation.Nonnull TermRequestDto termRequestDto, Map headers) throws ApiException { + // verify the required parameter 'termRequestDto' is set + if (termRequestDto == null) { + throw new ApiException(400, "Missing the required parameter 'termRequestDto' when calling dot"); + } + + HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); + + String localVarPath = "/analyze/dot"; + + localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); + + localVarRequestBuilder.header("Content-Type", "application/json"); + localVarRequestBuilder.header("Accept", "application/json"); + + try { + byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(termRequestDto); + localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); + } catch (IOException e) { + throw new ApiException(e); + } + if (memberVarReadTimeout != null) { + localVarRequestBuilder.timeout(memberVarReadTimeout); + } + // Add custom headers if provided + localVarRequestBuilder = HttpRequestBuilderExtensions.withAdditionalHeaders(localVarRequestBuilder, headers); + if (memberVarInterceptor != null) { + memberVarInterceptor.accept(localVarRequestBuilder); + } + return localVarRequestBuilder; + } + + /** + * Empty + * Check if the term matches no strings. + * @param termRequestDto (required) + * @return CompletableFuture<Empty200ResponseDto> + * @throws ApiException if fails to make API call + */ + public CompletableFuture empty(@jakarta.annotation.Nonnull TermRequestDto termRequestDto) throws ApiException { + return empty(termRequestDto, null); + } + + /** + * Empty + * Check if the term matches no strings. + * @param termRequestDto (required) + * @param headers Optional headers to include in the request + * @return CompletableFuture<Empty200ResponseDto> + * @throws ApiException if fails to make API call + */ + public CompletableFuture empty(@jakarta.annotation.Nonnull TermRequestDto termRequestDto, Map headers) throws ApiException { + try { + return emptyWithHttpInfo(termRequestDto, headers) + .thenApply(ApiResponse::getData); + } + catch (ApiException e) { + return CompletableFuture.failedFuture(e); + } + } + + /** + * Empty + * Check if the term matches no strings. + * @param termRequestDto (required) + * @return CompletableFuture<ApiResponse<Empty200ResponseDto>> + * @throws ApiException if fails to make API call + */ + public CompletableFuture> emptyWithHttpInfo(@jakarta.annotation.Nonnull TermRequestDto termRequestDto) throws ApiException { + return emptyWithHttpInfo(termRequestDto, null); + } + + /** + * Empty + * Check if the term matches no strings. + * @param termRequestDto (required) + * @param headers Optional headers to include in the request + * @return CompletableFuture<ApiResponse<Empty200ResponseDto>> + * @throws ApiException if fails to make API call + */ + public CompletableFuture> emptyWithHttpInfo(@jakarta.annotation.Nonnull TermRequestDto termRequestDto, Map headers) throws ApiException { + try { + HttpRequest.Builder localVarRequestBuilder = emptyRequestBuilder(termRequestDto, headers); + return memberVarHttpClient.sendAsync( + localVarRequestBuilder.build(), + HttpResponse.BodyHandlers.ofInputStream()).thenComposeAsync(localVarResponse -> { + if (memberVarAsyncResponseInterceptor != null) { + memberVarAsyncResponseInterceptor.accept(localVarResponse); + } + if (localVarResponse.statusCode()/ 100 != 2) { + return CompletableFuture.failedFuture(getApiException("empty", localVarResponse)); + } + try { + InputStream localVarResponseBody = ApiClient.getResponseBody(localVarResponse); + try { + if (localVarResponseBody == null) { + return CompletableFuture.completedFuture( + new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + null + ) + ); + } + + + String responseBody = new String(localVarResponseBody.readAllBytes()); + Empty200ResponseDto responseValue = responseBody.isBlank()? null: memberVarObjectMapper.readValue(responseBody, new TypeReference() {}); + + return CompletableFuture.completedFuture( + new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + responseValue + ) + ); + } finally { + if (localVarResponseBody != null) { + localVarResponseBody.close(); + } + } + } catch (IOException e) { + return CompletableFuture.failedFuture(new ApiException(e)); + } + } + ); + } + catch (ApiException e) { + return CompletableFuture.failedFuture(e); + } + } + + private HttpRequest.Builder emptyRequestBuilder(@jakarta.annotation.Nonnull TermRequestDto termRequestDto, Map headers) throws ApiException { + // verify the required parameter 'termRequestDto' is set + if (termRequestDto == null) { + throw new ApiException(400, "Missing the required parameter 'termRequestDto' when calling empty"); + } + + HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); + + String localVarPath = "/analyze/empty"; + + localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); + + localVarRequestBuilder.header("Content-Type", "application/json"); + localVarRequestBuilder.header("Accept", "application/json"); + + try { + byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(termRequestDto); + localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); + } catch (IOException e) { + throw new ApiException(e); + } + if (memberVarReadTimeout != null) { + localVarRequestBuilder.timeout(memberVarReadTimeout); + } + // Add custom headers if provided + localVarRequestBuilder = HttpRequestBuilderExtensions.withAdditionalHeaders(localVarRequestBuilder, headers); + if (memberVarInterceptor != null) { + memberVarInterceptor.accept(localVarRequestBuilder); + } + return localVarRequestBuilder; + } + + /** + * Empty String Only + * Check if the term matches only the empty string. + * @param termRequestDto (required) + * @return CompletableFuture<Empty200ResponseDto> + * @throws ApiException if fails to make API call + */ + public CompletableFuture emptyString(@jakarta.annotation.Nonnull TermRequestDto termRequestDto) throws ApiException { + return emptyString(termRequestDto, null); + } + + /** + * Empty String Only + * Check if the term matches only the empty string. + * @param termRequestDto (required) + * @param headers Optional headers to include in the request + * @return CompletableFuture<Empty200ResponseDto> + * @throws ApiException if fails to make API call + */ + public CompletableFuture emptyString(@jakarta.annotation.Nonnull TermRequestDto termRequestDto, Map headers) throws ApiException { + try { + return emptyStringWithHttpInfo(termRequestDto, headers) + .thenApply(ApiResponse::getData); + } + catch (ApiException e) { + return CompletableFuture.failedFuture(e); + } + } + + /** + * Empty String Only + * Check if the term matches only the empty string. + * @param termRequestDto (required) + * @return CompletableFuture<ApiResponse<Empty200ResponseDto>> + * @throws ApiException if fails to make API call + */ + public CompletableFuture> emptyStringWithHttpInfo(@jakarta.annotation.Nonnull TermRequestDto termRequestDto) throws ApiException { + return emptyStringWithHttpInfo(termRequestDto, null); + } + + /** + * Empty String Only + * Check if the term matches only the empty string. + * @param termRequestDto (required) + * @param headers Optional headers to include in the request + * @return CompletableFuture<ApiResponse<Empty200ResponseDto>> + * @throws ApiException if fails to make API call + */ + public CompletableFuture> emptyStringWithHttpInfo(@jakarta.annotation.Nonnull TermRequestDto termRequestDto, Map headers) throws ApiException { + try { + HttpRequest.Builder localVarRequestBuilder = emptyStringRequestBuilder(termRequestDto, headers); + return memberVarHttpClient.sendAsync( + localVarRequestBuilder.build(), + HttpResponse.BodyHandlers.ofInputStream()).thenComposeAsync(localVarResponse -> { + if (memberVarAsyncResponseInterceptor != null) { + memberVarAsyncResponseInterceptor.accept(localVarResponse); + } + if (localVarResponse.statusCode()/ 100 != 2) { + return CompletableFuture.failedFuture(getApiException("emptyString", localVarResponse)); + } + try { + InputStream localVarResponseBody = ApiClient.getResponseBody(localVarResponse); + try { + if (localVarResponseBody == null) { + return CompletableFuture.completedFuture( + new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + null + ) + ); + } + + + String responseBody = new String(localVarResponseBody.readAllBytes()); + Empty200ResponseDto responseValue = responseBody.isBlank()? null: memberVarObjectMapper.readValue(responseBody, new TypeReference() {}); + + return CompletableFuture.completedFuture( + new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + responseValue + ) + ); + } finally { + if (localVarResponseBody != null) { + localVarResponseBody.close(); + } + } + } catch (IOException e) { + return CompletableFuture.failedFuture(new ApiException(e)); + } + } + ); + } + catch (ApiException e) { + return CompletableFuture.failedFuture(e); + } + } + + private HttpRequest.Builder emptyStringRequestBuilder(@jakarta.annotation.Nonnull TermRequestDto termRequestDto, Map headers) throws ApiException { + // verify the required parameter 'termRequestDto' is set + if (termRequestDto == null) { + throw new ApiException(400, "Missing the required parameter 'termRequestDto' when calling emptyString"); + } + + HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); + + String localVarPath = "/analyze/empty_string"; + + localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); + + localVarRequestBuilder.header("Content-Type", "application/json"); + localVarRequestBuilder.header("Accept", "application/json"); + + try { + byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(termRequestDto); + localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); + } catch (IOException e) { + throw new ApiException(e); + } + if (memberVarReadTimeout != null) { + localVarRequestBuilder.timeout(memberVarReadTimeout); + } + // Add custom headers if provided + localVarRequestBuilder = HttpRequestBuilderExtensions.withAdditionalHeaders(localVarRequestBuilder, headers); + if (memberVarInterceptor != null) { + memberVarInterceptor.accept(localVarRequestBuilder); + } + return localVarRequestBuilder; + } + + /** + * Equivalent + * Check if the two terms accept exactly the same language. + * @param twoTermsRequestDto (required) + * @return CompletableFuture<Empty200ResponseDto> + * @throws ApiException if fails to make API call + */ + public CompletableFuture equivalent(@jakarta.annotation.Nonnull TwoTermsRequestDto twoTermsRequestDto) throws ApiException { + return equivalent(twoTermsRequestDto, null); + } + + /** + * Equivalent + * Check if the two terms accept exactly the same language. + * @param twoTermsRequestDto (required) + * @param headers Optional headers to include in the request + * @return CompletableFuture<Empty200ResponseDto> + * @throws ApiException if fails to make API call + */ + public CompletableFuture equivalent(@jakarta.annotation.Nonnull TwoTermsRequestDto twoTermsRequestDto, Map headers) throws ApiException { + try { + return equivalentWithHttpInfo(twoTermsRequestDto, headers) + .thenApply(ApiResponse::getData); + } + catch (ApiException e) { + return CompletableFuture.failedFuture(e); + } + } + + /** + * Equivalent + * Check if the two terms accept exactly the same language. + * @param twoTermsRequestDto (required) + * @return CompletableFuture<ApiResponse<Empty200ResponseDto>> + * @throws ApiException if fails to make API call + */ + public CompletableFuture> equivalentWithHttpInfo(@jakarta.annotation.Nonnull TwoTermsRequestDto twoTermsRequestDto) throws ApiException { + return equivalentWithHttpInfo(twoTermsRequestDto, null); + } + + /** + * Equivalent + * Check if the two terms accept exactly the same language. + * @param twoTermsRequestDto (required) + * @param headers Optional headers to include in the request + * @return CompletableFuture<ApiResponse<Empty200ResponseDto>> + * @throws ApiException if fails to make API call + */ + public CompletableFuture> equivalentWithHttpInfo(@jakarta.annotation.Nonnull TwoTermsRequestDto twoTermsRequestDto, Map headers) throws ApiException { + try { + HttpRequest.Builder localVarRequestBuilder = equivalentRequestBuilder(twoTermsRequestDto, headers); + return memberVarHttpClient.sendAsync( + localVarRequestBuilder.build(), + HttpResponse.BodyHandlers.ofInputStream()).thenComposeAsync(localVarResponse -> { + if (memberVarAsyncResponseInterceptor != null) { + memberVarAsyncResponseInterceptor.accept(localVarResponse); + } + if (localVarResponse.statusCode()/ 100 != 2) { + return CompletableFuture.failedFuture(getApiException("equivalent", localVarResponse)); + } + try { + InputStream localVarResponseBody = ApiClient.getResponseBody(localVarResponse); + try { + if (localVarResponseBody == null) { + return CompletableFuture.completedFuture( + new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + null + ) + ); + } + + + String responseBody = new String(localVarResponseBody.readAllBytes()); + Empty200ResponseDto responseValue = responseBody.isBlank()? null: memberVarObjectMapper.readValue(responseBody, new TypeReference() {}); + + return CompletableFuture.completedFuture( + new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + responseValue + ) + ); + } finally { + if (localVarResponseBody != null) { + localVarResponseBody.close(); + } + } + } catch (IOException e) { + return CompletableFuture.failedFuture(new ApiException(e)); + } + } + ); + } + catch (ApiException e) { + return CompletableFuture.failedFuture(e); + } + } + + private HttpRequest.Builder equivalentRequestBuilder(@jakarta.annotation.Nonnull TwoTermsRequestDto twoTermsRequestDto, Map headers) throws ApiException { + // verify the required parameter 'twoTermsRequestDto' is set + if (twoTermsRequestDto == null) { + throw new ApiException(400, "Missing the required parameter 'twoTermsRequestDto' when calling equivalent"); + } + + HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); + + String localVarPath = "/analyze/equivalent"; + + localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); + + localVarRequestBuilder.header("Content-Type", "application/json"); + localVarRequestBuilder.header("Accept", "application/json"); + + try { + byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(twoTermsRequestDto); + localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); + } catch (IOException e) { + throw new ApiException(e); + } + if (memberVarReadTimeout != null) { + localVarRequestBuilder.timeout(memberVarReadTimeout); + } + // Add custom headers if provided + localVarRequestBuilder = HttpRequestBuilderExtensions.withAdditionalHeaders(localVarRequestBuilder, headers); + if (memberVarInterceptor != null) { + memberVarInterceptor.accept(localVarRequestBuilder); + } + return localVarRequestBuilder; + } + + /** + * Length + * Compute the minimum and maximum length of strings matched by the term. + * @param termRequestDto (required) + * @return CompletableFuture<Length200ResponseDto> + * @throws ApiException if fails to make API call + */ + public CompletableFuture length(@jakarta.annotation.Nonnull TermRequestDto termRequestDto) throws ApiException { + return length(termRequestDto, null); + } + + /** + * Length + * Compute the minimum and maximum length of strings matched by the term. + * @param termRequestDto (required) + * @param headers Optional headers to include in the request + * @return CompletableFuture<Length200ResponseDto> + * @throws ApiException if fails to make API call + */ + public CompletableFuture length(@jakarta.annotation.Nonnull TermRequestDto termRequestDto, Map headers) throws ApiException { + try { + return lengthWithHttpInfo(termRequestDto, headers) + .thenApply(ApiResponse::getData); + } + catch (ApiException e) { + return CompletableFuture.failedFuture(e); + } + } + + /** + * Length + * Compute the minimum and maximum length of strings matched by the term. + * @param termRequestDto (required) + * @return CompletableFuture<ApiResponse<Length200ResponseDto>> + * @throws ApiException if fails to make API call + */ + public CompletableFuture> lengthWithHttpInfo(@jakarta.annotation.Nonnull TermRequestDto termRequestDto) throws ApiException { + return lengthWithHttpInfo(termRequestDto, null); + } + + /** + * Length + * Compute the minimum and maximum length of strings matched by the term. + * @param termRequestDto (required) + * @param headers Optional headers to include in the request + * @return CompletableFuture<ApiResponse<Length200ResponseDto>> + * @throws ApiException if fails to make API call + */ + public CompletableFuture> lengthWithHttpInfo(@jakarta.annotation.Nonnull TermRequestDto termRequestDto, Map headers) throws ApiException { + try { + HttpRequest.Builder localVarRequestBuilder = lengthRequestBuilder(termRequestDto, headers); + return memberVarHttpClient.sendAsync( + localVarRequestBuilder.build(), + HttpResponse.BodyHandlers.ofInputStream()).thenComposeAsync(localVarResponse -> { + if (memberVarAsyncResponseInterceptor != null) { + memberVarAsyncResponseInterceptor.accept(localVarResponse); + } + if (localVarResponse.statusCode()/ 100 != 2) { + return CompletableFuture.failedFuture(getApiException("length", localVarResponse)); + } + try { + InputStream localVarResponseBody = ApiClient.getResponseBody(localVarResponse); + try { + if (localVarResponseBody == null) { + return CompletableFuture.completedFuture( + new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + null + ) + ); + } + + + String responseBody = new String(localVarResponseBody.readAllBytes()); + Length200ResponseDto responseValue = responseBody.isBlank()? null: memberVarObjectMapper.readValue(responseBody, new TypeReference() {}); + + return CompletableFuture.completedFuture( + new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + responseValue + ) + ); + } finally { + if (localVarResponseBody != null) { + localVarResponseBody.close(); + } + } + } catch (IOException e) { + return CompletableFuture.failedFuture(new ApiException(e)); + } + } + ); + } + catch (ApiException e) { + return CompletableFuture.failedFuture(e); + } + } + + private HttpRequest.Builder lengthRequestBuilder(@jakarta.annotation.Nonnull TermRequestDto termRequestDto, Map headers) throws ApiException { + // verify the required parameter 'termRequestDto' is set + if (termRequestDto == null) { + throw new ApiException(400, "Missing the required parameter 'termRequestDto' when calling length"); + } + + HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); + + String localVarPath = "/analyze/length"; + + localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); + + localVarRequestBuilder.header("Content-Type", "application/json"); + localVarRequestBuilder.header("Accept", "application/json"); + + try { + byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(termRequestDto); + localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); + } catch (IOException e) { + throw new ApiException(e); + } + if (memberVarReadTimeout != null) { + localVarRequestBuilder.timeout(memberVarReadTimeout); + } + // Add custom headers if provided + localVarRequestBuilder = HttpRequestBuilderExtensions.withAdditionalHeaders(localVarRequestBuilder, headers); + if (memberVarInterceptor != null) { + memberVarInterceptor.accept(localVarRequestBuilder); + } + return localVarRequestBuilder; + } + + /** + * Pattern + * Return a regular expression pattern that represents the term. + * @param termRequestDto (required) + * @return CompletableFuture<Dot200ResponseDto> + * @throws ApiException if fails to make API call + */ + public CompletableFuture pattern(@jakarta.annotation.Nonnull TermRequestDto termRequestDto) throws ApiException { + return pattern(termRequestDto, null); + } + + /** + * Pattern + * Return a regular expression pattern that represents the term. + * @param termRequestDto (required) + * @param headers Optional headers to include in the request + * @return CompletableFuture<Dot200ResponseDto> + * @throws ApiException if fails to make API call + */ + public CompletableFuture pattern(@jakarta.annotation.Nonnull TermRequestDto termRequestDto, Map headers) throws ApiException { + try { + return patternWithHttpInfo(termRequestDto, headers) + .thenApply(ApiResponse::getData); + } + catch (ApiException e) { + return CompletableFuture.failedFuture(e); + } + } + + /** + * Pattern + * Return a regular expression pattern that represents the term. + * @param termRequestDto (required) + * @return CompletableFuture<ApiResponse<Dot200ResponseDto>> + * @throws ApiException if fails to make API call + */ + public CompletableFuture> patternWithHttpInfo(@jakarta.annotation.Nonnull TermRequestDto termRequestDto) throws ApiException { + return patternWithHttpInfo(termRequestDto, null); + } + + /** + * Pattern + * Return a regular expression pattern that represents the term. + * @param termRequestDto (required) + * @param headers Optional headers to include in the request + * @return CompletableFuture<ApiResponse<Dot200ResponseDto>> + * @throws ApiException if fails to make API call + */ + public CompletableFuture> patternWithHttpInfo(@jakarta.annotation.Nonnull TermRequestDto termRequestDto, Map headers) throws ApiException { + try { + HttpRequest.Builder localVarRequestBuilder = patternRequestBuilder(termRequestDto, headers); + return memberVarHttpClient.sendAsync( + localVarRequestBuilder.build(), + HttpResponse.BodyHandlers.ofInputStream()).thenComposeAsync(localVarResponse -> { + if (memberVarAsyncResponseInterceptor != null) { + memberVarAsyncResponseInterceptor.accept(localVarResponse); + } + if (localVarResponse.statusCode()/ 100 != 2) { + return CompletableFuture.failedFuture(getApiException("pattern", localVarResponse)); + } + try { + InputStream localVarResponseBody = ApiClient.getResponseBody(localVarResponse); + try { + if (localVarResponseBody == null) { + return CompletableFuture.completedFuture( + new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + null + ) + ); + } + + + String responseBody = new String(localVarResponseBody.readAllBytes()); + Dot200ResponseDto responseValue = responseBody.isBlank()? null: memberVarObjectMapper.readValue(responseBody, new TypeReference() {}); + + return CompletableFuture.completedFuture( + new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + responseValue + ) + ); + } finally { + if (localVarResponseBody != null) { + localVarResponseBody.close(); + } + } + } catch (IOException e) { + return CompletableFuture.failedFuture(new ApiException(e)); + } + } + ); + } + catch (ApiException e) { + return CompletableFuture.failedFuture(e); + } + } + + private HttpRequest.Builder patternRequestBuilder(@jakarta.annotation.Nonnull TermRequestDto termRequestDto, Map headers) throws ApiException { + // verify the required parameter 'termRequestDto' is set + if (termRequestDto == null) { + throw new ApiException(400, "Missing the required parameter 'termRequestDto' when calling pattern"); + } + + HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); + + String localVarPath = "/analyze/pattern"; + + localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); + + localVarRequestBuilder.header("Content-Type", "application/json"); + localVarRequestBuilder.header("Accept", "application/json"); + + try { + byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(termRequestDto); + localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); + } catch (IOException e) { + throw new ApiException(e); + } + if (memberVarReadTimeout != null) { + localVarRequestBuilder.timeout(memberVarReadTimeout); + } + // Add custom headers if provided + localVarRequestBuilder = HttpRequestBuilderExtensions.withAdditionalHeaders(localVarRequestBuilder, headers); + if (memberVarInterceptor != null) { + memberVarInterceptor.accept(localVarRequestBuilder); + } + return localVarRequestBuilder; + } + + /** + * Subset + * Check if the first term's language is a subset of the second term's language. + * @param twoTermsRequestDto (required) + * @return CompletableFuture<Empty200ResponseDto> + * @throws ApiException if fails to make API call + */ + public CompletableFuture subset(@jakarta.annotation.Nonnull TwoTermsRequestDto twoTermsRequestDto) throws ApiException { + return subset(twoTermsRequestDto, null); + } + + /** + * Subset + * Check if the first term's language is a subset of the second term's language. + * @param twoTermsRequestDto (required) + * @param headers Optional headers to include in the request + * @return CompletableFuture<Empty200ResponseDto> + * @throws ApiException if fails to make API call + */ + public CompletableFuture subset(@jakarta.annotation.Nonnull TwoTermsRequestDto twoTermsRequestDto, Map headers) throws ApiException { + try { + return subsetWithHttpInfo(twoTermsRequestDto, headers) + .thenApply(ApiResponse::getData); + } + catch (ApiException e) { + return CompletableFuture.failedFuture(e); + } + } + + /** + * Subset + * Check if the first term's language is a subset of the second term's language. + * @param twoTermsRequestDto (required) + * @return CompletableFuture<ApiResponse<Empty200ResponseDto>> + * @throws ApiException if fails to make API call + */ + public CompletableFuture> subsetWithHttpInfo(@jakarta.annotation.Nonnull TwoTermsRequestDto twoTermsRequestDto) throws ApiException { + return subsetWithHttpInfo(twoTermsRequestDto, null); + } + + /** + * Subset + * Check if the first term's language is a subset of the second term's language. + * @param twoTermsRequestDto (required) + * @param headers Optional headers to include in the request + * @return CompletableFuture<ApiResponse<Empty200ResponseDto>> + * @throws ApiException if fails to make API call + */ + public CompletableFuture> subsetWithHttpInfo(@jakarta.annotation.Nonnull TwoTermsRequestDto twoTermsRequestDto, Map headers) throws ApiException { + try { + HttpRequest.Builder localVarRequestBuilder = subsetRequestBuilder(twoTermsRequestDto, headers); + return memberVarHttpClient.sendAsync( + localVarRequestBuilder.build(), + HttpResponse.BodyHandlers.ofInputStream()).thenComposeAsync(localVarResponse -> { + if (memberVarAsyncResponseInterceptor != null) { + memberVarAsyncResponseInterceptor.accept(localVarResponse); + } + if (localVarResponse.statusCode()/ 100 != 2) { + return CompletableFuture.failedFuture(getApiException("subset", localVarResponse)); + } + try { + InputStream localVarResponseBody = ApiClient.getResponseBody(localVarResponse); + try { + if (localVarResponseBody == null) { + return CompletableFuture.completedFuture( + new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + null + ) + ); + } + + + String responseBody = new String(localVarResponseBody.readAllBytes()); + Empty200ResponseDto responseValue = responseBody.isBlank()? null: memberVarObjectMapper.readValue(responseBody, new TypeReference() {}); + + return CompletableFuture.completedFuture( + new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + responseValue + ) + ); + } finally { + if (localVarResponseBody != null) { + localVarResponseBody.close(); + } + } + } catch (IOException e) { + return CompletableFuture.failedFuture(new ApiException(e)); + } + } + ); + } + catch (ApiException e) { + return CompletableFuture.failedFuture(e); + } + } + + private HttpRequest.Builder subsetRequestBuilder(@jakarta.annotation.Nonnull TwoTermsRequestDto twoTermsRequestDto, Map headers) throws ApiException { + // verify the required parameter 'twoTermsRequestDto' is set + if (twoTermsRequestDto == null) { + throw new ApiException(400, "Missing the required parameter 'twoTermsRequestDto' when calling subset"); + } + + HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); + + String localVarPath = "/analyze/subset"; + + localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); + + localVarRequestBuilder.header("Content-Type", "application/json"); + localVarRequestBuilder.header("Accept", "application/json"); + + try { + byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(twoTermsRequestDto); + localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); + } catch (IOException e) { + throw new ApiException(e); + } + if (memberVarReadTimeout != null) { + localVarRequestBuilder.timeout(memberVarReadTimeout); + } + // Add custom headers if provided + localVarRequestBuilder = HttpRequestBuilderExtensions.withAdditionalHeaders(localVarRequestBuilder, headers); + if (memberVarInterceptor != null) { + memberVarInterceptor.accept(localVarRequestBuilder); + } + return localVarRequestBuilder; + } + + /** + * Totality + * Check if the term matches all the possible strings. + * @param termRequestDto (required) + * @return CompletableFuture<Empty200ResponseDto> + * @throws ApiException if fails to make API call + */ + public CompletableFuture total(@jakarta.annotation.Nonnull TermRequestDto termRequestDto) throws ApiException { + return total(termRequestDto, null); + } + + /** + * Totality + * Check if the term matches all the possible strings. + * @param termRequestDto (required) + * @param headers Optional headers to include in the request + * @return CompletableFuture<Empty200ResponseDto> + * @throws ApiException if fails to make API call + */ + public CompletableFuture total(@jakarta.annotation.Nonnull TermRequestDto termRequestDto, Map headers) throws ApiException { + try { + return totalWithHttpInfo(termRequestDto, headers) + .thenApply(ApiResponse::getData); + } + catch (ApiException e) { + return CompletableFuture.failedFuture(e); + } + } + + /** + * Totality + * Check if the term matches all the possible strings. + * @param termRequestDto (required) + * @return CompletableFuture<ApiResponse<Empty200ResponseDto>> + * @throws ApiException if fails to make API call + */ + public CompletableFuture> totalWithHttpInfo(@jakarta.annotation.Nonnull TermRequestDto termRequestDto) throws ApiException { + return totalWithHttpInfo(termRequestDto, null); + } + + /** + * Totality + * Check if the term matches all the possible strings. + * @param termRequestDto (required) + * @param headers Optional headers to include in the request + * @return CompletableFuture<ApiResponse<Empty200ResponseDto>> + * @throws ApiException if fails to make API call + */ + public CompletableFuture> totalWithHttpInfo(@jakarta.annotation.Nonnull TermRequestDto termRequestDto, Map headers) throws ApiException { + try { + HttpRequest.Builder localVarRequestBuilder = totalRequestBuilder(termRequestDto, headers); + return memberVarHttpClient.sendAsync( + localVarRequestBuilder.build(), + HttpResponse.BodyHandlers.ofInputStream()).thenComposeAsync(localVarResponse -> { + if (memberVarAsyncResponseInterceptor != null) { + memberVarAsyncResponseInterceptor.accept(localVarResponse); + } + if (localVarResponse.statusCode()/ 100 != 2) { + return CompletableFuture.failedFuture(getApiException("total", localVarResponse)); + } + try { + InputStream localVarResponseBody = ApiClient.getResponseBody(localVarResponse); + try { + if (localVarResponseBody == null) { + return CompletableFuture.completedFuture( + new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + null + ) + ); + } + + + String responseBody = new String(localVarResponseBody.readAllBytes()); + Empty200ResponseDto responseValue = responseBody.isBlank()? null: memberVarObjectMapper.readValue(responseBody, new TypeReference() {}); + + return CompletableFuture.completedFuture( + new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + responseValue + ) + ); + } finally { + if (localVarResponseBody != null) { + localVarResponseBody.close(); + } + } + } catch (IOException e) { + return CompletableFuture.failedFuture(new ApiException(e)); + } + } + ); + } + catch (ApiException e) { + return CompletableFuture.failedFuture(e); + } + } + + private HttpRequest.Builder totalRequestBuilder(@jakarta.annotation.Nonnull TermRequestDto termRequestDto, Map headers) throws ApiException { + // verify the required parameter 'termRequestDto' is set + if (termRequestDto == null) { + throw new ApiException(400, "Missing the required parameter 'termRequestDto' when calling total"); + } + + HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); + + String localVarPath = "/analyze/total"; + + localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); + + localVarRequestBuilder.header("Content-Type", "application/json"); + localVarRequestBuilder.header("Accept", "application/json"); + + try { + byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(termRequestDto); + localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); + } catch (IOException e) { + throw new ApiException(e); + } + if (memberVarReadTimeout != null) { + localVarRequestBuilder.timeout(memberVarReadTimeout); + } + // Add custom headers if provided + localVarRequestBuilder = HttpRequestBuilderExtensions.withAdditionalHeaders(localVarRequestBuilder, headers); + if (memberVarInterceptor != null) { + memberVarInterceptor.accept(localVarRequestBuilder); + } + return localVarRequestBuilder; + } + +} diff --git a/src/main/java/com/regexsolver/api/generated/api/ComputeApi.java b/src/main/java/com/regexsolver/api/generated/api/ComputeApi.java new file mode 100644 index 0000000..8cb6303 --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/api/ComputeApi.java @@ -0,0 +1,1100 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +package com.regexsolver.api.generated.api; + +import com.regexsolver.api.generated.ApiClient; +import com.regexsolver.api.generated.ApiException; +import com.regexsolver.api.generated.ApiResponse; +import com.regexsolver.api.generated.Configuration; +import com.regexsolver.api.generated.Pair; + +import com.regexsolver.api.generated.model.Concat200ResponseDto; +import com.regexsolver.api.generated.model.ErrorResponse400Dto; +import com.regexsolver.api.generated.model.ErrorResponse401Dto; +import com.regexsolver.api.generated.model.ErrorResponse403Dto; +import com.regexsolver.api.generated.model.ErrorResponseDto; +import com.regexsolver.api.generated.model.MultiTermsRequestDto; +import com.regexsolver.api.generated.model.RepeatRequestDto; +import com.regexsolver.api.generated.model.TermRequestDto; +import com.regexsolver.api.generated.model.TwoTermsRequestDto; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.InputStream; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.net.http.HttpRequest; +import java.nio.channels.Channels; +import java.nio.channels.Pipe; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.time.Duration; + +import java.util.ArrayList; +import java.util.StringJoiner; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Consumer; + +import java.util.concurrent.CompletableFuture; + +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class ComputeApi { + /** + * Utility class for extending HttpRequest.Builder functionality. + */ + private static class HttpRequestBuilderExtensions { + /** + * Adds additional headers to the provided HttpRequest.Builder. Useful for adding method/endpoint specific headers. + * + * @param builder the HttpRequest.Builder to which headers will be added + * @param headers a map of header names and values to add; may be null + * @return the same HttpRequest.Builder instance with the additional headers set + */ + static HttpRequest.Builder withAdditionalHeaders(HttpRequest.Builder builder, Map headers) { + if (headers != null) { + for (Map.Entry entry : headers.entrySet()) { + builder.header(entry.getKey(), entry.getValue()); + } + } + return builder; + } + } + private final HttpClient memberVarHttpClient; + private final ObjectMapper memberVarObjectMapper; + private final String memberVarBaseUri; + private final Consumer memberVarInterceptor; + private final Duration memberVarReadTimeout; + private final Consumer> memberVarResponseInterceptor; + private final Consumer> memberVarAsyncResponseInterceptor; + + public ComputeApi() { + this(Configuration.getDefaultApiClient()); + } + + public ComputeApi(ApiClient apiClient) { + memberVarHttpClient = apiClient.getHttpClient(); + memberVarObjectMapper = apiClient.getObjectMapper(); + memberVarBaseUri = apiClient.getBaseUri(); + memberVarInterceptor = apiClient.getRequestInterceptor(); + memberVarReadTimeout = apiClient.getReadTimeout(); + memberVarResponseInterceptor = apiClient.getResponseInterceptor(); + memberVarAsyncResponseInterceptor = apiClient.getAsyncResponseInterceptor(); + } + + + private ApiException getApiException(String operationId, HttpResponse response) { + try { + InputStream responseBody = ApiClient.getResponseBody(response); + String body = null; + if (responseBody != null) { + body = new String(responseBody.readAllBytes()); + responseBody.close(); + } + String message = formatExceptionMessage(operationId, response.statusCode(), body); + return new ApiException(response.statusCode(), message, response.headers(), body); + } catch (IOException e) { + return new ApiException(e); + } + } + + private String formatExceptionMessage(String operationId, int statusCode, String body) { + if (body == null || body.isEmpty()) { + body = "[no body]"; + } + return operationId + " call failed with: " + statusCode + " - " + body; + } + + /** + * Download file from the given response. + * + * @param response Response + * @return File + * @throws ApiException If fail to read file content from response and write to disk + */ + public File downloadFileFromResponse(HttpResponse response, InputStream responseBody) throws ApiException { + if (responseBody == null) { + throw new ApiException(new IOException("Response body is empty")); + } + try { + File file = prepareDownloadFile(response); + java.nio.file.Files.copy(responseBody, file.toPath(), java.nio.file.StandardCopyOption.REPLACE_EXISTING); + return file; + } catch (IOException e) { + throw new ApiException(e); + } + } + + /** + *

Prepare the file for download from the response.

+ * + * @param response a {@link java.net.http.HttpResponse} object. + * @return a {@link java.io.File} object. + * @throws java.io.IOException if any. + */ + private File prepareDownloadFile(HttpResponse response) throws IOException { + String filename = null; + java.util.Optional contentDisposition = response.headers().firstValue("Content-Disposition"); + if (contentDisposition.isPresent() && !"".equals(contentDisposition.get())) { + // Get filename from the Content-Disposition header. + java.util.regex.Pattern pattern = java.util.regex.Pattern.compile("filename=['\"]?([^'\"\\s]+)['\"]?"); + java.util.regex.Matcher matcher = pattern.matcher(contentDisposition.get()); + if (matcher.find()) + filename = matcher.group(1); + } + File file = null; + if (filename != null) { + java.nio.file.Path tempDir = java.nio.file.Files.createTempDirectory("swagger-gen-native"); + java.nio.file.Path filePath = java.nio.file.Files.createFile(tempDir.resolve(filename)); + file = filePath.toFile(); + tempDir.toFile().deleteOnExit(); // best effort cleanup + file.deleteOnExit(); // best effort cleanup + } else { + file = java.nio.file.Files.createTempFile("download-", "").toFile(); + file.deleteOnExit(); // best effort cleanup + } + return file; + } + + /** + * Complement + * Compute the complement of the given term. + * @param termRequestDto (required) + * @return CompletableFuture<Concat200ResponseDto> + * @throws ApiException if fails to make API call + */ + public CompletableFuture complement(@jakarta.annotation.Nonnull TermRequestDto termRequestDto) throws ApiException { + return complement(termRequestDto, null); + } + + /** + * Complement + * Compute the complement of the given term. + * @param termRequestDto (required) + * @param headers Optional headers to include in the request + * @return CompletableFuture<Concat200ResponseDto> + * @throws ApiException if fails to make API call + */ + public CompletableFuture complement(@jakarta.annotation.Nonnull TermRequestDto termRequestDto, Map headers) throws ApiException { + try { + return complementWithHttpInfo(termRequestDto, headers) + .thenApply(ApiResponse::getData); + } + catch (ApiException e) { + return CompletableFuture.failedFuture(e); + } + } + + /** + * Complement + * Compute the complement of the given term. + * @param termRequestDto (required) + * @return CompletableFuture<ApiResponse<Concat200ResponseDto>> + * @throws ApiException if fails to make API call + */ + public CompletableFuture> complementWithHttpInfo(@jakarta.annotation.Nonnull TermRequestDto termRequestDto) throws ApiException { + return complementWithHttpInfo(termRequestDto, null); + } + + /** + * Complement + * Compute the complement of the given term. + * @param termRequestDto (required) + * @param headers Optional headers to include in the request + * @return CompletableFuture<ApiResponse<Concat200ResponseDto>> + * @throws ApiException if fails to make API call + */ + public CompletableFuture> complementWithHttpInfo(@jakarta.annotation.Nonnull TermRequestDto termRequestDto, Map headers) throws ApiException { + try { + HttpRequest.Builder localVarRequestBuilder = complementRequestBuilder(termRequestDto, headers); + return memberVarHttpClient.sendAsync( + localVarRequestBuilder.build(), + HttpResponse.BodyHandlers.ofInputStream()).thenComposeAsync(localVarResponse -> { + if (memberVarAsyncResponseInterceptor != null) { + memberVarAsyncResponseInterceptor.accept(localVarResponse); + } + if (localVarResponse.statusCode()/ 100 != 2) { + return CompletableFuture.failedFuture(getApiException("complement", localVarResponse)); + } + try { + InputStream localVarResponseBody = ApiClient.getResponseBody(localVarResponse); + try { + if (localVarResponseBody == null) { + return CompletableFuture.completedFuture( + new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + null + ) + ); + } + + + String responseBody = new String(localVarResponseBody.readAllBytes()); + Concat200ResponseDto responseValue = responseBody.isBlank()? null: memberVarObjectMapper.readValue(responseBody, new TypeReference() {}); + + return CompletableFuture.completedFuture( + new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + responseValue + ) + ); + } finally { + if (localVarResponseBody != null) { + localVarResponseBody.close(); + } + } + } catch (IOException e) { + return CompletableFuture.failedFuture(new ApiException(e)); + } + } + ); + } + catch (ApiException e) { + return CompletableFuture.failedFuture(e); + } + } + + private HttpRequest.Builder complementRequestBuilder(@jakarta.annotation.Nonnull TermRequestDto termRequestDto, Map headers) throws ApiException { + // verify the required parameter 'termRequestDto' is set + if (termRequestDto == null) { + throw new ApiException(400, "Missing the required parameter 'termRequestDto' when calling complement"); + } + + HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); + + String localVarPath = "/compute/complement"; + + localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); + + localVarRequestBuilder.header("Content-Type", "application/json"); + localVarRequestBuilder.header("Accept", "application/json"); + + try { + byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(termRequestDto); + localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); + } catch (IOException e) { + throw new ApiException(e); + } + if (memberVarReadTimeout != null) { + localVarRequestBuilder.timeout(memberVarReadTimeout); + } + // Add custom headers if provided + localVarRequestBuilder = HttpRequestBuilderExtensions.withAdditionalHeaders(localVarRequestBuilder, headers); + if (memberVarInterceptor != null) { + memberVarInterceptor.accept(localVarRequestBuilder); + } + return localVarRequestBuilder; + } + + /** + * Concatenation + * Concatenate the given terms in order. + * @param multiTermsRequestDto (required) + * @return CompletableFuture<Concat200ResponseDto> + * @throws ApiException if fails to make API call + */ + public CompletableFuture concat(@jakarta.annotation.Nonnull MultiTermsRequestDto multiTermsRequestDto) throws ApiException { + return concat(multiTermsRequestDto, null); + } + + /** + * Concatenation + * Concatenate the given terms in order. + * @param multiTermsRequestDto (required) + * @param headers Optional headers to include in the request + * @return CompletableFuture<Concat200ResponseDto> + * @throws ApiException if fails to make API call + */ + public CompletableFuture concat(@jakarta.annotation.Nonnull MultiTermsRequestDto multiTermsRequestDto, Map headers) throws ApiException { + try { + return concatWithHttpInfo(multiTermsRequestDto, headers) + .thenApply(ApiResponse::getData); + } + catch (ApiException e) { + return CompletableFuture.failedFuture(e); + } + } + + /** + * Concatenation + * Concatenate the given terms in order. + * @param multiTermsRequestDto (required) + * @return CompletableFuture<ApiResponse<Concat200ResponseDto>> + * @throws ApiException if fails to make API call + */ + public CompletableFuture> concatWithHttpInfo(@jakarta.annotation.Nonnull MultiTermsRequestDto multiTermsRequestDto) throws ApiException { + return concatWithHttpInfo(multiTermsRequestDto, null); + } + + /** + * Concatenation + * Concatenate the given terms in order. + * @param multiTermsRequestDto (required) + * @param headers Optional headers to include in the request + * @return CompletableFuture<ApiResponse<Concat200ResponseDto>> + * @throws ApiException if fails to make API call + */ + public CompletableFuture> concatWithHttpInfo(@jakarta.annotation.Nonnull MultiTermsRequestDto multiTermsRequestDto, Map headers) throws ApiException { + try { + HttpRequest.Builder localVarRequestBuilder = concatRequestBuilder(multiTermsRequestDto, headers); + return memberVarHttpClient.sendAsync( + localVarRequestBuilder.build(), + HttpResponse.BodyHandlers.ofInputStream()).thenComposeAsync(localVarResponse -> { + if (memberVarAsyncResponseInterceptor != null) { + memberVarAsyncResponseInterceptor.accept(localVarResponse); + } + if (localVarResponse.statusCode()/ 100 != 2) { + return CompletableFuture.failedFuture(getApiException("concat", localVarResponse)); + } + try { + InputStream localVarResponseBody = ApiClient.getResponseBody(localVarResponse); + try { + if (localVarResponseBody == null) { + return CompletableFuture.completedFuture( + new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + null + ) + ); + } + + + String responseBody = new String(localVarResponseBody.readAllBytes()); + Concat200ResponseDto responseValue = responseBody.isBlank()? null: memberVarObjectMapper.readValue(responseBody, new TypeReference() {}); + + return CompletableFuture.completedFuture( + new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + responseValue + ) + ); + } finally { + if (localVarResponseBody != null) { + localVarResponseBody.close(); + } + } + } catch (IOException e) { + return CompletableFuture.failedFuture(new ApiException(e)); + } + } + ); + } + catch (ApiException e) { + return CompletableFuture.failedFuture(e); + } + } + + private HttpRequest.Builder concatRequestBuilder(@jakarta.annotation.Nonnull MultiTermsRequestDto multiTermsRequestDto, Map headers) throws ApiException { + // verify the required parameter 'multiTermsRequestDto' is set + if (multiTermsRequestDto == null) { + throw new ApiException(400, "Missing the required parameter 'multiTermsRequestDto' when calling concat"); + } + + HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); + + String localVarPath = "/compute/concat"; + + localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); + + localVarRequestBuilder.header("Content-Type", "application/json"); + localVarRequestBuilder.header("Accept", "application/json"); + + try { + byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(multiTermsRequestDto); + localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); + } catch (IOException e) { + throw new ApiException(e); + } + if (memberVarReadTimeout != null) { + localVarRequestBuilder.timeout(memberVarReadTimeout); + } + // Add custom headers if provided + localVarRequestBuilder = HttpRequestBuilderExtensions.withAdditionalHeaders(localVarRequestBuilder, headers); + if (memberVarInterceptor != null) { + memberVarInterceptor.accept(localVarRequestBuilder); + } + return localVarRequestBuilder; + } + + /** + * Determinize + * Compute a deterministic FAIR. + * @param termRequestDto (required) + * @return CompletableFuture<Concat200ResponseDto> + * @throws ApiException if fails to make API call + */ + public CompletableFuture determinize(@jakarta.annotation.Nonnull TermRequestDto termRequestDto) throws ApiException { + return determinize(termRequestDto, null); + } + + /** + * Determinize + * Compute a deterministic FAIR. + * @param termRequestDto (required) + * @param headers Optional headers to include in the request + * @return CompletableFuture<Concat200ResponseDto> + * @throws ApiException if fails to make API call + */ + public CompletableFuture determinize(@jakarta.annotation.Nonnull TermRequestDto termRequestDto, Map headers) throws ApiException { + try { + return determinizeWithHttpInfo(termRequestDto, headers) + .thenApply(ApiResponse::getData); + } + catch (ApiException e) { + return CompletableFuture.failedFuture(e); + } + } + + /** + * Determinize + * Compute a deterministic FAIR. + * @param termRequestDto (required) + * @return CompletableFuture<ApiResponse<Concat200ResponseDto>> + * @throws ApiException if fails to make API call + */ + public CompletableFuture> determinizeWithHttpInfo(@jakarta.annotation.Nonnull TermRequestDto termRequestDto) throws ApiException { + return determinizeWithHttpInfo(termRequestDto, null); + } + + /** + * Determinize + * Compute a deterministic FAIR. + * @param termRequestDto (required) + * @param headers Optional headers to include in the request + * @return CompletableFuture<ApiResponse<Concat200ResponseDto>> + * @throws ApiException if fails to make API call + */ + public CompletableFuture> determinizeWithHttpInfo(@jakarta.annotation.Nonnull TermRequestDto termRequestDto, Map headers) throws ApiException { + try { + HttpRequest.Builder localVarRequestBuilder = determinizeRequestBuilder(termRequestDto, headers); + return memberVarHttpClient.sendAsync( + localVarRequestBuilder.build(), + HttpResponse.BodyHandlers.ofInputStream()).thenComposeAsync(localVarResponse -> { + if (memberVarAsyncResponseInterceptor != null) { + memberVarAsyncResponseInterceptor.accept(localVarResponse); + } + if (localVarResponse.statusCode()/ 100 != 2) { + return CompletableFuture.failedFuture(getApiException("determinize", localVarResponse)); + } + try { + InputStream localVarResponseBody = ApiClient.getResponseBody(localVarResponse); + try { + if (localVarResponseBody == null) { + return CompletableFuture.completedFuture( + new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + null + ) + ); + } + + + String responseBody = new String(localVarResponseBody.readAllBytes()); + Concat200ResponseDto responseValue = responseBody.isBlank()? null: memberVarObjectMapper.readValue(responseBody, new TypeReference() {}); + + return CompletableFuture.completedFuture( + new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + responseValue + ) + ); + } finally { + if (localVarResponseBody != null) { + localVarResponseBody.close(); + } + } + } catch (IOException e) { + return CompletableFuture.failedFuture(new ApiException(e)); + } + } + ); + } + catch (ApiException e) { + return CompletableFuture.failedFuture(e); + } + } + + private HttpRequest.Builder determinizeRequestBuilder(@jakarta.annotation.Nonnull TermRequestDto termRequestDto, Map headers) throws ApiException { + // verify the required parameter 'termRequestDto' is set + if (termRequestDto == null) { + throw new ApiException(400, "Missing the required parameter 'termRequestDto' when calling determinize"); + } + + HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); + + String localVarPath = "/compute/determinize"; + + localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); + + localVarRequestBuilder.header("Content-Type", "application/json"); + localVarRequestBuilder.header("Accept", "application/json"); + + try { + byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(termRequestDto); + localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); + } catch (IOException e) { + throw new ApiException(e); + } + if (memberVarReadTimeout != null) { + localVarRequestBuilder.timeout(memberVarReadTimeout); + } + // Add custom headers if provided + localVarRequestBuilder = HttpRequestBuilderExtensions.withAdditionalHeaders(localVarRequestBuilder, headers); + if (memberVarInterceptor != null) { + memberVarInterceptor.accept(localVarRequestBuilder); + } + return localVarRequestBuilder; + } + + /** + * Difference + * Compute the difference between the two given terms. + * @param twoTermsRequestDto (required) + * @return CompletableFuture<Concat200ResponseDto> + * @throws ApiException if fails to make API call + */ + public CompletableFuture difference(@jakarta.annotation.Nonnull TwoTermsRequestDto twoTermsRequestDto) throws ApiException { + return difference(twoTermsRequestDto, null); + } + + /** + * Difference + * Compute the difference between the two given terms. + * @param twoTermsRequestDto (required) + * @param headers Optional headers to include in the request + * @return CompletableFuture<Concat200ResponseDto> + * @throws ApiException if fails to make API call + */ + public CompletableFuture difference(@jakarta.annotation.Nonnull TwoTermsRequestDto twoTermsRequestDto, Map headers) throws ApiException { + try { + return differenceWithHttpInfo(twoTermsRequestDto, headers) + .thenApply(ApiResponse::getData); + } + catch (ApiException e) { + return CompletableFuture.failedFuture(e); + } + } + + /** + * Difference + * Compute the difference between the two given terms. + * @param twoTermsRequestDto (required) + * @return CompletableFuture<ApiResponse<Concat200ResponseDto>> + * @throws ApiException if fails to make API call + */ + public CompletableFuture> differenceWithHttpInfo(@jakarta.annotation.Nonnull TwoTermsRequestDto twoTermsRequestDto) throws ApiException { + return differenceWithHttpInfo(twoTermsRequestDto, null); + } + + /** + * Difference + * Compute the difference between the two given terms. + * @param twoTermsRequestDto (required) + * @param headers Optional headers to include in the request + * @return CompletableFuture<ApiResponse<Concat200ResponseDto>> + * @throws ApiException if fails to make API call + */ + public CompletableFuture> differenceWithHttpInfo(@jakarta.annotation.Nonnull TwoTermsRequestDto twoTermsRequestDto, Map headers) throws ApiException { + try { + HttpRequest.Builder localVarRequestBuilder = differenceRequestBuilder(twoTermsRequestDto, headers); + return memberVarHttpClient.sendAsync( + localVarRequestBuilder.build(), + HttpResponse.BodyHandlers.ofInputStream()).thenComposeAsync(localVarResponse -> { + if (memberVarAsyncResponseInterceptor != null) { + memberVarAsyncResponseInterceptor.accept(localVarResponse); + } + if (localVarResponse.statusCode()/ 100 != 2) { + return CompletableFuture.failedFuture(getApiException("difference", localVarResponse)); + } + try { + InputStream localVarResponseBody = ApiClient.getResponseBody(localVarResponse); + try { + if (localVarResponseBody == null) { + return CompletableFuture.completedFuture( + new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + null + ) + ); + } + + + String responseBody = new String(localVarResponseBody.readAllBytes()); + Concat200ResponseDto responseValue = responseBody.isBlank()? null: memberVarObjectMapper.readValue(responseBody, new TypeReference() {}); + + return CompletableFuture.completedFuture( + new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + responseValue + ) + ); + } finally { + if (localVarResponseBody != null) { + localVarResponseBody.close(); + } + } + } catch (IOException e) { + return CompletableFuture.failedFuture(new ApiException(e)); + } + } + ); + } + catch (ApiException e) { + return CompletableFuture.failedFuture(e); + } + } + + private HttpRequest.Builder differenceRequestBuilder(@jakarta.annotation.Nonnull TwoTermsRequestDto twoTermsRequestDto, Map headers) throws ApiException { + // verify the required parameter 'twoTermsRequestDto' is set + if (twoTermsRequestDto == null) { + throw new ApiException(400, "Missing the required parameter 'twoTermsRequestDto' when calling difference"); + } + + HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); + + String localVarPath = "/compute/difference"; + + localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); + + localVarRequestBuilder.header("Content-Type", "application/json"); + localVarRequestBuilder.header("Accept", "application/json"); + + try { + byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(twoTermsRequestDto); + localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); + } catch (IOException e) { + throw new ApiException(e); + } + if (memberVarReadTimeout != null) { + localVarRequestBuilder.timeout(memberVarReadTimeout); + } + // Add custom headers if provided + localVarRequestBuilder = HttpRequestBuilderExtensions.withAdditionalHeaders(localVarRequestBuilder, headers); + if (memberVarInterceptor != null) { + memberVarInterceptor.accept(localVarRequestBuilder); + } + return localVarRequestBuilder; + } + + /** + * Intersection + * Compute the intersection of the given terms. + * @param multiTermsRequestDto (required) + * @return CompletableFuture<Concat200ResponseDto> + * @throws ApiException if fails to make API call + */ + public CompletableFuture intersection(@jakarta.annotation.Nonnull MultiTermsRequestDto multiTermsRequestDto) throws ApiException { + return intersection(multiTermsRequestDto, null); + } + + /** + * Intersection + * Compute the intersection of the given terms. + * @param multiTermsRequestDto (required) + * @param headers Optional headers to include in the request + * @return CompletableFuture<Concat200ResponseDto> + * @throws ApiException if fails to make API call + */ + public CompletableFuture intersection(@jakarta.annotation.Nonnull MultiTermsRequestDto multiTermsRequestDto, Map headers) throws ApiException { + try { + return intersectionWithHttpInfo(multiTermsRequestDto, headers) + .thenApply(ApiResponse::getData); + } + catch (ApiException e) { + return CompletableFuture.failedFuture(e); + } + } + + /** + * Intersection + * Compute the intersection of the given terms. + * @param multiTermsRequestDto (required) + * @return CompletableFuture<ApiResponse<Concat200ResponseDto>> + * @throws ApiException if fails to make API call + */ + public CompletableFuture> intersectionWithHttpInfo(@jakarta.annotation.Nonnull MultiTermsRequestDto multiTermsRequestDto) throws ApiException { + return intersectionWithHttpInfo(multiTermsRequestDto, null); + } + + /** + * Intersection + * Compute the intersection of the given terms. + * @param multiTermsRequestDto (required) + * @param headers Optional headers to include in the request + * @return CompletableFuture<ApiResponse<Concat200ResponseDto>> + * @throws ApiException if fails to make API call + */ + public CompletableFuture> intersectionWithHttpInfo(@jakarta.annotation.Nonnull MultiTermsRequestDto multiTermsRequestDto, Map headers) throws ApiException { + try { + HttpRequest.Builder localVarRequestBuilder = intersectionRequestBuilder(multiTermsRequestDto, headers); + return memberVarHttpClient.sendAsync( + localVarRequestBuilder.build(), + HttpResponse.BodyHandlers.ofInputStream()).thenComposeAsync(localVarResponse -> { + if (memberVarAsyncResponseInterceptor != null) { + memberVarAsyncResponseInterceptor.accept(localVarResponse); + } + if (localVarResponse.statusCode()/ 100 != 2) { + return CompletableFuture.failedFuture(getApiException("intersection", localVarResponse)); + } + try { + InputStream localVarResponseBody = ApiClient.getResponseBody(localVarResponse); + try { + if (localVarResponseBody == null) { + return CompletableFuture.completedFuture( + new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + null + ) + ); + } + + + String responseBody = new String(localVarResponseBody.readAllBytes()); + Concat200ResponseDto responseValue = responseBody.isBlank()? null: memberVarObjectMapper.readValue(responseBody, new TypeReference() {}); + + return CompletableFuture.completedFuture( + new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + responseValue + ) + ); + } finally { + if (localVarResponseBody != null) { + localVarResponseBody.close(); + } + } + } catch (IOException e) { + return CompletableFuture.failedFuture(new ApiException(e)); + } + } + ); + } + catch (ApiException e) { + return CompletableFuture.failedFuture(e); + } + } + + private HttpRequest.Builder intersectionRequestBuilder(@jakarta.annotation.Nonnull MultiTermsRequestDto multiTermsRequestDto, Map headers) throws ApiException { + // verify the required parameter 'multiTermsRequestDto' is set + if (multiTermsRequestDto == null) { + throw new ApiException(400, "Missing the required parameter 'multiTermsRequestDto' when calling intersection"); + } + + HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); + + String localVarPath = "/compute/intersection"; + + localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); + + localVarRequestBuilder.header("Content-Type", "application/json"); + localVarRequestBuilder.header("Accept", "application/json"); + + try { + byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(multiTermsRequestDto); + localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); + } catch (IOException e) { + throw new ApiException(e); + } + if (memberVarReadTimeout != null) { + localVarRequestBuilder.timeout(memberVarReadTimeout); + } + // Add custom headers if provided + localVarRequestBuilder = HttpRequestBuilderExtensions.withAdditionalHeaders(localVarRequestBuilder, headers); + if (memberVarInterceptor != null) { + memberVarInterceptor.accept(localVarRequestBuilder); + } + return localVarRequestBuilder; + } + + /** + * Repeat + * Repeat a term between `min` and `max` times. + * @param repeatRequestDto (required) + * @return CompletableFuture<Concat200ResponseDto> + * @throws ApiException if fails to make API call + */ + public CompletableFuture repeat(@jakarta.annotation.Nonnull RepeatRequestDto repeatRequestDto) throws ApiException { + return repeat(repeatRequestDto, null); + } + + /** + * Repeat + * Repeat a term between `min` and `max` times. + * @param repeatRequestDto (required) + * @param headers Optional headers to include in the request + * @return CompletableFuture<Concat200ResponseDto> + * @throws ApiException if fails to make API call + */ + public CompletableFuture repeat(@jakarta.annotation.Nonnull RepeatRequestDto repeatRequestDto, Map headers) throws ApiException { + try { + return repeatWithHttpInfo(repeatRequestDto, headers) + .thenApply(ApiResponse::getData); + } + catch (ApiException e) { + return CompletableFuture.failedFuture(e); + } + } + + /** + * Repeat + * Repeat a term between `min` and `max` times. + * @param repeatRequestDto (required) + * @return CompletableFuture<ApiResponse<Concat200ResponseDto>> + * @throws ApiException if fails to make API call + */ + public CompletableFuture> repeatWithHttpInfo(@jakarta.annotation.Nonnull RepeatRequestDto repeatRequestDto) throws ApiException { + return repeatWithHttpInfo(repeatRequestDto, null); + } + + /** + * Repeat + * Repeat a term between `min` and `max` times. + * @param repeatRequestDto (required) + * @param headers Optional headers to include in the request + * @return CompletableFuture<ApiResponse<Concat200ResponseDto>> + * @throws ApiException if fails to make API call + */ + public CompletableFuture> repeatWithHttpInfo(@jakarta.annotation.Nonnull RepeatRequestDto repeatRequestDto, Map headers) throws ApiException { + try { + HttpRequest.Builder localVarRequestBuilder = repeatRequestBuilder(repeatRequestDto, headers); + return memberVarHttpClient.sendAsync( + localVarRequestBuilder.build(), + HttpResponse.BodyHandlers.ofInputStream()).thenComposeAsync(localVarResponse -> { + if (memberVarAsyncResponseInterceptor != null) { + memberVarAsyncResponseInterceptor.accept(localVarResponse); + } + if (localVarResponse.statusCode()/ 100 != 2) { + return CompletableFuture.failedFuture(getApiException("repeat", localVarResponse)); + } + try { + InputStream localVarResponseBody = ApiClient.getResponseBody(localVarResponse); + try { + if (localVarResponseBody == null) { + return CompletableFuture.completedFuture( + new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + null + ) + ); + } + + + String responseBody = new String(localVarResponseBody.readAllBytes()); + Concat200ResponseDto responseValue = responseBody.isBlank()? null: memberVarObjectMapper.readValue(responseBody, new TypeReference() {}); + + return CompletableFuture.completedFuture( + new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + responseValue + ) + ); + } finally { + if (localVarResponseBody != null) { + localVarResponseBody.close(); + } + } + } catch (IOException e) { + return CompletableFuture.failedFuture(new ApiException(e)); + } + } + ); + } + catch (ApiException e) { + return CompletableFuture.failedFuture(e); + } + } + + private HttpRequest.Builder repeatRequestBuilder(@jakarta.annotation.Nonnull RepeatRequestDto repeatRequestDto, Map headers) throws ApiException { + // verify the required parameter 'repeatRequestDto' is set + if (repeatRequestDto == null) { + throw new ApiException(400, "Missing the required parameter 'repeatRequestDto' when calling repeat"); + } + + HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); + + String localVarPath = "/compute/repeat"; + + localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); + + localVarRequestBuilder.header("Content-Type", "application/json"); + localVarRequestBuilder.header("Accept", "application/json"); + + try { + byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(repeatRequestDto); + localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); + } catch (IOException e) { + throw new ApiException(e); + } + if (memberVarReadTimeout != null) { + localVarRequestBuilder.timeout(memberVarReadTimeout); + } + // Add custom headers if provided + localVarRequestBuilder = HttpRequestBuilderExtensions.withAdditionalHeaders(localVarRequestBuilder, headers); + if (memberVarInterceptor != null) { + memberVarInterceptor.accept(localVarRequestBuilder); + } + return localVarRequestBuilder; + } + + /** + * Union + * Compute the union of the given terms. + * @param multiTermsRequestDto (required) + * @return CompletableFuture<Concat200ResponseDto> + * @throws ApiException if fails to make API call + */ + public CompletableFuture union(@jakarta.annotation.Nonnull MultiTermsRequestDto multiTermsRequestDto) throws ApiException { + return union(multiTermsRequestDto, null); + } + + /** + * Union + * Compute the union of the given terms. + * @param multiTermsRequestDto (required) + * @param headers Optional headers to include in the request + * @return CompletableFuture<Concat200ResponseDto> + * @throws ApiException if fails to make API call + */ + public CompletableFuture union(@jakarta.annotation.Nonnull MultiTermsRequestDto multiTermsRequestDto, Map headers) throws ApiException { + try { + return unionWithHttpInfo(multiTermsRequestDto, headers) + .thenApply(ApiResponse::getData); + } + catch (ApiException e) { + return CompletableFuture.failedFuture(e); + } + } + + /** + * Union + * Compute the union of the given terms. + * @param multiTermsRequestDto (required) + * @return CompletableFuture<ApiResponse<Concat200ResponseDto>> + * @throws ApiException if fails to make API call + */ + public CompletableFuture> unionWithHttpInfo(@jakarta.annotation.Nonnull MultiTermsRequestDto multiTermsRequestDto) throws ApiException { + return unionWithHttpInfo(multiTermsRequestDto, null); + } + + /** + * Union + * Compute the union of the given terms. + * @param multiTermsRequestDto (required) + * @param headers Optional headers to include in the request + * @return CompletableFuture<ApiResponse<Concat200ResponseDto>> + * @throws ApiException if fails to make API call + */ + public CompletableFuture> unionWithHttpInfo(@jakarta.annotation.Nonnull MultiTermsRequestDto multiTermsRequestDto, Map headers) throws ApiException { + try { + HttpRequest.Builder localVarRequestBuilder = unionRequestBuilder(multiTermsRequestDto, headers); + return memberVarHttpClient.sendAsync( + localVarRequestBuilder.build(), + HttpResponse.BodyHandlers.ofInputStream()).thenComposeAsync(localVarResponse -> { + if (memberVarAsyncResponseInterceptor != null) { + memberVarAsyncResponseInterceptor.accept(localVarResponse); + } + if (localVarResponse.statusCode()/ 100 != 2) { + return CompletableFuture.failedFuture(getApiException("union", localVarResponse)); + } + try { + InputStream localVarResponseBody = ApiClient.getResponseBody(localVarResponse); + try { + if (localVarResponseBody == null) { + return CompletableFuture.completedFuture( + new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + null + ) + ); + } + + + String responseBody = new String(localVarResponseBody.readAllBytes()); + Concat200ResponseDto responseValue = responseBody.isBlank()? null: memberVarObjectMapper.readValue(responseBody, new TypeReference() {}); + + return CompletableFuture.completedFuture( + new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + responseValue + ) + ); + } finally { + if (localVarResponseBody != null) { + localVarResponseBody.close(); + } + } + } catch (IOException e) { + return CompletableFuture.failedFuture(new ApiException(e)); + } + } + ); + } + catch (ApiException e) { + return CompletableFuture.failedFuture(e); + } + } + + private HttpRequest.Builder unionRequestBuilder(@jakarta.annotation.Nonnull MultiTermsRequestDto multiTermsRequestDto, Map headers) throws ApiException { + // verify the required parameter 'multiTermsRequestDto' is set + if (multiTermsRequestDto == null) { + throw new ApiException(400, "Missing the required parameter 'multiTermsRequestDto' when calling union"); + } + + HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); + + String localVarPath = "/compute/union"; + + localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); + + localVarRequestBuilder.header("Content-Type", "application/json"); + localVarRequestBuilder.header("Accept", "application/json"); + + try { + byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(multiTermsRequestDto); + localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); + } catch (IOException e) { + throw new ApiException(e); + } + if (memberVarReadTimeout != null) { + localVarRequestBuilder.timeout(memberVarReadTimeout); + } + // Add custom headers if provided + localVarRequestBuilder = HttpRequestBuilderExtensions.withAdditionalHeaders(localVarRequestBuilder, headers); + if (memberVarInterceptor != null) { + memberVarInterceptor.accept(localVarRequestBuilder); + } + return localVarRequestBuilder; + } + +} diff --git a/src/main/java/com/regexsolver/api/generated/api/GenerateApi.java b/src/main/java/com/regexsolver/api/generated/api/GenerateApi.java new file mode 100644 index 0000000..b204531 --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/api/GenerateApi.java @@ -0,0 +1,305 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +package com.regexsolver.api.generated.api; + +import com.regexsolver.api.generated.ApiClient; +import com.regexsolver.api.generated.ApiException; +import com.regexsolver.api.generated.ApiResponse; +import com.regexsolver.api.generated.Configuration; +import com.regexsolver.api.generated.Pair; + +import com.regexsolver.api.generated.model.ErrorResponse400Dto; +import com.regexsolver.api.generated.model.ErrorResponse401Dto; +import com.regexsolver.api.generated.model.ErrorResponse403Dto; +import com.regexsolver.api.generated.model.ErrorResponseDto; +import com.regexsolver.api.generated.model.GenerateStringsRequestDto; +import com.regexsolver.api.generated.model.Strings200ResponseDto; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.InputStream; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.net.http.HttpRequest; +import java.nio.channels.Channels; +import java.nio.channels.Pipe; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.time.Duration; + +import java.util.ArrayList; +import java.util.StringJoiner; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Consumer; + +import java.util.concurrent.CompletableFuture; + +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class GenerateApi { + /** + * Utility class for extending HttpRequest.Builder functionality. + */ + private static class HttpRequestBuilderExtensions { + /** + * Adds additional headers to the provided HttpRequest.Builder. Useful for adding method/endpoint specific headers. + * + * @param builder the HttpRequest.Builder to which headers will be added + * @param headers a map of header names and values to add; may be null + * @return the same HttpRequest.Builder instance with the additional headers set + */ + static HttpRequest.Builder withAdditionalHeaders(HttpRequest.Builder builder, Map headers) { + if (headers != null) { + for (Map.Entry entry : headers.entrySet()) { + builder.header(entry.getKey(), entry.getValue()); + } + } + return builder; + } + } + private final HttpClient memberVarHttpClient; + private final ObjectMapper memberVarObjectMapper; + private final String memberVarBaseUri; + private final Consumer memberVarInterceptor; + private final Duration memberVarReadTimeout; + private final Consumer> memberVarResponseInterceptor; + private final Consumer> memberVarAsyncResponseInterceptor; + + public GenerateApi() { + this(Configuration.getDefaultApiClient()); + } + + public GenerateApi(ApiClient apiClient) { + memberVarHttpClient = apiClient.getHttpClient(); + memberVarObjectMapper = apiClient.getObjectMapper(); + memberVarBaseUri = apiClient.getBaseUri(); + memberVarInterceptor = apiClient.getRequestInterceptor(); + memberVarReadTimeout = apiClient.getReadTimeout(); + memberVarResponseInterceptor = apiClient.getResponseInterceptor(); + memberVarAsyncResponseInterceptor = apiClient.getAsyncResponseInterceptor(); + } + + + private ApiException getApiException(String operationId, HttpResponse response) { + try { + InputStream responseBody = ApiClient.getResponseBody(response); + String body = null; + if (responseBody != null) { + body = new String(responseBody.readAllBytes()); + responseBody.close(); + } + String message = formatExceptionMessage(operationId, response.statusCode(), body); + return new ApiException(response.statusCode(), message, response.headers(), body); + } catch (IOException e) { + return new ApiException(e); + } + } + + private String formatExceptionMessage(String operationId, int statusCode, String body) { + if (body == null || body.isEmpty()) { + body = "[no body]"; + } + return operationId + " call failed with: " + statusCode + " - " + body; + } + + /** + * Download file from the given response. + * + * @param response Response + * @return File + * @throws ApiException If fail to read file content from response and write to disk + */ + public File downloadFileFromResponse(HttpResponse response, InputStream responseBody) throws ApiException { + if (responseBody == null) { + throw new ApiException(new IOException("Response body is empty")); + } + try { + File file = prepareDownloadFile(response); + java.nio.file.Files.copy(responseBody, file.toPath(), java.nio.file.StandardCopyOption.REPLACE_EXISTING); + return file; + } catch (IOException e) { + throw new ApiException(e); + } + } + + /** + *

Prepare the file for download from the response.

+ * + * @param response a {@link java.net.http.HttpResponse} object. + * @return a {@link java.io.File} object. + * @throws java.io.IOException if any. + */ + private File prepareDownloadFile(HttpResponse response) throws IOException { + String filename = null; + java.util.Optional contentDisposition = response.headers().firstValue("Content-Disposition"); + if (contentDisposition.isPresent() && !"".equals(contentDisposition.get())) { + // Get filename from the Content-Disposition header. + java.util.regex.Pattern pattern = java.util.regex.Pattern.compile("filename=['\"]?([^'\"\\s]+)['\"]?"); + java.util.regex.Matcher matcher = pattern.matcher(contentDisposition.get()); + if (matcher.find()) + filename = matcher.group(1); + } + File file = null; + if (filename != null) { + java.nio.file.Path tempDir = java.nio.file.Files.createTempDirectory("swagger-gen-native"); + java.nio.file.Path filePath = java.nio.file.Files.createFile(tempDir.resolve(filename)); + file = filePath.toFile(); + tempDir.toFile().deleteOnExit(); // best effort cleanup + file.deleteOnExit(); // best effort cleanup + } else { + file = java.nio.file.Files.createTempFile("download-", "").toFile(); + file.deleteOnExit(); // best effort cleanup + } + return file; + } + + /** + * Strings + * Generate up to `limit` distinct strings matched by `term`, skipping the first `offset` strings, scheduling the paths of the language in `pathOrder`, producing the strings within each path in `characterOrder`, confined to lengths between `minLength` and `maxLength` and to the characters of `charset`. Strings are only guaranteed to be distinct within a single call; pagination across calls is only consistent (no repeats or gaps) if `term` is deterministic. Call `/analyze/deterministic` to check, and `/compute/determinize` first if needed. + * @param generateStringsRequestDto (required) + * @return CompletableFuture<Strings200ResponseDto> + * @throws ApiException if fails to make API call + */ + public CompletableFuture strings(@jakarta.annotation.Nonnull GenerateStringsRequestDto generateStringsRequestDto) throws ApiException { + return strings(generateStringsRequestDto, null); + } + + /** + * Strings + * Generate up to `limit` distinct strings matched by `term`, skipping the first `offset` strings, scheduling the paths of the language in `pathOrder`, producing the strings within each path in `characterOrder`, confined to lengths between `minLength` and `maxLength` and to the characters of `charset`. Strings are only guaranteed to be distinct within a single call; pagination across calls is only consistent (no repeats or gaps) if `term` is deterministic. Call `/analyze/deterministic` to check, and `/compute/determinize` first if needed. + * @param generateStringsRequestDto (required) + * @param headers Optional headers to include in the request + * @return CompletableFuture<Strings200ResponseDto> + * @throws ApiException if fails to make API call + */ + public CompletableFuture strings(@jakarta.annotation.Nonnull GenerateStringsRequestDto generateStringsRequestDto, Map headers) throws ApiException { + try { + return stringsWithHttpInfo(generateStringsRequestDto, headers) + .thenApply(ApiResponse::getData); + } + catch (ApiException e) { + return CompletableFuture.failedFuture(e); + } + } + + /** + * Strings + * Generate up to `limit` distinct strings matched by `term`, skipping the first `offset` strings, scheduling the paths of the language in `pathOrder`, producing the strings within each path in `characterOrder`, confined to lengths between `minLength` and `maxLength` and to the characters of `charset`. Strings are only guaranteed to be distinct within a single call; pagination across calls is only consistent (no repeats or gaps) if `term` is deterministic. Call `/analyze/deterministic` to check, and `/compute/determinize` first if needed. + * @param generateStringsRequestDto (required) + * @return CompletableFuture<ApiResponse<Strings200ResponseDto>> + * @throws ApiException if fails to make API call + */ + public CompletableFuture> stringsWithHttpInfo(@jakarta.annotation.Nonnull GenerateStringsRequestDto generateStringsRequestDto) throws ApiException { + return stringsWithHttpInfo(generateStringsRequestDto, null); + } + + /** + * Strings + * Generate up to `limit` distinct strings matched by `term`, skipping the first `offset` strings, scheduling the paths of the language in `pathOrder`, producing the strings within each path in `characterOrder`, confined to lengths between `minLength` and `maxLength` and to the characters of `charset`. Strings are only guaranteed to be distinct within a single call; pagination across calls is only consistent (no repeats or gaps) if `term` is deterministic. Call `/analyze/deterministic` to check, and `/compute/determinize` first if needed. + * @param generateStringsRequestDto (required) + * @param headers Optional headers to include in the request + * @return CompletableFuture<ApiResponse<Strings200ResponseDto>> + * @throws ApiException if fails to make API call + */ + public CompletableFuture> stringsWithHttpInfo(@jakarta.annotation.Nonnull GenerateStringsRequestDto generateStringsRequestDto, Map headers) throws ApiException { + try { + HttpRequest.Builder localVarRequestBuilder = stringsRequestBuilder(generateStringsRequestDto, headers); + return memberVarHttpClient.sendAsync( + localVarRequestBuilder.build(), + HttpResponse.BodyHandlers.ofInputStream()).thenComposeAsync(localVarResponse -> { + if (memberVarAsyncResponseInterceptor != null) { + memberVarAsyncResponseInterceptor.accept(localVarResponse); + } + if (localVarResponse.statusCode()/ 100 != 2) { + return CompletableFuture.failedFuture(getApiException("strings", localVarResponse)); + } + try { + InputStream localVarResponseBody = ApiClient.getResponseBody(localVarResponse); + try { + if (localVarResponseBody == null) { + return CompletableFuture.completedFuture( + new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + null + ) + ); + } + + + String responseBody = new String(localVarResponseBody.readAllBytes()); + Strings200ResponseDto responseValue = responseBody.isBlank()? null: memberVarObjectMapper.readValue(responseBody, new TypeReference() {}); + + return CompletableFuture.completedFuture( + new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + responseValue + ) + ); + } finally { + if (localVarResponseBody != null) { + localVarResponseBody.close(); + } + } + } catch (IOException e) { + return CompletableFuture.failedFuture(new ApiException(e)); + } + } + ); + } + catch (ApiException e) { + return CompletableFuture.failedFuture(e); + } + } + + private HttpRequest.Builder stringsRequestBuilder(@jakarta.annotation.Nonnull GenerateStringsRequestDto generateStringsRequestDto, Map headers) throws ApiException { + // verify the required parameter 'generateStringsRequestDto' is set + if (generateStringsRequestDto == null) { + throw new ApiException(400, "Missing the required parameter 'generateStringsRequestDto' when calling strings"); + } + + HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); + + String localVarPath = "/generate/strings"; + + localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); + + localVarRequestBuilder.header("Content-Type", "application/json"); + localVarRequestBuilder.header("Accept", "application/json"); + + try { + byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(generateStringsRequestDto); + localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); + } catch (IOException e) { + throw new ApiException(e); + } + if (memberVarReadTimeout != null) { + localVarRequestBuilder.timeout(memberVarReadTimeout); + } + // Add custom headers if provided + localVarRequestBuilder = HttpRequestBuilderExtensions.withAdditionalHeaders(localVarRequestBuilder, headers); + if (memberVarInterceptor != null) { + memberVarInterceptor.accept(localVarRequestBuilder); + } + return localVarRequestBuilder; + } + +} diff --git a/src/main/java/com/regexsolver/api/generated/model/AbstractOpenApiSchema.java b/src/main/java/com/regexsolver/api/generated/model/AbstractOpenApiSchema.java new file mode 100644 index 0000000..6b195a3 --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/model/AbstractOpenApiSchema.java @@ -0,0 +1,144 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.regexsolver.api.generated.model; + +import java.util.Objects; +import java.lang.reflect.Type; +import java.util.Map; + +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * Abstract class for oneOf,anyOf schemas defined in OpenAPI spec + */ +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public abstract class AbstractOpenApiSchema { + + // store the actual instance of the schema/object + private Object instance; + + // is nullable + private Boolean isNullable; + + // schema type (e.g. oneOf, anyOf) + private final String schemaType; + + public AbstractOpenApiSchema(String schemaType, Boolean isNullable) { + this.schemaType = schemaType; + this.isNullable = isNullable; + } + + /** + * Get the list of oneOf/anyOf composed schemas allowed to be stored in this object + * + * @return an instance of the actual schema/object + */ + public abstract Map> getSchemas(); + + /** + * Get the actual instance + * + * @return an instance of the actual schema/object + */ + @JsonValue + public Object getActualInstance() {return instance;} + + /** + * Set the actual instance + * + * @param instance the actual instance of the schema/object + */ + public void setActualInstance(Object instance) {this.instance = instance;} + + /** + * Get the instant recursively when the schemas defined in oneOf/anyof happen to be oneOf/anyOf schema as well + * + * @return an instance of the actual schema/object + */ + public Object getActualInstanceRecursively() { + return getActualInstanceRecursively(this); + } + + private Object getActualInstanceRecursively(AbstractOpenApiSchema object) { + if (object.getActualInstance() == null) { + return null; + } else if (object.getActualInstance() instanceof AbstractOpenApiSchema) { + return getActualInstanceRecursively((AbstractOpenApiSchema)object.getActualInstance()); + } else { + return object.getActualInstance(); + } + } + + /** + * Get the schema type (e.g. anyOf, oneOf) + * + * @return the schema type + */ + public String getSchemaType() { + return schemaType; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ").append(getClass()).append(" {\n"); + sb.append(" instance: ").append(toIndentedString(instance)).append("\n"); + sb.append(" isNullable: ").append(toIndentedString(isNullable)).append("\n"); + sb.append(" schemaType: ").append(toIndentedString(schemaType)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + AbstractOpenApiSchema a = (AbstractOpenApiSchema) o; + return Objects.equals(this.instance, a.instance) && + Objects.equals(this.isNullable, a.isNullable) && + Objects.equals(this.schemaType, a.schemaType); + } + + @Override + public int hashCode() { + return Objects.hash(instance, isNullable, schemaType); + } + + /** + * Is nullable + * + * @return true if it's nullable + */ + public Boolean isNullable() { + if (Boolean.TRUE.equals(isNullable)) { + return Boolean.TRUE; + } else { + return Boolean.FALSE; + } + } + + + +} diff --git a/src/main/java/com/regexsolver/api/generated/model/AccountLimitsDto.java b/src/main/java/com/regexsolver/api/generated/model/AccountLimitsDto.java new file mode 100644 index 0000000..672d1fe --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/model/AccountLimitsDto.java @@ -0,0 +1,361 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.regexsolver.api.generated.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.regexsolver.api.generated.ApiClient; +/** + * The plan limits currently applying to the account. + */ +@JsonPropertyOrder({ + AccountLimitsDto.JSON_PROPERTY_TYPE, + AccountLimitsDto.JSON_PROPERTY_MAX_REQUESTS_COUNT, + AccountLimitsDto.JSON_PROPERTY_MAX_REQUESTS_RATE, + AccountLimitsDto.JSON_PROPERTY_MAX_TERMS_COUNT, + AccountLimitsDto.JSON_PROPERTY_MAX_TIMEOUT, + AccountLimitsDto.JSON_PROPERTY_MAX_STATES_COUNT +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class AccountLimitsDto { + /** + * Gets or Sets type + */ + public enum TypeEnum { + ACCOUNT_LIMITS(String.valueOf("accountLimits")); + + private String value; + + TypeEnum(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static TypeEnum fromValue(String value) { + for (TypeEnum b : TypeEnum.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } + } + + public static final String JSON_PROPERTY_TYPE = "type"; + @jakarta.annotation.Nonnull + private TypeEnum type; + + public static final String JSON_PROPERTY_MAX_REQUESTS_COUNT = "maxRequestsCount"; + @jakarta.annotation.Nonnull + private Long maxRequestsCount; + + public static final String JSON_PROPERTY_MAX_REQUESTS_RATE = "maxRequestsRate"; + @jakarta.annotation.Nonnull + private Long maxRequestsRate; + + public static final String JSON_PROPERTY_MAX_TERMS_COUNT = "maxTermsCount"; + @jakarta.annotation.Nonnull + private Long maxTermsCount; + + public static final String JSON_PROPERTY_MAX_TIMEOUT = "maxTimeout"; + @jakarta.annotation.Nonnull + private Long maxTimeout; + + public static final String JSON_PROPERTY_MAX_STATES_COUNT = "maxStatesCount"; + @jakarta.annotation.Nonnull + private Long maxStatesCount; + + public AccountLimitsDto() { + } + + public AccountLimitsDto type(@jakarta.annotation.Nonnull TypeEnum type) { + this.type = type; + return this; + } + + /** + * Get type + * @return type + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_TYPE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public TypeEnum getType() { + return type; + } + + + @JsonProperty(value = JSON_PROPERTY_TYPE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setType(@jakarta.annotation.Nonnull TypeEnum type) { + this.type = type; + } + + + public AccountLimitsDto maxRequestsCount(@jakarta.annotation.Nonnull Long maxRequestsCount) { + this.maxRequestsCount = maxRequestsCount; + return this; + } + + /** + * Maximum number of requests allowed per billing period. + * @return maxRequestsCount + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_MAX_REQUESTS_COUNT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Long getMaxRequestsCount() { + return maxRequestsCount; + } + + + @JsonProperty(value = JSON_PROPERTY_MAX_REQUESTS_COUNT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setMaxRequestsCount(@jakarta.annotation.Nonnull Long maxRequestsCount) { + this.maxRequestsCount = maxRequestsCount; + } + + + public AccountLimitsDto maxRequestsRate(@jakarta.annotation.Nonnull Long maxRequestsRate) { + this.maxRequestsRate = maxRequestsRate; + return this; + } + + /** + * Maximum number of requests allowed per second. `0` means no rate limit is enforced. + * @return maxRequestsRate + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_MAX_REQUESTS_RATE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Long getMaxRequestsRate() { + return maxRequestsRate; + } + + + @JsonProperty(value = JSON_PROPERTY_MAX_REQUESTS_RATE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setMaxRequestsRate(@jakarta.annotation.Nonnull Long maxRequestsRate) { + this.maxRequestsRate = maxRequestsRate; + } + + + public AccountLimitsDto maxTermsCount(@jakarta.annotation.Nonnull Long maxTermsCount) { + this.maxTermsCount = maxTermsCount; + return this; + } + + /** + * Maximum number of terms accepted in a single request. + * @return maxTermsCount + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_MAX_TERMS_COUNT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Long getMaxTermsCount() { + return maxTermsCount; + } + + + @JsonProperty(value = JSON_PROPERTY_MAX_TERMS_COUNT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setMaxTermsCount(@jakarta.annotation.Nonnull Long maxTermsCount) { + this.maxTermsCount = maxTermsCount; + } + + + public AccountLimitsDto maxTimeout(@jakarta.annotation.Nonnull Long maxTimeout) { + this.maxTimeout = maxTimeout; + return this; + } + + /** + * Maximum execution timeout per request, in milliseconds. + * @return maxTimeout + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_MAX_TIMEOUT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Long getMaxTimeout() { + return maxTimeout; + } + + + @JsonProperty(value = JSON_PROPERTY_MAX_TIMEOUT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setMaxTimeout(@jakarta.annotation.Nonnull Long maxTimeout) { + this.maxTimeout = maxTimeout; + } + + + public AccountLimitsDto maxStatesCount(@jakarta.annotation.Nonnull Long maxStatesCount) { + this.maxStatesCount = maxStatesCount; + return this; + } + + /** + * Maximum number of automaton states an operation may build. + * @return maxStatesCount + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_MAX_STATES_COUNT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Long getMaxStatesCount() { + return maxStatesCount; + } + + + @JsonProperty(value = JSON_PROPERTY_MAX_STATES_COUNT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setMaxStatesCount(@jakarta.annotation.Nonnull Long maxStatesCount) { + this.maxStatesCount = maxStatesCount; + } + + + /** + * Return true if this AccountLimits object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + AccountLimitsDto accountLimits = (AccountLimitsDto) o; + return Objects.equals(this.type, accountLimits.type) && + Objects.equals(this.maxRequestsCount, accountLimits.maxRequestsCount) && + Objects.equals(this.maxRequestsRate, accountLimits.maxRequestsRate) && + Objects.equals(this.maxTermsCount, accountLimits.maxTermsCount) && + Objects.equals(this.maxTimeout, accountLimits.maxTimeout) && + Objects.equals(this.maxStatesCount, accountLimits.maxStatesCount); + } + + @Override + public int hashCode() { + return Objects.hash(type, maxRequestsCount, maxRequestsRate, maxTermsCount, maxTimeout, maxStatesCount); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class AccountLimitsDto {\n"); + sb.append(" type: ").append(toIndentedString(type)).append("\n"); + sb.append(" maxRequestsCount: ").append(toIndentedString(maxRequestsCount)).append("\n"); + sb.append(" maxRequestsRate: ").append(toIndentedString(maxRequestsRate)).append("\n"); + sb.append(" maxTermsCount: ").append(toIndentedString(maxTermsCount)).append("\n"); + sb.append(" maxTimeout: ").append(toIndentedString(maxTimeout)).append("\n"); + sb.append(" maxStatesCount: ").append(toIndentedString(maxStatesCount)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `type` to the URL query string + if (getType() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%stype%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getType())))); + } + + // add `maxRequestsCount` to the URL query string + if (getMaxRequestsCount() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%smaxRequestsCount%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getMaxRequestsCount())))); + } + + // add `maxRequestsRate` to the URL query string + if (getMaxRequestsRate() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%smaxRequestsRate%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getMaxRequestsRate())))); + } + + // add `maxTermsCount` to the URL query string + if (getMaxTermsCount() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%smaxTermsCount%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getMaxTermsCount())))); + } + + // add `maxTimeout` to the URL query string + if (getMaxTimeout() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%smaxTimeout%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getMaxTimeout())))); + } + + // add `maxStatesCount` to the URL query string + if (getMaxStatesCount() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%smaxStatesCount%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getMaxStatesCount())))); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/regexsolver/api/generated/model/BooleanDto.java b/src/main/java/com/regexsolver/api/generated/model/BooleanDto.java new file mode 100644 index 0000000..a6f6b9e --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/model/BooleanDto.java @@ -0,0 +1,217 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.regexsolver.api.generated.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.regexsolver.api.generated.ApiClient; +/** + * Wrapper for a boolean value. + */ +@JsonPropertyOrder({ + BooleanDto.JSON_PROPERTY_TYPE, + BooleanDto.JSON_PROPERTY_VALUE +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class BooleanDto { + /** + * Gets or Sets type + */ + public enum TypeEnum { + BOOLEAN(String.valueOf("boolean")); + + private String value; + + TypeEnum(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static TypeEnum fromValue(String value) { + for (TypeEnum b : TypeEnum.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } + } + + public static final String JSON_PROPERTY_TYPE = "type"; + @jakarta.annotation.Nonnull + private TypeEnum type; + + public static final String JSON_PROPERTY_VALUE = "value"; + @jakarta.annotation.Nonnull + private Boolean value; + + public BooleanDto() { + } + + public BooleanDto type(@jakarta.annotation.Nonnull TypeEnum type) { + this.type = type; + return this; + } + + /** + * Get type + * @return type + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_TYPE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public TypeEnum getType() { + return type; + } + + + @JsonProperty(value = JSON_PROPERTY_TYPE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setType(@jakarta.annotation.Nonnull TypeEnum type) { + this.type = type; + } + + + public BooleanDto value(@jakarta.annotation.Nonnull Boolean value) { + this.value = value; + return this; + } + + /** + * Boolean value. + * @return value + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_VALUE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Boolean getValue() { + return value; + } + + + @JsonProperty(value = JSON_PROPERTY_VALUE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setValue(@jakarta.annotation.Nonnull Boolean value) { + this.value = value; + } + + + /** + * Return true if this Boolean object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + BooleanDto _boolean = (BooleanDto) o; + return Objects.equals(this.type, _boolean.type) && + Objects.equals(this.value, _boolean.value); + } + + @Override + public int hashCode() { + return Objects.hash(type, value); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class BooleanDto {\n"); + sb.append(" type: ").append(toIndentedString(type)).append("\n"); + sb.append(" value: ").append(toIndentedString(value)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `type` to the URL query string + if (getType() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%stype%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getType())))); + } + + // add `value` to the URL query string + if (getValue() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%svalue%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getValue())))); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/regexsolver/api/generated/model/Cardinality200ResponseDto.java b/src/main/java/com/regexsolver/api/generated/model/Cardinality200ResponseDto.java new file mode 100644 index 0000000..c1925cd --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/model/Cardinality200ResponseDto.java @@ -0,0 +1,185 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.regexsolver.api.generated.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.regexsolver.api.generated.model.CardinalityDto; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.regexsolver.api.generated.ApiClient; +/** + * Cardinality200ResponseDto + */ +@JsonPropertyOrder({ + Cardinality200ResponseDto.JSON_PROPERTY_SUCCESS, + Cardinality200ResponseDto.JSON_PROPERTY_DATA +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class Cardinality200ResponseDto { + public static final String JSON_PROPERTY_SUCCESS = "success"; + @jakarta.annotation.Nonnull + private Boolean success; + + public static final String JSON_PROPERTY_DATA = "data"; + @jakarta.annotation.Nonnull + private CardinalityDto data; + + public Cardinality200ResponseDto() { + } + + public Cardinality200ResponseDto success(@jakarta.annotation.Nonnull Boolean success) { + this.success = success; + return this; + } + + /** + * Get success + * @return success + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_SUCCESS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Boolean getSuccess() { + return success; + } + + + @JsonProperty(value = JSON_PROPERTY_SUCCESS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setSuccess(@jakarta.annotation.Nonnull Boolean success) { + this.success = success; + } + + + public Cardinality200ResponseDto data(@jakarta.annotation.Nonnull CardinalityDto data) { + this.data = data; + return this; + } + + /** + * Get data + * @return data + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_DATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public CardinalityDto getData() { + return data; + } + + + @JsonProperty(value = JSON_PROPERTY_DATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setData(@jakarta.annotation.Nonnull CardinalityDto data) { + this.data = data; + } + + + /** + * Return true if this cardinality_200_response object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Cardinality200ResponseDto cardinality200Response = (Cardinality200ResponseDto) o; + return Objects.equals(this.success, cardinality200Response.success) && + Objects.equals(this.data, cardinality200Response.data); + } + + @Override + public int hashCode() { + return Objects.hash(success, data); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Cardinality200ResponseDto {\n"); + sb.append(" success: ").append(toIndentedString(success)).append("\n"); + sb.append(" data: ").append(toIndentedString(data)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `success` to the URL query string + if (getSuccess() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%ssuccess%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getSuccess())))); + } + + // add `data` to the URL query string + if (getData() != null) { + joiner.add(getData().toUrlQueryString(prefix + "data" + suffix)); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/regexsolver/api/generated/model/CardinalityBigIntegerDto.java b/src/main/java/com/regexsolver/api/generated/model/CardinalityBigIntegerDto.java new file mode 100644 index 0000000..e325454 --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/model/CardinalityBigIntegerDto.java @@ -0,0 +1,181 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.regexsolver.api.generated.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.regexsolver.api.generated.ApiClient; +/** + * The set of matched strings is finite but too large to be returned. + */ +@JsonPropertyOrder({ + CardinalityBigIntegerDto.JSON_PROPERTY_TYPE +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class CardinalityBigIntegerDto { + /** + * Gets or Sets type + */ + public enum TypeEnum { + BIG_INTEGER(String.valueOf("bigInteger")); + + private String value; + + TypeEnum(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static TypeEnum fromValue(String value) { + for (TypeEnum b : TypeEnum.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } + } + + public static final String JSON_PROPERTY_TYPE = "type"; + @jakarta.annotation.Nonnull + private TypeEnum type; + + public CardinalityBigIntegerDto() { + } + + public CardinalityBigIntegerDto type(@jakarta.annotation.Nonnull TypeEnum type) { + this.type = type; + return this; + } + + /** + * Get type + * @return type + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_TYPE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public TypeEnum getType() { + return type; + } + + + @JsonProperty(value = JSON_PROPERTY_TYPE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setType(@jakarta.annotation.Nonnull TypeEnum type) { + this.type = type; + } + + + /** + * Return true if this CardinalityBigInteger object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + CardinalityBigIntegerDto cardinalityBigInteger = (CardinalityBigIntegerDto) o; + return Objects.equals(this.type, cardinalityBigInteger.type); + } + + @Override + public int hashCode() { + return Objects.hash(type); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class CardinalityBigIntegerDto {\n"); + sb.append(" type: ").append(toIndentedString(type)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `type` to the URL query string + if (getType() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%stype%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getType())))); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/regexsolver/api/generated/model/CardinalityDto.java b/src/main/java/com/regexsolver/api/generated/model/CardinalityDto.java new file mode 100644 index 0000000..67d7435 --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/model/CardinalityDto.java @@ -0,0 +1,362 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.regexsolver.api.generated.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.regexsolver.api.generated.model.CardinalityBigIntegerDto; +import com.regexsolver.api.generated.model.CardinalityInfiniteDto; +import com.regexsolver.api.generated.model.CardinalityIntegerDto; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +import com.fasterxml.jackson.core.type.TypeReference; + +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.MapperFeature; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; +import com.regexsolver.api.generated.ApiClient; +import com.regexsolver.api.generated.JSON; + +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +@JsonDeserialize(using = CardinalityDto.CardinalityDtoDeserializer.class) +@JsonSerialize(using = CardinalityDto.CardinalityDtoSerializer.class) +public class CardinalityDto extends AbstractOpenApiSchema { + private static final Logger log = Logger.getLogger(CardinalityDto.class.getName()); + + public static class CardinalityDtoSerializer extends StdSerializer { + public CardinalityDtoSerializer(Class t) { + super(t); + } + + public CardinalityDtoSerializer() { + this(null); + } + + @Override + public void serialize(CardinalityDto value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { + jgen.writeObject(value.getActualInstance()); + } + } + + public static class CardinalityDtoDeserializer extends StdDeserializer { + public CardinalityDtoDeserializer() { + this(CardinalityDto.class); + } + + public CardinalityDtoDeserializer(Class vc) { + super(vc); + } + + @Override + public CardinalityDto deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { + JsonNode tree = ctxt.readTree(jp); + Object deserialized = null; + boolean typeCoercion = ctxt.isEnabled(MapperFeature.ALLOW_COERCION_OF_SCALARS); + int match = 0; + JsonToken token = tree.traverse(jp.getCodec()).nextToken(); + // deserialize CardinalityBigIntegerDto + try { + boolean attemptParsing = true; + // ensure that we respect type coercion as set on the client ObjectMapper + if (CardinalityBigIntegerDto.class.equals(Integer.class) || CardinalityBigIntegerDto.class.equals(Long.class) || CardinalityBigIntegerDto.class.equals(Float.class) || CardinalityBigIntegerDto.class.equals(Double.class) || CardinalityBigIntegerDto.class.equals(Boolean.class) || CardinalityBigIntegerDto.class.equals(String.class)) { + attemptParsing = typeCoercion; + if (!attemptParsing) { + attemptParsing |= ((CardinalityBigIntegerDto.class.equals(Integer.class) || CardinalityBigIntegerDto.class.equals(Long.class)) && token == JsonToken.VALUE_NUMBER_INT); + attemptParsing |= ((CardinalityBigIntegerDto.class.equals(Float.class) || CardinalityBigIntegerDto.class.equals(Double.class)) && token == JsonToken.VALUE_NUMBER_FLOAT); + attemptParsing |= (CardinalityBigIntegerDto.class.equals(Boolean.class) && (token == JsonToken.VALUE_FALSE || token == JsonToken.VALUE_TRUE)); + attemptParsing |= (CardinalityBigIntegerDto.class.equals(String.class) && token == JsonToken.VALUE_STRING); + } + } + if (attemptParsing) { + deserialized = tree.traverse(jp.getCodec()).readValueAs(CardinalityBigIntegerDto.class); + // TODO: there is no validation against JSON schema constraints + // (min, max, enum, pattern...), this does not perform a strict JSON + // validation, which means the 'match' count may be higher than it should be. + match++; + log.log(Level.FINER, "Input data matches schema 'CardinalityBigIntegerDto'"); + } + } catch (Exception e) { + // deserialization failed, continue + log.log(Level.FINER, "Input data does not match schema 'CardinalityBigIntegerDto'", e); + } + + // deserialize CardinalityInfiniteDto + try { + boolean attemptParsing = true; + // ensure that we respect type coercion as set on the client ObjectMapper + if (CardinalityInfiniteDto.class.equals(Integer.class) || CardinalityInfiniteDto.class.equals(Long.class) || CardinalityInfiniteDto.class.equals(Float.class) || CardinalityInfiniteDto.class.equals(Double.class) || CardinalityInfiniteDto.class.equals(Boolean.class) || CardinalityInfiniteDto.class.equals(String.class)) { + attemptParsing = typeCoercion; + if (!attemptParsing) { + attemptParsing |= ((CardinalityInfiniteDto.class.equals(Integer.class) || CardinalityInfiniteDto.class.equals(Long.class)) && token == JsonToken.VALUE_NUMBER_INT); + attemptParsing |= ((CardinalityInfiniteDto.class.equals(Float.class) || CardinalityInfiniteDto.class.equals(Double.class)) && token == JsonToken.VALUE_NUMBER_FLOAT); + attemptParsing |= (CardinalityInfiniteDto.class.equals(Boolean.class) && (token == JsonToken.VALUE_FALSE || token == JsonToken.VALUE_TRUE)); + attemptParsing |= (CardinalityInfiniteDto.class.equals(String.class) && token == JsonToken.VALUE_STRING); + } + } + if (attemptParsing) { + deserialized = tree.traverse(jp.getCodec()).readValueAs(CardinalityInfiniteDto.class); + // TODO: there is no validation against JSON schema constraints + // (min, max, enum, pattern...), this does not perform a strict JSON + // validation, which means the 'match' count may be higher than it should be. + match++; + log.log(Level.FINER, "Input data matches schema 'CardinalityInfiniteDto'"); + } + } catch (Exception e) { + // deserialization failed, continue + log.log(Level.FINER, "Input data does not match schema 'CardinalityInfiniteDto'", e); + } + + // deserialize CardinalityIntegerDto + try { + boolean attemptParsing = true; + // ensure that we respect type coercion as set on the client ObjectMapper + if (CardinalityIntegerDto.class.equals(Integer.class) || CardinalityIntegerDto.class.equals(Long.class) || CardinalityIntegerDto.class.equals(Float.class) || CardinalityIntegerDto.class.equals(Double.class) || CardinalityIntegerDto.class.equals(Boolean.class) || CardinalityIntegerDto.class.equals(String.class)) { + attemptParsing = typeCoercion; + if (!attemptParsing) { + attemptParsing |= ((CardinalityIntegerDto.class.equals(Integer.class) || CardinalityIntegerDto.class.equals(Long.class)) && token == JsonToken.VALUE_NUMBER_INT); + attemptParsing |= ((CardinalityIntegerDto.class.equals(Float.class) || CardinalityIntegerDto.class.equals(Double.class)) && token == JsonToken.VALUE_NUMBER_FLOAT); + attemptParsing |= (CardinalityIntegerDto.class.equals(Boolean.class) && (token == JsonToken.VALUE_FALSE || token == JsonToken.VALUE_TRUE)); + attemptParsing |= (CardinalityIntegerDto.class.equals(String.class) && token == JsonToken.VALUE_STRING); + } + } + if (attemptParsing) { + deserialized = tree.traverse(jp.getCodec()).readValueAs(CardinalityIntegerDto.class); + // TODO: there is no validation against JSON schema constraints + // (min, max, enum, pattern...), this does not perform a strict JSON + // validation, which means the 'match' count may be higher than it should be. + match++; + log.log(Level.FINER, "Input data matches schema 'CardinalityIntegerDto'"); + } + } catch (Exception e) { + // deserialization failed, continue + log.log(Level.FINER, "Input data does not match schema 'CardinalityIntegerDto'", e); + } + + if (match == 1) { + CardinalityDto ret = new CardinalityDto(); + ret.setActualInstance(deserialized); + return ret; + } + throw new IOException(String.format(java.util.Locale.ROOT, "Failed deserialization for CardinalityDto: %d classes match result, expected 1", match)); + } + + /** + * Handle deserialization of the 'null' value. + */ + @Override + public CardinalityDto getNullValue(DeserializationContext ctxt) throws JsonMappingException { + throw new JsonMappingException(ctxt.getParser(), "CardinalityDto cannot be null"); + } + } + + // store a list of schema names defined in oneOf + public static final Map> schemas = new HashMap<>(); + + public CardinalityDto() { + super("oneOf", Boolean.FALSE); + } + + public CardinalityDto(CardinalityBigIntegerDto o) { + super("oneOf", Boolean.FALSE); + setActualInstance(o); + } + + public CardinalityDto(CardinalityInfiniteDto o) { + super("oneOf", Boolean.FALSE); + setActualInstance(o); + } + + public CardinalityDto(CardinalityIntegerDto o) { + super("oneOf", Boolean.FALSE); + setActualInstance(o); + } + + static { + schemas.put("CardinalityBigIntegerDto", CardinalityBigIntegerDto.class); + schemas.put("CardinalityInfiniteDto", CardinalityInfiniteDto.class); + schemas.put("CardinalityIntegerDto", CardinalityIntegerDto.class); + JSON.registerDescendants(CardinalityDto.class, Collections.unmodifiableMap(schemas)); + // Initialize and register the discriminator mappings. + Map> mappings = new HashMap>(); + mappings.put("bigInteger", CardinalityBigIntegerDto.class); + mappings.put("infinite", CardinalityInfiniteDto.class); + mappings.put("integer", CardinalityIntegerDto.class); + mappings.put("Cardinality", CardinalityDto.class); + JSON.registerDiscriminator(CardinalityDto.class, "type", mappings); + } + + @Override + public Map> getSchemas() { + return CardinalityDto.schemas; + } + + /** + * Set the instance that matches the oneOf child schema, check + * the instance parameter is valid against the oneOf child schemas: + * CardinalityBigIntegerDto, CardinalityInfiniteDto, CardinalityIntegerDto + * + * It could be an instance of the 'oneOf' schemas. + * The oneOf child schemas may themselves be a composed schema (allOf, anyOf, oneOf). + */ + @Override + public void setActualInstance(Object instance) { + if (JSON.isInstanceOf(CardinalityBigIntegerDto.class, instance, new HashSet>())) { + super.setActualInstance(instance); + return; + } + + if (JSON.isInstanceOf(CardinalityInfiniteDto.class, instance, new HashSet>())) { + super.setActualInstance(instance); + return; + } + + if (JSON.isInstanceOf(CardinalityIntegerDto.class, instance, new HashSet>())) { + super.setActualInstance(instance); + return; + } + + throw new RuntimeException("Invalid instance type. Must be CardinalityBigIntegerDto, CardinalityInfiniteDto, CardinalityIntegerDto"); + } + + /** + * Get the actual instance, which can be the following: + * CardinalityBigIntegerDto, CardinalityInfiniteDto, CardinalityIntegerDto + * + * @return The actual instance (CardinalityBigIntegerDto, CardinalityInfiniteDto, CardinalityIntegerDto) + */ + @Override + public Object getActualInstance() { + return super.getActualInstance(); + } + + /** + * Get the actual instance of `CardinalityBigIntegerDto`. If the actual instance is not `CardinalityBigIntegerDto`, + * the ClassCastException will be thrown. + * + * @return The actual instance of `CardinalityBigIntegerDto` + * @throws ClassCastException if the instance is not `CardinalityBigIntegerDto` + */ + public CardinalityBigIntegerDto getCardinalityBigIntegerDto() throws ClassCastException { + return (CardinalityBigIntegerDto)super.getActualInstance(); + } + + /** + * Get the actual instance of `CardinalityInfiniteDto`. If the actual instance is not `CardinalityInfiniteDto`, + * the ClassCastException will be thrown. + * + * @return The actual instance of `CardinalityInfiniteDto` + * @throws ClassCastException if the instance is not `CardinalityInfiniteDto` + */ + public CardinalityInfiniteDto getCardinalityInfiniteDto() throws ClassCastException { + return (CardinalityInfiniteDto)super.getActualInstance(); + } + + /** + * Get the actual instance of `CardinalityIntegerDto`. If the actual instance is not `CardinalityIntegerDto`, + * the ClassCastException will be thrown. + * + * @return The actual instance of `CardinalityIntegerDto` + * @throws ClassCastException if the instance is not `CardinalityIntegerDto` + */ + public CardinalityIntegerDto getCardinalityIntegerDto() throws ClassCastException { + return (CardinalityIntegerDto)super.getActualInstance(); + } + + + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + if (getActualInstance() instanceof CardinalityInfiniteDto) { + if (getActualInstance() != null) { + joiner.add(((CardinalityInfiniteDto)getActualInstance()).toUrlQueryString(prefix + "one_of_0" + suffix)); + } + return joiner.toString(); + } + if (getActualInstance() instanceof CardinalityBigIntegerDto) { + if (getActualInstance() != null) { + joiner.add(((CardinalityBigIntegerDto)getActualInstance()).toUrlQueryString(prefix + "one_of_1" + suffix)); + } + return joiner.toString(); + } + if (getActualInstance() instanceof CardinalityIntegerDto) { + if (getActualInstance() != null) { + joiner.add(((CardinalityIntegerDto)getActualInstance()).toUrlQueryString(prefix + "one_of_2" + suffix)); + } + return joiner.toString(); + } + return null; + } + +} + diff --git a/src/main/java/com/regexsolver/api/generated/model/CardinalityInfiniteDto.java b/src/main/java/com/regexsolver/api/generated/model/CardinalityInfiniteDto.java new file mode 100644 index 0000000..2d74e69 --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/model/CardinalityInfiniteDto.java @@ -0,0 +1,181 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.regexsolver.api.generated.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.regexsolver.api.generated.ApiClient; +/** + * The set of matched strings is infinite. + */ +@JsonPropertyOrder({ + CardinalityInfiniteDto.JSON_PROPERTY_TYPE +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class CardinalityInfiniteDto { + /** + * Gets or Sets type + */ + public enum TypeEnum { + INFINITE(String.valueOf("infinite")); + + private String value; + + TypeEnum(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static TypeEnum fromValue(String value) { + for (TypeEnum b : TypeEnum.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } + } + + public static final String JSON_PROPERTY_TYPE = "type"; + @jakarta.annotation.Nonnull + private TypeEnum type; + + public CardinalityInfiniteDto() { + } + + public CardinalityInfiniteDto type(@jakarta.annotation.Nonnull TypeEnum type) { + this.type = type; + return this; + } + + /** + * Get type + * @return type + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_TYPE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public TypeEnum getType() { + return type; + } + + + @JsonProperty(value = JSON_PROPERTY_TYPE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setType(@jakarta.annotation.Nonnull TypeEnum type) { + this.type = type; + } + + + /** + * Return true if this CardinalityInfinite object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + CardinalityInfiniteDto cardinalityInfinite = (CardinalityInfiniteDto) o; + return Objects.equals(this.type, cardinalityInfinite.type); + } + + @Override + public int hashCode() { + return Objects.hash(type); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class CardinalityInfiniteDto {\n"); + sb.append(" type: ").append(toIndentedString(type)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `type` to the URL query string + if (getType() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%stype%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getType())))); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/regexsolver/api/generated/model/CardinalityIntegerDto.java b/src/main/java/com/regexsolver/api/generated/model/CardinalityIntegerDto.java new file mode 100644 index 0000000..32bc491 --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/model/CardinalityIntegerDto.java @@ -0,0 +1,218 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.regexsolver.api.generated.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.regexsolver.api.generated.ApiClient; +/** + * The set of matched strings is finite. + */ +@JsonPropertyOrder({ + CardinalityIntegerDto.JSON_PROPERTY_TYPE, + CardinalityIntegerDto.JSON_PROPERTY_VALUE +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class CardinalityIntegerDto { + /** + * Gets or Sets type + */ + public enum TypeEnum { + INTEGER(String.valueOf("integer")); + + private String value; + + TypeEnum(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static TypeEnum fromValue(String value) { + for (TypeEnum b : TypeEnum.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } + } + + public static final String JSON_PROPERTY_TYPE = "type"; + @jakarta.annotation.Nonnull + private TypeEnum type; + + public static final String JSON_PROPERTY_VALUE = "value"; + @jakarta.annotation.Nonnull + private Long value; + + public CardinalityIntegerDto() { + } + + public CardinalityIntegerDto type(@jakarta.annotation.Nonnull TypeEnum type) { + this.type = type; + return this; + } + + /** + * Get type + * @return type + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_TYPE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public TypeEnum getType() { + return type; + } + + + @JsonProperty(value = JSON_PROPERTY_TYPE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setType(@jakarta.annotation.Nonnull TypeEnum type) { + this.type = type; + } + + + public CardinalityIntegerDto value(@jakarta.annotation.Nonnull Long value) { + this.value = value; + return this; + } + + /** + * Exact count. + * minimum: 0 + * @return value + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_VALUE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Long getValue() { + return value; + } + + + @JsonProperty(value = JSON_PROPERTY_VALUE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setValue(@jakarta.annotation.Nonnull Long value) { + this.value = value; + } + + + /** + * Return true if this CardinalityInteger object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + CardinalityIntegerDto cardinalityInteger = (CardinalityIntegerDto) o; + return Objects.equals(this.type, cardinalityInteger.type) && + Objects.equals(this.value, cardinalityInteger.value); + } + + @Override + public int hashCode() { + return Objects.hash(type, value); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class CardinalityIntegerDto {\n"); + sb.append(" type: ").append(toIndentedString(type)).append("\n"); + sb.append(" value: ").append(toIndentedString(value)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `type` to the URL query string + if (getType() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%stype%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getType())))); + } + + // add `value` to the URL query string + if (getValue() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%svalue%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getValue())))); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/regexsolver/api/generated/model/Concat200ResponseDto.java b/src/main/java/com/regexsolver/api/generated/model/Concat200ResponseDto.java new file mode 100644 index 0000000..79991ef --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/model/Concat200ResponseDto.java @@ -0,0 +1,185 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.regexsolver.api.generated.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.regexsolver.api.generated.model.TermDto; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.regexsolver.api.generated.ApiClient; +/** + * Concat200ResponseDto + */ +@JsonPropertyOrder({ + Concat200ResponseDto.JSON_PROPERTY_SUCCESS, + Concat200ResponseDto.JSON_PROPERTY_DATA +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class Concat200ResponseDto { + public static final String JSON_PROPERTY_SUCCESS = "success"; + @jakarta.annotation.Nonnull + private Boolean success; + + public static final String JSON_PROPERTY_DATA = "data"; + @jakarta.annotation.Nonnull + private TermDto data; + + public Concat200ResponseDto() { + } + + public Concat200ResponseDto success(@jakarta.annotation.Nonnull Boolean success) { + this.success = success; + return this; + } + + /** + * Get success + * @return success + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_SUCCESS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Boolean getSuccess() { + return success; + } + + + @JsonProperty(value = JSON_PROPERTY_SUCCESS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setSuccess(@jakarta.annotation.Nonnull Boolean success) { + this.success = success; + } + + + public Concat200ResponseDto data(@jakarta.annotation.Nonnull TermDto data) { + this.data = data; + return this; + } + + /** + * Get data + * @return data + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_DATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public TermDto getData() { + return data; + } + + + @JsonProperty(value = JSON_PROPERTY_DATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setData(@jakarta.annotation.Nonnull TermDto data) { + this.data = data; + } + + + /** + * Return true if this concat_200_response object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Concat200ResponseDto concat200Response = (Concat200ResponseDto) o; + return Objects.equals(this.success, concat200Response.success) && + Objects.equals(this.data, concat200Response.data); + } + + @Override + public int hashCode() { + return Objects.hash(success, data); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Concat200ResponseDto {\n"); + sb.append(" success: ").append(toIndentedString(success)).append("\n"); + sb.append(" data: ").append(toIndentedString(data)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `success` to the URL query string + if (getSuccess() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%ssuccess%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getSuccess())))); + } + + // add `data` to the URL query string + if (getData() != null) { + joiner.add(getData().toUrlQueryString(prefix + "data" + suffix)); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/regexsolver/api/generated/model/Dot200ResponseDto.java b/src/main/java/com/regexsolver/api/generated/model/Dot200ResponseDto.java new file mode 100644 index 0000000..7f2c65a --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/model/Dot200ResponseDto.java @@ -0,0 +1,185 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.regexsolver.api.generated.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.regexsolver.api.generated.model.StringDto; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.regexsolver.api.generated.ApiClient; +/** + * Dot200ResponseDto + */ +@JsonPropertyOrder({ + Dot200ResponseDto.JSON_PROPERTY_SUCCESS, + Dot200ResponseDto.JSON_PROPERTY_DATA +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class Dot200ResponseDto { + public static final String JSON_PROPERTY_SUCCESS = "success"; + @jakarta.annotation.Nonnull + private Boolean success; + + public static final String JSON_PROPERTY_DATA = "data"; + @jakarta.annotation.Nonnull + private StringDto data; + + public Dot200ResponseDto() { + } + + public Dot200ResponseDto success(@jakarta.annotation.Nonnull Boolean success) { + this.success = success; + return this; + } + + /** + * Get success + * @return success + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_SUCCESS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Boolean getSuccess() { + return success; + } + + + @JsonProperty(value = JSON_PROPERTY_SUCCESS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setSuccess(@jakarta.annotation.Nonnull Boolean success) { + this.success = success; + } + + + public Dot200ResponseDto data(@jakarta.annotation.Nonnull StringDto data) { + this.data = data; + return this; + } + + /** + * Get data + * @return data + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_DATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public StringDto getData() { + return data; + } + + + @JsonProperty(value = JSON_PROPERTY_DATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setData(@jakarta.annotation.Nonnull StringDto data) { + this.data = data; + } + + + /** + * Return true if this dot_200_response object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Dot200ResponseDto dot200Response = (Dot200ResponseDto) o; + return Objects.equals(this.success, dot200Response.success) && + Objects.equals(this.data, dot200Response.data); + } + + @Override + public int hashCode() { + return Objects.hash(success, data); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Dot200ResponseDto {\n"); + sb.append(" success: ").append(toIndentedString(success)).append("\n"); + sb.append(" data: ").append(toIndentedString(data)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `success` to the URL query string + if (getSuccess() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%ssuccess%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getSuccess())))); + } + + // add `data` to the URL query string + if (getData() != null) { + joiner.add(getData().toUrlQueryString(prefix + "data" + suffix)); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/regexsolver/api/generated/model/Empty200ResponseDto.java b/src/main/java/com/regexsolver/api/generated/model/Empty200ResponseDto.java new file mode 100644 index 0000000..a920228 --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/model/Empty200ResponseDto.java @@ -0,0 +1,185 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.regexsolver.api.generated.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.regexsolver.api.generated.model.BooleanDto; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.regexsolver.api.generated.ApiClient; +/** + * Empty200ResponseDto + */ +@JsonPropertyOrder({ + Empty200ResponseDto.JSON_PROPERTY_SUCCESS, + Empty200ResponseDto.JSON_PROPERTY_DATA +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class Empty200ResponseDto { + public static final String JSON_PROPERTY_SUCCESS = "success"; + @jakarta.annotation.Nonnull + private Boolean success; + + public static final String JSON_PROPERTY_DATA = "data"; + @jakarta.annotation.Nonnull + private BooleanDto data; + + public Empty200ResponseDto() { + } + + public Empty200ResponseDto success(@jakarta.annotation.Nonnull Boolean success) { + this.success = success; + return this; + } + + /** + * Get success + * @return success + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_SUCCESS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Boolean getSuccess() { + return success; + } + + + @JsonProperty(value = JSON_PROPERTY_SUCCESS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setSuccess(@jakarta.annotation.Nonnull Boolean success) { + this.success = success; + } + + + public Empty200ResponseDto data(@jakarta.annotation.Nonnull BooleanDto data) { + this.data = data; + return this; + } + + /** + * Get data + * @return data + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_DATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public BooleanDto getData() { + return data; + } + + + @JsonProperty(value = JSON_PROPERTY_DATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setData(@jakarta.annotation.Nonnull BooleanDto data) { + this.data = data; + } + + + /** + * Return true if this empty_200_response object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Empty200ResponseDto empty200Response = (Empty200ResponseDto) o; + return Objects.equals(this.success, empty200Response.success) && + Objects.equals(this.data, empty200Response.data); + } + + @Override + public int hashCode() { + return Objects.hash(success, data); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Empty200ResponseDto {\n"); + sb.append(" success: ").append(toIndentedString(success)).append("\n"); + sb.append(" data: ").append(toIndentedString(data)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `success` to the URL query string + if (getSuccess() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%ssuccess%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getSuccess())))); + } + + // add `data` to the URL query string + if (getData() != null) { + joiner.add(getData().toUrlQueryString(prefix + "data" + suffix)); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/regexsolver/api/generated/model/ErrorResponse400Dto.java b/src/main/java/com/regexsolver/api/generated/model/ErrorResponse400Dto.java new file mode 100644 index 0000000..c474de2 --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/model/ErrorResponse400Dto.java @@ -0,0 +1,269 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.regexsolver.api.generated.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.regexsolver.api.generated.ApiClient; +/** + * ErrorResponse400Dto + */ +@JsonPropertyOrder({ + ErrorResponse400Dto.JSON_PROPERTY_SUCCESS, + ErrorResponse400Dto.JSON_PROPERTY_ERROR, + ErrorResponse400Dto.JSON_PROPERTY_ERROR_CODE +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class ErrorResponse400Dto { + public static final String JSON_PROPERTY_SUCCESS = "success"; + @jakarta.annotation.Nonnull + private Boolean success; + + public static final String JSON_PROPERTY_ERROR = "error"; + @jakarta.annotation.Nonnull + private String error; + + /** + * Gets or Sets errorCode + */ + public enum ErrorCodeEnum { + INVALID_JSON(String.valueOf("InvalidJson")), + + TOO_MANY_TERMS(String.valueOf("TooManyTerms")), + + TOO_FEW_TERMS(String.valueOf("TooFewTerms")), + + TIMEOUT_TOO_LARGE(String.valueOf("TimeoutTooLarge")), + + TIMEOUT_EXCEEDED(String.valueOf("TimeoutExceeded")), + + INVALID_NUMBER_OF_STRINGS_TO_GENERATE(String.valueOf("InvalidNumberOfStringsToGenerate")), + + AUTOMATON_TOO_MANY_STATES(String.valueOf("AutomatonTooManyStates")), + + REGEX_SYNTAX_ERROR(String.valueOf("RegexSyntaxError")), + + FAIR_SYNTAX_ERROR(String.valueOf("FairSyntaxError")); + + private String value; + + ErrorCodeEnum(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static ErrorCodeEnum fromValue(String value) { + for (ErrorCodeEnum b : ErrorCodeEnum.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } + } + + public static final String JSON_PROPERTY_ERROR_CODE = "errorCode"; + @jakarta.annotation.Nullable + private ErrorCodeEnum errorCode; + + public ErrorResponse400Dto() { + } + + public ErrorResponse400Dto success(@jakarta.annotation.Nonnull Boolean success) { + this.success = success; + return this; + } + + /** + * Get success + * @return success + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_SUCCESS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Boolean getSuccess() { + return success; + } + + + @JsonProperty(value = JSON_PROPERTY_SUCCESS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setSuccess(@jakarta.annotation.Nonnull Boolean success) { + this.success = success; + } + + + public ErrorResponse400Dto error(@jakarta.annotation.Nonnull String error) { + this.error = error; + return this; + } + + /** + * Human readable error message. + * @return error + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_ERROR, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getError() { + return error; + } + + + @JsonProperty(value = JSON_PROPERTY_ERROR, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setError(@jakarta.annotation.Nonnull String error) { + this.error = error; + } + + + public ErrorResponse400Dto errorCode(@jakarta.annotation.Nullable ErrorCodeEnum errorCode) { + this.errorCode = errorCode; + return this; + } + + /** + * Get errorCode + * @return errorCode + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_ERROR_CODE, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public ErrorCodeEnum getErrorCode() { + return errorCode; + } + + + @JsonProperty(value = JSON_PROPERTY_ERROR_CODE, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setErrorCode(@jakarta.annotation.Nullable ErrorCodeEnum errorCode) { + this.errorCode = errorCode; + } + + + /** + * Return true if this ErrorResponse400 object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ErrorResponse400Dto errorResponse400 = (ErrorResponse400Dto) o; + return Objects.equals(this.success, errorResponse400.success) && + Objects.equals(this.error, errorResponse400.error) && + Objects.equals(this.errorCode, errorResponse400.errorCode); + } + + @Override + public int hashCode() { + return Objects.hash(success, error, errorCode); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ErrorResponse400Dto {\n"); + sb.append(" success: ").append(toIndentedString(success)).append("\n"); + sb.append(" error: ").append(toIndentedString(error)).append("\n"); + sb.append(" errorCode: ").append(toIndentedString(errorCode)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `success` to the URL query string + if (getSuccess() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%ssuccess%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getSuccess())))); + } + + // add `error` to the URL query string + if (getError() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%serror%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getError())))); + } + + // add `errorCode` to the URL query string + if (getErrorCode() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%serrorCode%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getErrorCode())))); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/regexsolver/api/generated/model/ErrorResponse401Dto.java b/src/main/java/com/regexsolver/api/generated/model/ErrorResponse401Dto.java new file mode 100644 index 0000000..08e39a2 --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/model/ErrorResponse401Dto.java @@ -0,0 +1,255 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.regexsolver.api.generated.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.regexsolver.api.generated.ApiClient; +/** + * ErrorResponse401Dto + */ +@JsonPropertyOrder({ + ErrorResponse401Dto.JSON_PROPERTY_SUCCESS, + ErrorResponse401Dto.JSON_PROPERTY_ERROR, + ErrorResponse401Dto.JSON_PROPERTY_ERROR_CODE +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class ErrorResponse401Dto { + public static final String JSON_PROPERTY_SUCCESS = "success"; + @jakarta.annotation.Nonnull + private Boolean success; + + public static final String JSON_PROPERTY_ERROR = "error"; + @jakarta.annotation.Nonnull + private String error; + + /** + * Gets or Sets errorCode + */ + public enum ErrorCodeEnum { + MISSING_OR_MALFORMED_TOKEN(String.valueOf("MissingOrMalformedToken")), + + INVALID_TOKEN(String.valueOf("InvalidToken")); + + private String value; + + ErrorCodeEnum(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static ErrorCodeEnum fromValue(String value) { + for (ErrorCodeEnum b : ErrorCodeEnum.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } + } + + public static final String JSON_PROPERTY_ERROR_CODE = "errorCode"; + @jakarta.annotation.Nullable + private ErrorCodeEnum errorCode; + + public ErrorResponse401Dto() { + } + + public ErrorResponse401Dto success(@jakarta.annotation.Nonnull Boolean success) { + this.success = success; + return this; + } + + /** + * Get success + * @return success + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_SUCCESS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Boolean getSuccess() { + return success; + } + + + @JsonProperty(value = JSON_PROPERTY_SUCCESS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setSuccess(@jakarta.annotation.Nonnull Boolean success) { + this.success = success; + } + + + public ErrorResponse401Dto error(@jakarta.annotation.Nonnull String error) { + this.error = error; + return this; + } + + /** + * Human readable error message. + * @return error + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_ERROR, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getError() { + return error; + } + + + @JsonProperty(value = JSON_PROPERTY_ERROR, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setError(@jakarta.annotation.Nonnull String error) { + this.error = error; + } + + + public ErrorResponse401Dto errorCode(@jakarta.annotation.Nullable ErrorCodeEnum errorCode) { + this.errorCode = errorCode; + return this; + } + + /** + * Get errorCode + * @return errorCode + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_ERROR_CODE, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public ErrorCodeEnum getErrorCode() { + return errorCode; + } + + + @JsonProperty(value = JSON_PROPERTY_ERROR_CODE, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setErrorCode(@jakarta.annotation.Nullable ErrorCodeEnum errorCode) { + this.errorCode = errorCode; + } + + + /** + * Return true if this ErrorResponse401 object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ErrorResponse401Dto errorResponse401 = (ErrorResponse401Dto) o; + return Objects.equals(this.success, errorResponse401.success) && + Objects.equals(this.error, errorResponse401.error) && + Objects.equals(this.errorCode, errorResponse401.errorCode); + } + + @Override + public int hashCode() { + return Objects.hash(success, error, errorCode); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ErrorResponse401Dto {\n"); + sb.append(" success: ").append(toIndentedString(success)).append("\n"); + sb.append(" error: ").append(toIndentedString(error)).append("\n"); + sb.append(" errorCode: ").append(toIndentedString(errorCode)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `success` to the URL query string + if (getSuccess() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%ssuccess%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getSuccess())))); + } + + // add `error` to the URL query string + if (getError() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%serror%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getError())))); + } + + // add `errorCode` to the URL query string + if (getErrorCode() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%serrorCode%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getErrorCode())))); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/regexsolver/api/generated/model/ErrorResponse403Dto.java b/src/main/java/com/regexsolver/api/generated/model/ErrorResponse403Dto.java new file mode 100644 index 0000000..acb9d9c --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/model/ErrorResponse403Dto.java @@ -0,0 +1,253 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.regexsolver.api.generated.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.regexsolver.api.generated.ApiClient; +/** + * ErrorResponse403Dto + */ +@JsonPropertyOrder({ + ErrorResponse403Dto.JSON_PROPERTY_SUCCESS, + ErrorResponse403Dto.JSON_PROPERTY_ERROR, + ErrorResponse403Dto.JSON_PROPERTY_ERROR_CODE +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class ErrorResponse403Dto { + public static final String JSON_PROPERTY_SUCCESS = "success"; + @jakarta.annotation.Nonnull + private Boolean success; + + public static final String JSON_PROPERTY_ERROR = "error"; + @jakarta.annotation.Nonnull + private String error; + + /** + * Gets or Sets errorCode + */ + public enum ErrorCodeEnum { + QUOTA_EXCEEDED(String.valueOf("QuotaExceeded")); + + private String value; + + ErrorCodeEnum(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static ErrorCodeEnum fromValue(String value) { + for (ErrorCodeEnum b : ErrorCodeEnum.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } + } + + public static final String JSON_PROPERTY_ERROR_CODE = "errorCode"; + @jakarta.annotation.Nullable + private ErrorCodeEnum errorCode; + + public ErrorResponse403Dto() { + } + + public ErrorResponse403Dto success(@jakarta.annotation.Nonnull Boolean success) { + this.success = success; + return this; + } + + /** + * Get success + * @return success + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_SUCCESS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Boolean getSuccess() { + return success; + } + + + @JsonProperty(value = JSON_PROPERTY_SUCCESS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setSuccess(@jakarta.annotation.Nonnull Boolean success) { + this.success = success; + } + + + public ErrorResponse403Dto error(@jakarta.annotation.Nonnull String error) { + this.error = error; + return this; + } + + /** + * Human readable error message. + * @return error + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_ERROR, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getError() { + return error; + } + + + @JsonProperty(value = JSON_PROPERTY_ERROR, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setError(@jakarta.annotation.Nonnull String error) { + this.error = error; + } + + + public ErrorResponse403Dto errorCode(@jakarta.annotation.Nullable ErrorCodeEnum errorCode) { + this.errorCode = errorCode; + return this; + } + + /** + * Get errorCode + * @return errorCode + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_ERROR_CODE, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public ErrorCodeEnum getErrorCode() { + return errorCode; + } + + + @JsonProperty(value = JSON_PROPERTY_ERROR_CODE, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setErrorCode(@jakarta.annotation.Nullable ErrorCodeEnum errorCode) { + this.errorCode = errorCode; + } + + + /** + * Return true if this ErrorResponse403 object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ErrorResponse403Dto errorResponse403 = (ErrorResponse403Dto) o; + return Objects.equals(this.success, errorResponse403.success) && + Objects.equals(this.error, errorResponse403.error) && + Objects.equals(this.errorCode, errorResponse403.errorCode); + } + + @Override + public int hashCode() { + return Objects.hash(success, error, errorCode); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ErrorResponse403Dto {\n"); + sb.append(" success: ").append(toIndentedString(success)).append("\n"); + sb.append(" error: ").append(toIndentedString(error)).append("\n"); + sb.append(" errorCode: ").append(toIndentedString(errorCode)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `success` to the URL query string + if (getSuccess() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%ssuccess%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getSuccess())))); + } + + // add `error` to the URL query string + if (getError() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%serror%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getError())))); + } + + // add `errorCode` to the URL query string + if (getErrorCode() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%serrorCode%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getErrorCode())))); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/regexsolver/api/generated/model/ErrorResponseDto.java b/src/main/java/com/regexsolver/api/generated/model/ErrorResponseDto.java new file mode 100644 index 0000000..acd377d --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/model/ErrorResponseDto.java @@ -0,0 +1,220 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.regexsolver.api.generated.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.regexsolver.api.generated.ApiClient; +/** + * ErrorResponseDto + */ +@JsonPropertyOrder({ + ErrorResponseDto.JSON_PROPERTY_SUCCESS, + ErrorResponseDto.JSON_PROPERTY_ERROR, + ErrorResponseDto.JSON_PROPERTY_ERROR_CODE +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class ErrorResponseDto { + public static final String JSON_PROPERTY_SUCCESS = "success"; + @jakarta.annotation.Nonnull + private Boolean success; + + public static final String JSON_PROPERTY_ERROR = "error"; + @jakarta.annotation.Nonnull + private String error; + + public static final String JSON_PROPERTY_ERROR_CODE = "errorCode"; + @jakarta.annotation.Nullable + private String errorCode; + + public ErrorResponseDto() { + } + + public ErrorResponseDto success(@jakarta.annotation.Nonnull Boolean success) { + this.success = success; + return this; + } + + /** + * Get success + * @return success + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_SUCCESS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Boolean getSuccess() { + return success; + } + + + @JsonProperty(value = JSON_PROPERTY_SUCCESS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setSuccess(@jakarta.annotation.Nonnull Boolean success) { + this.success = success; + } + + + public ErrorResponseDto error(@jakarta.annotation.Nonnull String error) { + this.error = error; + return this; + } + + /** + * Human readable error message. + * @return error + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_ERROR, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getError() { + return error; + } + + + @JsonProperty(value = JSON_PROPERTY_ERROR, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setError(@jakarta.annotation.Nonnull String error) { + this.error = error; + } + + + public ErrorResponseDto errorCode(@jakarta.annotation.Nullable String errorCode) { + this.errorCode = errorCode; + return this; + } + + /** + * The error code. + * @return errorCode + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_ERROR_CODE, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public String getErrorCode() { + return errorCode; + } + + + @JsonProperty(value = JSON_PROPERTY_ERROR_CODE, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setErrorCode(@jakarta.annotation.Nullable String errorCode) { + this.errorCode = errorCode; + } + + + /** + * Return true if this ErrorResponse object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ErrorResponseDto errorResponse = (ErrorResponseDto) o; + return Objects.equals(this.success, errorResponse.success) && + Objects.equals(this.error, errorResponse.error) && + Objects.equals(this.errorCode, errorResponse.errorCode); + } + + @Override + public int hashCode() { + return Objects.hash(success, error, errorCode); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ErrorResponseDto {\n"); + sb.append(" success: ").append(toIndentedString(success)).append("\n"); + sb.append(" error: ").append(toIndentedString(error)).append("\n"); + sb.append(" errorCode: ").append(toIndentedString(errorCode)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `success` to the URL query string + if (getSuccess() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%ssuccess%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getSuccess())))); + } + + // add `error` to the URL query string + if (getError() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%serror%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getError())))); + } + + // add `errorCode` to the URL query string + if (getErrorCode() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%serrorCode%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getErrorCode())))); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/regexsolver/api/generated/model/ExecutionOptionsDto.java b/src/main/java/com/regexsolver/api/generated/model/ExecutionOptionsDto.java new file mode 100644 index 0000000..07cf8d6 --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/model/ExecutionOptionsDto.java @@ -0,0 +1,149 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.regexsolver.api.generated.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.regexsolver.api.generated.ApiClient; +/** + * Change how the engine executes the operation. + */ +@JsonPropertyOrder({ + ExecutionOptionsDto.JSON_PROPERTY_TIMEOUT +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class ExecutionOptionsDto { + public static final String JSON_PROPERTY_TIMEOUT = "timeout"; + @jakarta.annotation.Nullable + private Integer timeout; + + public ExecutionOptionsDto() { + } + + public ExecutionOptionsDto timeout(@jakarta.annotation.Nullable Integer timeout) { + this.timeout = timeout; + return this; + } + + /** + * Timeout in milliseconds for the operation. + * minimum: 1 + * @return timeout + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_TIMEOUT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public Integer getTimeout() { + return timeout; + } + + + @JsonProperty(value = JSON_PROPERTY_TIMEOUT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setTimeout(@jakarta.annotation.Nullable Integer timeout) { + this.timeout = timeout; + } + + + /** + * Return true if this ExecutionOptions object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ExecutionOptionsDto executionOptions = (ExecutionOptionsDto) o; + return Objects.equals(this.timeout, executionOptions.timeout); + } + + @Override + public int hashCode() { + return Objects.hash(timeout); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ExecutionOptionsDto {\n"); + sb.append(" timeout: ").append(toIndentedString(timeout)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `timeout` to the URL query string + if (getTimeout() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%stimeout%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getTimeout())))); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/regexsolver/api/generated/model/FairResponseOptionsDto.java b/src/main/java/com/regexsolver/api/generated/model/FairResponseOptionsDto.java new file mode 100644 index 0000000..a67160b --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/model/FairResponseOptionsDto.java @@ -0,0 +1,148 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.regexsolver.api.generated.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.regexsolver.api.generated.ApiClient; +/** + * Options controlling the FAIR output. Only applied when response format is \"fair\". + */ +@JsonPropertyOrder({ + FairResponseOptionsDto.JSON_PROPERTY_DETERMINISTIC +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class FairResponseOptionsDto { + public static final String JSON_PROPERTY_DETERMINISTIC = "deterministic"; + @jakarta.annotation.Nullable + private Boolean deterministic; + + public FairResponseOptionsDto() { + } + + public FairResponseOptionsDto deterministic(@jakarta.annotation.Nullable Boolean deterministic) { + this.deterministic = deterministic; + return this; + } + + /** + * When true, the returned FAIR is guaranteed to be a deterministic automaton, suitable for consistent pagination with /generate/strings. + * @return deterministic + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_DETERMINISTIC, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public Boolean getDeterministic() { + return deterministic; + } + + + @JsonProperty(value = JSON_PROPERTY_DETERMINISTIC, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setDeterministic(@jakarta.annotation.Nullable Boolean deterministic) { + this.deterministic = deterministic; + } + + + /** + * Return true if this FairResponseOptions object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + FairResponseOptionsDto fairResponseOptions = (FairResponseOptionsDto) o; + return Objects.equals(this.deterministic, fairResponseOptions.deterministic); + } + + @Override + public int hashCode() { + return Objects.hash(deterministic); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class FairResponseOptionsDto {\n"); + sb.append(" deterministic: ").append(toIndentedString(deterministic)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `deterministic` to the URL query string + if (getDeterministic() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sdeterministic%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getDeterministic())))); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/regexsolver/api/generated/model/GenerateStringsCharacterOrderDto.java b/src/main/java/com/regexsolver/api/generated/model/GenerateStringsCharacterOrderDto.java new file mode 100644 index 0000000..5d29a7d --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/model/GenerateStringsCharacterOrderDto.java @@ -0,0 +1,78 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.regexsolver.api.generated.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * Order in which the strings within each path are produced. Orthogonal to `pathOrder`: it does not change *what* can be generated, only which strings are reached first. `ascending` expands each position from the low end of its character range first, so `[a-z]{8}` yields `aaaaaaaa`, `aaaaaaab`, ... — a stable, spec-defined order returning the smallest witnesses of a path first. `shuffled` applies a permutation drawn from `seed`, so `[a-z]{8}` yields something like `sjtwsive` instead: the strings look like real inputs. Random in look only — generation stays reproducible and pages with `offset`, though offsets are only consistent between calls sharing the same `seed`, and the exact sequence may change between releases. Use `charset` to restrict generation to specific characters. + */ +public enum GenerateStringsCharacterOrderDto { + + ASCENDING("ascending"), + + SHUFFLED("shuffled"); + + private String value; + + GenerateStringsCharacterOrderDto(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static GenerateStringsCharacterOrderDto fromValue(String value) { + for (GenerateStringsCharacterOrderDto b : GenerateStringsCharacterOrderDto.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + if (prefix == null) { + prefix = ""; + } + + return String.format(java.util.Locale.ROOT, "%s=%s", prefix, this.toString()); + } + +} + diff --git a/src/main/java/com/regexsolver/api/generated/model/GenerateStringsPathOrderDto.java b/src/main/java/com/regexsolver/api/generated/model/GenerateStringsPathOrderDto.java new file mode 100644 index 0000000..d1568dc --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/model/GenerateStringsPathOrderDto.java @@ -0,0 +1,80 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.regexsolver.api.generated.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * Order in which the paths of the language are scheduled — the *shapes* the term allows, as opposed to the characters filling them (`characterOrder`). `sweep` expands one path in full, shortest first, before moving to the next one: the cheapest way to page through a whole language with `offset`. `interleave` covers every path the term holds before any path is asked for a second string, so a `limit` smaller than the number of shapes is spent entirely on distinct shapes; slower than `sweep`, but better suited to deriving test cases. `shuffled` is `interleave` with same-length paths visited in an order drawn by `seed`. Shorter paths still come first, so the seed only draws among paths of equal length. All three are deterministic and page with `offset`; for `shuffled`, offsets are only consistent between calls sharing the same `seed`. + */ +public enum GenerateStringsPathOrderDto { + + SWEEP("sweep"), + + INTERLEAVE("interleave"), + + SHUFFLED("shuffled"); + + private String value; + + GenerateStringsPathOrderDto(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static GenerateStringsPathOrderDto fromValue(String value) { + for (GenerateStringsPathOrderDto b : GenerateStringsPathOrderDto.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + if (prefix == null) { + prefix = ""; + } + + return String.format(java.util.Locale.ROOT, "%s=%s", prefix, this.toString()); + } + +} + diff --git a/src/main/java/com/regexsolver/api/generated/model/GenerateStringsRequestDto.java b/src/main/java/com/regexsolver/api/generated/model/GenerateStringsRequestDto.java new file mode 100644 index 0000000..8af2777 --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/model/GenerateStringsRequestDto.java @@ -0,0 +1,483 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.regexsolver.api.generated.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.regexsolver.api.generated.model.GenerateStringsCharacterOrderDto; +import com.regexsolver.api.generated.model.GenerateStringsPathOrderDto; +import com.regexsolver.api.generated.model.RequestOptionsDto; +import com.regexsolver.api.generated.model.TermDto; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.regexsolver.api.generated.ApiClient; +/** + * Request to generate up to `limit` distinct strings matched by `term`, skipping the first `offset` strings and confined to lengths between `minLength` and `maxLength`. For consistent pagination, `term` should be deterministic. + */ +@JsonPropertyOrder({ + GenerateStringsRequestDto.JSON_PROPERTY_TERM, + GenerateStringsRequestDto.JSON_PROPERTY_LIMIT, + GenerateStringsRequestDto.JSON_PROPERTY_OFFSET, + GenerateStringsRequestDto.JSON_PROPERTY_MIN_LENGTH, + GenerateStringsRequestDto.JSON_PROPERTY_MAX_LENGTH, + GenerateStringsRequestDto.JSON_PROPERTY_PATH_ORDER, + GenerateStringsRequestDto.JSON_PROPERTY_CHARACTER_ORDER, + GenerateStringsRequestDto.JSON_PROPERTY_SEED, + GenerateStringsRequestDto.JSON_PROPERTY_CHARSET, + GenerateStringsRequestDto.JSON_PROPERTY_OPTIONS +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class GenerateStringsRequestDto { + public static final String JSON_PROPERTY_TERM = "term"; + @jakarta.annotation.Nonnull + private TermDto term; + + public static final String JSON_PROPERTY_LIMIT = "limit"; + @jakarta.annotation.Nonnull + private Integer limit; + + public static final String JSON_PROPERTY_OFFSET = "offset"; + @jakarta.annotation.Nullable + private Integer offset = 0; + + public static final String JSON_PROPERTY_MIN_LENGTH = "minLength"; + @jakarta.annotation.Nullable + private Integer minLength = 0; + + public static final String JSON_PROPERTY_MAX_LENGTH = "maxLength"; + @jakarta.annotation.Nullable + private Integer maxLength = 100; + + public static final String JSON_PROPERTY_PATH_ORDER = "pathOrder"; + @jakarta.annotation.Nullable + private GenerateStringsPathOrderDto pathOrder; + + public static final String JSON_PROPERTY_CHARACTER_ORDER = "characterOrder"; + @jakarta.annotation.Nullable + private GenerateStringsCharacterOrderDto characterOrder; + + public static final String JSON_PROPERTY_SEED = "seed"; + @jakarta.annotation.Nullable + private Long seed = 0l; + + public static final String JSON_PROPERTY_CHARSET = "charset"; + @jakarta.annotation.Nullable + private String charset; + + public static final String JSON_PROPERTY_OPTIONS = "options"; + @jakarta.annotation.Nullable + private RequestOptionsDto options; + + public GenerateStringsRequestDto() { + } + + public GenerateStringsRequestDto term(@jakarta.annotation.Nonnull TermDto term) { + this.term = term; + return this; + } + + /** + * Source term to generate strings from. + * @return term + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_TERM, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public TermDto getTerm() { + return term; + } + + + @JsonProperty(value = JSON_PROPERTY_TERM, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setTerm(@jakarta.annotation.Nonnull TermDto term) { + this.term = term; + } + + + public GenerateStringsRequestDto limit(@jakarta.annotation.Nonnull Integer limit) { + this.limit = limit; + return this; + } + + /** + * Maximum number of unique strings to return. + * minimum: 1 + * maximum: 100 + * @return limit + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_LIMIT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Integer getLimit() { + return limit; + } + + + @JsonProperty(value = JSON_PROPERTY_LIMIT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setLimit(@jakarta.annotation.Nonnull Integer limit) { + this.limit = limit; + } + + + public GenerateStringsRequestDto offset(@jakarta.annotation.Nullable Integer offset) { + this.offset = offset; + return this; + } + + /** + * Number of matched strings to skip before starting to collect the results. Used for pagination. + * minimum: 0 + * @return offset + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_OFFSET, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public Integer getOffset() { + return offset; + } + + + @JsonProperty(value = JSON_PROPERTY_OFFSET, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setOffset(@jakarta.annotation.Nullable Integer offset) { + this.offset = offset; + } + + + public GenerateStringsRequestDto minLength(@jakarta.annotation.Nullable Integer minLength) { + this.minLength = minLength; + return this; + } + + /** + * Shortest string to generate. Strings shorter than this are left out of the enumeration entirely, `offset` never counting them. + * minimum: 0 + * @return minLength + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_MIN_LENGTH, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public Integer getMinLength() { + return minLength; + } + + + @JsonProperty(value = JSON_PROPERTY_MIN_LENGTH, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setMinLength(@jakarta.annotation.Nullable Integer minLength) { + this.minLength = minLength; + } + + + public GenerateStringsRequestDto maxLength(@jakarta.annotation.Nullable Integer maxLength) { + this.maxLength = maxLength; + return this; + } + + /** + * Longest string to generate. Strings longer than this are left out of the enumeration entirely, `offset` never counting them. A value below `minLength` leaves nothing to generate. + * minimum: 1 + * maximum: 100 + * @return maxLength + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_MAX_LENGTH, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public Integer getMaxLength() { + return maxLength; + } + + + @JsonProperty(value = JSON_PROPERTY_MAX_LENGTH, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setMaxLength(@jakarta.annotation.Nullable Integer maxLength) { + this.maxLength = maxLength; + } + + + public GenerateStringsRequestDto pathOrder(@jakarta.annotation.Nullable GenerateStringsPathOrderDto pathOrder) { + this.pathOrder = pathOrder; + return this; + } + + /** + * Order in which the paths of the language are scheduled. Defaults to `sweep`. + * @return pathOrder + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_PATH_ORDER, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public GenerateStringsPathOrderDto getPathOrder() { + return pathOrder; + } + + + @JsonProperty(value = JSON_PROPERTY_PATH_ORDER, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setPathOrder(@jakarta.annotation.Nullable GenerateStringsPathOrderDto pathOrder) { + this.pathOrder = pathOrder; + } + + + public GenerateStringsRequestDto characterOrder(@jakarta.annotation.Nullable GenerateStringsCharacterOrderDto characterOrder) { + this.characterOrder = characterOrder; + return this; + } + + /** + * Order in which the strings within each path are produced. Defaults to `ascending`. + * @return characterOrder + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_CHARACTER_ORDER, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public GenerateStringsCharacterOrderDto getCharacterOrder() { + return characterOrder; + } + + + @JsonProperty(value = JSON_PROPERTY_CHARACTER_ORDER, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setCharacterOrder(@jakarta.annotation.Nullable GenerateStringsCharacterOrderDto characterOrder) { + this.characterOrder = characterOrder; + } + + + public GenerateStringsRequestDto seed(@jakarta.annotation.Nullable Long seed) { + this.seed = seed; + return this; + } + + /** + * Seed behind the `shuffled` modes of `pathOrder` and `characterOrder`; ignored when neither is used. The default seed is fixed rather than random, so two calls sharing a seed generate the same strings and `offset` pages through them consistently. Change it to draw a different sequence from the same term. + * minimum: 0 + * @return seed + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_SEED, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public Long getSeed() { + return seed; + } + + + @JsonProperty(value = JSON_PROPERTY_SEED, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setSeed(@jakarta.annotation.Nullable Long seed) { + this.seed = seed; + } + + + public GenerateStringsRequestDto charset(@jakarta.annotation.Nullable String charset) { + this.charset = charset; + return this; + } + + /** + * Character class the generated strings are restricted to, such as `[a-z]` or `\\P{C}`. Paths needing a character outside of it are dropped entirely. If omitted, every character the term allows is used. + * @return charset + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_CHARSET, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public String getCharset() { + return charset; + } + + + @JsonProperty(value = JSON_PROPERTY_CHARSET, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setCharset(@jakarta.annotation.Nullable String charset) { + this.charset = charset; + } + + + public GenerateStringsRequestDto options(@jakarta.annotation.Nullable RequestOptionsDto options) { + this.options = options; + return this; + } + + /** + * Get options + * @return options + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_OPTIONS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public RequestOptionsDto getOptions() { + return options; + } + + + @JsonProperty(value = JSON_PROPERTY_OPTIONS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setOptions(@jakarta.annotation.Nullable RequestOptionsDto options) { + this.options = options; + } + + + /** + * Return true if this GenerateStringsRequest object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + GenerateStringsRequestDto generateStringsRequest = (GenerateStringsRequestDto) o; + return Objects.equals(this.term, generateStringsRequest.term) && + Objects.equals(this.limit, generateStringsRequest.limit) && + Objects.equals(this.offset, generateStringsRequest.offset) && + Objects.equals(this.minLength, generateStringsRequest.minLength) && + Objects.equals(this.maxLength, generateStringsRequest.maxLength) && + Objects.equals(this.pathOrder, generateStringsRequest.pathOrder) && + Objects.equals(this.characterOrder, generateStringsRequest.characterOrder) && + Objects.equals(this.seed, generateStringsRequest.seed) && + Objects.equals(this.charset, generateStringsRequest.charset) && + Objects.equals(this.options, generateStringsRequest.options); + } + + @Override + public int hashCode() { + return Objects.hash(term, limit, offset, minLength, maxLength, pathOrder, characterOrder, seed, charset, options); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class GenerateStringsRequestDto {\n"); + sb.append(" term: ").append(toIndentedString(term)).append("\n"); + sb.append(" limit: ").append(toIndentedString(limit)).append("\n"); + sb.append(" offset: ").append(toIndentedString(offset)).append("\n"); + sb.append(" minLength: ").append(toIndentedString(minLength)).append("\n"); + sb.append(" maxLength: ").append(toIndentedString(maxLength)).append("\n"); + sb.append(" pathOrder: ").append(toIndentedString(pathOrder)).append("\n"); + sb.append(" characterOrder: ").append(toIndentedString(characterOrder)).append("\n"); + sb.append(" seed: ").append(toIndentedString(seed)).append("\n"); + sb.append(" charset: ").append(toIndentedString(charset)).append("\n"); + sb.append(" options: ").append(toIndentedString(options)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `term` to the URL query string + if (getTerm() != null) { + joiner.add(getTerm().toUrlQueryString(prefix + "term" + suffix)); + } + + // add `limit` to the URL query string + if (getLimit() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%slimit%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getLimit())))); + } + + // add `offset` to the URL query string + if (getOffset() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%soffset%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getOffset())))); + } + + // add `minLength` to the URL query string + if (getMinLength() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sminLength%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getMinLength())))); + } + + // add `maxLength` to the URL query string + if (getMaxLength() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%smaxLength%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getMaxLength())))); + } + + // add `pathOrder` to the URL query string + if (getPathOrder() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%spathOrder%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getPathOrder())))); + } + + // add `characterOrder` to the URL query string + if (getCharacterOrder() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%scharacterOrder%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getCharacterOrder())))); + } + + // add `seed` to the URL query string + if (getSeed() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sseed%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getSeed())))); + } + + // add `charset` to the URL query string + if (getCharset() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%scharset%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getCharset())))); + } + + // add `options` to the URL query string + if (getOptions() != null) { + joiner.add(getOptions().toUrlQueryString(prefix + "options" + suffix)); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/regexsolver/api/generated/model/GenerateStringsResponseDto.java b/src/main/java/com/regexsolver/api/generated/model/GenerateStringsResponseDto.java new file mode 100644 index 0000000..b51e843 --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/model/GenerateStringsResponseDto.java @@ -0,0 +1,218 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.regexsolver.api.generated.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.regexsolver.api.generated.model.StringsDto; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.regexsolver.api.generated.ApiClient; +/** + * Response containing distinct strings generated from the requested `term`. + */ +@JsonPropertyOrder({ + GenerateStringsResponseDto.JSON_PROPERTY_TYPE, + GenerateStringsResponseDto.JSON_PROPERTY_STRINGS +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class GenerateStringsResponseDto { + /** + * Gets or Sets type + */ + public enum TypeEnum { + GENERATED_STRINGS(String.valueOf("generatedStrings")); + + private String value; + + TypeEnum(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static TypeEnum fromValue(String value) { + for (TypeEnum b : TypeEnum.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } + } + + public static final String JSON_PROPERTY_TYPE = "type"; + @jakarta.annotation.Nonnull + private TypeEnum type; + + public static final String JSON_PROPERTY_STRINGS = "strings"; + @jakarta.annotation.Nonnull + private StringsDto strings; + + public GenerateStringsResponseDto() { + } + + public GenerateStringsResponseDto type(@jakarta.annotation.Nonnull TypeEnum type) { + this.type = type; + return this; + } + + /** + * Get type + * @return type + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_TYPE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public TypeEnum getType() { + return type; + } + + + @JsonProperty(value = JSON_PROPERTY_TYPE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setType(@jakarta.annotation.Nonnull TypeEnum type) { + this.type = type; + } + + + public GenerateStringsResponseDto strings(@jakarta.annotation.Nonnull StringsDto strings) { + this.strings = strings; + return this; + } + + /** + * The generated distinct strings. + * @return strings + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_STRINGS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public StringsDto getStrings() { + return strings; + } + + + @JsonProperty(value = JSON_PROPERTY_STRINGS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setStrings(@jakarta.annotation.Nonnull StringsDto strings) { + this.strings = strings; + } + + + /** + * Return true if this GenerateStringsResponse object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + GenerateStringsResponseDto generateStringsResponse = (GenerateStringsResponseDto) o; + return Objects.equals(this.type, generateStringsResponse.type) && + Objects.equals(this.strings, generateStringsResponse.strings); + } + + @Override + public int hashCode() { + return Objects.hash(type, strings); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class GenerateStringsResponseDto {\n"); + sb.append(" type: ").append(toIndentedString(type)).append("\n"); + sb.append(" strings: ").append(toIndentedString(strings)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `type` to the URL query string + if (getType() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%stype%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getType())))); + } + + // add `strings` to the URL query string + if (getStrings() != null) { + joiner.add(getStrings().toUrlQueryString(prefix + "strings" + suffix)); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/regexsolver/api/generated/model/Length200ResponseDto.java b/src/main/java/com/regexsolver/api/generated/model/Length200ResponseDto.java new file mode 100644 index 0000000..7a096bc --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/model/Length200ResponseDto.java @@ -0,0 +1,185 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.regexsolver.api.generated.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.regexsolver.api.generated.model.LengthDto; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.regexsolver.api.generated.ApiClient; +/** + * Length200ResponseDto + */ +@JsonPropertyOrder({ + Length200ResponseDto.JSON_PROPERTY_SUCCESS, + Length200ResponseDto.JSON_PROPERTY_DATA +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class Length200ResponseDto { + public static final String JSON_PROPERTY_SUCCESS = "success"; + @jakarta.annotation.Nonnull + private Boolean success; + + public static final String JSON_PROPERTY_DATA = "data"; + @jakarta.annotation.Nonnull + private LengthDto data; + + public Length200ResponseDto() { + } + + public Length200ResponseDto success(@jakarta.annotation.Nonnull Boolean success) { + this.success = success; + return this; + } + + /** + * Get success + * @return success + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_SUCCESS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Boolean getSuccess() { + return success; + } + + + @JsonProperty(value = JSON_PROPERTY_SUCCESS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setSuccess(@jakarta.annotation.Nonnull Boolean success) { + this.success = success; + } + + + public Length200ResponseDto data(@jakarta.annotation.Nonnull LengthDto data) { + this.data = data; + return this; + } + + /** + * Get data + * @return data + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_DATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public LengthDto getData() { + return data; + } + + + @JsonProperty(value = JSON_PROPERTY_DATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setData(@jakarta.annotation.Nonnull LengthDto data) { + this.data = data; + } + + + /** + * Return true if this length_200_response object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Length200ResponseDto length200Response = (Length200ResponseDto) o; + return Objects.equals(this.success, length200Response.success) && + Objects.equals(this.data, length200Response.data); + } + + @Override + public int hashCode() { + return Objects.hash(success, data); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Length200ResponseDto {\n"); + sb.append(" success: ").append(toIndentedString(success)).append("\n"); + sb.append(" data: ").append(toIndentedString(data)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `success` to the URL query string + if (getSuccess() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%ssuccess%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getSuccess())))); + } + + // add `data` to the URL query string + if (getData() != null) { + joiner.add(getData().toUrlQueryString(prefix + "data" + suffix)); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/regexsolver/api/generated/model/LengthDto.java b/src/main/java/com/regexsolver/api/generated/model/LengthDto.java new file mode 100644 index 0000000..47c90a5 --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/model/LengthDto.java @@ -0,0 +1,253 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.regexsolver.api.generated.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.regexsolver.api.generated.ApiClient; +/** + * Minimum and maximum length of any string in the language. + */ +@JsonPropertyOrder({ + LengthDto.JSON_PROPERTY_TYPE, + LengthDto.JSON_PROPERTY_MIN, + LengthDto.JSON_PROPERTY_MAX +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class LengthDto { + /** + * Gets or Sets type + */ + public enum TypeEnum { + LENGTH(String.valueOf("length")); + + private String value; + + TypeEnum(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static TypeEnum fromValue(String value) { + for (TypeEnum b : TypeEnum.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } + } + + public static final String JSON_PROPERTY_TYPE = "type"; + @jakarta.annotation.Nonnull + private TypeEnum type; + + public static final String JSON_PROPERTY_MIN = "min"; + @jakarta.annotation.Nullable + private Integer min; + + public static final String JSON_PROPERTY_MAX = "max"; + @jakarta.annotation.Nullable + private Integer max; + + public LengthDto() { + } + + public LengthDto type(@jakarta.annotation.Nonnull TypeEnum type) { + this.type = type; + return this; + } + + /** + * Get type + * @return type + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_TYPE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public TypeEnum getType() { + return type; + } + + + @JsonProperty(value = JSON_PROPERTY_TYPE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setType(@jakarta.annotation.Nonnull TypeEnum type) { + this.type = type; + } + + + public LengthDto min(@jakarta.annotation.Nullable Integer min) { + this.min = min; + return this; + } + + /** + * Shortest possible length, or null if empty. + * @return min + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_MIN, required = false) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Integer getMin() { + return min; + } + + + @JsonProperty(value = JSON_PROPERTY_MIN, required = false) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setMin(@jakarta.annotation.Nullable Integer min) { + this.min = min; + } + + + public LengthDto max(@jakarta.annotation.Nullable Integer max) { + this.max = max; + return this; + } + + /** + * Longest possible length, or null if unbounded. + * @return max + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_MAX, required = false) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Integer getMax() { + return max; + } + + + @JsonProperty(value = JSON_PROPERTY_MAX, required = false) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setMax(@jakarta.annotation.Nullable Integer max) { + this.max = max; + } + + + /** + * Return true if this Length object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + LengthDto length = (LengthDto) o; + return Objects.equals(this.type, length.type) && + Objects.equals(this.min, length.min) && + Objects.equals(this.max, length.max); + } + + @Override + public int hashCode() { + return Objects.hash(type, min, max); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class LengthDto {\n"); + sb.append(" type: ").append(toIndentedString(type)).append("\n"); + sb.append(" min: ").append(toIndentedString(min)).append("\n"); + sb.append(" max: ").append(toIndentedString(max)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `type` to the URL query string + if (getType() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%stype%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getType())))); + } + + // add `min` to the URL query string + if (getMin() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%smin%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getMin())))); + } + + // add `max` to the URL query string + if (getMax() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%smax%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getMax())))); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/regexsolver/api/generated/model/Limits200ResponseDto.java b/src/main/java/com/regexsolver/api/generated/model/Limits200ResponseDto.java new file mode 100644 index 0000000..a021669 --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/model/Limits200ResponseDto.java @@ -0,0 +1,185 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.regexsolver.api.generated.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.regexsolver.api.generated.model.AccountLimitsDto; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.regexsolver.api.generated.ApiClient; +/** + * Limits200ResponseDto + */ +@JsonPropertyOrder({ + Limits200ResponseDto.JSON_PROPERTY_SUCCESS, + Limits200ResponseDto.JSON_PROPERTY_DATA +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class Limits200ResponseDto { + public static final String JSON_PROPERTY_SUCCESS = "success"; + @jakarta.annotation.Nonnull + private Boolean success; + + public static final String JSON_PROPERTY_DATA = "data"; + @jakarta.annotation.Nonnull + private AccountLimitsDto data; + + public Limits200ResponseDto() { + } + + public Limits200ResponseDto success(@jakarta.annotation.Nonnull Boolean success) { + this.success = success; + return this; + } + + /** + * Get success + * @return success + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_SUCCESS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Boolean getSuccess() { + return success; + } + + + @JsonProperty(value = JSON_PROPERTY_SUCCESS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setSuccess(@jakarta.annotation.Nonnull Boolean success) { + this.success = success; + } + + + public Limits200ResponseDto data(@jakarta.annotation.Nonnull AccountLimitsDto data) { + this.data = data; + return this; + } + + /** + * Get data + * @return data + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_DATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public AccountLimitsDto getData() { + return data; + } + + + @JsonProperty(value = JSON_PROPERTY_DATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setData(@jakarta.annotation.Nonnull AccountLimitsDto data) { + this.data = data; + } + + + /** + * Return true if this limits_200_response object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Limits200ResponseDto limits200Response = (Limits200ResponseDto) o; + return Objects.equals(this.success, limits200Response.success) && + Objects.equals(this.data, limits200Response.data); + } + + @Override + public int hashCode() { + return Objects.hash(success, data); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Limits200ResponseDto {\n"); + sb.append(" success: ").append(toIndentedString(success)).append("\n"); + sb.append(" data: ").append(toIndentedString(data)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `success` to the URL query string + if (getSuccess() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%ssuccess%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getSuccess())))); + } + + // add `data` to the URL query string + if (getData() != null) { + joiner.add(getData().toUrlQueryString(prefix + "data" + suffix)); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/regexsolver/api/generated/model/MultiTermsRequestDto.java b/src/main/java/com/regexsolver/api/generated/model/MultiTermsRequestDto.java new file mode 100644 index 0000000..72ed918 --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/model/MultiTermsRequestDto.java @@ -0,0 +1,201 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.regexsolver.api.generated.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.regexsolver.api.generated.model.RequestOptionsDto; +import com.regexsolver.api.generated.model.TermDto; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.regexsolver.api.generated.ApiClient; +/** + * Request carrying 2 or more terms for n-ary operations. + */ +@JsonPropertyOrder({ + MultiTermsRequestDto.JSON_PROPERTY_TERMS, + MultiTermsRequestDto.JSON_PROPERTY_OPTIONS +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class MultiTermsRequestDto { + public static final String JSON_PROPERTY_TERMS = "terms"; + @jakarta.annotation.Nonnull + private List terms = new ArrayList<>(); + + public static final String JSON_PROPERTY_OPTIONS = "options"; + @jakarta.annotation.Nullable + private RequestOptionsDto options; + + public MultiTermsRequestDto() { + } + + public MultiTermsRequestDto terms(@jakarta.annotation.Nonnull List terms) { + this.terms = terms; + return this; + } + + public MultiTermsRequestDto addTermsItem(TermDto termsItem) { + if (this.terms == null) { + this.terms = new ArrayList<>(); + } + this.terms.add(termsItem); + return this; + } + + /** + * Terms to process. Order matters for some operations. + * @return terms + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_TERMS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public List getTerms() { + return terms; + } + + + @JsonProperty(value = JSON_PROPERTY_TERMS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setTerms(@jakarta.annotation.Nonnull List terms) { + this.terms = terms; + } + + + public MultiTermsRequestDto options(@jakarta.annotation.Nullable RequestOptionsDto options) { + this.options = options; + return this; + } + + /** + * Get options + * @return options + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_OPTIONS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public RequestOptionsDto getOptions() { + return options; + } + + + @JsonProperty(value = JSON_PROPERTY_OPTIONS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setOptions(@jakarta.annotation.Nullable RequestOptionsDto options) { + this.options = options; + } + + + /** + * Return true if this MultiTermsRequest object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + MultiTermsRequestDto multiTermsRequest = (MultiTermsRequestDto) o; + return Objects.equals(this.terms, multiTermsRequest.terms) && + Objects.equals(this.options, multiTermsRequest.options); + } + + @Override + public int hashCode() { + return Objects.hash(terms, options); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class MultiTermsRequestDto {\n"); + sb.append(" terms: ").append(toIndentedString(terms)).append("\n"); + sb.append(" options: ").append(toIndentedString(options)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `terms` to the URL query string + if (getTerms() != null) { + for (int i = 0; i < getTerms().size(); i++) { + if (getTerms().get(i) != null) { + joiner.add(getTerms().get(i).toUrlQueryString(String.format(java.util.Locale.ROOT, "%sterms%s%s", prefix, suffix, + "".equals(suffix) ? "" : String.format(java.util.Locale.ROOT, "%s%d%s", containerPrefix, i, containerSuffix)))); + } + } + } + + // add `options` to the URL query string + if (getOptions() != null) { + joiner.add(getOptions().toUrlQueryString(prefix + "options" + suffix)); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/regexsolver/api/generated/model/RepeatRequestDto.java b/src/main/java/com/regexsolver/api/generated/model/RepeatRequestDto.java new file mode 100644 index 0000000..6499ca1 --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/model/RepeatRequestDto.java @@ -0,0 +1,260 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.regexsolver.api.generated.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.regexsolver.api.generated.model.RequestOptionsDto; +import com.regexsolver.api.generated.model.TermDto; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.regexsolver.api.generated.ApiClient; +/** + * Request to repeat a term between `min` and `max` times. + */ +@JsonPropertyOrder({ + RepeatRequestDto.JSON_PROPERTY_TERM, + RepeatRequestDto.JSON_PROPERTY_MIN, + RepeatRequestDto.JSON_PROPERTY_MAX, + RepeatRequestDto.JSON_PROPERTY_OPTIONS +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class RepeatRequestDto { + public static final String JSON_PROPERTY_TERM = "term"; + @jakarta.annotation.Nonnull + private TermDto term; + + public static final String JSON_PROPERTY_MIN = "min"; + @jakarta.annotation.Nonnull + private Integer min; + + public static final String JSON_PROPERTY_MAX = "max"; + @jakarta.annotation.Nullable + private Integer max; + + public static final String JSON_PROPERTY_OPTIONS = "options"; + @jakarta.annotation.Nullable + private RequestOptionsDto options; + + public RepeatRequestDto() { + } + + public RepeatRequestDto term(@jakarta.annotation.Nonnull TermDto term) { + this.term = term; + return this; + } + + /** + * Term to repeat. + * @return term + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_TERM, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public TermDto getTerm() { + return term; + } + + + @JsonProperty(value = JSON_PROPERTY_TERM, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setTerm(@jakarta.annotation.Nonnull TermDto term) { + this.term = term; + } + + + public RepeatRequestDto min(@jakarta.annotation.Nonnull Integer min) { + this.min = min; + return this; + } + + /** + * Inclusive lower bound of repetitions. + * minimum: 0 + * @return min + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_MIN, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Integer getMin() { + return min; + } + + + @JsonProperty(value = JSON_PROPERTY_MIN, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setMin(@jakarta.annotation.Nonnull Integer min) { + this.min = min; + } + + + public RepeatRequestDto max(@jakarta.annotation.Nullable Integer max) { + this.max = max; + return this; + } + + /** + * Inclusive upper bound. If omitted or null, the repetition is unbounded. + * minimum: 0 + * @return max + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_MAX, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public Integer getMax() { + return max; + } + + + @JsonProperty(value = JSON_PROPERTY_MAX, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setMax(@jakarta.annotation.Nullable Integer max) { + this.max = max; + } + + + public RepeatRequestDto options(@jakarta.annotation.Nullable RequestOptionsDto options) { + this.options = options; + return this; + } + + /** + * Get options + * @return options + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_OPTIONS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public RequestOptionsDto getOptions() { + return options; + } + + + @JsonProperty(value = JSON_PROPERTY_OPTIONS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setOptions(@jakarta.annotation.Nullable RequestOptionsDto options) { + this.options = options; + } + + + /** + * Return true if this RepeatRequest object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + RepeatRequestDto repeatRequest = (RepeatRequestDto) o; + return Objects.equals(this.term, repeatRequest.term) && + Objects.equals(this.min, repeatRequest.min) && + Objects.equals(this.max, repeatRequest.max) && + Objects.equals(this.options, repeatRequest.options); + } + + @Override + public int hashCode() { + return Objects.hash(term, min, max, options); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class RepeatRequestDto {\n"); + sb.append(" term: ").append(toIndentedString(term)).append("\n"); + sb.append(" min: ").append(toIndentedString(min)).append("\n"); + sb.append(" max: ").append(toIndentedString(max)).append("\n"); + sb.append(" options: ").append(toIndentedString(options)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `term` to the URL query string + if (getTerm() != null) { + joiner.add(getTerm().toUrlQueryString(prefix + "term" + suffix)); + } + + // add `min` to the URL query string + if (getMin() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%smin%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getMin())))); + } + + // add `max` to the URL query string + if (getMax() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%smax%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getMax())))); + } + + // add `options` to the URL query string + if (getOptions() != null) { + joiner.add(getOptions().toUrlQueryString(prefix + "options" + suffix)); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/regexsolver/api/generated/model/RequestOptionsDto.java b/src/main/java/com/regexsolver/api/generated/model/RequestOptionsDto.java new file mode 100644 index 0000000..43142ac --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/model/RequestOptionsDto.java @@ -0,0 +1,222 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.regexsolver.api.generated.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.regexsolver.api.generated.model.ExecutionOptionsDto; +import com.regexsolver.api.generated.model.ResponseOptionsDto; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.regexsolver.api.generated.ApiClient; +/** + * Change how the engine handles the operation. + */ +@JsonPropertyOrder({ + RequestOptionsDto.JSON_PROPERTY_SCHEMA_VERSION, + RequestOptionsDto.JSON_PROPERTY_RESPONSE, + RequestOptionsDto.JSON_PROPERTY_EXECUTION +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class RequestOptionsDto { + public static final String JSON_PROPERTY_SCHEMA_VERSION = "schemaVersion"; + @jakarta.annotation.Nonnull + private Integer schemaVersion; + + public static final String JSON_PROPERTY_RESPONSE = "response"; + @jakarta.annotation.Nullable + private ResponseOptionsDto response; + + public static final String JSON_PROPERTY_EXECUTION = "execution"; + @jakarta.annotation.Nullable + private ExecutionOptionsDto execution; + + public RequestOptionsDto() { + } + + public RequestOptionsDto schemaVersion(@jakarta.annotation.Nonnull Integer schemaVersion) { + this.schemaVersion = schemaVersion; + return this; + } + + /** + * Client-expected schema version. + * @return schemaVersion + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_SCHEMA_VERSION, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Integer getSchemaVersion() { + return schemaVersion; + } + + + @JsonProperty(value = JSON_PROPERTY_SCHEMA_VERSION, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setSchemaVersion(@jakarta.annotation.Nonnull Integer schemaVersion) { + this.schemaVersion = schemaVersion; + } + + + public RequestOptionsDto response(@jakarta.annotation.Nullable ResponseOptionsDto response) { + this.response = response; + return this; + } + + /** + * Get response + * @return response + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_RESPONSE, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public ResponseOptionsDto getResponse() { + return response; + } + + + @JsonProperty(value = JSON_PROPERTY_RESPONSE, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setResponse(@jakarta.annotation.Nullable ResponseOptionsDto response) { + this.response = response; + } + + + public RequestOptionsDto execution(@jakarta.annotation.Nullable ExecutionOptionsDto execution) { + this.execution = execution; + return this; + } + + /** + * Get execution + * @return execution + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_EXECUTION, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public ExecutionOptionsDto getExecution() { + return execution; + } + + + @JsonProperty(value = JSON_PROPERTY_EXECUTION, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setExecution(@jakarta.annotation.Nullable ExecutionOptionsDto execution) { + this.execution = execution; + } + + + /** + * Return true if this RequestOptions object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + RequestOptionsDto requestOptions = (RequestOptionsDto) o; + return Objects.equals(this.schemaVersion, requestOptions.schemaVersion) && + Objects.equals(this.response, requestOptions.response) && + Objects.equals(this.execution, requestOptions.execution); + } + + @Override + public int hashCode() { + return Objects.hash(schemaVersion, response, execution); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class RequestOptionsDto {\n"); + sb.append(" schemaVersion: ").append(toIndentedString(schemaVersion)).append("\n"); + sb.append(" response: ").append(toIndentedString(response)).append("\n"); + sb.append(" execution: ").append(toIndentedString(execution)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `schemaVersion` to the URL query string + if (getSchemaVersion() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sschemaVersion%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getSchemaVersion())))); + } + + // add `response` to the URL query string + if (getResponse() != null) { + joiner.add(getResponse().toUrlQueryString(prefix + "response" + suffix)); + } + + // add `execution` to the URL query string + if (getExecution() != null) { + joiner.add(getExecution().toUrlQueryString(prefix + "execution" + suffix)); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/regexsolver/api/generated/model/ResponseOptionsDto.java b/src/main/java/com/regexsolver/api/generated/model/ResponseOptionsDto.java new file mode 100644 index 0000000..73c6fcc --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/model/ResponseOptionsDto.java @@ -0,0 +1,222 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.regexsolver.api.generated.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.regexsolver.api.generated.model.FairResponseOptionsDto; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.regexsolver.api.generated.ApiClient; +/** + * Change how the engine returns results. + */ +@JsonPropertyOrder({ + ResponseOptionsDto.JSON_PROPERTY_FORMAT, + ResponseOptionsDto.JSON_PROPERTY_FAIR +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class ResponseOptionsDto { + /** + * Return format of the term. + */ + public enum FormatEnum { + ANY(String.valueOf("any")), + + FAIR(String.valueOf("fair")), + + REGEX(String.valueOf("regex")); + + private String value; + + FormatEnum(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static FormatEnum fromValue(String value) { + for (FormatEnum b : FormatEnum.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } + } + + public static final String JSON_PROPERTY_FORMAT = "format"; + @jakarta.annotation.Nullable + private FormatEnum format; + + public static final String JSON_PROPERTY_FAIR = "fair"; + @jakarta.annotation.Nullable + private FairResponseOptionsDto fair; + + public ResponseOptionsDto() { + } + + public ResponseOptionsDto format(@jakarta.annotation.Nullable FormatEnum format) { + this.format = format; + return this; + } + + /** + * Return format of the term. + * @return format + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_FORMAT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public FormatEnum getFormat() { + return format; + } + + + @JsonProperty(value = JSON_PROPERTY_FORMAT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setFormat(@jakarta.annotation.Nullable FormatEnum format) { + this.format = format; + } + + + public ResponseOptionsDto fair(@jakarta.annotation.Nullable FairResponseOptionsDto fair) { + this.fair = fair; + return this; + } + + /** + * Options applied when format is \"fair\". Ignored otherwise. + * @return fair + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_FAIR, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public FairResponseOptionsDto getFair() { + return fair; + } + + + @JsonProperty(value = JSON_PROPERTY_FAIR, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setFair(@jakarta.annotation.Nullable FairResponseOptionsDto fair) { + this.fair = fair; + } + + + /** + * Return true if this ResponseOptions object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ResponseOptionsDto responseOptions = (ResponseOptionsDto) o; + return Objects.equals(this.format, responseOptions.format) && + Objects.equals(this.fair, responseOptions.fair); + } + + @Override + public int hashCode() { + return Objects.hash(format, fair); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ResponseOptionsDto {\n"); + sb.append(" format: ").append(toIndentedString(format)).append("\n"); + sb.append(" fair: ").append(toIndentedString(fair)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `format` to the URL query string + if (getFormat() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sformat%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getFormat())))); + } + + // add `fair` to the URL query string + if (getFair() != null) { + joiner.add(getFair().toUrlQueryString(prefix + "fair" + suffix)); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/regexsolver/api/generated/model/StringDto.java b/src/main/java/com/regexsolver/api/generated/model/StringDto.java new file mode 100644 index 0000000..579ec7c --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/model/StringDto.java @@ -0,0 +1,217 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.regexsolver.api.generated.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.regexsolver.api.generated.ApiClient; +/** + * Wrapper for a string value. + */ +@JsonPropertyOrder({ + StringDto.JSON_PROPERTY_TYPE, + StringDto.JSON_PROPERTY_VALUE +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class StringDto { + /** + * Gets or Sets type + */ + public enum TypeEnum { + STRING(String.valueOf("string")); + + private String value; + + TypeEnum(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static TypeEnum fromValue(String value) { + for (TypeEnum b : TypeEnum.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } + } + + public static final String JSON_PROPERTY_TYPE = "type"; + @jakarta.annotation.Nonnull + private TypeEnum type; + + public static final String JSON_PROPERTY_VALUE = "value"; + @jakarta.annotation.Nonnull + private String value; + + public StringDto() { + } + + public StringDto type(@jakarta.annotation.Nonnull TypeEnum type) { + this.type = type; + return this; + } + + /** + * Get type + * @return type + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_TYPE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public TypeEnum getType() { + return type; + } + + + @JsonProperty(value = JSON_PROPERTY_TYPE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setType(@jakarta.annotation.Nonnull TypeEnum type) { + this.type = type; + } + + + public StringDto value(@jakarta.annotation.Nonnull String value) { + this.value = value; + return this; + } + + /** + * String value. + * @return value + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_VALUE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getValue() { + return value; + } + + + @JsonProperty(value = JSON_PROPERTY_VALUE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setValue(@jakarta.annotation.Nonnull String value) { + this.value = value; + } + + + /** + * Return true if this String object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + StringDto string = (StringDto) o; + return Objects.equals(this.type, string.type) && + Objects.equals(this.value, string.value); + } + + @Override + public int hashCode() { + return Objects.hash(type, value); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class StringDto {\n"); + sb.append(" type: ").append(toIndentedString(type)).append("\n"); + sb.append(" value: ").append(toIndentedString(value)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `type` to the URL query string + if (getType() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%stype%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getType())))); + } + + // add `value` to the URL query string + if (getValue() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%svalue%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getValue())))); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/regexsolver/api/generated/model/Strings200ResponseDto.java b/src/main/java/com/regexsolver/api/generated/model/Strings200ResponseDto.java new file mode 100644 index 0000000..bc3de55 --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/model/Strings200ResponseDto.java @@ -0,0 +1,185 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.regexsolver.api.generated.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.regexsolver.api.generated.model.GenerateStringsResponseDto; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.regexsolver.api.generated.ApiClient; +/** + * Strings200ResponseDto + */ +@JsonPropertyOrder({ + Strings200ResponseDto.JSON_PROPERTY_SUCCESS, + Strings200ResponseDto.JSON_PROPERTY_DATA +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class Strings200ResponseDto { + public static final String JSON_PROPERTY_SUCCESS = "success"; + @jakarta.annotation.Nonnull + private Boolean success; + + public static final String JSON_PROPERTY_DATA = "data"; + @jakarta.annotation.Nonnull + private GenerateStringsResponseDto data; + + public Strings200ResponseDto() { + } + + public Strings200ResponseDto success(@jakarta.annotation.Nonnull Boolean success) { + this.success = success; + return this; + } + + /** + * Get success + * @return success + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_SUCCESS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Boolean getSuccess() { + return success; + } + + + @JsonProperty(value = JSON_PROPERTY_SUCCESS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setSuccess(@jakarta.annotation.Nonnull Boolean success) { + this.success = success; + } + + + public Strings200ResponseDto data(@jakarta.annotation.Nonnull GenerateStringsResponseDto data) { + this.data = data; + return this; + } + + /** + * Get data + * @return data + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_DATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public GenerateStringsResponseDto getData() { + return data; + } + + + @JsonProperty(value = JSON_PROPERTY_DATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setData(@jakarta.annotation.Nonnull GenerateStringsResponseDto data) { + this.data = data; + } + + + /** + * Return true if this strings_200_response object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Strings200ResponseDto strings200Response = (Strings200ResponseDto) o; + return Objects.equals(this.success, strings200Response.success) && + Objects.equals(this.data, strings200Response.data); + } + + @Override + public int hashCode() { + return Objects.hash(success, data); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Strings200ResponseDto {\n"); + sb.append(" success: ").append(toIndentedString(success)).append("\n"); + sb.append(" data: ").append(toIndentedString(data)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `success` to the URL query string + if (getSuccess() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%ssuccess%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getSuccess())))); + } + + // add `data` to the URL query string + if (getData() != null) { + joiner.add(getData().toUrlQueryString(prefix + "data" + suffix)); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/regexsolver/api/generated/model/StringsDto.java b/src/main/java/com/regexsolver/api/generated/model/StringsDto.java new file mode 100644 index 0000000..b24d74c --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/model/StringsDto.java @@ -0,0 +1,231 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.regexsolver.api.generated.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.regexsolver.api.generated.ApiClient; +/** + * Wrapper for a list of strings. + */ +@JsonPropertyOrder({ + StringsDto.JSON_PROPERTY_TYPE, + StringsDto.JSON_PROPERTY_VALUE +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class StringsDto { + /** + * Gets or Sets type + */ + public enum TypeEnum { + STRINGS(String.valueOf("strings")); + + private String value; + + TypeEnum(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static TypeEnum fromValue(String value) { + for (TypeEnum b : TypeEnum.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } + } + + public static final String JSON_PROPERTY_TYPE = "type"; + @jakarta.annotation.Nonnull + private TypeEnum type; + + public static final String JSON_PROPERTY_VALUE = "value"; + @jakarta.annotation.Nonnull + private List value = new ArrayList<>(); + + public StringsDto() { + } + + public StringsDto type(@jakarta.annotation.Nonnull TypeEnum type) { + this.type = type; + return this; + } + + /** + * Get type + * @return type + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_TYPE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public TypeEnum getType() { + return type; + } + + + @JsonProperty(value = JSON_PROPERTY_TYPE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setType(@jakarta.annotation.Nonnull TypeEnum type) { + this.type = type; + } + + + public StringsDto value(@jakarta.annotation.Nonnull List value) { + this.value = value; + return this; + } + + public StringsDto addValueItem(String valueItem) { + if (this.value == null) { + this.value = new ArrayList<>(); + } + this.value.add(valueItem); + return this; + } + + /** + * Array of unique strings. + * @return value + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_VALUE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public List getValue() { + return value; + } + + + @JsonProperty(value = JSON_PROPERTY_VALUE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setValue(@jakarta.annotation.Nonnull List value) { + this.value = value; + } + + + /** + * Return true if this Strings object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + StringsDto strings = (StringsDto) o; + return Objects.equals(this.type, strings.type) && + Objects.equals(this.value, strings.value); + } + + @Override + public int hashCode() { + return Objects.hash(type, value); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class StringsDto {\n"); + sb.append(" type: ").append(toIndentedString(type)).append("\n"); + sb.append(" value: ").append(toIndentedString(value)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `type` to the URL query string + if (getType() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%stype%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getType())))); + } + + // add `value` to the URL query string + if (getValue() != null) { + for (int i = 0; i < getValue().size(); i++) { + joiner.add(String.format(java.util.Locale.ROOT, "%svalue%s%s=%s", prefix, suffix, + "".equals(suffix) ? "" : String.format(java.util.Locale.ROOT, "%s%d%s", containerPrefix, i, containerSuffix), + ApiClient.urlEncode(ApiClient.valueToString(getValue().get(i))))); + } + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/regexsolver/api/generated/model/TermDto.java b/src/main/java/com/regexsolver/api/generated/model/TermDto.java new file mode 100644 index 0000000..3f8b5fb --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/model/TermDto.java @@ -0,0 +1,307 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.regexsolver.api.generated.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.regexsolver.api.generated.model.TermFairDto; +import com.regexsolver.api.generated.model.TermFairMetadataDto; +import com.regexsolver.api.generated.model.TermRegexDto; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +import com.fasterxml.jackson.core.type.TypeReference; + +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.MapperFeature; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; +import com.regexsolver.api.generated.ApiClient; +import com.regexsolver.api.generated.JSON; + +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +@JsonDeserialize(using = TermDto.TermDtoDeserializer.class) +@JsonSerialize(using = TermDto.TermDtoSerializer.class) +public class TermDto extends AbstractOpenApiSchema { + private static final Logger log = Logger.getLogger(TermDto.class.getName()); + + public static class TermDtoSerializer extends StdSerializer { + public TermDtoSerializer(Class t) { + super(t); + } + + public TermDtoSerializer() { + this(null); + } + + @Override + public void serialize(TermDto value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { + jgen.writeObject(value.getActualInstance()); + } + } + + public static class TermDtoDeserializer extends StdDeserializer { + public TermDtoDeserializer() { + this(TermDto.class); + } + + public TermDtoDeserializer(Class vc) { + super(vc); + } + + @Override + public TermDto deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { + JsonNode tree = ctxt.readTree(jp); + Object deserialized = null; + boolean typeCoercion = ctxt.isEnabled(MapperFeature.ALLOW_COERCION_OF_SCALARS); + int match = 0; + JsonToken token = tree.traverse(jp.getCodec()).nextToken(); + // deserialize TermFairDto + try { + boolean attemptParsing = true; + // ensure that we respect type coercion as set on the client ObjectMapper + if (TermFairDto.class.equals(Integer.class) || TermFairDto.class.equals(Long.class) || TermFairDto.class.equals(Float.class) || TermFairDto.class.equals(Double.class) || TermFairDto.class.equals(Boolean.class) || TermFairDto.class.equals(String.class)) { + attemptParsing = typeCoercion; + if (!attemptParsing) { + attemptParsing |= ((TermFairDto.class.equals(Integer.class) || TermFairDto.class.equals(Long.class)) && token == JsonToken.VALUE_NUMBER_INT); + attemptParsing |= ((TermFairDto.class.equals(Float.class) || TermFairDto.class.equals(Double.class)) && token == JsonToken.VALUE_NUMBER_FLOAT); + attemptParsing |= (TermFairDto.class.equals(Boolean.class) && (token == JsonToken.VALUE_FALSE || token == JsonToken.VALUE_TRUE)); + attemptParsing |= (TermFairDto.class.equals(String.class) && token == JsonToken.VALUE_STRING); + } + } + if (attemptParsing) { + deserialized = tree.traverse(jp.getCodec()).readValueAs(TermFairDto.class); + // TODO: there is no validation against JSON schema constraints + // (min, max, enum, pattern...), this does not perform a strict JSON + // validation, which means the 'match' count may be higher than it should be. + match++; + log.log(Level.FINER, "Input data matches schema 'TermFairDto'"); + } + } catch (Exception e) { + // deserialization failed, continue + log.log(Level.FINER, "Input data does not match schema 'TermFairDto'", e); + } + + // deserialize TermRegexDto + try { + boolean attemptParsing = true; + // ensure that we respect type coercion as set on the client ObjectMapper + if (TermRegexDto.class.equals(Integer.class) || TermRegexDto.class.equals(Long.class) || TermRegexDto.class.equals(Float.class) || TermRegexDto.class.equals(Double.class) || TermRegexDto.class.equals(Boolean.class) || TermRegexDto.class.equals(String.class)) { + attemptParsing = typeCoercion; + if (!attemptParsing) { + attemptParsing |= ((TermRegexDto.class.equals(Integer.class) || TermRegexDto.class.equals(Long.class)) && token == JsonToken.VALUE_NUMBER_INT); + attemptParsing |= ((TermRegexDto.class.equals(Float.class) || TermRegexDto.class.equals(Double.class)) && token == JsonToken.VALUE_NUMBER_FLOAT); + attemptParsing |= (TermRegexDto.class.equals(Boolean.class) && (token == JsonToken.VALUE_FALSE || token == JsonToken.VALUE_TRUE)); + attemptParsing |= (TermRegexDto.class.equals(String.class) && token == JsonToken.VALUE_STRING); + } + } + if (attemptParsing) { + deserialized = tree.traverse(jp.getCodec()).readValueAs(TermRegexDto.class); + // TODO: there is no validation against JSON schema constraints + // (min, max, enum, pattern...), this does not perform a strict JSON + // validation, which means the 'match' count may be higher than it should be. + match++; + log.log(Level.FINER, "Input data matches schema 'TermRegexDto'"); + } + } catch (Exception e) { + // deserialization failed, continue + log.log(Level.FINER, "Input data does not match schema 'TermRegexDto'", e); + } + + if (match == 1) { + TermDto ret = new TermDto(); + ret.setActualInstance(deserialized); + return ret; + } + throw new IOException(String.format(java.util.Locale.ROOT, "Failed deserialization for TermDto: %d classes match result, expected 1", match)); + } + + /** + * Handle deserialization of the 'null' value. + */ + @Override + public TermDto getNullValue(DeserializationContext ctxt) throws JsonMappingException { + throw new JsonMappingException(ctxt.getParser(), "TermDto cannot be null"); + } + } + + // store a list of schema names defined in oneOf + public static final Map> schemas = new HashMap<>(); + + public TermDto() { + super("oneOf", Boolean.FALSE); + } + + public TermDto(TermFairDto o) { + super("oneOf", Boolean.FALSE); + setActualInstance(o); + } + + public TermDto(TermRegexDto o) { + super("oneOf", Boolean.FALSE); + setActualInstance(o); + } + + static { + schemas.put("TermFairDto", TermFairDto.class); + schemas.put("TermRegexDto", TermRegexDto.class); + JSON.registerDescendants(TermDto.class, Collections.unmodifiableMap(schemas)); + // Initialize and register the discriminator mappings. + Map> mappings = new HashMap>(); + mappings.put("fair", TermFairDto.class); + mappings.put("regex", TermRegexDto.class); + mappings.put("Term", TermDto.class); + JSON.registerDiscriminator(TermDto.class, "type", mappings); + } + + @Override + public Map> getSchemas() { + return TermDto.schemas; + } + + /** + * Set the instance that matches the oneOf child schema, check + * the instance parameter is valid against the oneOf child schemas: + * TermFairDto, TermRegexDto + * + * It could be an instance of the 'oneOf' schemas. + * The oneOf child schemas may themselves be a composed schema (allOf, anyOf, oneOf). + */ + @Override + public void setActualInstance(Object instance) { + if (JSON.isInstanceOf(TermFairDto.class, instance, new HashSet>())) { + super.setActualInstance(instance); + return; + } + + if (JSON.isInstanceOf(TermRegexDto.class, instance, new HashSet>())) { + super.setActualInstance(instance); + return; + } + + throw new RuntimeException("Invalid instance type. Must be TermFairDto, TermRegexDto"); + } + + /** + * Get the actual instance, which can be the following: + * TermFairDto, TermRegexDto + * + * @return The actual instance (TermFairDto, TermRegexDto) + */ + @Override + public Object getActualInstance() { + return super.getActualInstance(); + } + + /** + * Get the actual instance of `TermFairDto`. If the actual instance is not `TermFairDto`, + * the ClassCastException will be thrown. + * + * @return The actual instance of `TermFairDto` + * @throws ClassCastException if the instance is not `TermFairDto` + */ + public TermFairDto getTermFairDto() throws ClassCastException { + return (TermFairDto)super.getActualInstance(); + } + + /** + * Get the actual instance of `TermRegexDto`. If the actual instance is not `TermRegexDto`, + * the ClassCastException will be thrown. + * + * @return The actual instance of `TermRegexDto` + * @throws ClassCastException if the instance is not `TermRegexDto` + */ + public TermRegexDto getTermRegexDto() throws ClassCastException { + return (TermRegexDto)super.getActualInstance(); + } + + + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + if (getActualInstance() instanceof TermRegexDto) { + if (getActualInstance() != null) { + joiner.add(((TermRegexDto)getActualInstance()).toUrlQueryString(prefix + "one_of_0" + suffix)); + } + return joiner.toString(); + } + if (getActualInstance() instanceof TermFairDto) { + if (getActualInstance() != null) { + joiner.add(((TermFairDto)getActualInstance()).toUrlQueryString(prefix + "one_of_1" + suffix)); + } + return joiner.toString(); + } + return null; + } + +} + diff --git a/src/main/java/com/regexsolver/api/generated/model/TermFairDto.java b/src/main/java/com/regexsolver/api/generated/model/TermFairDto.java new file mode 100644 index 0000000..679975d --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/model/TermFairDto.java @@ -0,0 +1,252 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.regexsolver.api.generated.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.regexsolver.api.generated.model.TermFairMetadataDto; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.regexsolver.api.generated.ApiClient; +/** + * Term encoded as FAIR (Fast Automaton Internal Representation), a stable, signed format used internally by the engine. + */ +@JsonPropertyOrder({ + TermFairDto.JSON_PROPERTY_TYPE, + TermFairDto.JSON_PROPERTY_VALUE, + TermFairDto.JSON_PROPERTY_METADATA +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class TermFairDto { + /** + * Gets or Sets type + */ + public enum TypeEnum { + FAIR(String.valueOf("fair")); + + private String value; + + TypeEnum(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static TypeEnum fromValue(String value) { + for (TypeEnum b : TypeEnum.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } + } + + public static final String JSON_PROPERTY_TYPE = "type"; + @jakarta.annotation.Nonnull + private TypeEnum type; + + public static final String JSON_PROPERTY_VALUE = "value"; + @jakarta.annotation.Nonnull + private String value; + + public static final String JSON_PROPERTY_METADATA = "metadata"; + @jakarta.annotation.Nullable + private TermFairMetadataDto metadata; + + public TermFairDto() { + } + + @JsonCreator + public TermFairDto( + @JsonProperty(JSON_PROPERTY_METADATA) TermFairMetadataDto metadata + ) { + this(); + this.metadata = metadata; + } + + public TermFairDto type(@jakarta.annotation.Nonnull TypeEnum type) { + this.type = type; + return this; + } + + /** + * Get type + * @return type + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_TYPE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public TypeEnum getType() { + return type; + } + + + @JsonProperty(value = JSON_PROPERTY_TYPE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setType(@jakarta.annotation.Nonnull TypeEnum type) { + this.type = type; + } + + + public TermFairDto value(@jakarta.annotation.Nonnull String value) { + this.value = value; + return this; + } + + /** + * FAIR payload. + * @return value + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_VALUE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getValue() { + return value; + } + + + @JsonProperty(value = JSON_PROPERTY_VALUE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setValue(@jakarta.annotation.Nonnull String value) { + this.value = value; + } + + + /** + * Get metadata + * @return metadata + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_METADATA, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public TermFairMetadataDto getMetadata() { + return metadata; + } + + + + + /** + * Return true if this TermFair object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + TermFairDto termFair = (TermFairDto) o; + return Objects.equals(this.type, termFair.type) && + Objects.equals(this.value, termFair.value) && + Objects.equals(this.metadata, termFair.metadata); + } + + @Override + public int hashCode() { + return Objects.hash(type, value, metadata); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class TermFairDto {\n"); + sb.append(" type: ").append(toIndentedString(type)).append("\n"); + sb.append(" value: ").append(toIndentedString(value)).append("\n"); + sb.append(" metadata: ").append(toIndentedString(metadata)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `type` to the URL query string + if (getType() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%stype%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getType())))); + } + + // add `value` to the URL query string + if (getValue() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%svalue%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getValue())))); + } + + // add `metadata` to the URL query string + if (getMetadata() != null) { + joiner.add(getMetadata().toUrlQueryString(prefix + "metadata" + suffix)); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/regexsolver/api/generated/model/TermFairMetadataDto.java b/src/main/java/com/regexsolver/api/generated/model/TermFairMetadataDto.java new file mode 100644 index 0000000..a372879 --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/model/TermFairMetadataDto.java @@ -0,0 +1,148 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.regexsolver.api.generated.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.regexsolver.api.generated.ApiClient; +/** + * Metadata describing properties of a FAIR automaton. + */ +@JsonPropertyOrder({ + TermFairMetadataDto.JSON_PROPERTY_DETERMINISTIC +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class TermFairMetadataDto { + public static final String JSON_PROPERTY_DETERMINISTIC = "deterministic"; + @jakarta.annotation.Nullable + private Boolean deterministic; + + public TermFairMetadataDto() { + } + + public TermFairMetadataDto deterministic(@jakarta.annotation.Nullable Boolean deterministic) { + this.deterministic = deterministic; + return this; + } + + /** + * Whether this FAIR encodes a deterministic automaton. Only a deterministic FAIR guarantees consistent string ordering across paginated /generate/strings requests; call /compute/determinize first if this is false. + * @return deterministic + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_DETERMINISTIC, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public Boolean getDeterministic() { + return deterministic; + } + + + @JsonProperty(value = JSON_PROPERTY_DETERMINISTIC, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setDeterministic(@jakarta.annotation.Nullable Boolean deterministic) { + this.deterministic = deterministic; + } + + + /** + * Return true if this TermFairMetadata object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + TermFairMetadataDto termFairMetadata = (TermFairMetadataDto) o; + return Objects.equals(this.deterministic, termFairMetadata.deterministic); + } + + @Override + public int hashCode() { + return Objects.hash(deterministic); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class TermFairMetadataDto {\n"); + sb.append(" deterministic: ").append(toIndentedString(deterministic)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `deterministic` to the URL query string + if (getDeterministic() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sdeterministic%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getDeterministic())))); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/regexsolver/api/generated/model/TermRegexDto.java b/src/main/java/com/regexsolver/api/generated/model/TermRegexDto.java new file mode 100644 index 0000000..185aff4 --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/model/TermRegexDto.java @@ -0,0 +1,217 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.regexsolver.api.generated.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.regexsolver.api.generated.ApiClient; +/** + * Term encoded as a regular expression pattern. + */ +@JsonPropertyOrder({ + TermRegexDto.JSON_PROPERTY_TYPE, + TermRegexDto.JSON_PROPERTY_VALUE +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class TermRegexDto { + /** + * Gets or Sets type + */ + public enum TypeEnum { + REGEX(String.valueOf("regex")); + + private String value; + + TypeEnum(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static TypeEnum fromValue(String value) { + for (TypeEnum b : TypeEnum.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } + } + + public static final String JSON_PROPERTY_TYPE = "type"; + @jakarta.annotation.Nonnull + private TypeEnum type; + + public static final String JSON_PROPERTY_VALUE = "value"; + @jakarta.annotation.Nonnull + private String value; + + public TermRegexDto() { + } + + public TermRegexDto type(@jakarta.annotation.Nonnull TypeEnum type) { + this.type = type; + return this; + } + + /** + * Get type + * @return type + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_TYPE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public TypeEnum getType() { + return type; + } + + + @JsonProperty(value = JSON_PROPERTY_TYPE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setType(@jakarta.annotation.Nonnull TypeEnum type) { + this.type = type; + } + + + public TermRegexDto value(@jakarta.annotation.Nonnull String value) { + this.value = value; + return this; + } + + /** + * Regular expression pattern. + * @return value + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_VALUE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getValue() { + return value; + } + + + @JsonProperty(value = JSON_PROPERTY_VALUE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setValue(@jakarta.annotation.Nonnull String value) { + this.value = value; + } + + + /** + * Return true if this TermRegex object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + TermRegexDto termRegex = (TermRegexDto) o; + return Objects.equals(this.type, termRegex.type) && + Objects.equals(this.value, termRegex.value); + } + + @Override + public int hashCode() { + return Objects.hash(type, value); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class TermRegexDto {\n"); + sb.append(" type: ").append(toIndentedString(type)).append("\n"); + sb.append(" value: ").append(toIndentedString(value)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `type` to the URL query string + if (getType() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%stype%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getType())))); + } + + // add `value` to the URL query string + if (getValue() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%svalue%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getValue())))); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/regexsolver/api/generated/model/TermRequestDto.java b/src/main/java/com/regexsolver/api/generated/model/TermRequestDto.java new file mode 100644 index 0000000..227ce92 --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/model/TermRequestDto.java @@ -0,0 +1,186 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.regexsolver.api.generated.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.regexsolver.api.generated.model.RequestOptionsDto; +import com.regexsolver.api.generated.model.TermDto; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.regexsolver.api.generated.ApiClient; +/** + * Request carrying a single term. + */ +@JsonPropertyOrder({ + TermRequestDto.JSON_PROPERTY_TERM, + TermRequestDto.JSON_PROPERTY_OPTIONS +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class TermRequestDto { + public static final String JSON_PROPERTY_TERM = "term"; + @jakarta.annotation.Nonnull + private TermDto term; + + public static final String JSON_PROPERTY_OPTIONS = "options"; + @jakarta.annotation.Nullable + private RequestOptionsDto options; + + public TermRequestDto() { + } + + public TermRequestDto term(@jakarta.annotation.Nonnull TermDto term) { + this.term = term; + return this; + } + + /** + * Get term + * @return term + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_TERM, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public TermDto getTerm() { + return term; + } + + + @JsonProperty(value = JSON_PROPERTY_TERM, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setTerm(@jakarta.annotation.Nonnull TermDto term) { + this.term = term; + } + + + public TermRequestDto options(@jakarta.annotation.Nullable RequestOptionsDto options) { + this.options = options; + return this; + } + + /** + * Get options + * @return options + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_OPTIONS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public RequestOptionsDto getOptions() { + return options; + } + + + @JsonProperty(value = JSON_PROPERTY_OPTIONS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setOptions(@jakarta.annotation.Nullable RequestOptionsDto options) { + this.options = options; + } + + + /** + * Return true if this TermRequest object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + TermRequestDto termRequest = (TermRequestDto) o; + return Objects.equals(this.term, termRequest.term) && + Objects.equals(this.options, termRequest.options); + } + + @Override + public int hashCode() { + return Objects.hash(term, options); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class TermRequestDto {\n"); + sb.append(" term: ").append(toIndentedString(term)).append("\n"); + sb.append(" options: ").append(toIndentedString(options)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `term` to the URL query string + if (getTerm() != null) { + joiner.add(getTerm().toUrlQueryString(prefix + "term" + suffix)); + } + + // add `options` to the URL query string + if (getOptions() != null) { + joiner.add(getOptions().toUrlQueryString(prefix + "options" + suffix)); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/regexsolver/api/generated/model/TwoTermsRequestDto.java b/src/main/java/com/regexsolver/api/generated/model/TwoTermsRequestDto.java new file mode 100644 index 0000000..cd31384 --- /dev/null +++ b/src/main/java/com/regexsolver/api/generated/model/TwoTermsRequestDto.java @@ -0,0 +1,201 @@ +/* + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.regexsolver.api.generated.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.regexsolver.api.generated.model.RequestOptionsDto; +import com.regexsolver.api.generated.model.TermDto; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.regexsolver.api.generated.ApiClient; +/** + * Request carrying exactly 2 terms. + */ +@JsonPropertyOrder({ + TwoTermsRequestDto.JSON_PROPERTY_TERMS, + TwoTermsRequestDto.JSON_PROPERTY_OPTIONS +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-08-04T20:54:20.558114023+02:00[Europe/Zurich]", comments = "Generator version: 7.21.0") +public class TwoTermsRequestDto { + public static final String JSON_PROPERTY_TERMS = "terms"; + @jakarta.annotation.Nonnull + private List terms = new ArrayList<>(); + + public static final String JSON_PROPERTY_OPTIONS = "options"; + @jakarta.annotation.Nullable + private RequestOptionsDto options; + + public TwoTermsRequestDto() { + } + + public TwoTermsRequestDto terms(@jakarta.annotation.Nonnull List terms) { + this.terms = terms; + return this; + } + + public TwoTermsRequestDto addTermsItem(TermDto termsItem) { + if (this.terms == null) { + this.terms = new ArrayList<>(); + } + this.terms.add(termsItem); + return this; + } + + /** + * Exactly 2 terms. + * @return terms + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_TERMS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public List getTerms() { + return terms; + } + + + @JsonProperty(value = JSON_PROPERTY_TERMS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setTerms(@jakarta.annotation.Nonnull List terms) { + this.terms = terms; + } + + + public TwoTermsRequestDto options(@jakarta.annotation.Nullable RequestOptionsDto options) { + this.options = options; + return this; + } + + /** + * Get options + * @return options + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_OPTIONS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public RequestOptionsDto getOptions() { + return options; + } + + + @JsonProperty(value = JSON_PROPERTY_OPTIONS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setOptions(@jakarta.annotation.Nullable RequestOptionsDto options) { + this.options = options; + } + + + /** + * Return true if this TwoTermsRequest object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + TwoTermsRequestDto twoTermsRequest = (TwoTermsRequestDto) o; + return Objects.equals(this.terms, twoTermsRequest.terms) && + Objects.equals(this.options, twoTermsRequest.options); + } + + @Override + public int hashCode() { + return Objects.hash(terms, options); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class TwoTermsRequestDto {\n"); + sb.append(" terms: ").append(toIndentedString(terms)).append("\n"); + sb.append(" options: ").append(toIndentedString(options)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `terms` to the URL query string + if (getTerms() != null) { + for (int i = 0; i < getTerms().size(); i++) { + if (getTerms().get(i) != null) { + joiner.add(getTerms().get(i).toUrlQueryString(String.format(java.util.Locale.ROOT, "%sterms%s%s", prefix, suffix, + "".equals(suffix) ? "" : String.format(java.util.Locale.ROOT, "%s%d%s", containerPrefix, i, containerSuffix)))); + } + } + } + + // add `options` to the URL query string + if (getOptions() != null) { + joiner.add(getOptions().toUrlQueryString(prefix + "options" + suffix)); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/regexsolver/api/package-info.java b/src/main/java/com/regexsolver/api/package-info.java index 1870e39..30a5a14 100644 --- a/src/main/java/com/regexsolver/api/package-info.java +++ b/src/main/java/com/regexsolver/api/package-info.java @@ -1,11 +1,4 @@ /** - * Contains all the classes you need to start using the library. - *

- * To start using this library you need to first request an API token at RegexSolver Console, - * then call RegexSolverApiWrapper.initialize("YOUR_TOKEN") to set it. - *

- *

- * You can find some examples in our documentation. - *

+ * Main package for the RegexSolver Java client API. */ -package com.regexsolver.api; \ No newline at end of file +package com.regexsolver.api; diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java new file mode 100644 index 0000000..2def0e9 --- /dev/null +++ b/src/main/java/module-info.java @@ -0,0 +1,19 @@ +module com.regexsolver.api { + exports com.regexsolver.api; + exports com.regexsolver.api.exceptions; + + // Jackson reflects over the generated DTOs to (de)serialize request and + // response bodies; without this the package stays closed on the module path. + opens com.regexsolver.api.generated.model to + com.fasterxml.jackson.databind; + + requires java.net.http; + requires java.logging; + requires com.fasterxml.jackson.annotation; + requires com.fasterxml.jackson.core; + requires com.fasterxml.jackson.databind; + requires com.fasterxml.jackson.datatype.jsr310; + requires org.openapitools.jackson.nullable; + + requires static jakarta.annotation; +} diff --git a/src/test/java/com/regexsolver/api/AsyncRegexSolverClientTest.java b/src/test/java/com/regexsolver/api/AsyncRegexSolverClientTest.java new file mode 100644 index 0000000..7167723 --- /dev/null +++ b/src/test/java/com/regexsolver/api/AsyncRegexSolverClientTest.java @@ -0,0 +1,909 @@ +package com.regexsolver.api; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; + +import com.regexsolver.api.exceptions.*; +import com.regexsolver.api.generated.ApiException; +import com.regexsolver.api.generated.api.AccountApi; +import com.regexsolver.api.generated.api.AnalyzeApi; +import com.regexsolver.api.generated.api.ComputeApi; +import com.regexsolver.api.generated.api.GenerateApi; +import com.regexsolver.api.generated.model.*; +import java.lang.reflect.Field; +import java.net.http.HttpHeaders; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class AsyncRegexSolverClientTest { + + @Mock + private AccountApi accountApi; + + @Mock + private AnalyzeApi analyzeApi; + + @Mock + private ComputeApi computeApi; + + @Mock + private GenerateApi generateApi; + + private AsyncRegexSolverClient client; + + @BeforeEach + void setUp() throws Exception { + // Build the real client + client = AsyncRegexSolverClient.builder() + .apiToken("test-token") + .build(); + + // Use reflection to inject the mocks into the final class fields + injectMocks(client); + } + + private void injectMocks(AsyncRegexSolverClient target) throws Exception { + injectMock(target, "accountApi", accountApi); + injectMock(target, "analyzeApi", analyzeApi); + injectMock(target, "computeApi", computeApi); + injectMock(target, "generateApi", generateApi); + } + + private void injectMock(Object target, String fieldName, Object mock) + throws Exception { + Field field = target.getClass().getDeclaredField(fieldName); + field.setAccessible(true); + field.set(target, mock); + } + + @Test + void testGetCardinalityInteger() { + Term term = Term.regex("abc"); + + Cardinality200ResponseDto responseDto = new Cardinality200ResponseDto(); + CardinalityDto data = new CardinalityDto( + new CardinalityIntegerDto().value(42L) + ); + responseDto.setData(data); + + when(analyzeApi.cardinality(any())).thenReturn( + CompletableFuture.completedFuture(responseDto) + ); + + Cardinality result = client.getCardinality(term).join(); + + assertThat(result).isInstanceOf(Cardinality.Integer.class); + assertThat(((Cardinality.Integer) result).getValue()).isEqualTo(42L); + assertThat(term.getCachedCardinality()).isEqualTo(result); + } + + @Test + void testGetCardinalityInfinite() { + Term term = Term.regex(".*"); + + Cardinality200ResponseDto responseDto = new Cardinality200ResponseDto(); + CardinalityDto data = new CardinalityDto(new CardinalityInfiniteDto()); + responseDto.setData(data); + + when(analyzeApi.cardinality(any())).thenReturn( + CompletableFuture.completedFuture(responseDto) + ); + + Cardinality result = client.getCardinality(term).join(); + + assertThat(result).isInstanceOf(Cardinality.Infinite.class); + } + + @Test + void testGetLength() { + Term term = Term.regex("abc"); + + Length200ResponseDto responseDto = new Length200ResponseDto(); + LengthDto data = new LengthDto(); + data.setMin(3); + data.setMax(3); + responseDto.setData(data); + + when(analyzeApi.length(any())).thenReturn( + CompletableFuture.completedFuture(responseDto) + ); + + Length result = client.getLength(term).join(); + + assertThat(result.getMin()).contains(3); + assertThat(result.getMax()).contains(3); + } + + @Test + void testIsEmpty() { + Term term = Term.regex("[]"); + + Empty200ResponseDto responseDto = new Empty200ResponseDto(); + BooleanDto data = new BooleanDto(); + data.setValue(true); + responseDto.setData(data); + + when(analyzeApi.empty(any())).thenReturn( + CompletableFuture.completedFuture(responseDto) + ); + + Boolean result = client.isEmpty(term).join(); + + assertThat(result).isTrue(); + assertThat(term.getCachedEmpty()).isTrue(); + } + + @Test + void testComputeUnion() { + Term term1 = Term.regex("a"); + Term term2 = Term.regex("b"); + + Concat200ResponseDto responseDto = new Concat200ResponseDto(); + TermDto data = new TermDto(new TermRegexDto().value("a|b")); + responseDto.setData(data); + + when(computeApi.union(any())).thenReturn( + CompletableFuture.completedFuture(responseDto) + ); + + Term result = client.union(List.of(term1, term2)).join(); + + assertThat(result).isNotNull(); + assertThat(result.getPattern()).contains("a|b"); + } + + @Test + void testErrorHandling400_BadRequest() { + Term term = Term.regex("invalid["); + + String body = "{\"error\": \"Invalid regex\"}"; + ApiException apiException = new ApiException( + 400, + "Bad Request", + null, + body + ); + + when(analyzeApi.empty(any())).thenReturn( + CompletableFuture.failedFuture(apiException) + ); + + assertThatThrownBy(() -> client.isEmpty(term).join()) + .hasCauseInstanceOf(BadRequestException.class) + .hasMessageContaining("Invalid regex"); + } + + @Test + void testErrorHandling_InvalidJson() { + String body = + "{\"success\": false, \"error\": \"Invalid JSON\", \"errorCode\": \"InvalidJson\"}"; + ApiException apiException = new ApiException( + 400, + "Bad Request", + null, + body + ); + + when(analyzeApi.empty(any())).thenReturn( + CompletableFuture.failedFuture(apiException) + ); + + assertThatThrownBy(() -> + client.isEmpty(Term.regex("abc")).join() + ).hasCauseInstanceOf(InvalidJsonException.class); + } + + @Test + void testErrorHandling_TooManyTerms() { + String body = + "{\"success\": false, \"error\": \"Too many terms\", \"errorCode\": \"TooManyTerms\"}"; + ApiException apiException = new ApiException( + 400, + "Bad Request", + null, + body + ); + + when(computeApi.union(any())).thenReturn( + CompletableFuture.failedFuture(apiException) + ); + + assertThatThrownBy(() -> + client.union(List.of(Term.regex("a"), Term.regex("b"))).join() + ).hasCauseInstanceOf(TooManyTermsException.class); + } + + @Test + void testErrorHandling_TimeoutTooLarge() { + String body = + "{\"success\": false, \"error\": \"Timeout too large\", \"errorCode\": \"TimeoutTooLarge\"}"; + ApiException apiException = new ApiException( + 400, + "Bad Request", + null, + body + ); + + when(analyzeApi.empty(any())).thenReturn( + CompletableFuture.failedFuture(apiException) + ); + + assertThatThrownBy(() -> + client.isEmpty(Term.regex("abc")).join() + ).hasCauseInstanceOf(TimeoutTooLargeException.class); + } + + @Test + void testErrorHandling_MissingOrMalformedToken() { + String body = + "{\"success\": false, \"error\": \"Missing token\", \"errorCode\": \"MissingOrMalformedToken\"}"; + ApiException apiException = new ApiException( + 401, + "Unauthorized", + null, + body + ); + + when(analyzeApi.empty(any())).thenReturn( + CompletableFuture.failedFuture(apiException) + ); + + assertThatThrownBy(() -> + client.isEmpty(Term.regex("abc")).join() + ).hasCauseInstanceOf(MissingOrMalformedTokenException.class); + } + + @Test + void testErrorHandling_QuotaExceeded() { + String body = + "{\"success\": false, \"error\": \"Quota exceeded\", \"errorCode\": \"QuotaExceeded\"}"; + ApiException apiException = new ApiException( + 403, + "Forbidden", + null, + body + ); + + when(analyzeApi.empty(any())).thenReturn( + CompletableFuture.failedFuture(apiException) + ); + + assertThatThrownBy(() -> + client.isEmpty(Term.regex("abc")).join() + ).hasCauseInstanceOf(QuotaExceededException.class); + } + + @Test + void testErrorHandling_500() { + ApiException apiException = new ApiException( + 500, + "Internal Server Error", + null, + null + ); + + when(analyzeApi.empty(any())).thenReturn( + CompletableFuture.failedFuture(apiException) + ); + + assertThatThrownBy(() -> + client.isEmpty(Term.regex("abc")).join() + ).hasCauseInstanceOf(InternalServerException.class); + } + + @Test + void testErrorHandling_OtherApiError() { + ApiException apiException = new ApiException( + 418, + "I'm a teapot", + null, + null + ); + + when(analyzeApi.empty(any())).thenReturn( + CompletableFuture.failedFuture(apiException) + ); + + assertThatThrownBy(() -> client.isEmpty(Term.regex("abc")).join()) + .hasCauseInstanceOf( + com.regexsolver.api.exceptions.ApiException.class + ) + .satisfies(e -> + assertThat( + ( + (com.regexsolver.api.exceptions.ApiException) e.getCause() + ).getStatusCode() + ).isEqualTo(418) + ); + } + + @Test + void testRetryOn429() { + Term term = Term.regex("abc"); + + HttpHeaders mockHeaders = mock(HttpHeaders.class); + when(mockHeaders.firstValue("Retry-After")).thenReturn( + Optional.of("0.1") + ); + ApiException error429 = new ApiException( + 429, + "Too Many Requests", + mockHeaders, + null + ); + + Empty200ResponseDto successResponse = new Empty200ResponseDto(); + BooleanDto data = new BooleanDto(); + data.setValue(true); + successResponse.setData(data); + + // First call fails with 429, second call succeeds + when(analyzeApi.empty(any())) + .thenReturn(CompletableFuture.failedFuture(error429)) + .thenReturn(CompletableFuture.completedFuture(successResponse)); + + Boolean result = client.isEmpty(term).join(); + + assertThat(result).isTrue(); + // Verify it was called exactly twice + verify(analyzeApi, times(2)).empty(any()); + } + + @Test + void testEquivalent() { + Term term1 = Term.regex("a"); + Term term2 = Term.regex("a"); + Empty200ResponseDto responseDto = new Empty200ResponseDto(); + BooleanDto data = new BooleanDto(); + data.setValue(true); + responseDto.setData(data); + + when(analyzeApi.equivalent(any())).thenReturn( + CompletableFuture.completedFuture(responseDto) + ); + + assertThat(client.equivalent(term1, term2).join()).isTrue(); + } + + @Test + void testSubset() { + Term term1 = Term.regex("a"); + Term term2 = Term.regex("a|b"); + Empty200ResponseDto responseDto = new Empty200ResponseDto(); + BooleanDto data = new BooleanDto(); + data.setValue(true); + responseDto.setData(data); + + when(analyzeApi.subset(any())).thenReturn( + CompletableFuture.completedFuture(responseDto) + ); + + assertThat(client.subset(term1, term2).join()).isTrue(); + } + + @Test + void testIsEmptyString() { + Term term = Term.regex(""); + Empty200ResponseDto responseDto = new Empty200ResponseDto(); + BooleanDto data = new BooleanDto(); + data.setValue(true); + responseDto.setData(data); + + when(analyzeApi.emptyString(any())).thenReturn( + CompletableFuture.completedFuture(responseDto) + ); + + assertThat(client.isEmptyString(term).join()).isTrue(); + } + + @Test + void testIsTotal() { + Term term = Term.regex(".*"); + Empty200ResponseDto responseDto = new Empty200ResponseDto(); + BooleanDto data = new BooleanDto(); + data.setValue(true); + responseDto.setData(data); + + when(analyzeApi.total(any())).thenReturn( + CompletableFuture.completedFuture(responseDto) + ); + + assertThat(client.isTotal(term).join()).isTrue(); + } + + @Test + void testIsDeterministic() { + Term term = Term.fair("payload"); + Empty200ResponseDto responseDto = new Empty200ResponseDto(); + BooleanDto data = new BooleanDto(); + data.setValue(true); + responseDto.setData(data); + + when(analyzeApi.deterministic(any())).thenReturn( + CompletableFuture.completedFuture(responseDto) + ); + + assertThat(client.isDeterministic(term).join()).isTrue(); + } + + @Test + void testIsDeterministicFalseForRegexTerm() { + Term term = Term.regex("a"); + + assertThat(client.isDeterministic(term).join()).isFalse(); + } + + @Test + void testGetPattern() { + Term term = Term.regex("a"); + Dot200ResponseDto responseDto = new Dot200ResponseDto(); + StringDto data = new StringDto(); + data.setValue("a"); + responseDto.setData(data); + + when(analyzeApi.pattern(any())).thenReturn( + CompletableFuture.completedFuture(responseDto) + ); + + assertThat(client.getPattern(term).join()).isEqualTo("a"); + } + + @Test + void testGetDot() { + Term term = Term.regex("a"); + Dot200ResponseDto responseDto = new Dot200ResponseDto(); + StringDto data = new StringDto(); + data.setValue("digraph {...}"); + responseDto.setData(data); + + when(analyzeApi.dot(any())).thenReturn( + CompletableFuture.completedFuture(responseDto) + ); + + assertThat(client.getDot(term).join()).isEqualTo("digraph {...}"); + } + + @Test + void testConcat() { + Term term1 = Term.regex("a"); + Term term2 = Term.regex("b"); + Concat200ResponseDto responseDto = new Concat200ResponseDto(); + TermDto data = new TermDto(new TermRegexDto().value("ab")); + responseDto.setData(data); + + when(computeApi.concat(any())).thenReturn( + CompletableFuture.completedFuture(responseDto) + ); + + Term result = client.concat(List.of(term1, term2)).join(); + assertThat(result.getPattern()).contains("ab"); + } + + @Test + void testIntersection() { + Term term1 = Term.regex("a."); + Term term2 = Term.regex(".b"); + Concat200ResponseDto responseDto = new Concat200ResponseDto(); + TermDto data = new TermDto(new TermRegexDto().value("ab")); + responseDto.setData(data); + + when(computeApi.intersection(any())).thenReturn( + CompletableFuture.completedFuture(responseDto) + ); + + Term result = client.intersection(List.of(term1, term2)).join(); + assertThat(result.getPattern()).contains("ab"); + } + + @Test + void testDifference() { + Term term1 = Term.regex("a|b"); + Term term2 = Term.regex("b"); + Concat200ResponseDto responseDto = new Concat200ResponseDto(); + TermDto data = new TermDto(new TermRegexDto().value("a")); + responseDto.setData(data); + + when(computeApi.difference(any())).thenReturn( + CompletableFuture.completedFuture(responseDto) + ); + + Term result = client.difference(term1, term2).join(); + assertThat(result.getPattern()).contains("a"); + } + + @Test + void testRepeat() { + Term term = Term.regex("a"); + Concat200ResponseDto responseDto = new Concat200ResponseDto(); + TermDto data = new TermDto(new TermRegexDto().value("a{2,3}")); + responseDto.setData(data); + + when(computeApi.repeat(any())).thenReturn( + CompletableFuture.completedFuture(responseDto) + ); + + Term result = client.repeat(term, 2, 3).join(); + assertThat(result.getPattern()).contains("a{2,3}"); + } + + @Test + void testDeterminize() { + Term term = Term.regex("a"); + Concat200ResponseDto responseDto = new Concat200ResponseDto(); + TermDto data = new TermDto(new TermFairDto().value("fair-payload")); + responseDto.setData(data); + + when(computeApi.determinize(any())).thenReturn( + CompletableFuture.completedFuture(responseDto) + ); + + Term result = client.determinize(term).join(); + assertThat(result.getFair()).contains("fair-payload"); + } + + @Test + void testComplement() { + Term term = Term.regex(".*a.*"); + Concat200ResponseDto responseDto = new Concat200ResponseDto(); + TermDto data = new TermDto(new TermRegexDto().value("[^a].*")); + responseDto.setData(data); + + when(computeApi.complement(any())).thenReturn( + CompletableFuture.completedFuture(responseDto) + ); + + Term result = client.complement(term).join(); + assertThat(result.getPattern()).contains("[^a].*"); + } + + @Test + void testGenerateStrings() { + Term term = Term.regex("a*"); + Strings200ResponseDto responseDto = new Strings200ResponseDto(); + StringsDto stringsDto = new StringsDto(); + stringsDto.setValue(List.of("", "a", "aa")); + GenerateStringsResponseDto generateStrings = + new GenerateStringsResponseDto(); + generateStrings.setStrings(stringsDto); + responseDto.setData(generateStrings); + + when(generateApi.strings(any())).thenReturn( + CompletableFuture.completedFuture(responseDto) + ); + + List result = client.generateStrings(term, 3, 0).join(); + assertThat(result).containsExactly("", "a", "aa"); + } + + @Test + void testGenerateStringsWithOptions() { + Term term = Term.regex("[a-z]{2}"); + Strings200ResponseDto responseDto = new Strings200ResponseDto(); + StringsDto stringsDto = new StringsDto(); + stringsDto.setValue(List.of("xy")); + GenerateStringsResponseDto generateStrings = + new GenerateStringsResponseDto(); + generateStrings.setStrings(stringsDto); + responseDto.setData(generateStrings); + + when(generateApi.strings(any())).thenReturn( + CompletableFuture.completedFuture(responseDto) + ); + + GenerateStringsOptions options = GenerateStringsOptions.builder() + .pathOrder(PathOrder.INTERLEAVE) + .characterOrder(CharacterOrder.SHUFFLED) + .seed(42L) + .minLength(1) + .maxLength(10) + .charset("[a-z]"); + List result = client + .generateStrings(term, 5, 0, options) + .join(); + assertThat(result).containsExactly("xy"); + + ArgumentCaptor captor = + ArgumentCaptor.forClass(GenerateStringsRequestDto.class); + verify(generateApi).strings(captor.capture()); + GenerateStringsRequestDto request = captor.getValue(); + assertThat(request.getPathOrder()).isEqualTo( + GenerateStringsPathOrderDto.INTERLEAVE + ); + assertThat(request.getCharacterOrder()).isEqualTo( + GenerateStringsCharacterOrderDto.SHUFFLED + ); + assertThat(request.getSeed()).isEqualTo(42L); + assertThat(request.getMinLength()).isEqualTo(1); + assertThat(request.getMaxLength()).isEqualTo(10); + assertThat(request.getCharset()).isEqualTo("[a-z]"); + } + + @Test + void testGenerateStringsOmitsUnsetOptions() { + Term term = Term.regex("a"); + Strings200ResponseDto responseDto = new Strings200ResponseDto(); + StringsDto stringsDto = new StringsDto(); + stringsDto.setValue(List.of("a")); + GenerateStringsResponseDto generateStrings = + new GenerateStringsResponseDto(); + generateStrings.setStrings(stringsDto); + responseDto.setData(generateStrings); + + when(generateApi.strings(any())).thenReturn( + CompletableFuture.completedFuture(responseDto) + ); + + client.generateStrings(term, 1, 0).join(); + + ArgumentCaptor captor = + ArgumentCaptor.forClass(GenerateStringsRequestDto.class); + verify(generateApi).strings(captor.capture()); + GenerateStringsRequestDto request = captor.getValue(); + // Omitted options fall back to the spec defaults baked into the DTO. + assertThat(request.getPathOrder()).isNull(); + assertThat(request.getCharacterOrder()).isNull(); + assertThat(request.getSeed()).isEqualTo(0L); + assertThat(request.getMinLength()).isEqualTo(0); + assertThat(request.getMaxLength()).isEqualTo(100); + assertThat(request.getCharset()).isNull(); + } + + // --- ACCOUNT LIMITS & AUTO-BATCHING --- + + private static Concat200ResponseDto termResponse(String value) { + Concat200ResponseDto responseDto = new Concat200ResponseDto(); + responseDto.setData(new TermDto(new TermRegexDto().value(value))); + return responseDto; + } + + private static Limits200ResponseDto limitsResponse(long maxTerms) { + AccountLimitsDto limits = new AccountLimitsDto() + .type(AccountLimitsDto.TypeEnum.ACCOUNT_LIMITS) + .maxRequestsCount(1000L) + .maxRequestsRate(10L) + .maxTermsCount(maxTerms) + .maxTimeout(60000L) + .maxStatesCount(8192L); + return new Limits200ResponseDto().data(limits); + } + + private static ApiException tooManyTermsError(int provided, int allowed) { + return new ApiException( + 400, + "Bad Request", + null, + "{\"success\":false,\"error\":\"" + + provided + + " terms provided. Maximum allowed is " + + allowed + + ".\",\"errorCode\":\"TooManyTerms\"}" + ); + } + + private static List termValues(MultiTermsRequestDto request) { + return request + .getTerms() + .stream() + .map(t -> { + Object instance = t.getActualInstance(); + return instance instanceof TermRegexDto + ? ((TermRegexDto) instance).getValue() + : instance.toString(); + }) + .collect(java.util.stream.Collectors.toList()); + } + + @Test + void testGetAccountLimitsMemoized() { + when(accountApi.limits()).thenReturn( + CompletableFuture.completedFuture(limitsResponse(4L)) + ); + + AccountLimits limits = client.getAccountLimits().join(); + assertThat(limits.getMaxRequestsCount()).isEqualTo(1000L); + assertThat(limits.getMaxRequestsRate()).isEqualTo(10L); + assertThat(limits.getMaxTermsCount()).isEqualTo(4L); + assertThat(limits.getMaxTimeout()).isEqualTo(60000L); + assertThat(limits.getMaxStatesCount()).isEqualTo(8192L); + + client.getAccountLimits().join(); + verify(accountApi, times(1)).limits(); + } + + @Test + void testProactiveBatchingWithOverride() throws Exception { + AsyncRegexSolverClient batchClient = AsyncRegexSolverClient.builder() + .apiToken("batch-token") + .maxTermsPerRequest(3) + .build(); + injectMocks(batchClient); + + when(computeApi.concat(any())) + .thenReturn(CompletableFuture.completedFuture(termResponse("r0"))) + .thenReturn(CompletableFuture.completedFuture(termResponse("r1"))) + .thenReturn(CompletableFuture.completedFuture(termResponse("r2"))) + .thenReturn(CompletableFuture.completedFuture(termResponse("r3"))); + + List terms = new java.util.ArrayList<>(); + for (int i = 0; i < 8; i++) { + terms.add(Term.regex("t" + i)); + } + Term result = batchClient + .concat( + terms, + OperationOptions.builder().responseFormat(ResponseFormat.REGEX) + ) + .join(); + assertThat(result.getPattern()).contains("r3"); + + ArgumentCaptor captor = ArgumentCaptor.forClass( + MultiTermsRequestDto.class + ); + verify(computeApi, times(4)).concat(captor.capture()); + List requests = captor.getAllValues(); + // Left fold preserves concat order: contiguous chunks, accumulator first. + assertThat(termValues(requests.get(0))).containsExactly( + "t0", + "t1", + "t2" + ); + assertThat(termValues(requests.get(1))).containsExactly( + "r0", + "t3", + "t4" + ); + assertThat(termValues(requests.get(2))).containsExactly( + "r1", + "t5", + "t6" + ); + assertThat(termValues(requests.get(3))).containsExactly("r2", "t7"); + // Only the final request carries the caller's response options. + assertThat(requests.get(0).getOptions().getResponse()).isNull(); + assertThat(requests.get(1).getOptions().getResponse()).isNull(); + assertThat(requests.get(2).getOptions().getResponse()).isNull(); + assertThat(requests.get(3).getOptions().getResponse()).isNotNull(); + // The limit was known up front, so no limits fetch happened. + verify(accountApi, never()).limits(); + } + + @Test + void testReactiveBatchingFetchesLimits() { + when(accountApi.limits()).thenReturn( + CompletableFuture.completedFuture(limitsResponse(4L)) + ); + when(computeApi.union(any())) + .thenReturn(CompletableFuture.failedFuture(tooManyTermsError(9, 4))) + .thenReturn(CompletableFuture.completedFuture(termResponse("r0"))) + .thenReturn(CompletableFuture.completedFuture(termResponse("r1"))) + .thenReturn(CompletableFuture.completedFuture(termResponse("r2"))); + + List terms = new java.util.ArrayList<>(); + for (int i = 0; i < 9; i++) { + terms.add(Term.regex("t" + i)); + } + Term result = client.union(terms).join(); + assertThat(result.getPattern()).contains("r2"); + + ArgumentCaptor captor = ArgumentCaptor.forClass( + MultiTermsRequestDto.class + ); + verify(computeApi, times(4)).union(captor.capture()); + List requests = captor.getAllValues(); + assertThat(termValues(requests.get(1))).containsExactly( + "t0", + "t1", + "t2", + "t3" + ); + assertThat(termValues(requests.get(2))).containsExactly( + "r0", + "t4", + "t5", + "t6" + ); + assertThat(termValues(requests.get(3))).containsExactly( + "r1", + "t7", + "t8" + ); + verify(accountApi, times(1)).limits(); + } + + @Test + void testAutoBatchOptOut() throws Exception { + AsyncRegexSolverClient noBatchClient = AsyncRegexSolverClient.builder() + .apiToken("no-batch-token") + .autoBatch(false) + .build(); + injectMocks(noBatchClient); + + when(computeApi.union(any())).thenReturn( + CompletableFuture.failedFuture(tooManyTermsError(9, 4)) + ); + + List terms = new java.util.ArrayList<>(); + for (int i = 0; i < 9; i++) { + terms.add(Term.regex("t" + i)); + } + assertThatThrownBy(() -> noBatchClient.union(terms).join()) + .hasCauseInstanceOf(TooManyTermsException.class); + verify(accountApi, never()).limits(); + } + + @Test + void testLimitsFetchFailureRethrowsOriginal() { + when(accountApi.limits()).thenReturn( + CompletableFuture.failedFuture( + new ApiException(500, "Internal Server Error", null, null) + ) + ); + when(computeApi.union(any())).thenReturn( + CompletableFuture.failedFuture(tooManyTermsError(9, 4)) + ); + + List terms = new java.util.ArrayList<>(); + for (int i = 0; i < 9; i++) { + terms.add(Term.regex("t" + i)); + } + assertThatThrownBy(() -> client.union(terms).join()) + .hasCauseInstanceOf(TooManyTermsException.class); + verify(accountApi, times(1)).limits(); + } + + @Test + void testRetrySurvivesManyConsecutive429s() { + Term term = Term.regex("abc"); + + HttpHeaders mockHeaders = mock(HttpHeaders.class); + when(mockHeaders.firstValue("Retry-After")).thenReturn( + Optional.of("0.01") + ); + ApiException error429 = new ApiException( + 429, + "Too Many Requests", + mockHeaders, + null + ); + + Empty200ResponseDto successResponse = new Empty200ResponseDto(); + BooleanDto data = new BooleanDto(); + data.setValue(true); + successResponse.setData(data); + + // Six consecutive 429s exceed the old cap of five attempts. + when(analyzeApi.empty(any())) + .thenReturn(CompletableFuture.failedFuture(error429)) + .thenReturn(CompletableFuture.failedFuture(error429)) + .thenReturn(CompletableFuture.failedFuture(error429)) + .thenReturn(CompletableFuture.failedFuture(error429)) + .thenReturn(CompletableFuture.failedFuture(error429)) + .thenReturn(CompletableFuture.failedFuture(error429)) + .thenReturn(CompletableFuture.completedFuture(successResponse)); + + Boolean result = client.isEmpty(term).join(); + + assertThat(result).isTrue(); + verify(analyzeApi, times(7)).empty(any()); + } + + @Test + void testBuilderRejectsInvalidMaxTermsPerRequest() { + assertThatThrownBy(() -> + AsyncRegexSolverClient.builder() + .apiToken("test-token") + .maxTermsPerRequest(1) + .build() + ).isInstanceOf(IllegalArgumentException.class); + } +} diff --git a/src/test/java/com/regexsolver/api/ModelsTest.java b/src/test/java/com/regexsolver/api/ModelsTest.java new file mode 100644 index 0000000..5a12757 --- /dev/null +++ b/src/test/java/com/regexsolver/api/ModelsTest.java @@ -0,0 +1,220 @@ +package com.regexsolver.api; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import com.regexsolver.api.generated.model.*; +import java.util.Optional; +import org.junit.jupiter.api.Test; + +class ModelsTest { + + @Test + void testTermCreationRegex() { + Term term = Term.regex("abc"); + assertThat(term.serialize()).isEqualTo("regex=abc"); + assertThat(term.toDto()).isNotNull(); + } + + @Test + void testTermCreationFair() { + Term term = Term.fair("fair_payload"); + assertThat(term.serialize()).isEqualTo("fair=fair_payload"); + assertThat(term.toDto()).isNotNull(); + } + + @Test + void testTermFromDtoRegex() { + TermDto genTerm = new TermDto(new TermRegexDto().value("abc")); + Term term = Term.fromDto(genTerm); + assertThat(term.serialize()).isEqualTo("regex=abc"); + assertThat(term.toDto()).isNotNull(); + } + + @Test + void testTermFromDtoFair() { + TermDto genTerm = new TermDto(new TermFairDto().value("payload")); + Term term = Term.fromDto(genTerm); + assertThat(term.serialize()).isEqualTo("fair=payload"); + assertThat(term.toDto()).isNotNull(); + } + + @Test + void testCardinalityInteger() { + Cardinality.Integer c = new Cardinality.Integer(10L); + assertThat(c.getValue()).isEqualTo(10L); + assertThat(c.isEmpty()).contains(false); + assertThat(c.isEmptyString()).contains(false); + assertThat(c.isTotal()).contains(false); + assertThat(c.toString()).isEqualTo(""); + } + + @Test + void testCardinalityFromDtoInteger() { + CardinalityDto genCard = new CardinalityDto( + new CardinalityIntegerDto().value(10L) + ); + Cardinality c = Cardinality.fromDto(genCard); + assertThat(c).isInstanceOf(Cardinality.Integer.class); + assertThat(((Cardinality.Integer) c).getValue()).isEqualTo(10L); + } + + @Test + void testCardinalityFromDtoBigInteger() { + CardinalityDto genCard = new CardinalityDto( + new CardinalityBigIntegerDto() + ); + Cardinality c = Cardinality.fromDto(genCard); + assertThat(c).isInstanceOf(Cardinality.BigInteger.class); + } + + @Test + void testCardinalityFromDtoInfinite() { + CardinalityDto genCard = new CardinalityDto( + new CardinalityInfiniteDto() + ); + Cardinality c = Cardinality.fromDto(genCard); + assertThat(c).isInstanceOf(Cardinality.Infinite.class); + } + + @Test + void testCardinalityIntegerZero() { + Cardinality.Integer c = new Cardinality.Integer(0L); + assertThat(c.isEmpty()).contains(true); + assertThat(c.isEmptyString()).contains(false); + } + + @Test + void testCardinalityIntegerOne() { + Cardinality.Integer c = new Cardinality.Integer(1L); + assertThat(c.isEmpty()).contains(false); + // Equivalent to Python's `is None` + assertThat(c.isEmptyString()).isEmpty(); + } + + @Test + void testCardinalityBigInteger() { + Cardinality.BigInteger c = new Cardinality.BigInteger(); + assertThat(c.isEmpty()).contains(false); + assertThat(c.isEmptyString()).contains(false); + assertThat(c.isTotal()).contains(false); + assertThat(c.toString()).isEqualTo(""); + } + + @Test + void testCardinalityInfinite() { + Cardinality.Infinite c = new Cardinality.Infinite(); + assertThat(c.isEmpty()).contains(false); + assertThat(c.isEmptyString()).contains(false); + assertThat(c.toString()).isEqualTo(""); + } + + @Test + void testLength() { + Length length = new Length(1, 5); + assertThat(length.getMin()).contains(1); + assertThat(length.getMax()).contains(5); + assertThat(length.isEmpty()).contains(false); + assertThat(length.isEmptyString()).contains(false); + assertThat(length.isTotal()).contains(false); + assertThat(length.toString()).isEqualTo(""); + } + + @Test + void testLengthFromDto() { + LengthDto genLen = new LengthDto(); + genLen.setMin(1); + genLen.setMax(5); + + Length lengthObj = Length.fromDto(genLen); + assertThat(lengthObj.getMin()).contains(1); + assertThat(lengthObj.getMax()).contains(5); + } + + @Test + void testLengthEmpty() { + Length length = new Length(null, null); + assertThat(length.isEmpty()).contains(true); + } + + @Test + void testLengthEmptyString() { + Length length = new Length(0, 0); + assertThat(length.isEmptyString()).contains(true); + } + + @Test + void testLengthTotalCandidate() { + Length length = new Length(0, null); + assertThat(length.isTotal()).isEmpty(); + } + + @Test + void testTermPropertiesCaching() { + Term term = Term.regex("abc"); + assertThat(term.getCachedCardinality()).isNull(); + + Cardinality.Integer c = new Cardinality.Integer(5L); + term.setCachedCardinality(c); + + // Simulate AsyncRegexSolverClient behavior + term.setPropertiesMixin(c); + + assertThat(term.getCachedCardinality()).isEqualTo(c); + // Since Integer(5).isEmpty() contains false, it should set _empty to false + assertThat(term.getCachedEmpty()).isFalse(); + } + + @Test + void testTermGetFairAndPattern() { + Term regexTerm = Term.regex("abc"); + assertThat(regexTerm.getPattern()).contains("abc"); + assertThat(regexTerm.getFair()).isEmpty(); + + Term fairTerm = Term.fair("payload"); + assertThat(fairTerm.getFair()).contains("payload"); + assertThat(fairTerm.getPattern()).isEmpty(); + + fairTerm.setCachedPattern("abc"); + assertThat(fairTerm.getPattern()).contains("abc"); + } + + @Test + void testTermSerializeDeserialize() { + Term term = Term.regex("abc"); + String serialized = term.serialize(); + assertThat(serialized).isEqualTo("regex=abc"); + assertThat(term.toString()).isEqualTo("regex=abc"); + + Optional deserializedOpt = Term.deserialize(serialized); + Term deserialized = deserializedOpt.get(); + assertThat(deserialized).isEqualTo(term); + assertThat(deserialized.hashCode()).isEqualTo(term.hashCode()); + + Term fairTerm = Term.fair("payload"); + assertThat(Term.deserialize(fairTerm.serialize())).contains(fairTerm); + + assertThat(Term.deserialize("invalid")).isEmpty(); + assertThat(Term.deserialize("unknown=value")).isEmpty(); + } + + @Test + void testTermIsMatch() { + Term term = Term.regex("a.b"); + assertThat(term.matches("axb")).isTrue(); + assertThat(term.matches("a\nb")).isTrue(); // DOTALL behavior + assertThat(term.matches("ab")).isFalse(); + assertThat(term.matches("axxb")).isFalse(); // anchored (fullmatch) + + Term fairTerm = Term.fair("payload"); + assertThatThrownBy(() -> fairTerm.matches("abc")).isInstanceOf( + IllegalStateException.class + ); + } + + @Test + void testTermRepr() { + Term term = Term.regex("abc"); + assertThat(term.toString()).isEqualTo("regex=abc"); + } +} diff --git a/src/test/java/com/regexsolver/api/RateLimiterTest.java b/src/test/java/com/regexsolver/api/RateLimiterTest.java new file mode 100644 index 0000000..418977c --- /dev/null +++ b/src/test/java/com/regexsolver/api/RateLimiterTest.java @@ -0,0 +1,113 @@ +package com.regexsolver.api; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; + +class RateLimiterTest { + + @Test + void testRateLimiterWaitIfNecessaryNoWait() { + RateLimiter rl = RateLimiter.getInstance("test-token-1"); + + long start = System.currentTimeMillis(); + // Should complete immediately since we haven't triggered a wait + rl.waitIfNecessary().join(); + long end = System.currentTimeMillis(); + + assertThat(end - start).isLessThan(50); // Allowing a small buffer for execution time + } + + @Test + void testRateLimiterTriggerAndWait() { + RateLimiter rl = RateLimiter.getInstance("test-token-2"); + + // Trigger a 0.2 second (200ms) delay + rl.trigger(0.2); + + long start = System.currentTimeMillis(); + rl.waitIfNecessary().join(); + long end = System.currentTimeMillis(); + + long duration = end - start; + // It should have waited at least ~200ms + assertThat(duration).isGreaterThanOrEqualTo(150); // 150ms to prevent flaky tests on slow CI + } + + @Test + void testRateLimiterTriggerAlreadyCleared() { + RateLimiter rl = RateLimiter.getInstance("test-token-3"); + + // Trigger a 0.1 second delay + rl.trigger(0.1); + + // Immediately trigger a shorter delay (0.05 seconds) + rl.trigger(0.05); + + long start = System.currentTimeMillis(); + rl.waitIfNecessary().join(); + long end = System.currentTimeMillis(); + + long duration = end - start; + + // The rate limiter should respect the LONGER of the two triggered delays + // Next retry was set to now + 100ms, the second call tried to set it to now + 50ms, + // but updateAndGet ensures it keeps the later Instant. + assertThat(duration).isGreaterThanOrEqualTo(80); + } + + @Test + void testRateLimiterDeadlineExtendedWhileWaiting() throws Exception { + RateLimiter rl = RateLimiter.getInstance("test-token-4"); + + rl.trigger(0.1); + long start = System.currentTimeMillis(); + java.util.concurrent.CompletableFuture waiter = + rl.waitIfNecessary(); + + Thread.sleep(50); + rl.trigger(0.25); + + waiter.join(); + long duration = System.currentTimeMillis() - start; + // The waiter woke at the original deadline, re-checked, and waited + // again until the extended one (~50ms + 250ms from the second trigger). + assertThat(duration).isGreaterThanOrEqualTo(250); + } + + @Test + void testWaitIfNecessaryDoesNotBlockCaller() { + RateLimiter rl = RateLimiter.getInstance("test-token-5"); + + rl.trigger(0.2); + long start = System.currentTimeMillis(); + java.util.concurrent.CompletableFuture waiter = + rl.waitIfNecessary(); + long returned = System.currentTimeMillis(); + + // The call returns immediately with a pending future; no thread is + // parked on behalf of the caller. + assertThat(returned - start).isLessThan(50); + assertThat(waiter).isNotDone(); + waiter.join(); + assertThat(System.currentTimeMillis() - start).isGreaterThanOrEqualTo( + 150 + ); + } + + @Test + void testGetInstanceReturnsSameInstanceForSameToken() { + RateLimiter rl1 = RateLimiter.getInstance("tokenA"); + RateLimiter rl2 = RateLimiter.getInstance("tokenA"); + + assertThat(rl1).isSameAs(rl2); + } + + @Test + void testGetInstanceReturnsDifferentInstanceForDifferentTokens() { + RateLimiter rl1 = RateLimiter.getInstance("tokenB"); + RateLimiter rl2 = RateLimiter.getInstance("tokenC"); + + assertThat(rl1).isNotSameAs(rl2); + } +} diff --git a/src/test/java/com/regexsolver/api/RegexSolverClientTest.java b/src/test/java/com/regexsolver/api/RegexSolverClientTest.java new file mode 100644 index 0000000..bea61aa --- /dev/null +++ b/src/test/java/com/regexsolver/api/RegexSolverClientTest.java @@ -0,0 +1,179 @@ +package com.regexsolver.api; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyList; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.isNull; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.lang.reflect.Field; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class RegexSolverClientTest { + + @Mock + private AsyncRegexSolverClient asyncClient; + + private RegexSolverClient client; + + @BeforeEach + void setUp() throws Exception { + // Build the synchronous client + client = RegexSolverClient.builder().apiToken("test-token").build(); + + // Use reflection to inject the mocked Async client into the private field + Field field = RegexSolverClient.class.getDeclaredField("asyncClient"); + field.setAccessible(true); + field.set(client, asyncClient); + } + + @Test + void testSyncClientGetCardinality() { + Term term = Term.regex("abc"); + Cardinality.Integer mockResult = new Cardinality.Integer(42L); + + when(asyncClient.getCardinality(any(), isNull())).thenReturn( + CompletableFuture.completedFuture(mockResult) + ); + + Cardinality result = client.getCardinality(term); + + assertThat(result).isInstanceOf(Cardinality.Integer.class); + assertThat(((Cardinality.Integer) result).getValue()).isEqualTo(42L); + + // Verify the async client was called + verify(asyncClient).getCardinality(term, null); + } + + @Test + void testSyncClientIsEmpty() { + Term term = Term.regex("abc"); + + when(asyncClient.isEmpty(any(), isNull())).thenReturn( + CompletableFuture.completedFuture(false) + ); + + boolean result = client.isEmpty(term); + + assertThat(result).isFalse(); + verify(asyncClient).isEmpty(term, null); + } + + @Test + void testSyncClientIsDeterministic() { + Term term = Term.fair("payload"); + + when(asyncClient.isDeterministic(any(), isNull())).thenReturn( + CompletableFuture.completedFuture(true) + ); + + boolean result = client.isDeterministic(term); + + assertThat(result).isTrue(); + verify(asyncClient).isDeterministic(term, null); + } + + @Test + void testSyncClientDeterminize() { + Term term = Term.regex("a"); + Term mockResultTerm = Term.fair("fair-payload"); + + when(asyncClient.determinize(any(), isNull())).thenReturn( + CompletableFuture.completedFuture(mockResultTerm) + ); + + Term result = client.determinize(term); + + assertThat(result.getFair()).contains("fair-payload"); + verify(asyncClient).determinize(term, null); + } + + @Test + void testSyncClientUnion() { + Term term1 = Term.regex("a"); + Term term2 = Term.regex("b"); + Term mockResultTerm = Term.regex("a|b"); + List termList = List.of(term1, term2); + + when(asyncClient.union(anyList(), isNull())).thenReturn( + CompletableFuture.completedFuture(mockResultTerm) + ); + + Term result = client.union(termList); + + assertThat(result.getPattern()).contains("a|b"); + verify(asyncClient).union(termList, null); + } + + @Test + void testSyncClientComplement() { + Term term = Term.regex(".*a.*"); + Term mockResultTerm = Term.regex("[^a].*"); + + when(asyncClient.complement(any(), isNull())).thenReturn( + CompletableFuture.completedFuture(mockResultTerm) + ); + + Term result = client.complement(term); + + assertThat(result.getPattern()).contains("[^a].*"); + verify(asyncClient).complement(term, null); + } + + @Test + void testSyncClientGetLength() { + Term term = Term.regex("(abc)?d"); + Length mockLength = new Length(1, 4); + + when(asyncClient.getLength(any(), isNull())).thenReturn( + CompletableFuture.completedFuture(mockLength) + ); + + Length result = client.getLength(term); + + assertThat(result.getMin()).contains(1); + assertThat(result.getMax()).contains(4); + verify(asyncClient).getLength(term, null); + } + + @Test + void testSyncClientIntersection() { + Term term1 = Term.regex("a"); + Term term2 = Term.regex("ab"); + Term mockResultTerm = Term.regex("a"); + List termList = List.of(term1, term2); + + when(asyncClient.intersection(anyList(), isNull())).thenReturn( + CompletableFuture.completedFuture(mockResultTerm) + ); + + Term result = client.intersection(termList); + + assertThat(result.getPattern()).contains("a"); + verify(asyncClient).intersection(termList, null); + } + + @Test + void testSyncClientGenerateStrings() { + Term term = Term.regex("a*"); + List mockStrings = List.of("", "a", "aa"); + + when(asyncClient.generateStrings(any(), eq(3), eq(0), isNull())).thenReturn( + CompletableFuture.completedFuture(mockStrings) + ); + + List result = client.generateStrings(term, 3, 0); + + assertThat(result).containsExactly("", "a", "aa"); + verify(asyncClient).generateStrings(term, 3, 0, null); + } +} diff --git a/src/test/java/com/regexsolver/api/TermOperationTest.java b/src/test/java/com/regexsolver/api/TermOperationTest.java deleted file mode 100644 index c7b7549..0000000 --- a/src/test/java/com/regexsolver/api/TermOperationTest.java +++ /dev/null @@ -1,207 +0,0 @@ -package com.regexsolver.api; - -import com.regexsolver.api.dto.Cardinality; -import com.regexsolver.api.dto.Details; -import com.regexsolver.api.dto.Length; -import com.regexsolver.api.exception.ApiError; -import okhttp3.mockwebserver.MockResponse; -import okhttp3.mockwebserver.MockWebServer; -import okhttp3.mockwebserver.RecordedRequest; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import java.io.IOException; -import java.util.List; - -import static org.junit.Assert.*; - -public class TermOperationTest { - private MockWebServer server; - - @Before - public void setUp() throws Exception { - server = new MockWebServer(); - server.start(); - - RegexSolver.initialize("TOKEN", server.url("/").toString()); - } - - @After - public void tearDown() throws IOException { - server.shutdown(); - } - - @Test - public void test_getDetails() throws IOException, ApiError, InterruptedException { - int requestCount = server.getRequestCount(); - - MockResponse response = TestUtils.generateMockResponse(TestUtils.getResourceFileContent("response_getDetails.json")); - server.enqueue(response); - - Term.Regex regex = Term.regex("(abc|de)"); - - Details details = regex.getDetails(); - - Cardinality cardinality = details.getCardinality(); - assertTrue(cardinality instanceof Cardinality.Integer); - assertEquals(2, ((Cardinality.Integer) cardinality).getCount()); - - Length length = details.getLength(); - assertEquals(2L, length.getMinimum().getAsLong()); - assertEquals(3L, length.getMaximum().getAsLong()); - - assertFalse(details.isEmpty()); - assertFalse(details.isTotal()); - - RecordedRequest request = server.takeRequest(); - assertEquals("/api/analyze/details", request.getPath()); - assertEquals(regex, TestUtils.readBuffer(request.getBody(), Term.class)); - - Details detailsInCache = regex.getDetails(); - assertEquals(details, detailsInCache); - - assertEquals(1, server.getRequestCount() - requestCount); - } - - @Test - public void test_generateStrings() throws IOException, ApiError, InterruptedException { - MockResponse response = TestUtils.generateMockResponse(TestUtils.getResourceFileContent("response_generateStrings.json")); - server.enqueue(response); - - Term.Regex regex = Term.regex("(abc|de){2}"); - - List strings = regex.generateStrings(10); - assertEquals(4, strings.size()); - - RecordedRequest request = server.takeRequest(); - assertEquals("/api/generate/strings", request.getPath()); - - Request.GenerateStringsRequest generateStringsRequest = TestUtils.readBuffer(request.getBody(), Request.GenerateStringsRequest.class); - assertEquals(10, generateStringsRequest.getCount()); - assertEquals(regex, generateStringsRequest.getTerm()); - } - - @Test - public void test_intersection() throws IOException, ApiError, InterruptedException { - MockResponse response = TestUtils.generateMockResponse(TestUtils.getResourceFileContent("response_intersection.json")); - server.enqueue(response); - - Term.Regex term1 = Term.regex("(abc|de){2}"); - Term.Regex term2 = Term.regex("de.*"); - Term.Regex term3 = Term.regex(".*abc"); - - Term result = term1.intersection(term2, term3); - assertTrue(result instanceof Term.Regex); - assertEquals("deabc", ((Term.Regex) result).getPattern()); - - RecordedRequest request = server.takeRequest(); - assertEquals("/api/compute/intersection", request.getPath()); - - Request.MultiTermsRequest multiTermsRequest = TestUtils.readBuffer(request.getBody(), Request.MultiTermsRequest.class); - List terms = multiTermsRequest.getTerms(); - assertEquals(term1, terms.get(0)); - assertEquals(term2, terms.get(1)); - assertEquals(term3, terms.get(2)); - } - - @Test - public void test_union() throws IOException, ApiError, InterruptedException { - MockResponse response = TestUtils.generateMockResponse(TestUtils.getResourceFileContent("response_union.json")); - server.enqueue(response); - - Term.Regex term1 = Term.regex("abc"); - Term.Regex term2 = Term.regex("de"); - Term.Regex term3 = Term.regex("fghi"); - - Term result = term1.union(term2, term3); - assertTrue(result instanceof Term.Regex); - assertEquals("(abc|de|fghi)", ((Term.Regex) result).getPattern()); - - RecordedRequest request = server.takeRequest(); - assertEquals("/api/compute/union", request.getPath()); - - Request.MultiTermsRequest multiTermsRequest = TestUtils.readBuffer(request.getBody(), Request.MultiTermsRequest.class); - List terms = multiTermsRequest.getTerms(); - assertEquals(term1, terms.get(0)); - assertEquals(term2, terms.get(1)); - assertEquals(term3, terms.get(2)); - } - - @Test - public void test_subtraction() throws IOException, ApiError, InterruptedException { - MockResponse response = TestUtils.generateMockResponse(TestUtils.getResourceFileContent("response_subtraction.json")); - server.enqueue(response); - - Term.Regex term1 = Term.regex("(abc|de)"); - Term.Regex term2 = Term.regex("de"); - - Term result = term1.subtraction(term2); - assertTrue(result instanceof Term.Regex); - assertEquals("abc", ((Term.Regex) result).getPattern()); - - RecordedRequest request = server.takeRequest(); - assertEquals("/api/compute/subtraction", request.getPath()); - - Request.MultiTermsRequest multiTermsRequest = TestUtils.readBuffer(request.getBody(), Request.MultiTermsRequest.class); - List terms = multiTermsRequest.getTerms(); - assertEquals(term1, terms.get(0)); - assertEquals(term2, terms.get(1)); - } - - @Test - public void test_isEquivalentTo() throws IOException, ApiError, InterruptedException { - MockResponse response = TestUtils.generateMockResponse(TestUtils.getResourceFileContent("response_isEquivalentTo.json")); - server.enqueue(response); - - Term.Regex term1 = Term.regex("(abc|de)"); - Term.Fair term2 = Term.fair("rgmsW[1g2LvP=Gr&V>sLc#w-!No&(oq@Sf>X).?lI3{uh{80qWEH[#0.pHq@B-9o[LpP-a#fYI+"); - - boolean result = term1.isEquivalentTo(term2); - assertFalse(result); - - RecordedRequest request = server.takeRequest(); - assertEquals("/api/analyze/equivalence", request.getPath()); - - Request.MultiTermsRequest multiTermsRequest = TestUtils.readBuffer(request.getBody(), Request.MultiTermsRequest.class); - List terms = multiTermsRequest.getTerms(); - assertEquals(term1, terms.get(0)); - assertEquals(term2, terms.get(1)); - } - - @Test - public void test_isSubsetOf() throws IOException, ApiError, InterruptedException { - MockResponse response = TestUtils.generateMockResponse(TestUtils.getResourceFileContent("response_isSubsetOf.json")); - server.enqueue(response); - - Term.Regex term1 = Term.regex("de"); - Term.Regex term2 = Term.regex("(abc|de)"); - - boolean result = term1.isSubsetOf(term2); - assertTrue(result); - - RecordedRequest request = server.takeRequest(); - assertEquals("/api/analyze/subset", request.getPath()); - - Request.MultiTermsRequest multiTermsRequest = TestUtils.readBuffer(request.getBody(), Request.MultiTermsRequest.class); - List terms = multiTermsRequest.getTerms(); - assertEquals(term1, terms.get(0)); - assertEquals(term2, terms.get(1)); - } - - @Test - public void test_errorResponse() throws IOException { - MockResponse response = TestUtils.generateErrorMockResponse(TestUtils.getResourceFileContent("response_error.json"), 400); - server.enqueue(response); - - Term.Regex term1 = Term.regex("abc"); - Term.Regex term2 = Term.regex("de"); - - try { - term1.intersection(term2); - fail(); - } catch (ApiError e) { - assertEquals("The API returned the following error: A random error.", e.getMessage()); - } - } -} \ No newline at end of file diff --git a/src/test/java/com/regexsolver/api/TermSerializeTest.java b/src/test/java/com/regexsolver/api/TermSerializeTest.java deleted file mode 100644 index 4073af1..0000000 --- a/src/test/java/com/regexsolver/api/TermSerializeTest.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.regexsolver.api; - - -import org.junit.Test; - -import java.util.Optional; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -public class TermSerializeTest { - @Test - public void test_serialization_deserialization() { - assertSerialization(Term.regex(".*")); - assertSerialization(Term.regex("=")); - assertSerialization(Term.regex("")); - - assertSerialization(Term.fair("rgmsW[1g2LvP=Gr&V>sLc#w-!No&(oq@Sf>X).?lI3{uh{80qWEH[#0.pHq@B-9o[LpP-a#fYI+")); - assertSerialization(Term.fair("=rgmsW[1g2LvP=Gr&+")); - assertSerialization(Term.fair("")); - - assertTrue(Term.deserialize(null).isEmpty()); - assertTrue(Term.deserialize("not a term").isEmpty()); - } - - private void assertSerialization(Term term) { - String serialized = term.serialize(); - Optional deserializedOptional = Term.deserialize(serialized); - assertTrue(deserializedOptional.isPresent()); - Term deserialized = deserializedOptional.get(); - assertEquals(term, deserialized); - } -} \ No newline at end of file diff --git a/src/test/java/com/regexsolver/api/TestUtils.java b/src/test/java/com/regexsolver/api/TestUtils.java deleted file mode 100644 index 3553248..0000000 --- a/src/test/java/com/regexsolver/api/TestUtils.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.regexsolver.api; - -import com.fasterxml.jackson.databind.ObjectMapper; -import okhttp3.mockwebserver.MockResponse; -import okio.Buffer; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; - -import static org.junit.Assert.assertNotNull; - -class TestUtils { - public static String getResourceFileContent(String resourceName) throws IOException { - String content; - try (InputStream inputStream = TestUtils.class - .getClassLoader() - .getResourceAsStream(resourceName)) { - assertNotNull(inputStream); - content = new String(inputStream.readAllBytes()); - } - return content; - } - - public static MockResponse generateMockResponse(String content) { - return new MockResponse() - .addHeader("Content-Type", "application/json; charset=utf-8") - .addHeader("Cache-Control", "no-cache") - .setBody(content); - } - - public static MockResponse generateErrorMockResponse(String content, int code) { - return generateMockResponse(content) - .setResponseCode(code); - } - - public static T readBuffer(Buffer buffer, Class type) throws IOException { - ByteArrayOutputStream stream - = new ByteArrayOutputStream(); - buffer.writeTo(stream); - - String json = stream.toString(); - - ObjectMapper mapper = new ObjectMapper(); - return mapper.readValue(json, type); - } -} diff --git a/src/test/resources/response_error.json b/src/test/resources/response_error.json deleted file mode 100644 index 0faf2d7..0000000 --- a/src/test/resources/response_error.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "error", - "message": "A random error." -} \ No newline at end of file diff --git a/src/test/resources/response_generateStrings.json b/src/test/resources/response_generateStrings.json deleted file mode 100644 index 9ee8883..0000000 --- a/src/test/resources/response_generateStrings.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "type": "strings", - "value": [ - "abcde", - "dede", - "deabc", - "abcabc" - ] -} \ No newline at end of file diff --git a/src/test/resources/response_getDetails.json b/src/test/resources/response_getDetails.json deleted file mode 100644 index 65e0539..0000000 --- a/src/test/resources/response_getDetails.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "type": "details", - "cardinality": { - "type": "Integer", - "value": 2 - }, - "length": [ - 2, - 3 - ], - "empty": false, - "total": false -} \ No newline at end of file diff --git a/src/test/resources/response_intersection.json b/src/test/resources/response_intersection.json deleted file mode 100644 index e6b1a7a..0000000 --- a/src/test/resources/response_intersection.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "regex", - "value": "deabc" -} \ No newline at end of file diff --git a/src/test/resources/response_isEquivalentTo.json b/src/test/resources/response_isEquivalentTo.json deleted file mode 100644 index 25147f3..0000000 --- a/src/test/resources/response_isEquivalentTo.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "boolean", - "value": false -} \ No newline at end of file diff --git a/src/test/resources/response_isSubsetOf.json b/src/test/resources/response_isSubsetOf.json deleted file mode 100644 index 84ed493..0000000 --- a/src/test/resources/response_isSubsetOf.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "boolean", - "value": true -} \ No newline at end of file diff --git a/src/test/resources/response_subtraction.json b/src/test/resources/response_subtraction.json deleted file mode 100644 index 478ac72..0000000 --- a/src/test/resources/response_subtraction.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "regex", - "value": "abc" -} \ No newline at end of file diff --git a/src/test/resources/response_union.json b/src/test/resources/response_union.json deleted file mode 100644 index 27dae5e..0000000 --- a/src/test/resources/response_union.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "regex", - "value": "(abc|de|fghi)" -} \ No newline at end of file