diff --git a/.gitattributes b/.gitattributes index b12faa9..88c0e76 100644 --- a/.gitattributes +++ b/.gitattributes @@ -3,6 +3,7 @@ .github/workflows/dependencies_check.yml linguist-generated=true .github/workflows/dependencies_update.yml linguist-generated=true .github/workflows/release.yml linguist-generated=true +.github/zizmor.yml linguist-generated=true src/test/resources/logging.properties linguist-generated=true SECURITY.md linguist-generated=true diff --git a/.github/workflows/broken_links_checker.yml b/.github/workflows/broken_links_checker.yml index ee8df76..55d839d 100644 --- a/.github/workflows/broken_links_checker.yml +++ b/.github/workflows/broken_links_checker.yml @@ -21,10 +21,11 @@ jobs: cancel-in-progress: true } steps: - - { - id: checkout, - uses: actions/checkout@v5 - } + - id: checkout + uses: actions/checkout@v7 + with: { + persist-credentials: false + } - id: configure-broken-links-checker name: Configure broken links checker run: | @@ -36,7 +37,7 @@ jobs: '{"pattern": "^https?://projects.eclipse.org"}' \ ']}' > ./target/broken_links_checker.json - id: run-broken-links-checker - uses: tcort/github-action-markdown-link-check@v1 + uses: tcort/github-action-markdown-link-check@e7c7a18363c842693fadde5d41a3bd3573a7a225 with: { use-quiet-mode: yes, use-verbose-mode: yes, diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index 754f75f..f54f879 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -43,25 +43,23 @@ jobs: sudo rm -rf /usr/share/dotnet - name: Checkout the repository id: checkout - uses: actions/checkout@v5 + uses: actions/checkout@v7 with: { - fetch-depth: 0 + fetch-depth: 0, + persist-credentials: false } - name: Set up JDKs id: setup-java - uses: actions/setup-java@v5 + uses: actions/setup-java@v6 with: distribution: temurin java-version: |- - 11 17 + 21 cache: maven - server-id: ossindex - server-username: OSSINDEX_USERNAME - server-password: OSSINDEX_API_TOKEN - name: Cache SonarCloud packages id: cache-sonar - uses: actions/cache@v4 + uses: actions/cache@v6 with: { path: ~/.sonar/cache, key: '${{ runner.os }}-sonar', @@ -76,12 +74,9 @@ jobs: id: build-pk-verify run: | mvn --batch-mode clean verify \ - -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn \ + -DossindexSkip=true \ + --no-transfer-progress \ -DtrimStackTrace=false - env: { - OSSINDEX_USERNAME: '${{ secrets.OSSINDEX_USERNAME }}', - OSSINDEX_API_TOKEN: '${{ secrets.OSSINDEX_API_TOKEN }}' - } - { name: Generate dummy error code report, id: generate-dummy-error-code-report, @@ -92,7 +87,8 @@ jobs: if: ${{ env.SONAR_TOKEN != null }} run: | mvn --batch-mode org.sonarsource.scanner.maven:sonar-maven-plugin:sonar \ - -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn \ + -DossindexSkip=true \ + --no-transfer-progress \ -DtrimStackTrace=false \ -Dsonar.token=$SONAR_TOKEN env: { @@ -101,13 +97,41 @@ jobs: } - name: Verify Release Artifacts id: verify-release-artifacts - run: "print_message() {\n local -r message=$1\n echo \"$message\"\n echo \"$message\" >> \"$GITHUB_STEP_SUMMARY\"\n}\n\nprint_message \"### Release Artifacts\"\n\nIFS=$'\\n' artifacts_array=($ARTIFACTS)\nmissing_files=()\nfor file in \"${artifacts_array[@]}\";\ndo \n echo \"Checking if file $file exists...\"\n if ! [[ -f \"$file\" ]]; then\n print_message \"* ⚠️ \\`$file\\` does not exist ⚠️\"\n echo \"Content of directory $(dirname \"$file\"):\"\n ls \"$(dirname \"$file\")\"\n missing_files+=(\"$file\")\n else\n print_message \"* \\`$file\\` ✅\" \n fi\ndone\nprint_message \"\"\nnumber_of_missing_files=${#missing_files[@]}\nif [[ $number_of_missing_files -gt 0 ]]; then\n print_message \"⚠️ $number_of_missing_files release artifact(s) missing ⚠️\"\n exit 1\nfi\n" + run: | + print_message() { + local -r message=$1 + echo "$message" + echo "$message" >> "$GITHUB_STEP_SUMMARY" + } + + print_message "### Release Artifacts" + + IFS=$'\n' artifacts_array=($ARTIFACTS) + missing_files=() + for file in "${artifacts_array[@]}"; + do + echo "Checking if file $file exists..." + if ! [[ -f "$file" ]]; then + print_message "* ⚠️ \`$file\` does not exist ⚠️" + echo "Content of directory $(dirname "$file"):" + ls "$(dirname "$file")" + missing_files+=("$file") + else + print_message "* \`$file\` ✅" + fi + done + print_message "" + number_of_missing_files=${#missing_files[@]} + if [[ $number_of_missing_files -gt 0 ]]; then + print_message "⚠️ $number_of_missing_files release artifact(s) missing ⚠️" + exit 1 + fi env: { ARTIFACTS: '${{ steps.build-pk-verify.outputs.release-artifacts }}' } - name: Upload artifacts id: upload-artifacts - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: { name: artifacts, path: '${{ steps.build-pk-verify.outputs.release-artifacts }}', @@ -123,7 +147,7 @@ jobs: '{"pattern": "^https?://(www.)?eclipse.org"}' \ '{"pattern": "^https?://projects.eclipse.org"}' \ ']}' > ./target/broken_links_checker.json - - uses: tcort/github-action-markdown-link-check@v1 + - uses: tcort/github-action-markdown-link-check@e7c7a18363c842693fadde5d41a3bd3573a7a225 id: run-link-check with: { use-quiet-mode: yes, @@ -146,32 +170,100 @@ jobs: steps: - name: Checkout the repository id: checkout - uses: actions/checkout@v5 + uses: actions/checkout@v7 with: { - fetch-depth: 0 + fetch-depth: 0, + persist-credentials: false } - - name: Set up JDK 17 + - name: Set up JDK 21 id: setup-java - uses: actions/setup-java@v5 + uses: actions/setup-java@v6 with: { distribution: temurin, - java-version: '17', - cache: maven, - server-id: ossindex, - server-username: OSSINDEX_USERNAME, - server-password: OSSINDEX_API_TOKEN + java-version: '21', + cache: maven } - - name: Run tests and build with Maven 17 + - name: Run tests and build with Maven 21 id: build-next-java - run: mvn --batch-mode clean package -DtrimStackTrace=false -Djava.version=17 + run: | + mvn --batch-mode clean package -DtrimStackTrace=false -Djava.version=21 \ + --no-transfer-progress \ + -DossindexSkip=true \ + ossindex: + runs-on: ubuntu-latest + defaults: + run: { + shell: bash + } + permissions: { + contents: read + } + concurrency: { + group: '${{ github.workflow }}-ossindex-${{ github.ref }}', + cancel-in-progress: true + } + steps: + - name: Checkout the repository + id: checkout + uses: actions/checkout@v7 + with: { + persist-credentials: false + } + - name: Set up JDKs + id: setup-java + uses: actions/setup-java@v6 + with: + distribution: temurin + java-version: |- + 17 + 21 + cache: maven + server-id: ossindex + server-username-env-var: OSSINDEX_USERNAME + server-password-env-var: OSSINDEX_API_TOKEN + - name: Run Ossindex + id: ossindex + run: | + mvn --batch-mode test-compile \ + org.sonatype.ossindex.maven:ossindex-maven-plugin:audit \ + org.sonatype.ossindex.maven:ossindex-maven-plugin:audit-aggregate \ + --no-transfer-progress env: { OSSINDEX_USERNAME: '${{ secrets.OSSINDEX_USERNAME }}', OSSINDEX_API_TOKEN: '${{ secrets.OSSINDEX_API_TOKEN }}' } + lint-github-actions: + runs-on: ubuntu-latest + defaults: + run: { + shell: bash + } + permissions: { + contents: read + } + concurrency: { + group: '${{ github.workflow }}-github-actions-linter-${{ github.ref }}', + cancel-in-progress: true + } + steps: + - name: Checkout the repository + id: checkout + uses: actions/checkout@v7 + with: { + persist-credentials: false + } + - name: Lint GitHub actions with Zizmor + id: lint-github-actions + uses: zizmorcore/zizmor-action@cc914d7f3750a2d13d75c7f184a1060aa0e9d482 + with: { + advanced-security: false + } build: needs: [ build-and-test, - next-java-compatibility + next-java-compatibility, + ossindex, + lint-github-actions ] runs-on: ubuntu-latest defaults: @@ -188,18 +280,19 @@ jobs: steps: - name: Checkout the repository id: checkout - uses: actions/checkout@v5 + uses: actions/checkout@v7 with: { - fetch-depth: 0 + fetch-depth: 0, + persist-credentials: false } - name: Set up JDKs id: setup-java - uses: actions/setup-java@v5 + uses: actions/setup-java@v6 with: distribution: temurin java-version: |- - 11 17 + 21 cache: maven - name: Check if release is needed id: check-release @@ -229,7 +322,7 @@ jobs: actions: read, issues: read } - uses: ./.github/workflows/release.yml + uses: $/.github/workflows/release.yml with: { started-from-ci: true, maven-central-auto-publish: true diff --git a/.github/workflows/dependencies_check.yml b/.github/workflows/dependencies_check.yml index b0877fc..e6bd052 100644 --- a/.github/workflows/dependencies_check.yml +++ b/.github/workflows/dependencies_check.yml @@ -4,7 +4,7 @@ on: workflow_dispatch: null schedule: - { - cron: 0 2 * * * + cron: 42 22 * * 0 } jobs: report_security_issues: @@ -25,23 +25,24 @@ jobs: cancel-in-progress: true } steps: - - { - name: Checkout, - id: checkout, - uses: actions/checkout@v5 - } + - name: Checkout + id: checkout + uses: actions/checkout@v7 + with: { + persist-credentials: false + } - name: Set up JDKs id: setup-jdks - uses: actions/setup-java@v5 + uses: actions/setup-java@v6 with: distribution: temurin java-version: |- - 11 17 + 21 cache: maven server-id: ossindex - server-username: OSSINDEX_USERNAME - server-password: OSSINDEX_API_TOKEN + server-username-env-var: OSSINDEX_USERNAME + server-password-env-var: OSSINDEX_API_TOKEN - name: Generate ossindex report id: ossindex-report run: | @@ -55,7 +56,7 @@ jobs: } - name: Create GitHub Issues id: create-security-issues - uses: exasol/python-toolbox/.github/actions/security-issues@1.9.0 + uses: exasol/python-toolbox/.github/actions/security-issues@10.1.0 with: { format: maven, command: cat ossindex-report.json, @@ -81,7 +82,7 @@ jobs: contents: write, pull-requests: write } - uses: ./.github/workflows/dependencies_update.yml + uses: $/.github/workflows/dependencies_update.yml with: { vulnerability_issues: '${{ needs.report_security_issues.outputs.created-issues }}' } diff --git a/.github/workflows/dependencies_update.yml b/.github/workflows/dependencies_update.yml index 2ba2785..71573af 100644 --- a/.github/workflows/dependencies_update.yml +++ b/.github/workflows/dependencies_update.yml @@ -34,19 +34,20 @@ jobs: cancel-in-progress: false } steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v7 id: checkout with: { - fetch-depth: 0 + fetch-depth: 0, + persist-credentials: true } - name: Set up JDKs id: setup-jdks - uses: actions/setup-java@v5 + uses: actions/setup-java@v6 with: distribution: temurin java-version: |- - 11 17 + 21 cache: maven - name: Print issues id: debug-print-issues @@ -58,10 +59,14 @@ jobs: - name: Fail if not running on a branch id: check-branch if: ${{ !startsWith(github.ref, 'refs/heads/') }} - uses: actions/github-script@v8 + uses: actions/github-script@v9 with: script: | - core.setFailed('Not running on a branch, github.ref is ${{ github.ref }}. Please start this workflow only on main or a branch') + const ref = process.env.GITHUB_REF + core.setFailed(`Not running on a branch, github.ref is '${ref}'. Please start this workflow only on main or a branch`) + env: { + GITHUB_REF: '${{ github.ref }}' + } - name: Update dependencies id: update-dependencies run: | @@ -119,7 +124,7 @@ jobs: id: create-branch if: ${{ github.ref == 'refs/heads/main' }} run: | - branch_name="dependency-update/$(date "+%Y%m%d%H%M%S")" + branch_name="dependency-update/$(date "+%Y-%m-%d_%H-%M-%S")" echo "Creating branch $branch_name" git checkout -b "$branch_name" - name: Commit changes & push @@ -159,7 +164,7 @@ jobs: - name: Report failure Status to Slack channel id: report-failure-slack if: ${{ always() }} - uses: ravsamhq/notify-slack-action@v2 + uses: ravsamhq/notify-slack-action@be814b201e233b2dc673608aa46e5447c8ab13f2 with: { status: '${{ job.status }}', token: '${{ secrets.GITHUB_TOKEN }}', @@ -173,7 +178,7 @@ jobs: - name: Report new Pull Request to Slack channel id: report-pr-slack if: ${{ steps.create-pr.outputs.pr_url }} - uses: ravsamhq/notify-slack-action@v2 + uses: ravsamhq/notify-slack-action@be814b201e233b2dc673608aa46e5447c8ab13f2 with: { status: '${{ job.status }}', token: '${{ secrets.GITHUB_TOKEN }}', diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f75c3cc..73a0152 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -75,42 +75,46 @@ jobs: steps: - name: Checkout the repository id: checkout - uses: actions/checkout@v5 + uses: actions/checkout@v7 with: { - fetch-depth: 0 + fetch-depth: 0, + persist-credentials: true } - name: Set up Maven Central Repository id: configure-maven-central-credentials if: ${{ true }} - uses: actions/setup-java@v5 + uses: actions/setup-java@v6 with: distribution: temurin java-version: |- - 11 17 - cache: maven + 21 server-id: maven-central-portal - server-username: MAVEN_USERNAME - server-password: MAVEN_PASSWORD + server-username-env-var: MAVEN_USERNAME + server-password-env-var: MAVEN_PASSWORD gpg-private-key: ${{ secrets.OSSRH_GPG_SECRET_KEY }} - gpg-passphrase: MAVEN_GPG_PASSPHRASE + gpg-passphrase-env-var: MAVEN_GPG_PASSPHRASE - name: Set up JDKs id: setup-jdks if: ${{ ! true }} - uses: actions/setup-java@v5 + uses: actions/setup-java@v6 with: distribution: temurin java-version: |- - 11 17 + 21 cache: maven - name: Fail if not running on main or release branch id: check-main-or-release-branch if: ${{ github.ref != 'refs/heads/main' && !startsWith(github.ref, 'refs/heads/release/') }} - uses: actions/github-script@v8 + uses: actions/github-script@v9 with: script: | - core.setFailed('Not running on main or release branch, github.ref is ${{ github.ref }}. Please start this workflow only on main or a branch starting with release/') + const ref = process.env.GITHUB_REF + core.setFailed(`Not running on main or release branch, github.ref is '${ref}'. Please start this workflow only on main or a branch starting with release/`) + env: { + GITHUB_REF: '${{ github.ref }}' + } - name: Check CI build of this commit succeeded id: check-ci-build-status if: ${{ ! inputs.started-from-ci }} @@ -142,7 +146,7 @@ jobs: - { name: Build project, id: build, - run: mvn --batch-mode -DskipTests -Dossindex.skip=true clean verify + run: mvn --batch-mode -DskipTests -DskipITs -DossindexSkip=true clean verify } - { name: Generate dummy error code report, @@ -160,7 +164,7 @@ jobs: if: ${{ true && (! inputs.skip-maven-central) }} run: | echo "#### Maven Central Release" >> "$GITHUB_STEP_SUMMARY" - mvn --batch-mode -Dgpg.skip=false -DskipTests -Dossindex.skip=true deploy \ + mvn --batch-mode -Dgpg.skip=false -DskipTests -DskipITs -DossindexSkip=true deploy \ -Dcentral-publishing.deploymentName="Auto release of repo ${{ github.repository }} using PK release.yml" \ -Dcentral-publishing.autoPublish=${{ inputs.maven-central-auto-publish }} if [[ "${{ inputs.maven-central-auto-publish }}" == "true" ]]; then @@ -241,7 +245,7 @@ jobs: - name: Report failure Status to Slack channel id: report-failure-status-slack if: ${{ always() }} - uses: ravsamhq/notify-slack-action@v2 + uses: ravsamhq/notify-slack-action@be814b201e233b2dc673608aa46e5447c8ab13f2 with: { status: '${{ job.status }}', token: '${{ github.token }}', @@ -255,7 +259,7 @@ jobs: - name: Report new release to Slack channel id: report-new-release-slack if: ${{ steps.create-github-release.outputs.release-url }} - uses: ravsamhq/notify-slack-action@v2 + uses: ravsamhq/notify-slack-action@be814b201e233b2dc673608aa46e5447c8ab13f2 with: { status: '${{ job.status }}', token: '${{ github.token }}', diff --git a/.github/zizmor.yml b/.github/zizmor.yml new file mode 100644 index 0000000..a8508a1 --- /dev/null +++ b/.github/zizmor.yml @@ -0,0 +1,33 @@ +# Generated by Project Keeper +# https://github.com/exasol/project-keeper/blob/main/project-keeper/src/main/resources/templates/.github/zizmor.yml +# See https://docs.zizmor.sh/configuration/#settings +rules: + unpinned-uses: + config: + policies: + "actions/*": ref-pin + "exasol/python-toolbox/.github/actions/security-issues": ref-pin + "*": hash-pin + cache-poisoning: + ignore: + # Enabling caching is OK for non-release workflows + - ci-build.yml + - ci-build-native-build.yml + - ci-build-db-version-matrix.yml + - project-keeper-verify.yml + - test_on_windows.yml + - test_linux_build_on_windows.yml + obfuscation: + ignore: + # Generated workflows use boolean conditions like ${{ false }} + # Note: We cannot exclude this using inline comments because GitHubWorkflowIO does not preserve comments in the workflow YAML files. + - ci-build.yml + - release.yml + - project-keeper-verify.yml + secrets-inherit: + ignore: + # Required for passing slack webhooks + - ci-build.yml + - ci-build-db-version-matrix.yml + - dependencies_check.yml + - release.yml diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs index 7644ed3..fbf2df8 100644 --- a/.settings/org.eclipse.jdt.core.prefs +++ b/.settings/org.eclipse.jdt.core.prefs @@ -14,9 +14,9 @@ org.eclipse.jdt.core.compiler.annotation.owning=org.eclipse.jdt.annotation.Ownin org.eclipse.jdt.core.compiler.annotation.resourceanalysis=disabled org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.methodParameters=generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=17 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.compliance=17 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate @@ -120,10 +120,12 @@ org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning org.eclipse.jdt.core.compiler.processAnnotations=disabled -org.eclipse.jdt.core.compiler.release=disabled -org.eclipse.jdt.core.compiler.source=11 +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=17 +org.eclipse.jdt.core.formatter.align_arrows_in_switch_on_columns=false org.eclipse.jdt.core.formatter.align_assignment_statements_on_columns=false org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647 +org.eclipse.jdt.core.formatter.align_selector_in_method_invocation_on_expression_first_line=false org.eclipse.jdt.core.formatter.align_type_members_on_columns=false org.eclipse.jdt.core.formatter.align_variable_declarations_on_columns=false org.eclipse.jdt.core.formatter.align_with_spaces=false @@ -151,6 +153,8 @@ org.eclipse.jdt.core.formatter.alignment_for_conditional_expression_chain=0 org.eclipse.jdt.core.formatter.alignment_for_enum_constants=16 org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0 +org.eclipse.jdt.core.formatter.alignment_for_expressions_in_switch_case_with_arrow=0 +org.eclipse.jdt.core.formatter.alignment_for_expressions_in_switch_case_with_colon=0 org.eclipse.jdt.core.formatter.alignment_for_logical_operator=16 org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 org.eclipse.jdt.core.formatter.alignment_for_module_statements=16 @@ -159,6 +163,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_record_components=16 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 @@ -169,6 +174,7 @@ org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_record_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_switch_case_with_arrow=0 org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_type_annotations=0 @@ -194,6 +200,7 @@ org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block_in_case_after_arrow=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line @@ -213,6 +220,7 @@ org.eclipse.jdt.core.formatter.comment.format_header=false org.eclipse.jdt.core.formatter.comment.format_html=true org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true org.eclipse.jdt.core.formatter.comment.format_line_comments=true +org.eclipse.jdt.core.formatter.comment.format_markdown_comments=true org.eclipse.jdt.core.formatter.comment.format_source_code=true org.eclipse.jdt.core.formatter.comment.indent_parameter_description=false org.eclipse.jdt.core.formatter.comment.indent_root_tags=false @@ -220,7 +228,8 @@ org.eclipse.jdt.core.formatter.comment.indent_tag_description=false org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert org.eclipse.jdt.core.formatter.comment.insert_new_line_between_different_tags=do not insert org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert -org.eclipse.jdt.core.formatter.comment.line_length=120 +org.eclipse.jdt.core.formatter.comment.javadoc_do_not_separate_block_tags=false +org.eclipse.jdt.core.formatter.comment.line_length=160 org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false @@ -249,6 +258,7 @@ org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variabl org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_record_parameter=do not insert org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert @@ -292,6 +302,7 @@ org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arg org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_permitted_types=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_record_components=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_switch_case_expressions=insert @@ -383,6 +394,7 @@ org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_ar org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_permitted_types=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_record_components=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_switch_case_expressions=do not insert @@ -446,7 +458,8 @@ org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_ org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.join_lines_in_comments=true +org.eclipse.jdt.core.formatter.join_line_comments=false +org.eclipse.jdt.core.formatter.join_lines_in_comments=false org.eclipse.jdt.core.formatter.join_wrapped_lines=false org.eclipse.jdt.core.formatter.keep_annotation_declaration_on_one_line=one_line_never org.eclipse.jdt.core.formatter.keep_anonymous_type_declaration_on_one_line=one_line_never @@ -466,9 +479,11 @@ org.eclipse.jdt.core.formatter.keep_simple_do_while_body_on_same_line=false org.eclipse.jdt.core.formatter.keep_simple_for_body_on_same_line=false org.eclipse.jdt.core.formatter.keep_simple_getter_setter_on_one_line=false org.eclipse.jdt.core.formatter.keep_simple_while_body_on_same_line=false +org.eclipse.jdt.core.formatter.keep_switch_body_block_on_one_line=one_line_never +org.eclipse.jdt.core.formatter.keep_switch_case_with_arrow_on_one_line=one_line_never org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false org.eclipse.jdt.core.formatter.keep_type_declaration_on_one_line=one_line_never -org.eclipse.jdt.core.formatter.lineSplit=120 +org.eclipse.jdt.core.formatter.lineSplit=160 org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false org.eclipse.jdt.core.formatter.number_of_blank_lines_after_code_block=0 @@ -490,10 +505,11 @@ org.eclipse.jdt.core.formatter.parentheses_positions_in_record_declaration=commo org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true +org.eclipse.jdt.core.formatter.put_text_block_quotes_on_new_line=false org.eclipse.jdt.core.formatter.tabulation.char=space org.eclipse.jdt.core.formatter.tabulation.size=4 org.eclipse.jdt.core.formatter.text_block_indentation=0 -org.eclipse.jdt.core.formatter.use_on_off_tags=false +org.eclipse.jdt.core.formatter.use_on_off_tags=true org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=true org.eclipse.jdt.core.formatter.wrap_before_additive_operator=true org.eclipse.jdt.core.formatter.wrap_before_assertion_message_operator=true @@ -506,5 +522,6 @@ org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true org.eclipse.jdt.core.formatter.wrap_before_relational_operator=true org.eclipse.jdt.core.formatter.wrap_before_shift_operator=true org.eclipse.jdt.core.formatter.wrap_before_string_concatenation=true +org.eclipse.jdt.core.formatter.wrap_before_switch_case_arrow_operator=false org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter diff --git a/.settings/org.eclipse.jdt.ui.prefs b/.settings/org.eclipse.jdt.ui.prefs index 54d02ac..37cc471 100644 --- a/.settings/org.eclipse.jdt.ui.prefs +++ b/.settings/org.eclipse.jdt.ui.prefs @@ -1,211 +1,9 @@ -cleanup.add_default_serial_version_id=true -cleanup.add_generated_serial_version_id=false -cleanup.add_missing_annotations=true -cleanup.add_missing_deprecated_annotations=true -cleanup.add_missing_methods=false -cleanup.add_missing_nls_tags=false -cleanup.add_missing_override_annotations=true -cleanup.add_missing_override_annotations_interface_methods=true -cleanup.add_serial_version_id=false -cleanup.always_use_blocks=true -cleanup.always_use_parentheses_in_expressions=false -cleanup.always_use_this_for_non_static_field_access=true -cleanup.always_use_this_for_non_static_method_access=false -cleanup.convert_functional_interfaces=true -cleanup.convert_to_enhanced_for_loop=true -cleanup.correct_indentation=true -cleanup.format_source_code=true -cleanup.format_source_code_changes_only=false -cleanup.insert_inferred_type_arguments=false -cleanup.make_local_variable_final=true -cleanup.make_parameters_final=true -cleanup.make_private_fields_final=true -cleanup.make_type_abstract_if_missing_method=false -cleanup.make_variable_declarations_final=true -cleanup.never_use_blocks=false -cleanup.never_use_parentheses_in_expressions=true -cleanup.organize_imports=false -cleanup.qualify_static_field_accesses_with_declaring_class=false -cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true -cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true -cleanup.qualify_static_member_accesses_with_declaring_class=true -cleanup.qualify_static_method_accesses_with_declaring_class=false -cleanup.remove_private_constructors=true -cleanup.remove_redundant_modifiers=false -cleanup.remove_redundant_semicolons=true -cleanup.remove_redundant_type_arguments=true -cleanup.remove_trailing_whitespaces=true -cleanup.remove_trailing_whitespaces_all=true -cleanup.remove_trailing_whitespaces_ignore_empty=false -cleanup.remove_unnecessary_casts=true -cleanup.remove_unnecessary_nls_tags=true -cleanup.remove_unused_imports=true -cleanup.remove_unused_local_variables=false -cleanup.remove_unused_private_fields=true -cleanup.remove_unused_private_members=true -cleanup.remove_unused_private_methods=true -cleanup.remove_unused_private_types=true -cleanup.sort_members=false -cleanup.sort_members_all=false -cleanup.use_anonymous_class_creation=false -cleanup.use_blocks=true -cleanup.use_blocks_only_for_return_and_throw=false -cleanup.use_lambda=true -cleanup.use_parentheses_in_expressions=true -cleanup.use_this_for_non_static_field_access=true -cleanup.use_this_for_non_static_field_access_only_if_necessary=false -cleanup.use_this_for_non_static_method_access=false -cleanup.use_this_for_non_static_method_access_only_if_necessary=true -cleanup_profile=_Exasol cleanup_settings_version=2 eclipse.preferences.version=1 -editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true formatter_profile=_Exasol -formatter_settings_version=21 +formatter_settings_version=23 org.eclipse.jdt.ui.ignorelowercasenames=true org.eclipse.jdt.ui.importorder=java;javax;org;com; org.eclipse.jdt.ui.ondemandthreshold=3 org.eclipse.jdt.ui.staticondemandthreshold=3 -sp_cleanup.add_all=false -sp_cleanup.add_default_serial_version_id=true -sp_cleanup.add_generated_serial_version_id=false -sp_cleanup.add_missing_annotations=true -sp_cleanup.add_missing_deprecated_annotations=true -sp_cleanup.add_missing_methods=false -sp_cleanup.add_missing_nls_tags=false -sp_cleanup.add_missing_override_annotations=true -sp_cleanup.add_missing_override_annotations_interface_methods=true -sp_cleanup.add_serial_version_id=false -sp_cleanup.also_simplify_lambda=false -sp_cleanup.always_use_blocks=true -sp_cleanup.always_use_parentheses_in_expressions=true -sp_cleanup.always_use_this_for_non_static_field_access=true -sp_cleanup.always_use_this_for_non_static_method_access=false -sp_cleanup.array_with_curly=false -sp_cleanup.arrays_fill=false -sp_cleanup.bitwise_conditional_expression=false -sp_cleanup.boolean_literal=false -sp_cleanup.boolean_value_rather_than_comparison=false -sp_cleanup.break_loop=false -sp_cleanup.collection_cloning=false -sp_cleanup.comparing_on_criteria=false -sp_cleanup.comparison_statement=false -sp_cleanup.controlflow_merge=false -sp_cleanup.convert_functional_interfaces=true -sp_cleanup.convert_to_enhanced_for_loop=true -sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false -sp_cleanup.convert_to_switch_expressions=false -sp_cleanup.correct_indentation=true -sp_cleanup.do_while_rather_than_while=false -sp_cleanup.double_negation=false -sp_cleanup.else_if=false -sp_cleanup.embedded_if=false -sp_cleanup.evaluate_nullable=false -sp_cleanup.extract_increment=false -sp_cleanup.format_source_code=true -sp_cleanup.format_source_code_changes_only=false -sp_cleanup.hash=false -sp_cleanup.if_condition=false -sp_cleanup.insert_inferred_type_arguments=false -sp_cleanup.instanceof=false -sp_cleanup.instanceof_keyword=false -sp_cleanup.invert_equals=false -sp_cleanup.join=false -sp_cleanup.lazy_logical_operator=false -sp_cleanup.make_local_variable_final=true -sp_cleanup.make_parameters_final=true -sp_cleanup.make_private_fields_final=true -sp_cleanup.make_type_abstract_if_missing_method=false -sp_cleanup.make_variable_declarations_final=true -sp_cleanup.map_cloning=false -sp_cleanup.merge_conditional_blocks=false -sp_cleanup.multi_catch=false -sp_cleanup.never_use_blocks=false -sp_cleanup.never_use_parentheses_in_expressions=false -sp_cleanup.no_string_creation=false -sp_cleanup.no_super=false -sp_cleanup.number_suffix=false -sp_cleanup.objects_equals=false -sp_cleanup.on_save_use_additional_actions=true -sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false -sp_cleanup.operand_factorization=false -sp_cleanup.organize_imports=true -sp_cleanup.overridden_assignment=false -sp_cleanup.overridden_assignment_move_decl=false -sp_cleanup.plain_replacement=false -sp_cleanup.precompile_regex=false -sp_cleanup.primitive_comparison=false -sp_cleanup.primitive_parsing=false -sp_cleanup.primitive_rather_than_wrapper=false -sp_cleanup.primitive_serialization=false -sp_cleanup.pull_out_if_from_if_else=false -sp_cleanup.pull_up_assignment=false -sp_cleanup.push_down_negation=false -sp_cleanup.qualify_static_field_accesses_with_declaring_class=false -sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_with_declaring_class=true -sp_cleanup.qualify_static_method_accesses_with_declaring_class=false -sp_cleanup.reduce_indentation=false -sp_cleanup.redundant_comparator=false -sp_cleanup.redundant_falling_through_block_end=false -sp_cleanup.remove_private_constructors=true -sp_cleanup.remove_redundant_modifiers=false -sp_cleanup.remove_redundant_semicolons=true -sp_cleanup.remove_redundant_type_arguments=true -sp_cleanup.remove_trailing_whitespaces=true -sp_cleanup.remove_trailing_whitespaces_all=true -sp_cleanup.remove_trailing_whitespaces_ignore_empty=false -sp_cleanup.remove_unnecessary_array_creation=false -sp_cleanup.remove_unnecessary_casts=true -sp_cleanup.remove_unnecessary_nls_tags=true -sp_cleanup.remove_unused_imports=true -sp_cleanup.remove_unused_local_variables=false -sp_cleanup.remove_unused_method_parameters=false -sp_cleanup.remove_unused_private_fields=true -sp_cleanup.remove_unused_private_members=false -sp_cleanup.remove_unused_private_methods=true -sp_cleanup.remove_unused_private_types=true -sp_cleanup.replace_deprecated_calls=false -sp_cleanup.return_expression=false -sp_cleanup.simplify_lambda_expression_and_method_ref=false -sp_cleanup.single_used_field=false -sp_cleanup.sort_members=false -sp_cleanup.sort_members_all=false -sp_cleanup.standard_comparison=false -sp_cleanup.static_inner_class=false -sp_cleanup.strictly_equal_or_different=false -sp_cleanup.stringbuffer_to_stringbuilder=false -sp_cleanup.stringbuilder=false -sp_cleanup.stringbuilder_for_local_vars=false -sp_cleanup.stringconcat_stringbuffer_stringbuilder=false -sp_cleanup.stringconcat_to_textblock=false -sp_cleanup.substring=false -sp_cleanup.switch=false -sp_cleanup.system_property=false -sp_cleanup.system_property_boolean=false -sp_cleanup.system_property_file_encoding=false -sp_cleanup.system_property_file_separator=false -sp_cleanup.system_property_line_separator=false -sp_cleanup.system_property_path_separator=false -sp_cleanup.ternary_operator=false -sp_cleanup.try_with_resource=false -sp_cleanup.unlooped_while=false -sp_cleanup.unreachable_block=false -sp_cleanup.use_anonymous_class_creation=false -sp_cleanup.use_autoboxing=false -sp_cleanup.use_blocks=true -sp_cleanup.use_blocks_only_for_return_and_throw=false -sp_cleanup.use_directly_map_method=false -sp_cleanup.use_lambda=true -sp_cleanup.use_parentheses_in_expressions=true -sp_cleanup.use_string_is_blank=false -sp_cleanup.use_this_for_non_static_field_access=true -sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=false -sp_cleanup.use_this_for_non_static_method_access=false -sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true -sp_cleanup.use_unboxing=false -sp_cleanup.use_var=false -sp_cleanup.useless_continue=false -sp_cleanup.useless_return=false -sp_cleanup.valueof_rather_than_instantiation=false +org.eclipse.jdt.ui.text.custom_code_templates= diff --git a/dependencies.md b/dependencies.md index e0da0fc..031d8e7 100644 --- a/dependencies.md +++ b/dependencies.md @@ -10,46 +10,48 @@ ## Plugin Dependencies -| Dependency | License | -| ------------------------------------------------------- | ------------------------------------------- | -| [Apache Maven Clean Plugin][4] | [Apache-2.0][5] | -| [Apache Maven Install Plugin][6] | [Apache-2.0][5] | -| [Apache Maven Resources Plugin][7] | [Apache-2.0][5] | -| [Apache Maven Site Plugin][8] | [Apache-2.0][5] | -| [SonarQube Scanner for Maven][9] | [GNU LGPL 3][10] | -| [Apache Maven Toolchains Plugin][11] | [Apache-2.0][5] | -| [Apache Maven Compiler Plugin][12] | [Apache-2.0][5] | -| [Apache Maven Enforcer Plugin][13] | [Apache-2.0][5] | -| [Maven Flatten Plugin][14] | [Apache Software License][5] | -| [org.sonatype.ossindex.maven:ossindex-maven-plugin][15] | [ASL2][16] | -| [Maven Surefire Plugin][17] | [Apache-2.0][5] | -| [Versions Maven Plugin][18] | [Apache License, Version 2.0][5] | -| [duplicate-finder-maven-plugin Maven Mojo][19] | [Apache License 2.0][20] | -| [Apache Maven Artifact Plugin][21] | [Apache-2.0][5] | -| [Apache Maven Deploy Plugin][22] | [Apache-2.0][5] | -| [Apache Maven GPG Plugin][23] | [Apache-2.0][5] | -| [Apache Maven Source Plugin][24] | [Apache License, Version 2.0][5] | -| [Apache Maven Javadoc Plugin][25] | [Apache-2.0][5] | -| [Central Publishing Maven Plugin][26] | [The Apache License, Version 2.0][5] | -| [JaCoCo :: Maven Plugin][27] | [EPL-2.0][28] | -| [Quality Summarizer Maven Plugin][29] | [MIT License][30] | -| [error-code-crawler-maven-plugin][31] | [MIT License][32] | -| [Git Commit Id Maven Plugin][33] | [GNU Lesser General Public License 3.0][34] | -| [Project Keeper Maven plugin][35] | [The MIT License][36] | +| Dependency | License | +| ------------------------------------------------------- | ---------------------------------------------- | +| [SonarQube Scanner for Maven][4] | [GNU LGPL 3][5] | +| [Apache Maven Toolchains Plugin][6] | [Apache-2.0][7] | +| [Apache Maven Compiler Plugin][8] | [Apache-2.0][7] | +| [Project Keeper Maven plugin][9] | [The MIT License][10] | +| [OpenFastTrace Maven Plugin][11] | [GNU General Public License v3.0][12] | +| [Apache Maven Enforcer Plugin][13] | [Apache-2.0][7] | +| [Maven Flatten Plugin][14] | [Apache Software License][7] | +| [org.sonatype.ossindex.maven:ossindex-maven-plugin][15] | [ASL2][16] | +| [Maven Surefire Plugin][17] | [Apache-2.0][7] | +| [Versions Maven Plugin][18] | [Apache License, Version 2.0][7] | +| [duplicate-finder-maven-plugin Maven Mojo][19] | [Apache License 2.0][20] | +| [Apache Maven Artifact Plugin][21] | [Apache-2.0][7] | +| [Apache Maven Deploy Plugin][22] | [Apache-2.0][7] | +| [Apache Maven Source Plugin][23] | [Apache-2.0][7] | +| [Apache Maven Javadoc Plugin][24] | [Apache-2.0][7] | +| [spdx-maven-plugin Maven Plugin][25] | [The Apache Software License, Version 2.0][16] | +| [Build Helper Maven Plugin][26] | [The MIT License][27] | +| [Apache Maven GPG Plugin][28] | [Apache-2.0][7] | +| [Central Publishing Maven Plugin][29] | [The Apache License, Version 2.0][7] | +| [JaCoCo :: Maven Plugin][30] | [EPL-2.0][31] | +| [error-code-crawler-maven-plugin][32] | [MIT License][33] | +| [Git Commit Id Maven Plugin][34] | [GNU Lesser General Public License 3.0][35] | +| [Apache Maven Clean Plugin][36] | [Apache-2.0][7] | +| [Apache Maven Resources Plugin][37] | [Apache-2.0][7] | +| [Apache Maven Install Plugin][38] | [Apache-2.0][7] | +| [Apache Maven Site Plugin][39] | [Apache-2.0][7] | [0]: http://hamcrest.org/JavaHamcrest/ [1]: https://raw.githubusercontent.com/hamcrest/JavaHamcrest/master/LICENSE [2]: https://junit.org/ [3]: https://www.eclipse.org/legal/epl-v20.html -[4]: https://maven.apache.org/plugins/maven-clean-plugin/ -[5]: https://www.apache.org/licenses/LICENSE-2.0.txt -[6]: https://maven.apache.org/plugins/maven-install-plugin/ -[7]: https://maven.apache.org/plugins/maven-resources-plugin/ -[8]: https://maven.apache.org/plugins/maven-site-plugin/ -[9]: http://docs.sonarqube.org/display/PLUG/Plugin+Library/sonar-scanner-maven/sonar-maven-plugin -[10]: http://www.gnu.org/licenses/lgpl.txt -[11]: https://maven.apache.org/plugins/maven-toolchains-plugin/ -[12]: https://maven.apache.org/plugins/maven-compiler-plugin/ +[4]: https://docs.sonarsource.com/sonarqube-server/latest/extension-guide/developing-a-plugin/plugin-basics/sonar-scanner-maven/sonar-maven-plugin/ +[5]: http://www.gnu.org/licenses/lgpl.txt +[6]: https://maven.apache.org/plugins/maven-toolchains-plugin/ +[7]: https://www.apache.org/licenses/LICENSE-2.0.txt +[8]: https://maven.apache.org/plugins/maven-compiler-plugin/ +[9]: https://github.com/exasol/project-keeper/ +[10]: https://github.com/exasol/project-keeper/blob/main/LICENSE +[11]: https://github.com/itsallcode/openfasttrace-maven-plugin +[12]: https://www.gnu.org/licenses/gpl-3.0.html [13]: https://maven.apache.org/enforcer/maven-enforcer-plugin/ [14]: https://www.mojohaus.org/flatten-maven-plugin/ [15]: https://sonatype.github.io/ossindex-maven/maven-plugin/ @@ -60,17 +62,20 @@ [20]: http://www.apache.org/licenses/LICENSE-2.0.html [21]: https://maven.apache.org/plugins/maven-artifact-plugin/ [22]: https://maven.apache.org/plugins/maven-deploy-plugin/ -[23]: https://maven.apache.org/plugins/maven-gpg-plugin/ -[24]: https://maven.apache.org/plugins/maven-source-plugin/ -[25]: https://maven.apache.org/plugins/maven-javadoc-plugin/ -[26]: https://central.sonatype.org -[27]: https://www.jacoco.org/jacoco/trunk/doc/maven.html -[28]: https://www.eclipse.org/legal/epl-2.0/ -[29]: https://github.com/exasol/quality-summarizer-maven-plugin/ -[30]: https://github.com/exasol/quality-summarizer-maven-plugin/blob/main/LICENSE -[31]: https://github.com/exasol/error-code-crawler-maven-plugin/ -[32]: https://github.com/exasol/error-code-crawler-maven-plugin/blob/main/LICENSE -[33]: https://github.com/git-commit-id/git-commit-id-maven-plugin -[34]: http://www.gnu.org/licenses/lgpl-3.0.txt -[35]: https://github.com/exasol/project-keeper/ -[36]: https://github.com/exasol/project-keeper/blob/main/LICENSE +[23]: https://maven.apache.org/plugins/maven-source-plugin/ +[24]: https://maven.apache.org/plugins/maven-javadoc-plugin/ +[25]: https://github.com/spdx/spdx-maven-plugin +[26]: https://www.mojohaus.org/build-helper-maven-plugin/ +[27]: https://spdx.org/licenses/MIT.txt +[28]: https://maven.apache.org/plugins/maven-gpg-plugin/ +[29]: https://central.sonatype.org +[30]: https://www.jacoco.org/jacoco/trunk/doc/maven.html +[31]: https://www.eclipse.org/legal/epl-2.0/ +[32]: https://github.com/exasol/error-code-crawler-maven-plugin/ +[33]: https://github.com/exasol/error-code-crawler-maven-plugin/blob/main/LICENSE +[34]: https://github.com/git-commit-id/git-commit-id-maven-plugin +[35]: http://www.gnu.org/licenses/lgpl-3.0.txt +[36]: https://maven.apache.org/plugins/maven-clean-plugin/ +[37]: https://maven.apache.org/plugins/maven-resources-plugin/ +[38]: https://maven.apache.org/plugins/maven-install-plugin/ +[39]: https://maven.apache.org/plugins/maven-site-plugin/ diff --git a/doc/changes/changelog.md b/doc/changes/changelog.md index a73d5ed..fdda489 100644 --- a/doc/changes/changelog.md +++ b/doc/changes/changelog.md @@ -1,5 +1,6 @@ # Changes +* [1.0.3](changes_1.0.3.md) * [1.0.2](changes_1.0.2.md) * [1.0.1](changes_1.0.1.md) * [1.0.0](changes_1.0.0.md) diff --git a/doc/changes/changes_1.0.3.md b/doc/changes/changes_1.0.3.md new file mode 100644 index 0000000..0901664 --- /dev/null +++ b/doc/changes/changes_1.0.3.md @@ -0,0 +1,44 @@ +# Error Reporting Java 1.0.3, released 2025-10-01 + +Code name: Extract Specification + +## Summary + +This release adds user requirements and design, extracted with the [reverse-spec-skill](https://raw.githubusercontent.com/itsallcode/openfasttrace-ai-skills/refs/heads/main/skills/openfasttrace-reverse-specs/SKILL.md) of OpenFastTrace. + +We now build with Java 17 while still maintaining Java 11 binary compatibility. This allowed us to upgrade to JUnit 6. + +## Documentation + +* Reverse-engineered specification from user guide and code. + +## Dependency Updates + +### Test Dependency Updates + +* Updated `org.junit.jupiter:junit-jupiter-params:5.13.4` to `6.1.3` + +### Plugin Dependency Updates + +* Updated `com.exasol:error-code-crawler-maven-plugin:2.0.5` to `2.1.2` +* Updated `com.exasol:project-keeper-maven-plugin:5.4.3` to `5.7.6` +* Removed `com.exasol:quality-summarizer-maven-plugin:0.2.1` +* Updated `io.github.git-commit-id:git-commit-id-maven-plugin:9.0.2` to `10.0.1` +* Updated `org.apache.maven.plugins:maven-artifact-plugin:3.6.1` to `3.7.0` +* Updated `org.apache.maven.plugins:maven-compiler-plugin:3.14.1` to `3.16.0` +* Updated `org.apache.maven.plugins:maven-deploy-plugin:3.1.4` to `3.2.0` +* Updated `org.apache.maven.plugins:maven-enforcer-plugin:3.6.2` to `3.6.3` +* Updated `org.apache.maven.plugins:maven-install-plugin:3.1.4` to `3.2.0` +* Updated `org.apache.maven.plugins:maven-resources-plugin:3.3.1` to `3.5.0` +* Updated `org.apache.maven.plugins:maven-site-plugin:3.21.0` to `3.22.0` +* Updated `org.apache.maven.plugins:maven-source-plugin:3.2.1` to `3.4.0` +* Updated `org.apache.maven.plugins:maven-surefire-plugin:3.5.4` to `3.6.0` +* Updated `org.apache.maven.plugins:maven-toolchains-plugin:3.2.0` to `3.3.0` +* Added `org.codehaus.mojo:build-helper-maven-plugin:3.6.2` +* Updated `org.codehaus.mojo:flatten-maven-plugin:1.7.3` to `1.8.0` +* Updated `org.codehaus.mojo:versions-maven-plugin:2.19.1` to `2.22.0` +* Added `org.itsallcode:openfasttrace-maven-plugin:3.1.0` +* Updated `org.jacoco:jacoco-maven-plugin:0.8.14` to `0.8.15` +* Updated `org.sonarsource.scanner.maven:sonar-maven-plugin:5.2.0.4988` to `5.8.0.7211` +* Updated `org.sonatype.central:central-publishing-maven-plugin:0.9.0` to `0.11.0` +* Added `org.spdx:spdx-maven-plugin:1.0.4` diff --git a/doc/design/architecture_decisions.md b/doc/design/architecture_decisions.md new file mode 100644 index 0000000..06db059 --- /dev/null +++ b/doc/design/architecture_decisions.md @@ -0,0 +1,21 @@ +# Architecture Decisions + +## In-Memory Fluent Builder + +### How Are Error Messages Composed? + +The library uses a mutable fluent builder that defers rendering until `toString()`. + +#### Defer Rendering Until Builder Output +`dsn~defer-rendering-until-output~1` + +The system stores raw fragments and parameter definitions and performs placeholder replacement when the final string is requested. + +Rationale: + +Callers can define parameters before or after message fragments, while the final output remains deterministic. The builder makes the code more readable. It is functionally similar to Java's built-in `StringBuilder` which has the advantage of being well-known in the Java developer community. + +Covers: +- `constr~java-11-module-packaging~1` + +Needs: impl diff --git a/doc/design/building_block_view.md b/doc/design/building_block_view.md new file mode 100644 index 0000000..ecd807e --- /dev/null +++ b/doc/design/building_block_view.md @@ -0,0 +1,48 @@ +# Building Block View + +## Overview + +```plantuml +@startuml +hide empty members + +class ExaError <> +class ErrorMessageBuilder +class PlaceholderMatcher +class ParameterDefinitionList +class ParameterDefinition +class PlaceholdersFiller +class Mitigations +class Quoter + + +ExaError --> ErrorMessageBuilder : create builder +ErrorMessageBuilder *-- ParameterDefinitionList +ErrorMessageBuilder *-- "*" Mitigations +ParameterDefinitionList *-- "*" ParameterDefinition +ErrorMessageBuilder --> PlaceholdersFiller +PlaceholdersFiller --> ParameterDefinitionList +PlaceholdersFiller --> PlaceholderMatcher +PlaceholdersFiller --> Quoter +@enduml +``` + +The public facade creates builders. The builder owns accumulated text and delegates parsing, parameter lookup, substitution, and quoting to focused collaborators. + +## Building Blocks + +### Public Facade And Builder + +`ExaError` provides the static entry point. `ErrorMessageBuilder` accumulates the error code, message fragments, mitigations, and parameter definitions and assembles the final output. + +### Placeholder Processing + +`PlaceholderMatcher` exposes an iterable over regex matches. `Placeholder` parses the reference and switches and stores source indexes. `ParametersMapper` maps inline arguments to matched placeholders when message or mitigation text is added. + +### Parameter Model + +`ParameterDefinition` stores name, value, and description. `ParameterDefinitionList` provides first-match lookup and presence checks and intentionally tolerates absent or duplicate definitions. + +### Rendering And Quoting + +`PlaceholdersFiller` replaces placeholders or emits an unknown-placeholder diagnostic. `Quoter` formats nulls, collections, and scalar values according to automatic or explicit quoting. diff --git a/doc/design/constraints.md b/doc/design/constraints.md new file mode 100644 index 0000000..a3d6a9e --- /dev/null +++ b/doc/design/constraints.md @@ -0,0 +1,25 @@ +# Architecture Constraints + +## Technical Constraints + +The implementation is a Java library with no runtime dependencies declared in `pom.xml`. Java 11 is the minimum supported runtime and build target. Support follows the lifecycle of [Eclipse Adoptium OpenJDK releases](https://adoptium.net/support/). The library publishes the named module `error.reporting.java`. + +### Java 11 Module Packaging +`constr~java-11-module-packaging~1` + +The library remains usable on Java 11 and newer supported runtimes, and exports `com.exasol.errorreporting` from module `error.reporting.java`. + +Rationale: + +The generated parent sets `java.version` to 11 and `module-info.java` declares the module and export. The supported-runtime policy follows the [Adoptium support lifecycle](https://adoptium.net/support/) as it changes over time. + +Needs: dsn + +## Organizational Constraints + +No additional intentional organizational constraints were found in the repository. + +## Assumptions + +* The library is embedded in a consuming application rather than run as a standalone process. +* Error-code lifecycle and catalog generation are coordinated by consuming projects and the error-code crawler. diff --git a/doc/design/context_and_scope.md b/doc/design/context_and_scope.md new file mode 100644 index 0000000..12333a9 --- /dev/null +++ b/doc/design/context_and_scope.md @@ -0,0 +1,31 @@ +# Context and Scope + +## System Boundary + +Java Error Reporting includes the fluent error-message builder, placeholder parsing and matching, parameter metadata, value quoting, mitigation formatting, and the Java module declaration. It does not own error-code allocation, catalog persistence, application logging, exception transport, or user-interface presentation. + +## Users and Neighboring Systems + +* Java application code creates and renders error messages. +* Application users read the resulting strings. +* The error-code crawler Maven plugin parses builder invocations and parameter descriptions. +* Maven builds, tests, and publishes the library. + +## Supported Environment + +The project is built as a Java 11 Maven artifact and can be consumed on Java 11 or newer supported runtimes, either on the class path or through the declared Java module. Supported-runtime maintenance follows the [Eclipse Adoptium OpenJDK lifecycle](https://adoptium.net/support/). + +## External Interfaces + +The primary interface is the public API in `com.exasol.errorreporting`: `ExaError`, `ErrorMessageBuilder`, `ParameterDefinition`, `ParameterDefinitionList`, `Placeholder`, `PlaceholderMatcher`, and `Quoting`. + +## State and Persistence + +Builders hold message fragments, mitigations, and parameter definitions in memory. Rendering has no database, file, network, cache, or telemetry dependency. + +## Explicit Non-Goals + +* Allocating or validating globally unique error codes. +* Persisting an error catalog. +* Sending errors or tickets to remote services. +* Escaping arbitrary message syntax beyond the documented placeholder and quoting rules. diff --git a/doc/design/crosscutting_concepts.md b/doc/design/crosscutting_concepts.md new file mode 100644 index 0000000..2b409e8 --- /dev/null +++ b/doc/design/crosscutting_concepts.md @@ -0,0 +1,23 @@ +# Crosscutting Concepts + +## Domain Model + +An error message consists of an error code, zero or more message fragments, zero or more mitigations, and a set of named parameter definitions. A placeholder contains a reference and a quoting mode. A parameter definition contains a name, optional value, and optional catalog description. + +## Configuration + +There is no runtime configuration. Quoting is selected in placeholder text and error-code lifecycle configuration belongs to consuming projects. + +## Error Handling + +Missing placeholders become visible diagnostic text rather than exceptions. Null values become ``. The builder does not validate error-code syntax. + +An important design rule in this project is that it is always better to have incomplete error output than missing output. Especially, if the missing part is highlighted. + +## Logging and Observability + +The library emits no logs, metrics, traces, or telemetry. Its observable result is the returned string. + +## Security and Privacy + +The library has no authentication, authorization, storage, or network boundary. Parameter values are inserted into returned strings; callers remain responsible for avoiding secrets or sensitive data in error messages. diff --git a/doc/design/deployment_view.md b/doc/design/deployment_view.md new file mode 100644 index 0000000..82e5aaa --- /dev/null +++ b/doc/design/deployment_view.md @@ -0,0 +1,29 @@ +# Deployment View + +## Deployment Environment + +The system is packaged as a Maven Java library and loaded inside a consuming JVM application. + +## Runtime Nodes + +* Consuming JVM application +* Java Error Reporting library JAR +* Optional Maven build and error-code crawler tooling + +## Deployment Diagram + +```plantuml +@startuml +node "Consuming JVM" { + artifact "error-reporting-java JAR" as Jar + component "Application" as App + App --> Jar +} +node "Maven Build" as Maven +Maven ..> Jar : builds / publishes +@enduml +``` + +## Deployment Strategy + +Maven compiles, tests, verifies, and publishes the library. At runtime the library performs only in-process string construction and does not initiate network calls or require external state. diff --git a/doc/design/design.md b/doc/design/design.md new file mode 100644 index 0000000..066b671 --- /dev/null +++ b/doc/design/design.md @@ -0,0 +1,59 @@ +# Design + +This document describes the architecture of Java Error Reporting. + +The user perspective, features, requirements, and acceptance scenarios are defined in [User and System Requirements](../requirements/requirements.md). This design focuses on the public Java API, the rendering pipeline, and the packaging structure inferred from the source and tests. + +## Structure + +### Introduction and Goals + +The library realizes error-message construction, placeholder substitution, quoting, mitigation formatting, and Java-module integration through a small in-memory builder and rendering pipeline. + +### Architecture Constraints + +See [Architecture Constraints](constraints.md). + +### Context and Scope + +See [Context and Scope](context_and_scope.md). + +### Solution Strategy + +See [Solution Strategy](solution_strategy.md). + +### Building Block View + +See [Building Block View](building_block_view.md). + +### Runtime View + +See [Runtime View](runtime_view.md). + +### Deployment View + +See [Deployment View](deployment_view.md). + +### Crosscutting Concepts + +See [Crosscutting Concepts](crosscutting_concepts.md). + +### Architecture Decisions + +See [Architecture Decisions](architecture_decisions.md). + +### Quality Requirements + +See [Quality Requirements](quality_requirements.md). + +### Risks and Technical Debt + +See [Risks and Technical Debt](risks_and_technical_debt.md). + +### Glossary + +See [Glossary](glossary.md). + +### Open Issues + +See [Open Issues](open_issues.md). diff --git a/doc/design/glossary.md b/doc/design/glossary.md new file mode 100644 index 0000000..8b506b1 --- /dev/null +++ b/doc/design/glossary.md @@ -0,0 +1,17 @@ +# Glossary + +###### Builder + +The mutable `ErrorMessageBuilder` used to accumulate and render an error message. + +###### Parameter Definition + +The name, value, and optional description associated with a placeholder reference. + +###### Quoting Mode + +The `Quoting` value controlling automatic, single-quote, double-quote, or unquoted output. + +###### Catalog Tooling + +The external error-code crawler Maven plugin that parses builder invocations and parameter descriptions. diff --git a/doc/design/open_issues.md b/doc/design/open_issues.md new file mode 100644 index 0000000..c4ef8dc --- /dev/null +++ b/doc/design/open_issues.md @@ -0,0 +1,25 @@ +# Open Issues + +## Requirements And Design Mismatches + +* The requirement for crawler-compatible parameter descriptions has no crawler integration test in this repository. +* The Java module requirement is supported by `module-info.java`, but no modular runtime test is present. + +## Implemented Behavior Without Requirement + +* `ParameterDefinitionList` intentionally returns the first duplicate definition; this fault-tolerance detail is documented in code and tests but is not currently a separate user-level requirement. +* `PlaceholderMatcher` is a public iterable API beyond the primary builder workflow; its iterator contract is tested but only indirectly represented in the system requirements. + +## Requirement Without Observed Implementation + +* None of the drafted runtime scenarios lacks corresponding implementation evidence. + +## Contradictions Between Sources + +* README output examples contain stray backticks and inconsistent sample values, while tests define the exact implementation output. +* README lifecycle guidance mentions `error_code_config.yml`, but that file and enforcement logic are outside this repository. + +## Decisions Needed + +* Confirm whether crawler integration and module resolution need dedicated integration tests. +* OFT implementation and unit-test markers are now present for the covered design items; the module export item still lacks a modular runtime test. diff --git a/doc/design/quality_requirements.md b/doc/design/quality_requirements.md new file mode 100644 index 0000000..bbba0f4 --- /dev/null +++ b/doc/design/quality_requirements.md @@ -0,0 +1,25 @@ +# Quality Requirements + +## Requirement Quality + +Requirements use `feat` → `req` → `scn` and design uses `dsn`. The draft scenarios are intended to be directly verifiable from exact rendered strings or public API observations. + +## Code Quality + +The project uses Maven, Project Keeper, JavaDoc-style API documentation, and a Java module descriptor. Source is organized by focused package-private collaborators around the public builder API. Java 11 remains the minimum runtime and build target; newer supported runtimes follow the [Eclipse Adoptium OpenJDK lifecycle](https://adoptium.net/support/). + +## Test Quality + +JUnit Jupiter parameterized tests and Hamcrest assertions cover builder output, placeholder iteration, parameter metadata, and all quoting modes across representative Java types and collections. + +## Dependency Policy + +Runtime dependencies are absent from the project POM. Test dependencies are JUnit Jupiter Params and Hamcrest; build plugins provide verification, analysis, packaging, and catalog tooling. + +## Static Analysis and Security Gates + +Project Keeper configures Maven verification, quality summarization, dependency/security checks, JaCoCo, and Sonar-related build tooling through the generated parent. Exact gate thresholds are not stated in this repository. + +## Testability and Coverage + +The deterministic, in-memory design supports unit testing without external services. No integration or system-test suite is present; crawler compatibility and module resolution are currently evidenced by configuration and source rather than dedicated tests. diff --git a/doc/design/risks_and_technical_debt.md b/doc/design/risks_and_technical_debt.md new file mode 100644 index 0000000..56e2177 --- /dev/null +++ b/doc/design/risks_and_technical_debt.md @@ -0,0 +1,7 @@ +# Risks and Technical Debt + +## Risks + +* Placeholder syntax is parsed by a regular expression and may produce surprising results for malformed or nested braces. +* Error messages can expose any supplied value because the library performs no redaction or sensitive-data policy enforcement. +* Exact text output is a compatibility surface; changing automatic quoting for a Java type can break consumers that parse messages. diff --git a/doc/design/runtime_view.md b/doc/design/runtime_view.md new file mode 100644 index 0000000..c0fe682 --- /dev/null +++ b/doc/design/runtime_view.md @@ -0,0 +1,123 @@ +# Runtime View + +## Builder Rendering + +### Render A Code And Message +`dsn~render-code-and-message~1` + +**Given** a builder contains an error code and accumulated message text +**When** `toString()` is called +**Then** the builder emits the code, and the rendered message. + +Covers: +- `scn~render-code-without-message~1` +- `scn~render-appended-message-text~1` + +Needs: impl, utest + +### Resolve Explicit And Inline Parameters +`dsn~resolve-parameters~1` + +**Given** message or mitigation text contains placeholders +**When** explicit definitions and/or inline arguments are mapped +**Then** definitions are stored by reference and inline arguments are assigned in placeholder order. + +Covers: +- `scn~substitute-explicit-parameter~1` +- `scn~substitute-inline-arguments-in-order~1` + +Needs: impl, utest + +### Report Unknown And Null Values +`dsn~report-unknown-and-null-values~1` + +**Given** a placeholder has no definition or has a null value +**When** the text is rendered +**Then** the output contains either `UNKNOWN PLACEHOLDER('')` or ``. + +Covers: +- `scn~identify-unknown-placeholder~1` +- `scn~render-null-parameter~1` + +Needs: impl, utest + +### Apply Scalar Quoting +`dsn~apply-scalar-quoting~1` + +**Given** a non-null scalar parameter and a placeholder quoting mode +**When** the value is rendered +**Then** `Quoter` applies automatic type-based quoting or the selected explicit mode. + +Covers: +- `scn~automatically-quote-string~1` +- `scn~apply-explicit-quoting-modes~1` + +Needs: impl, utest + +### Apply Recursive Collection Quoting +`dsn~apply-collection-quoting~1` + +**Given** a collection parameter +**When** the value is rendered +**Then** `Quoter` renders bracketed elements separated by comma-space and recursively applies the mode. + +Covers: +- `scn~render-collection~1` + +Needs: impl, utest + +### Render Mitigation Advice +`dsn~render-mitigations~1` + +**Given** zero, one, or multiple mitigations have been added +**When** the builder is rendered +**Then** zero adds nothing, one is appended inline, and multiple use the ordered `Known mitigations` list format. + +Covers: +- `scn~render-single-mitigation~1` +- `scn~render-multiple-mitigations~1` + +Needs: impl, utest + +### Render Ticket Advice +`dsn~render-ticket-mitigation~1` + +**Given** a builder with a message +**When** `ticketMitigation()` is called +**Then** it adds the "internal-error" GitHub issue raising advice. + +Covers: +- `scn~render-ticket-mitigation~1` + +Needs: impl, utest + +## Public Integration + +### Expose Parameter Metadata +`dsn~expose-parameter-metadata~1` + +**Given** a `ParameterDefinition` has a description +**When** a catalog tool queries it +**Then** the name, value, and description are available through the public model. + +Rationale: + +One of the main points of uniform error definition is that you can apply a [crawler](https://github.com/exasol/error-code-crawler-maven-plugin) to assemble an error catalog. + +Covers: +- `scn~expose-parameter-description~1` + +Needs: impl, utest + +### Export The Java Module Package +`dsn~export-java-module-package~1` + +**Given** a modular client resolves the published artifact +**When** it reads module metadata +**Then** module `error.reporting.java` exports `com.exasol.errorreporting`. + +Covers: +- `scn~resolve-java-module-export~1` +- `constr~java-11-module-packaging~1` + +Needs: impl, utest diff --git a/doc/design/solution_strategy.md b/doc/design/solution_strategy.md new file mode 100644 index 0000000..028c008 --- /dev/null +++ b/doc/design/solution_strategy.md @@ -0,0 +1,22 @@ +# Solution Strategy + +## Main Technical Approach + +The library uses a fluent, mutable `ErrorMessageBuilder`. It accumulates message text and mitigations, stores parameter definitions in insertion order, and renders only when `toString()` is called. `PlaceholderMatcher` identifies placeholders, `Placeholder` stores their reference and quoting mode, and `PlaceholdersFiller` substitutes values. `Quoter` centralizes scalar and collection formatting. + +## Key Quality Drivers + +* Small API surface and fluent use in error-definition code. +* Deterministic text output suitable for users, tests, and catalog tooling. +* Fault tolerance for missing, duplicate, unnamed, and null parameters. +* No runtime service or persistence dependencies. +* Java-module compatibility. +* Low runtime overhead when rendering messages. + +## Reuse of Existing Facilities + +The implementation uses the Java standard library for collections, regular expressions, URLs, URIs, files, paths, and module packaging. JUnit Jupiter and Hamcrest verify behavior in tests; Maven and Project Keeper drive the build. + +## Data and Control Flow Strategy + +Message and mitigation calls append raw text and map inline arguments by placeholder order. Explicit `parameter` calls add definitions. At render time, each text fragment is scanned independently, placeholders are parsed, values are looked up by name, and the selected quoting strategy produces the final string. diff --git a/doc/requirements/requirements.md b/doc/requirements/requirements.md new file mode 100644 index 0000000..4b8a85e --- /dev/null +++ b/doc/requirements/requirements.md @@ -0,0 +1,453 @@ +# System Requirements + +## Introduction + +Java Error Reporting is a small library for constructing Exasol error messages in application code. A caller starts with an error code, adds a message, supplies named or inline parameter values, and optionally adds one or more mitigations. The resulting string contains predictable placeholder substitution and quoting and can be consumed by users. The source code can be consumed by the error-code crawler Maven plugin. + +## Goals + +* Construct consistent, readable Exasol error messages. +* Make parameterized messages concise while retaining an explicit named-parameter API. +* Quote values according to their type or an explicit placeholder switch. +* Communicate one or more possible mitigations, including a standard ticket message. +* Provide a public Java API that can be used from modular applications and tooling. +* Provide a base for publishing errors to an error catalog. +* The API must not throw exceptions at runtime to avoid suppressing other error messages which would make debugging harder. +* Low runtime overhead for rendering. + +## Notation + +This document uses OpenFastTrace specification items to express product features, user requirements, and acceptance scenarios. Each specification item has a unique identifier in the form `~~`. + +Feature items use `feat`, user requirements use `req`, and acceptance scenarios use `scn`. Design items under `doc/design/` cover the scenarios with `dsn`. + +## Out of Scope + +This library does not enforce unique error IDs in any way. It is the responsibility of the caller to assign and maintain IDs. + +Also, applying the [crawler](https://github.com/exasol/error-code-crawler-java) and publishing to an [error catalog](https://github.com/exasol/error-code-crawler-maven-plugin) are outside the scope of this project. The crawler checks for uniqueness of IDs. + +## Terms and Abbreviations + +###### Error Code + +The stable identifier at the beginning of a generated error message, for example `E-TEST-1`. + +###### Placeholder + +A double-curly-bracket expression in error messages or mitigations such as `{{input}}` that identifies a value to insert into text. + +###### Mitigation + +Advice appended to an error message that explains how a user can resolve or avoid the error. + +###### Automatic Quoting + +Quoting selected from the runtime type of a parameter value. + +## User Roles + +###### Java Application Developer + +Uses the fluent API to define and render error messages in application code. + +###### Error Catalog Maintainer + +Uses parameter descriptions and stable error codes as inputs to the error-code crawler and catalog lifecycle. + +Uses the error code crawler to +* Validate error codes +* Generate a report for the error catalog + +###### Application User + +Reads the rendered error message and its mitigation advice. + +## Features + +### Error Message Construction +`feat~error-message-construction~1` + +The library constructs a rendered message from an Exasol error code, message text, parameters, and optional mitigation advice. + +Needs: req + +### Parameter Substitution +`feat~parameter-substitution~1` + +The library replaces named placeholders with supplied values in messages and mitigations. + +Needs: req + +### Value Quoting +`feat~value-quoting~1` + +The library presents parameter values with automatic or explicitly selected quoting. + +Needs: req + +### Mitigation Advice +`feat~mitigation-advice~1` + +The library appends one or more mitigation messages, including a standard internal-error ticket mitigation. + +Needs: req + +### Public Java Integration +`feat~public-java-integration~1` + +The library exposes its builder and supporting value types as a reusable Java module and preserves parameter metadata for catalog tooling. + +Needs: req + +## User Requirements + +### Start A Message With Its Error Code +`req~start-message-with-error-code~1` + +The caller can create a builder with an error code, and rendering a builder without message text returns the error code unchanged. + +Rationale: + +Every error must retain a stable code, including messages that contain no additional text. + +Covers: +- `feat~error-message-construction~1` + +Needs: scn + +### Append Message Text Fluently +`req~append-message-text-fluently~1` + +The caller can append message fragments through repeated fluent `message` calls, and the rendered result places the complete message after the error code separated by `: `. + +Rationale: + +The README presents the builder as a fluent API and the implementation accumulates message fragments. + +Covers: +- `feat~error-message-construction~1` + +Needs: scn + +### Define Named Parameters Explicitly +`req~define-named-parameters~1` + +The caller can associate a name with a value through `parameter`, and the same name can be referenced from message or mitigation text. + +Rationale: + +The explicit API supports readable code and an optional catalog description argument. + +Covers: +- `feat~parameter-substitution~1` + +Needs: scn + +### Map Inline Arguments By Placeholder Order +`req~map-inline-arguments-by-order~1` + +The caller can pass values directly to `message` or `mitigation`; values map to placeholders in textual order, including unnamed placeholders. + +Rationale: + +This convenience API was introduced in version 0.3.0. + +Covers: +- `feat~parameter-substitution~1` + +Needs: scn + +### Render Unknown Placeholders Explicitly +`req~render-unknown-placeholders-explicitly~1` + +When no value is defined for a placeholder, rendering preserves an explicit `UNKNOWN PLACEHOLDER('')` diagnostic in its place. + +Rationale: + +The behavior is asserted for named and unnamed placeholders and avoids silently producing an incomplete error message. + +Covers: +- `feat~parameter-substitution~1` + +Needs: scn + +### Render Null Values +`req~render-null-values~1` + +When a referenced value is null or absent from a `ParameterDefinition`, rendering uses ``. + +Rationale: + +Visualizing null values is better in an error reporting library than rising `NullPointerExceptions`. + +Covers: +- `feat~parameter-substitution~1` + +Needs: scn + +### Apply Automatic Quoting By Type +`req~apply-automatic-quoting~1` + +With no quoting switch, + +1. strings, characters, paths, files, URLs, and URIs are enclosed in single quotes +2. other non-null values use their string representation +3. null uses ``. + +Rationale: + +The README defines automatic quoting as the default and lists the supported types. + +Covers: +- `feat~value-quoting~1` + +Needs: scn + +### Support Explicit Quoting Switches +`req~support-explicit-quoting-switches~1` + +The placeholder switches `u`, `q`, and `d` select unquoted, forced single-quoted, and forced double-quoted output respectively; when switches conflict, `u` has precedence over `q`, which has precedence over `d`. + +Rationale: + +Explicit switches let callers control presentation independently of the runtime type, while preserving the legacy `uq` behavior. + +Covers: +- `feat~value-quoting~1` + +Needs: scn + +### Render Collections Recursively +`req~render-collections-recursively~1` + +When a parameter is a collection, rendering encloses the elements in brackets, separates them with comma-space, and applies the selected quoting mode to each element. + +Covers: +- `feat~value-quoting~1` + +Needs: scn + +### Append A Single Mitigation +`req~append-single-mitigation~1` + +The caller can append one mitigation, and rendering places it after the message separated by a space, with its placeholders resolved using the same parameter rules as the message. + +Covers: +- `feat~mitigation-advice~1` + +Needs: scn + +### Format Multiple Mitigations As A List +`req~format-multiple-mitigations~1` + +When multiple mitigations are appended, rendering adds ` Known mitigations:` followed by one `* ` list item per mitigation in insertion order. + +Covers: +- `feat~mitigation-advice~1` + +Needs: scn + +### Provide A Ticket Mitigation +`req~provide-ticket-mitigation~1` + +The caller can append the standard internal-error mitigation through `ticketMitigation`. + +Rationale: + +The convenience API was introduced specifically for errors whose only mitigation is opening a ticket. + +Covers: +- `feat~mitigation-advice~1` + +Needs: scn + +### Preserve Parameter Metadata +`req~preserve-parameter-metadata~1` + +The parameter model exposes a name, value, and optional description so catalog tooling can inspect parameter descriptions independently of rendered output. + +Covers: +- `feat~public-java-integration~1` + +Needs: scn + +### Expose The Library As A Java Module +`req~expose-java-module~1` + +The published library exposes the `com.exasol.errorreporting` package from the `error.reporting.java` module. + +Covers: +- `feat~public-java-integration~1` + +Needs: scn + +## Acceptance Scenarios + +### Render A Code Without Message Text +`scn~render-code-without-message~1` + +**Given** a builder created with `E-ERJ-TEST-1` +**When** the builder is rendered without message text +**Then** the result is `E-ERJ-TEST-1` + +Covers: +- `req~start-message-with-error-code~1` + +Needs: dsn + +### Render Appended Message Text +`scn~render-appended-message-text~1` + +**Given** a builder created with `E-ERJ-TEST-1` +**When** the caller appends `Test ` and then `message.` +**Then** the result is `E-ERJ-TEST-1: Test message.` + +Covers: +- `req~append-message-text-fluently~1` + +Needs: dsn + +### Substitute An Explicit Parameter +`scn~substitute-explicit-parameter~1` + +**Given** message text `Test message {{name}}` and an explicit parameter `name` with value `Ada` +**When** the builder is rendered +**Then** the placeholder is replaced with the quoted value `'Ada'` + +Covers: +- `req~define-named-parameters~1` + +Needs: dsn + +### Substitute Inline Arguments In Order +`scn~substitute-inline-arguments-in-order~1` + +**Given** message text `{{first}} and {{second}}` +**When** the caller passes `one` and `2` directly to `message` +**Then** the result contains `'one' and 2` in that order + +Covers: +- `req~map-inline-arguments-by-order~1` + +Needs: dsn + +### Identify An Unknown Placeholder +`scn~identify-unknown-placeholder~1` + +**Given** message text `test {{unknown}}` with no parameter named `unknown` +**When** the builder is rendered +**Then** the result contains `UNKNOWN PLACEHOLDER('unknown')` + +Covers: +- `req~render-unknown-placeholders-explicitly~1` + +Needs: dsn + +### Render A Null Parameter +`scn~render-null-parameter~1` + +**Given** a referenced parameter whose value is null +**When** the builder is rendered +**Then** the placeholder is replaced with `` + +Covers: +- `req~render-null-values~1` + +Needs: dsn + +### Automatically Quote A String +`scn~automatically-quote-string~1` + +**Given** a string parameter with value `value` and no switch +**When** the placeholder is rendered +**Then** the value appears as `'value'` + +Covers: +- `req~apply-automatic-quoting~1` + +Needs: dsn + +### Apply Explicit Quoting Modes +`scn~apply-explicit-quoting-modes~1` + +**Given** a numeric parameter with value `42` +**When** it is rendered once with `|u`, once with `|q`, and once with `|d` +**Then** the outputs are `42`, `'42'`, and `"42"` respectively + +Covers: +- `req~support-explicit-quoting-switches~1` + +Needs: dsn + +### Render A Collection +`scn~render-collection~1` + +**Given** a collection containing `1` and the string `test` +**When** it is rendered with automatic quoting +**Then** the result is `[1, 'test']` + +Covers: +- `req~render-collections-recursively~1` + +Needs: dsn + +### Render A Single Mitigation +`scn~render-single-mitigation~1` + +**Given** message `Something went wrong.` and mitigation `Fix it.` +**When** the builder is rendered +**Then** the result ends with `Something went wrong. Fix it.` + +Covers: +- `req~append-single-mitigation~1` + +Needs: dsn + +### Render Multiple Mitigations +`scn~render-multiple-mitigations~1` + +**Given** mitigations `Fix it.` and `Contact support.` in that order +**When** the builder is rendered +**Then** the result contains `Known mitigations:` and two ordered `* ` list items + +Covers: +- `req~format-multiple-mitigations~1` + +Needs: dsn + +### Render The Ticket Mitigation +`scn~render-ticket-mitigation~1` + +**Given** a builder with a message +**When** the caller invokes `ticketMitigation` +**Then** the standard internal-error instruction to report a GitHub issue is appended + +Covers: +- `req~provide-ticket-mitigation~1` + +Needs: dsn + +### Expose Parameter Description Metadata +`scn~expose-parameter-description~1` + +**Given** a parameter definition built with description `small blue thing` +**When** its description is queried +**Then** `getDescription()` returns that description + +Covers: +- `req~preserve-parameter-metadata~1` + +Needs: dsn + +### Resolve The Java Module Export +`scn~resolve-java-module-export~1` + +**Given** the packaged library is used as a Java module +**When** a client resolves module `error.reporting.java` +**Then** package `com.exasol.errorreporting` is exported + +Covers: +- `req~expose-java-module~1` + +Needs: dsn diff --git a/pk_generated_parent.pom b/pk_generated_parent.pom index 73cc8a1..1ef7928 100644 --- a/pk_generated_parent.pom +++ b/pk_generated_parent.pom @@ -3,7 +3,7 @@ 4.0.0 com.exasol error-reporting-java-generated-parent - 1.0.2 + 1.0.3 pom UTF-8 @@ -13,6 +13,7 @@ exasol https://sonarcloud.io + false true false false @@ -41,36 +42,50 @@ + + + + org.apache.maven.plugins + maven-clean-plugin + 3.5.0 + + + org.apache.maven.plugins + maven-install-plugin + 3.2.0 + + + org.apache.maven.plugins + maven-resources-plugin + 3.5.0 + + + org.apache.maven.plugins + maven-site-plugin + 3.22.0 + + + org.codehaus.mojo + exec-maven-plugin + 3.6.4 + + + true + + + + + - - org.apache.maven.plugins - maven-clean-plugin - 3.5.0 - - - org.apache.maven.plugins - maven-install-plugin - 3.1.4 - - - org.apache.maven.plugins - maven-resources-plugin - 3.3.1 - - - org.apache.maven.plugins - maven-site-plugin - 3.21.0 - org.sonarsource.scanner.maven sonar-maven-plugin - 5.2.0.4988 + 5.8.0.7211 org.apache.maven.plugins maven-toolchains-plugin - 3.2.0 + 3.3.0 @@ -89,10 +104,9 @@ org.apache.maven.plugins maven-compiler-plugin - 3.14.1 + 3.16.0 - ${java.version} - ${java.version} + ${java.version} true -Xlint:all @@ -103,7 +117,7 @@ org.apache.maven.plugins maven-enforcer-plugin - 3.6.2 + 3.6.3 enforce-maven @@ -126,7 +140,7 @@ org.codehaus.mojo flatten-maven-plugin - 1.7.3 + 1.8.0 true oss @@ -154,6 +168,8 @@ 3.2.0 ossindex + + ${ossindexSkip} @@ -168,18 +184,23 @@ org.apache.maven.plugins maven-surefire-plugin - 3.5.4 + 3.6.0 - - -Djava.util.logging.config.file=src/test/resources/logging.properties ${argLine} + ${argLine} + + true + + + + src/test/resources/logging.properties + ${test.excludeTags} org.codehaus.mojo versions-maven-plugin - 2.19.1 + 2.22.0 display-updates @@ -234,7 +255,7 @@ org.apache.maven.plugins maven-artifact-plugin - 3.6.1 + 3.7.0 check-build-plan @@ -248,38 +269,15 @@ org.apache.maven.plugins maven-deploy-plugin - 3.1.4 + 3.2.0 true - - org.apache.maven.plugins - maven-gpg-plugin - 3.2.8 - - - sign-artifacts - verify - - sign - - - - --pinentry-mode - loopback - - - - - org.apache.maven.plugins maven-source-plugin - - 3.2.1 + 3.4.0 attach-sources @@ -303,18 +301,94 @@ UTF-8 + en true true true true - ${java.version} + ${java.version} + true + + + + + org.spdx + spdx-maven-plugin + 1.0.4 + + + build-spdx + package + + createSPDX + + + + + build + + true + true + true + true + false + false + Copyright (c) Exasol + false + JSON-LD + ${project.build.directory}/site/${project.groupId}.${project.artifactId}-${project.version}.spdx3.json + + + org.codehaus.mojo + build-helper-maven-plugin + 3.6.2 + + + attach-spdx-sbom + package + + attach-artifact + + + + + ${project.build.directory}/site/${project.groupId}.${project.artifactId}-${project.version}.spdx3.json + spdx + sbom + + + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 3.2.8 + + + sign-artifacts + verify + + sign + + + true + + --pinentry-mode + loopback + + + + + org.sonatype.central central-publishing-maven-plugin - 0.9.0 + 0.11.0 true maven-central-portal @@ -328,7 +402,7 @@ org.jacoco jacoco-maven-plugin - 0.8.14 + 0.8.15 prepare-agent @@ -366,23 +440,10 @@ - - com.exasol - quality-summarizer-maven-plugin - 0.2.1 - - - summarize-metrics - - summarize - - - - com.exasol error-code-crawler-maven-plugin - 2.0.5 + 2.1.2 verify @@ -395,7 +456,7 @@ io.github.git-commit-id git-commit-id-maven-plugin - 9.0.2 + 10.0.1 get-the-git-infos diff --git a/pom.xml b/pom.xml index 96356af..8829a67 100644 --- a/pom.xml +++ b/pom.xml @@ -2,12 +2,13 @@ 4.0.0 error-reporting-java - 1.0.2 + 1.0.3 error-reporting-java Builder for exasol error codes. https://github.com/exasol/error-reporting-java/ true + 17 @@ -19,8 +20,7 @@ org.junit.jupiter junit-jupiter-params - - 5.13.4 + 6.1.3 test @@ -29,7 +29,7 @@ com.exasol project-keeper-maven-plugin - 5.4.3 + 5.7.6 @@ -38,12 +38,41 @@ + + org.itsallcode + openfasttrace-maven-plugin + 3.1.0 + + + org.apache.maven.plugins + maven-enforcer-plugin + 3.6.3 + + + enforce-maven + + + + 3.9.9 + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 11 + + error-reporting-java-generated-parent com.exasol - 1.0.2 + 1.0.3 pk_generated_parent.pom diff --git a/src/main/java/com/exasol/errorreporting/ErrorMessageBuilder.java b/src/main/java/com/exasol/errorreporting/ErrorMessageBuilder.java index 5da462a..8812500 100644 --- a/src/main/java/com/exasol/errorreporting/ErrorMessageBuilder.java +++ b/src/main/java/com/exasol/errorreporting/ErrorMessageBuilder.java @@ -103,6 +103,7 @@ public ErrorMessageBuilder mitigation(final String mitigation, final Object... a * * @return self for fluent programming */ + // [impl->dsn~render-ticket-mitigation~1] public ErrorMessageBuilder ticketMitigation() { mitigation("This is an internal error that should not happen. Please report it by opening a GitHub issue."); return this; @@ -111,8 +112,11 @@ public ErrorMessageBuilder ticketMitigation() { /** * Build the error message. * - * @return built error massage string + * @return built error message string */ + // [impl->dsn~render-code-and-message~1] + // [impl->dsn~render-mitigations~1] + // [impl->dsn~defer-rendering-until-output~1] @Override public String toString() { final StringBuilder result = new StringBuilder(); diff --git a/src/main/java/com/exasol/errorreporting/ParameterDefinition.java b/src/main/java/com/exasol/errorreporting/ParameterDefinition.java index 0188bc4..603c4a5 100644 --- a/src/main/java/com/exasol/errorreporting/ParameterDefinition.java +++ b/src/main/java/com/exasol/errorreporting/ParameterDefinition.java @@ -50,6 +50,7 @@ public Object getValue() { * * @return description of the parameter */ + // [impl->dsn~expose-parameter-metadata~1] public String getDescription() { return this.description; } diff --git a/src/main/java/com/exasol/errorreporting/ParametersMapper.java b/src/main/java/com/exasol/errorreporting/ParametersMapper.java index 2580637..2acda68 100644 --- a/src/main/java/com/exasol/errorreporting/ParametersMapper.java +++ b/src/main/java/com/exasol/errorreporting/ParametersMapper.java @@ -17,6 +17,7 @@ class ParametersMapper { * @param parameters parameters to be mapped * @param errorMessageBuilder {@link ErrorMessageBuilder} to add the parameters to */ + // [impl->dsn~resolve-parameters~1] static void mapParametersByName(final String text, final Object[] parameters, final ErrorMessageBuilder errorMessageBuilder) { new ParametersMapper(text, parameters, errorMessageBuilder).mapParameters(); diff --git a/src/main/java/com/exasol/errorreporting/PlaceholdersFiller.java b/src/main/java/com/exasol/errorreporting/PlaceholdersFiller.java index 1d0da7e..f832472 100644 --- a/src/main/java/com/exasol/errorreporting/PlaceholdersFiller.java +++ b/src/main/java/com/exasol/errorreporting/PlaceholdersFiller.java @@ -70,6 +70,7 @@ private String getFullMessage() { return this.result.toString(); } + // [impl->dsn~report-unknown-and-null-values~1] private String getPlaceholderFilling(final Placeholder placeholder) { if (this.isParameterPresent(placeholder)) { return getPresentParameterPlaceholderFilling(placeholder); @@ -94,4 +95,4 @@ private String quoteParameterValue(final Placeholder placeholder) { private String getUnknownPlaceholderTextFor(final Placeholder placeholder) { return "UNKNOWN PLACEHOLDER('" + placeholder.getReference() + "')"; } -} \ No newline at end of file +} diff --git a/src/main/java/com/exasol/errorreporting/Quoter.java b/src/main/java/com/exasol/errorreporting/Quoter.java index d0dfb29..b0aeaf0 100644 --- a/src/main/java/com/exasol/errorreporting/Quoter.java +++ b/src/main/java/com/exasol/errorreporting/Quoter.java @@ -19,6 +19,8 @@ private Quoter() { * @param quoting quoting style to be used * @return quoted object */ + // [impl->dsn~apply-scalar-quoting~1] + // [impl->dsn~apply-collection-quoting~1] static String quoteObject(final Object object, final Quoting quoting) { if (object == null) { return ""; diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index fa6349b..c9e6924 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -1,6 +1,7 @@ /** * This module provides a Java-Builder for Exasol error messages. */ +// [impl->dsn~export-java-module-package~1] module error.reporting.java { exports com.exasol.errorreporting; } diff --git a/src/test/java/com/exasol/errorreporting/ErrorMessageBuilderTest.java b/src/test/java/com/exasol/errorreporting/ErrorMessageBuilderTest.java index 34d1d65..2e07413 100644 --- a/src/test/java/com/exasol/errorreporting/ErrorMessageBuilderTest.java +++ b/src/test/java/com/exasol/errorreporting/ErrorMessageBuilderTest.java @@ -17,12 +17,14 @@ void afterEach() { } @Test + // [utest->dsn~render-code-and-message~1] void testMessage() { final String message = new ErrorMessageBuilder("E-ERJ-TEST-1").message("Test message.").toString(); assertThat(message, equalTo("E-ERJ-TEST-1: Test message.")); } @Test + // [utest->dsn~resolve-parameters~1] void testMessageWithParameter() { final String message = new ErrorMessageBuilder("E-ERJ-TEST-1") .message("Test message {{myPlaceholder}} and a number {{number}}.") @@ -31,6 +33,7 @@ void testMessageWithParameter() { } @Test + // [utest->dsn~report-unknown-and-null-values~1] void testMessageWithNullParameter() { final String message = new ErrorMessageBuilder("E-ERJ-TEST-1").message("{{myPlaceholder}}") .parameter("myPlaceholder", null).toString(); @@ -44,6 +47,7 @@ void testMessageWithoutParameterName() { } @Test + // [utest->dsn~report-unknown-and-null-values~1] void testMessageUnknownParameter() { final ErrorMessageBuilder messageBuilder = new ErrorMessageBuilder("E-ERJ-TEST-1").message("test {{unknown}}"); assertThat(messageBuilder.toString(), equalTo("E-ERJ-TEST-1: test UNKNOWN PLACEHOLDER('unknown')")); @@ -64,6 +68,7 @@ void testSingleMitigationWithParameter() { } @Test + // [utest->dsn~render-mitigations~1] void testMitigations() { final String message = new ErrorMessageBuilder("E-ERJ-TEST-1").message("Something went wrong.") .mitigation("Fix it.").mitigation("Contact support under {{SUPPORT_HOTLINE}}.") @@ -73,6 +78,7 @@ void testMitigations() { } @Test + // [utest->dsn~render-ticket-mitigation~1] void testTicketMitigation() { final String message = new ErrorMessageBuilder("E-ERJ-TEST-1").message("Something went wrong.") .ticketMitigation().toString(); @@ -117,6 +123,7 @@ void testMitigationInlineMultipleNullParameters() { } @Test + // [utest->dsn~apply-scalar-quoting~1] void testMessageInlineSingleQuotedParameter() { final String message = new ErrorMessageBuilder("ERROR-CODE").message("Message with {{parameterName}}.", "value") .toString(); @@ -190,13 +197,6 @@ void testMessageInlineSingleNullUnquotedParameter() { assertThat(message, equalTo("ERROR-CODE: Message with .")); } - @Test - void testMessageInlineMultipleNullUnquotedParameters() { - final String message = new ErrorMessageBuilder("ERROR-CODE") - .message("Message with {{parameterName1}} {{parameterName2}}.", null, null).toString(); - assertThat(message, equalTo("ERROR-CODE: Message with .")); - } - @Test void testMessageInlineAndOutlineInOrder() { final ErrorMessageBuilder messageBuilder = new ErrorMessageBuilder("ERROR-CODE") diff --git a/src/test/java/com/exasol/errorreporting/ParameterDefinitionTest.java b/src/test/java/com/exasol/errorreporting/ParameterDefinitionTest.java index 3765ffe..0e0c563 100644 --- a/src/test/java/com/exasol/errorreporting/ParameterDefinitionTest.java +++ b/src/test/java/com/exasol/errorreporting/ParameterDefinitionTest.java @@ -19,6 +19,7 @@ void testGetValue() { } @Test + // [utest->dsn~expose-parameter-metadata~1] void testGetDescription() { final ParameterDefinition parameter = ParameterDefinition.builder("irrelevant").description("small blue thing") .build(); diff --git a/src/test/java/com/exasol/errorreporting/QuoterTest.java b/src/test/java/com/exasol/errorreporting/QuoterTest.java index 325a9cc..83e6a39 100644 --- a/src/test/java/com/exasol/errorreporting/QuoterTest.java +++ b/src/test/java/com/exasol/errorreporting/QuoterTest.java @@ -37,6 +37,8 @@ static Stream getAutoQuotingExamples() throws MalformedURLException, @ParameterizedTest @MethodSource("getAutoQuotingExamples") + // [utest->dsn~apply-scalar-quoting~1] + // [utest->dsn~apply-collection-quoting~1] void testAutoQuoting(final Object input, final String expectedOutput) { assertThat(Quoter.quoteObject(input, Quoting.AUTOMATIC), equalTo(expectedOutput)); } @@ -61,6 +63,7 @@ static Stream getUnquotedExamples() throws MalformedURLException, URI @ParameterizedTest @MethodSource("getUnquotedExamples") + // [utest->dsn~apply-scalar-quoting~1] void testForcedUnquoted(final Object input, final String expectedOutput) { assertThat(Quoter.quoteObject(input, Quoting.UNQUOTED), equalTo(expectedOutput)); }