diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..343fecc50 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,32 @@ +# https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file +version: 2 +updates: + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly + day: monday + time: "10:00" + commit-message: + prefix: ci + prefix-development: ci + include: scope + labels: + - pinned + - dependencies + - gha + + - package-ecosystem: maven + directory: / + schedule: + interval: weekly + day: monday + time: "10:00" + commit-message: + prefix: fix + prefix-development: build + include: scope + labels: + - pinned + - dependencies + - mvn diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 000000000..e751ce382 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,176 @@ +# SPDX-FileCopyrightText: © Vegard IT GmbH (https://vegardit.com) and others. +# SPDX-FileContributor: Sebastian Thomschke (Vegard IT GmbH) +# SPDX-License-Identifier: EPL-2.0 + +# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions +name: Build + +on: + push: + branches-ignore: # build all branches except: + - 'dependabot/**' # prevent GHA triggered twice (once for commit to the branch and once for opening/syncing the PR) + tags-ignore: # don't build tags + - '**' + paths-ignore: + - '**/*.adoc' + - '**/*.md' + - '.editorconfig' + - '.git*' + - '.github/*.yml' + - '.github/workflows/stale.yml' + - '.github/workflows/update-eea-files.yml' + pull_request: + paths-ignore: + - '**/*.adoc' + - '**/*.md' + - '.editorconfig' + - '.git*' + - '.github/*.yml' + workflow_dispatch: + # https://github.blog/changelog/2020-07-06-github-actions-manual-triggers-with-workflow_dispatch/ + inputs: + additional_maven_args: + description: 'Additional Maven Args' + required: false + default: '' + + +defaults: + run: + shell: bash + + +jobs: + + ########################################################### + build: + ########################################################### + runs-on: ubuntu-latest + + + # https://docs.github.com/en/actions/using-jobs/using-concurrency + concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: false + + + steps: + - name: "Show: GitHub context" + env: + GITHUB_CONTEXT: ${{ toJSON(github) }} + run: echo $GITHUB_CONTEXT + + + - name: "Show: environment variables" + run: env | sort + + + - name: Git Checkout + uses: actions/checkout@v4 # https://github.com/actions/checkout + + + - name: "Install: JDK 17 ☕" + uses: actions/setup-java@v4 # https://github.com/actions/setup-java + with: + distribution: temurin + java-version: 17 + - run: echo "JAVA17_HOME=$JAVA_HOME" >> $GITHUB_ENV + + + - name: "Install: JDK 21 ☕" + uses: actions/setup-java@v4 # https://github.com/actions/setup-java + with: + distribution: temurin + java-version: 21 + - run: echo "JAVA21_HOME=$JAVA_HOME" >> $GITHUB_ENV + + + - name: "Show: toolchains.xml" + run: cat "$HOME/.m2/toolchains.xml" + + + - name: "Cache: Local Maven Repository" + uses: actions/cache@v4 + if: ${{ !env.ACT }} # https://github.com/nektos/act#skipping-steps + with: + # Excluded sub directory not working https://github.com/actions/toolkit/issues/713 + path: | + ~/.m2/repository/* + !~/.m2/repository/*SNAPSHOT* + key: ${{ runner.os }}-mvn-${{ hashFiles('**/pom.xml') }} + + + - name: "Install: Maven 📦" + uses: stCarolas/setup-maven@v5 # https://github.com/stCarolas/setup-maven + with: + maven-version: 3.9.9 + + + - name: Prepare Maven Snapshots Repo + if: ${{ github.ref_name == 'main' && !env.ACT }} # https://github.com/nektos/act#skipping-steps + run: | + set -eux + + cd /tmp + github_repo_url="https://${{ github.actor }}:${{ github.token }}@github.com/${{ github.repository }}/" + if curl --output /dev/null --silent --head --fail "$github_repo_url/tree/mvn-snapshots-repo"; then + git clone https://${{ github.actor }}:${{ github.token }}@github.com/${{ github.repository }}/ --single-branch --branch mvn-snapshots-repo mvn-snapshots-repo + cd mvn-snapshots-repo + # https://github.community/t/github-actions-bot-email-address/17204 + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git reset --hard HEAD^ # revert previous commit + else + git clone https://${{ github.actor }}:${{ github.token }}@github.com/${{ github.repository }}/ mvn-snapshots-repo + cd mvn-snapshots-repo + git checkout --orphan mvn-snapshots-repo + git rm -rf . + cat < index.html + + + + ${{ github.repository }} - Maven Snapshots Repo + + +

${{ github.repository }} - Maven Snapshots Repo

+ + + EOF + git add index.html + # https://github.community/t/github-actions-bot-email-address/17204 + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git commit -am "Initialize Maven Snapshots Repo" + fi + + + - name: "Build with Maven 🔨" + run: | + set -euo pipefail + + MAVEN_OPTS="${MAVEN_OPTS:-}" + MAVEN_OPTS+=" -Djava.security.egd=file:/dev/./urandom" # https://stackoverflow.com/questions/58991966/what-java-security-egd-option-is-for/59097932#59097932 + MAVEN_OPTS+=" -Dorg.slf4j.simpleLogger.showDateTime=true -Dorg.slf4j.simpleLogger.dateTimeFormat=HH:mm:ss,SSS" # https://stackoverflow.com/questions/5120470/how-to-time-the-different-stages-of-maven-execution/49494561#49494561 + MAVEN_OPTS+=" -Xmx1024m -Djava.net.preferIPv4Stack=true -Dhttps.protocols=TLSv1.3,TLSv1.2" + export MAVEN_OPTS + echo "MAVEN_OPTS: $MAVEN_OPTS" + + mvn \ + --errors \ + --update-snapshots \ + --batch-mode \ + --show-version \ + ${{ github.event.inputs.additional_maven_args }} \ + clean ${{ (github.ref_name == 'main' && !env.ACT) && 'deploy' || 'verify' }} \ + -DaltSnapshotDeploymentRepository=temp-snapshots-repo::file:///tmp/mvn-snapshots-repo + + + - name: Update Maven Snapshots Repo + if: ${{ github.ref_name == 'main' && !env.ACT }} # https://github.com/nektos/act#skipping-steps + run: | + cd /tmp/mvn-snapshots-repo + if [[ $(git -C . ls-files -o -m -d --exclude-standard | wc -l) -gt 0 ]]; then + git add --all + git commit -am "Deploy snapshot version" + git push origin mvn-snapshots-repo --force + fi diff --git a/README.md b/README.md index 8172e5a2f..dacb056fd 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,31 @@ -[![Build Status](https://travis-ci.org/lastnpe/eclipse-null-eea-augments.svg)](https://travis-ci.org/lastnpe/eclipse-null-eea-augments) - # Eclipse External null Annotations (EEA) +[![Build Status](https://github.com/lastnpe/eclipse-null-eea-augments/workflows/Build/badge.svg "GitHub Actions")](https://github.com/lastnpe/eclipse-null-eea-augments/actions?query=workflow%3A%22Build%22) +[![License](https://img.shields.io/github/license/lastnpe/eclipse-null-eea-augments.svg?color=blue)](LICENSE.txt) +[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-v2.1%20adopted-ff69b4.svg)](CODE_OF_CONDUCT.md) + +1. [What is this?](#what-is-this) +1. [How to use this](#usage) + 1. [Binaries](#binaries) + 1. [Building from Sources](#building) + 1. [Validating/Updating EEA files](#validate_update) +1. [How to contribute](#contribute) +1. [Troubleshooting](#troubleshooting) +1. [Future](#future) +1. [License](#license) + + +## What is this? + This repository contains *.eea files and example projects how to use this. If you like/use this project, a Star / Watch / Follow on GitHub is appreciated. -## How to use this +## How to use this + +General usage of External Null Annotations in Eclipse is documented at +https://help.eclipse.org/latest/index.jsp?topic=/org.eclipse.jdt.doc.user/tasks/task-using_external_null_annotations.htm [See theses slides here](http://www.slideshare.net/mikervorburger/the-end-of-the-world-as-we-know-it-aka-your-last-nullpointerexception-1b-bugs) from this [EclipseCon Europe 2016 presentation](https://www.eclipsecon.org/europe2016/session/end-world-we-know-it-aka-your-last-nullpointerexception-1b-bugs) for some background about this project. @@ -17,7 +35,120 @@ recommend you install the [eclipse-external-annotations-m2e-plugin](https://gith (On Eclipse m2e versions < 1.8 (shipped with Oxygen), you also had to install [m2e-jdt-compiler](https://github.com/jbosstools/m2e-jdt-compiler), but with M2E 1.8 in Oxygen that is not necessary anymore, even harmful; see below.) -## Contribute +### Binaries + +Latest **Release** binaries are available on Maven central, see https://search.maven.org/search?q=g%3Aorg.lastnpe.eea + +Latest **Snapshot** binaries are available via the [mvn-snapshots-repo](https://github.com/lastnpe/eclipse-null-eea-augments/tree/mvn-snapshots-repo) git branch. +You need to add this repository configuration to your Maven `settings.xml`: + +```xml + + + + + + + lastnpe-snapshots + lastnpe-snapshots + https://raw.githubusercontent.com/lastnpe/eclipse-null-eea-augments/mvn-snapshots-repo + false + true + + + + + + lastnpe-snapshots + + +``` + + +### Building from Sources + +The project also uses the [maven-toolchains-plugin](http://maven.apache.org/plugins/maven-toolchains-plugin/) which decouples the JDK that is +used to execute Maven and it's plug-ins from the target JDK that is used for compilation and/or unit testing. This ensures full binary +compatibility of the compiled artifacts with the runtime library of the required target JDK. + +To build the project follow these steps: + +1. Download and install Java 17 **AND** Java 21 SDKs, e.g. from: + - Java 17: https://adoptium.net/releases.html?variant=openjdk17 or https://www.azul.com/downloads/?version=java-17-lts&package=jdk#download-openjdk + - Java 21: https://adoptium.net/releases.html?variant=openjdk21 or https://www.azul.com/downloads/?version=java-21-lts&package=jdk#download-openjdk + +1. Download and install the latest [Maven distribution](https://maven.apache.org/download.cgi). + +1. In your user home directory create the file `.m2/toolchains.xml` with the following content: + + ```xml + + + + jdk + + 17 + default + + + [PATH_TO_YOUR_JDK_17] + + + + jdk + + 21 + default + + + [PATH_TO_YOUR_JDK_21] + + + + ``` + + Set the `[PATH_TO_YOUR_JDK_17]`/`[PATH_TO_YOUR_JDK_21]` parameters accordingly + to where you installed the JDKs. + +1. Checkout the code, e.g. using: + + - `git clone https://github.com/lastnpe/eclipse-null-eea-augments` + +1. Run `mvn clean verify` in the project root directory. This will execute compilation, unit-testing, integration-testing and + packaging of all artifacts. + + +### Validating/Updating EEA files + +The EEA files can be validated/updated using: + +```bash +# validate all EEA files of all eea-* modules +mvn compile + +# validate all EEA files of a specific module +mvn compile -am -pl +mvn compile -am -pl libraries/gson + +# update/regenerate all EEA files of all eea-* modules +mvn compile -Deea-generator.action=generate + +# update/regenerate all EEA files of a specific module +mvn compile -Deea-generator.action=generate -am -pl +mvn compile -Deea-generator.action=generate -am -pl libraries/gson +``` + +Updating EEA files will: +- add new types/fields/methods found +- remove obsolete declarations from the EEA files +- preserve null/non-null annotations specified for existing fields/methods + + +## How to contribute + +Please consult the [CONTRIBUTING.md](CONTRIBUTING.md). This project aims to develop an active community of contributors, and not remain controlled by a single person. Anyone making 3 intelligent contributions to this repo may ask to be promoted from a contributor to a committer with full write access by opening an issue requesting it. @@ -33,13 +164,25 @@ When making contributions with changes, please explain what is wrong in the curr We generally do not "self merge", but let other committers merge our own changes. -## Troubleshooting +## Troubleshooting * Uninstall the [jbosstools/m2e-jdt-compiler](https://github.com/jbosstools/m2e-jdt-compiler) to fix this problem: _Conflicting lifecycle mapping (plugin execution "org.apache.maven.plugins:maven-compiler-plugin:3.5.1:compile (execution: default-compile, phase: compile)"). To enable full functionality, remove the conflicting mapping and run Maven->Update Project Configuration._ * Do `mvn install` of the `examples/maven/jdt-ecj-settings` to fix this problem, due to [M2E Bug 522393](https://bugs.eclipse.org/bugs/show_bug.cgi?id=522393): _CoreException: Could not get the value for parameter compilerId for plugin execution default-testCompile: PluginResolutionException: Plugin org.apache.maven.plugins:maven-compiler-plugin:3.5.1 or one of its dependencies could not be resolved: Failure to find ch.vorburger.nulls.examples:jdt-ecj-settings:jar:1.0.0-SNAPSHOT_ -## Future +## Future If this is found to be of general interest, perhaps this could move to eclipse.org. If this happens, it would be imperative to keep it very easy for anyone to contribute via Pull Requests on GitHub (and not, or not you only, eclipse.org Gerrit changes). + + +## License + +All files are released under the [Eclipse Public License 2.0](LICENSE.txt). + +Individual files contain the following tag instead of the full license text: +``` +SPDX-License-Identifier: EPL-2.0 +``` + +This enables machine processing of license information based on the SPDX License Identifiers that are available here: https://spdx.org/licenses/. diff --git a/eea-all/pom.xml b/eea-all/pom.xml new file mode 100644 index 000000000..12ae1e522 --- /dev/null +++ b/eea-all/pom.xml @@ -0,0 +1,106 @@ + + + + 4.0.0 + + + org.lastnpe.eea + eea-root + 3.0.0-SNAPSHOT + + + eea-all + EEA :: All-in-one + + + + + + + org.apache.felix + maven-bundle-plugin + 5.1.9 + + + manifest@process-classes + process-classes + + manifest + + + + + true + + + + + + + + maven-jar-plugin + + + + target/classes/META-INF/MANIFEST.MF + + + + + + org.codehaus.gmavenplus + gmavenplus-plugin + 3.0.2 + + + + collect-eeas + process-resources + + execute + + + + + + + + + + + ${project.groupId} + lastnpe-eea-generator + ${project.version} + + + org.codehaus.groovy + groovy-all + 3.0.22 + pom + + + + + + \ No newline at end of file diff --git a/generator/.gitignore b/generator/.gitignore new file mode 100644 index 000000000..5739a0920 --- /dev/null +++ b/generator/.gitignore @@ -0,0 +1,6 @@ +**/.settings/* +!**/.settings/ +!**/.settings/org.eclipse.core.resources.prefs +!**/.settings/org.eclipse.jdt.core.prefs +!**/.settings/org.eclipse.jdt.ui.prefs + diff --git a/generator/.settings/org.eclipse.core.resources.prefs b/generator/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 000000000..99f26c020 --- /dev/null +++ b/generator/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/generator/.settings/org.eclipse.jdt.core.prefs b/generator/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..fd7dda0bd --- /dev/null +++ b/generator/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,533 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.builder.annotationPath.allLocations=enabled +org.eclipse.jdt.core.codeComplete.argumentPrefixes= +org.eclipse.jdt.core.codeComplete.argumentSuffixes= +org.eclipse.jdt.core.codeComplete.fieldPrefixes= +org.eclipse.jdt.core.codeComplete.fieldSuffixes= +org.eclipse.jdt.core.codeComplete.localPrefixes= +org.eclipse.jdt.core.codeComplete.localSuffixes= +org.eclipse.jdt.core.codeComplete.staticFieldPrefixes= +org.eclipse.jdt.core.codeComplete.staticFieldSuffixes= +org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes= +org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes= +org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=enabled +org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore +org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull +org.eclipse.jdt.core.compiler.annotation.nonnull.secondary= +org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault +org.eclipse.jdt.core.compiler.annotation.nonnullbydefault.secondary= +org.eclipse.jdt.core.compiler.annotation.notowning=org.eclipse.jdt.annotation.NotOwning +org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable +org.eclipse.jdt.core.compiler.annotation.nullable.secondary= +org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled +org.eclipse.jdt.core.compiler.annotation.owning=org.eclipse.jdt.annotation.Owning +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=17 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +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 +org.eclipse.jdt.core.compiler.problem.APILeak=warning +org.eclipse.jdt.core.compiler.problem.annotatedTypeArgumentToUnannotated=info +org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.autoboxing=ignore +org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning +org.eclipse.jdt.core.compiler.problem.deadCode=warning +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=warning +org.eclipse.jdt.core.compiler.problem.emptyStatement=warning +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore +org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning +org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled +org.eclipse.jdt.core.compiler.problem.fieldHiding=warning +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=error +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=enabled +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompatibleOwningContract=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore +org.eclipse.jdt.core.compiler.problem.insufficientResourceAnalysis=warning +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning +org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled +org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=warning +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning +org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore +org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning +org.eclipse.jdt.core.compiler.problem.nonnullTypeVariableFromLegacyInvocation=warning +org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error +org.eclipse.jdt.core.compiler.problem.nullReference=warning +org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error +org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.pessimisticNullAnalysisForFreeTypeVariables=warning +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning +org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning +org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=warning +org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning +org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning +org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning +org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=warning +org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning +org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore +org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.suppressWarningsNotFullyAnalysed=info +org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=enabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.terminalDeprecation=warning +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=disabled +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentType=warning +org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentTypeStrict=disabled +org.eclipse.jdt.core.compiler.problem.unlikelyEqualsArgumentType=info +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unstableAutoModuleName=warning +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedImport=warning +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=warning +org.eclipse.jdt.core.compiler.problem.unusedParameter=warning +org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +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.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=true +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 +org.eclipse.jdt.core.formatter.alignment_for_additive_operator=16 +org.eclipse.jdt.core.formatter.alignment_for_annotations_on_enum_constant=49 +org.eclipse.jdt.core.formatter.alignment_for_annotations_on_field=49 +org.eclipse.jdt.core.formatter.alignment_for_annotations_on_local_variable=49 +org.eclipse.jdt.core.formatter.alignment_for_annotations_on_method=49 +org.eclipse.jdt.core.formatter.alignment_for_annotations_on_package=49 +org.eclipse.jdt.core.formatter.alignment_for_annotations_on_parameter=0 +org.eclipse.jdt.core.formatter.alignment_for_annotations_on_type=49 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_assertion_message=16 +org.eclipse.jdt.core.formatter.alignment_for_assignment=0 +org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator=16 +org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 +org.eclipse.jdt.core.formatter.alignment_for_compact_loops=16 +org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 +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=16 +org.eclipse.jdt.core.formatter.alignment_for_expressions_in_switch_case_with_colon=16 +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 +org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 +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 +org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_shift_operator=0 +org.eclipse.jdt.core.formatter.alignment_for_string_concatenation=16 +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=20 +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 +org.eclipse.jdt.core.formatter.alignment_for_type_arguments=0 +org.eclipse.jdt.core.formatter.alignment_for_type_parameters=0 +org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 +org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_after_last_class_body_declaration=0 +org.eclipse.jdt.core.formatter.blank_lines_after_package=1 +org.eclipse.jdt.core.formatter.blank_lines_before_abstract_method=1 +org.eclipse.jdt.core.formatter.blank_lines_before_field=0 +org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 +org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 +org.eclipse.jdt.core.formatter.blank_lines_before_method=1 +org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 +org.eclipse.jdt.core.formatter.blank_lines_before_package=0 +org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 +org.eclipse.jdt.core.formatter.blank_lines_between_statement_group_in_switch=0 +org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 +org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line +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 +org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_record_constructor=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_record_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.comment.align_tags_descriptions_grouped=true +org.eclipse.jdt.core.formatter.comment.align_tags_names_descriptions=false +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false +org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position=true +org.eclipse.jdt.core.formatter.comment.format_block_comments=true +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_source_code=true +org.eclipse.jdt.core.formatter.comment.indent_parameter_description=false +org.eclipse.jdt.core.formatter.comment.indent_root_tags=false +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.javadoc_do_not_separate_block_tags=false +org.eclipse.jdt.core.formatter.comment.line_length=80 +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 +org.eclipse.jdt.core.formatter.compact_else_if=true +org.eclipse.jdt.core.formatter.continuation_indentation=2 +org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 +org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off +org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on +org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false +org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=false +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_record_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true +org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_empty_lines=false +org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true +org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false +org.eclipse.jdt.core.formatter.indentation.size=4 +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert +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_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 +org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_additive_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_case=insert +org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_default=insert +org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert +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 +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert +org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert +org.eclipse.jdt.core.formatter.insert_space_after_logical_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_not_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_record_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_relational_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert +org.eclipse.jdt.core.formatter.insert_space_after_shift_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation=insert +org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_additive_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_case=insert +org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_default=insert +org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_record_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert +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 +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert +org.eclipse.jdt.core.formatter.insert_space_before_logical_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_constructor=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_record_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert +org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_relational_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_shift_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation=insert +org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert +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_line_comments=false +org.eclipse.jdt.core.formatter.join_lines_in_comments=true +org.eclipse.jdt.core.formatter.join_wrapped_lines=true +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 +org.eclipse.jdt.core.formatter.keep_code_block_on_one_line=one_line_never +org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false +org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false +org.eclipse.jdt.core.formatter.keep_enum_constant_declaration_on_one_line=one_line_never +org.eclipse.jdt.core.formatter.keep_enum_declaration_on_one_line=one_line_never +org.eclipse.jdt.core.formatter.keep_if_then_body_block_on_one_line=one_line_never +org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false +org.eclipse.jdt.core.formatter.keep_lambda_body_block_on_one_line=one_line_never +org.eclipse.jdt.core.formatter.keep_loop_body_block_on_one_line=one_line_never +org.eclipse.jdt.core.formatter.keep_method_body_on_one_line=one_line_never +org.eclipse.jdt.core.formatter.keep_record_constructor_on_one_line=one_line_never +org.eclipse.jdt.core.formatter.keep_record_declaration_on_one_line=one_line_never +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.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 +org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_code_block=0 +org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 +org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_code_block=0 +org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_method_body=0 +org.eclipse.jdt.core.formatter.number_of_blank_lines_before_code_block=0 +org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 +org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines +org.eclipse.jdt.core.formatter.parentheses_positions_in_record_declaration=common_lines +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.tabulation.char=tab +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=true +org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false +org.eclipse.jdt.core.formatter.wrap_before_additive_operator=true +org.eclipse.jdt.core.formatter.wrap_before_assertion_message_operator=true +org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false +org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator=true +org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true +org.eclipse.jdt.core.formatter.wrap_before_logical_operator=true +org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator=true +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/generator/.settings/org.eclipse.jdt.ui.prefs b/generator/.settings/org.eclipse.jdt.ui.prefs new file mode 100644 index 000000000..3da97ecf5 --- /dev/null +++ b/generator/.settings/org.eclipse.jdt.ui.prefs @@ -0,0 +1,13 @@ +cleanup_settings_version=2 +eclipse.preferences.version=1 +formatter_profile=org.eclipse.jdt.ui.default.eclipse_profile +formatter_settings_version=23 +org.eclipse.jdt.ui.exception.name=ex +org.eclipse.jdt.ui.gettersetter.use.is=true +org.eclipse.jdt.ui.ignorelowercasenames=true +org.eclipse.jdt.ui.importorder=java;javax;org;com; +org.eclipse.jdt.ui.keywordthis=false +org.eclipse.jdt.ui.ondemandthreshold=99 +org.eclipse.jdt.ui.overrideannotation=true +org.eclipse.jdt.ui.staticondemandthreshold=2 +org.eclipse.jdt.ui.text.custom_code_templates= diff --git a/generator/pom.xml b/generator/pom.xml new file mode 100644 index 000000000..76f3a9794 --- /dev/null +++ b/generator/pom.xml @@ -0,0 +1,64 @@ + + + + + 4.0.0 + + + org.lastnpe.eea + eea-root + 3.0.0-SNAPSHOT + ../pom.xml + + + lastnpe-eea-generator + This maven module contains classes to generate, parse and validate .eea files + + + + + org.junit + junit-bom + 5.10.3 + pom + import + + + + + + + org.eclipse.jdt + org.eclipse.jdt.annotation + 2.3.0 + provided + + + org.eclipse.jdt + ecj + 3.38.0 + + + io.github.classgraph + classgraph + 4.8.174 + + + + + org.assertj + assertj-core + 3.26.3 + test + + + org.junit.jupiter + junit-jupiter-api + test + + + \ No newline at end of file diff --git a/generator/src/main/java/org/lastnpe/eea/generator/EEAFile.java b/generator/src/main/java/org/lastnpe/eea/generator/EEAFile.java new file mode 100644 index 000000000..ed970d3e6 --- /dev/null +++ b/generator/src/main/java/org/lastnpe/eea/generator/EEAFile.java @@ -0,0 +1,703 @@ +/* + * SPDX-FileCopyrightText: © Vegard IT GmbH (https://vegardit.com) and others. + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * - Sebastian Thomschke (Vegard IT GmbH) - initial API and implementation + */ +package org.lastnpe.eea.generator; + +import static org.lastnpe.eea.generator.internal.MiscUtils.*; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.lang.System.Logger; +import java.lang.System.Logger.Level; +import java.nio.file.Files; +import java.nio.file.OpenOption; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Deque; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.jdt.internal.compiler.classfmt.ExternalAnnotationProvider; +import org.lastnpe.eea.generator.internal.MiscUtils; + +/** + * Represents an .eea file. See + * https://wiki.eclipse.org/JDT_Core/Null_Analysis/External_Annotations#File_layout + * + * @author Sebastian Thomschke (Vegard IT GmbH) + */ +public class EEAFile { + + /** + * Represents a type/class member, e.g. a field or method incl. it's original + * signature. + */ + public static class ClassMember { + + public enum Type { + FIELD, // + CONSTRUCTOR, // + METHOD + } + + public boolean isFollowedByEmptyLine = false; + public final ValueWithComment name; + + /** Plain signature without external Null Analysis annotations */ + public final ValueWithComment originalSignature; + + /** Signature with external Null Analysis annotations */ + public ValueWithComment annotatedSignature; + + public ClassMember(final String name, final String originalSignature) { + this(ValueWithComment.parse(name), ValueWithComment.parse(originalSignature)); + } + + public ClassMember(final ValueWithComment name, final ValueWithComment originalSignature) { + this.name = name; + this.originalSignature = originalSignature; + annotatedSignature = new ValueWithComment(originalSignature.value); + } + + public ClassMember(final ValueWithComment name, final ValueWithComment originalSignature, + final ValueWithComment annotatedSignature) { + this.name = name; + this.originalSignature = originalSignature; + this.annotatedSignature = annotatedSignature; + } + + @Override + public ClassMember clone() { + return new ClassMember(name.clone(), originalSignature.clone(), annotatedSignature.clone()); + } + + public boolean hasNullAnnotations() { + return !annotatedSignature.value.equals(originalSignature.value); + } + + public Type getType() { + if (name.value.equals("")) + return Type.CONSTRUCTOR; + return originalSignature.value.contains("(") // + ? Type.METHOD + : Type.FIELD; + } + + public void applyAnnotationsAndCommentsFrom(final ClassMember applyFrom, final boolean overrideOnConflict) { + if (applyFrom.getType() != getType()) + throw new IllegalArgumentException("Type mismatch for [" + name.value + "]:\n" // + + " Ours: " + getType() + "\n" // + + "Theirs: " + applyFrom.getType()); + + if (!applyFrom.originalSignature.value.equals(originalSignature.value)) { + LOG.log(Level.WARNING, "Signature mismatch for " + getType() + "[" + name.value + "]:\n" // + + " Ours: " + originalSignature.value + "\n" // + + "Theirs: " + applyFrom.originalSignature.value); + return; + } + + // apply name comment + if (overrideOnConflict || !name.hasComment()) { + name.comment = applyFrom.name.comment; + } + + // apply original signature comment + if (overrideOnConflict || !originalSignature.hasComment()) { + originalSignature.comment = applyFrom.originalSignature.comment; + } + + if (overrideOnConflict || !hasNullAnnotations()) { + if (applyFrom.hasNullAnnotations()) { + annotatedSignature = applyFrom.annotatedSignature.clone(); + } else if (overrideOnConflict || !annotatedSignature.hasComment()) { + annotatedSignature.comment = applyFrom.annotatedSignature.comment; + } + } + } + + @Override + public String toString() { + return name + System.lineSeparator() // + + " " + originalSignature + System.lineSeparator() // + + " " + annotatedSignature; + } + } + + public enum SaveOption { + DELETE_IF_EMPTY, // + OMIT_COMMENTS, // + OMIT_EMPTY_LINES, // + OMIT_REDUNDANT_ANNOTATED_SIGNATURES, // + OMIT_MEMBERS_WITH_INHERITED_ANNOTATED_SIGNATURES, // + OMIT_MEMBERS_WITHOUT_ANNOTATED_SIGNATURE, // + REPLACE_EXISTING, // + QUIET + } + + public static final class ValueWithComment implements Cloneable { + public static final char COMMENT_SEPARATOR = ' '; + + public static ValueWithComment parse(String text) { + text = text.strip(); + final int separatorPos = text.indexOf(COMMENT_SEPARATOR); + if (separatorPos == -1) + return new ValueWithComment(text); + return new ValueWithComment(text.substring(0, separatorPos), text.substring(separatorPos + 1)); + } + + public static String toString(final String value, final String comment) { + return comment.isBlank() ? value : value + COMMENT_SEPARATOR + comment; + } + + public String value; + public String comment; + + public ValueWithComment(final String value) { + this(value, ""); + } + + public ValueWithComment(final String value, final String comment) { + this.value = value; + this.comment = comment; + } + + @Override + public ValueWithComment clone() { + return new ValueWithComment(value, comment); + } + + public boolean hasComment() { + return !comment.isBlank(); + } + + @Override + public String toString() { + return toString(value, comment); + } + + public String toString(final boolean omitComment) { + return toString(value, omitComment ? "" : comment); + } + } + + private static final Logger LOG = System.getLogger(EEAFile.class.getName()); + + public static final String MARKER_KEEP = "@Keep"; + public static final String MARKER_OVERRIDES = "@Overrides"; + public static final String MARKER_INHERITED = "@Inherited"; + + /** + * Used to match the 0/1 null annotation of types generic type variables, which + * is especially tricky in cases such as + * + *
+	 * {@code
+	 * (L1com/example/L1;)V
+	 * (Ljava/lang/Class)V
+	 * }
+	 * 
+ * + * where the name of the type variable itself is T0 or T1 or when the class name + * itself is L0 or L1. + */ + protected static final Pattern PATTERN_CAPTURE_NULL_ANNOTATION_OF_TYPENAMES = Pattern + .compile("[TL]([01])[a-zA-Z_][a-zA-Z_0-9$\\/*]*[<;]"); + + /** + * see + * https://wiki.eclipse.org/JDT_Core/Null_Analysis/External_Annotations#Textual_encoding_of_signatures + */ + protected static String removeNullAnnotations(final String annotatedSignature) { + var strippedSignature = annotatedSignature // + .replace("[0", "[") // + .replace("[1", "[") // + .replace("-0", "-") // + .replace("-1", "-") // + .replace("+0", "+") // + .replace("+1", "+") // + .replace("*0", "*") // + .replace("<0", "<") // + .replace("<1", "<") // + .replace("*1", "*"); + + strippedSignature = replaceAll(strippedSignature, PATTERN_CAPTURE_NULL_ANNOTATION_OF_TYPENAMES, 1, match -> ""); + return strippedSignature; + } + + public final ClassMember classHeader; + public final List superTypes = new ArrayList<>(); + + public final Path relativePath; + + /** ordered list of declared class members */ + private final List members = new ArrayList<>(); + + /** + * @throws IOException in case the file cannot be read or contains syntax errors + */ + public static @Nullable EEAFile loadIfExists(final Path rootPath, final String className) throws IOException { + final Path eeaFilePath = rootPath.resolve(classNameToRelativePath(className)); + if (!Files.exists(eeaFilePath)) { + LOG.log(Level.DEBUG, "File [{0}] does not exist, skipping.", eeaFilePath); + return null; + } + return load(eeaFilePath); + } + + /** + * @throws IOException in case the file cannot be read or contains syntax errors + */ + public static EEAFile load(final Path rootPath, final String className) throws IOException { + final Path eeaFilePath = rootPath.resolve(classNameToRelativePath(className)); + return load(eeaFilePath); + } + + /** + * @throws IOException in case the file cannot be read or contains syntax errors + */ + public static EEAFile load(final Path filePath) throws IOException { + try (var reader = Files.newBufferedReader(filePath)) { + return load(reader, filePath.toString()); + } + } + + public static EEAFile load(final BufferedReader reader, final String path) throws IOException { + final Deque lines = reader.lines().collect(Collectors.toCollection(ArrayDeque::new)); + + // read type header + String line = lines.pollFirst(); + int lineNumber = 1; + assert line != null; + final var classNameRaw = ValueWithComment + .parse(line.substring(ExternalAnnotationProvider.CLASS_PREFIX.length())); + ExternalAnnotationProvider.assertClassHeader(line, classNameRaw.value); + + final var eeaFile = new EEAFile(classNameRaw.value.replace('/', '.')); + eeaFile.classHeader.name.comment = classNameRaw.comment; + + if (!path.replace('\\', '/').endsWith(eeaFile.relativePath.toString().replace('\\', '/'))) + throw new IOException("Mismatch between file path of [" + path + "] and contained class name definition [" + + eeaFile.classHeader.name.value + "]"); + + // read type signature if present + line = lines.peekFirst(); + if (line != null && !line.isBlank() + && line.startsWith(" <" /* ExternalAnnotationProvider.TYPE_PARAMETER_PREFIX */ )) { + lines.removeFirst(); + lineNumber++; + final var originalSignature = ValueWithComment.parse(line); + eeaFile.classHeader.originalSignature.value = originalSignature.value; + eeaFile.classHeader.originalSignature.comment = originalSignature.comment; + + line = lines.peekFirst(); + if (line != null && !line.isBlank() + && line.startsWith(" <" /* ExternalAnnotationProvider.TYPE_PARAMETER_PREFIX */ )) { + lines.removeFirst(); + lineNumber++; + eeaFile.classHeader.annotatedSignature = ValueWithComment.parse(line); + } else { + eeaFile.classHeader.annotatedSignature.value = eeaFile.classHeader.originalSignature.value; + } + } + + // read type members + while ((line = lines.pollFirst()) != null) { + line = line.stripTrailing(); + lineNumber++; + if (line.isEmpty()) { + eeaFile.addEmptyLine(); + continue; + } + + if (line.startsWith(" ")) + throw new IOException( + "Illegal format for field or method name [" + line + "] at " + path + ":" + lineNumber); + + /* + * read "super" declarations + */ + if (line.startsWith(ExternalAnnotationProvider.SUPER_PREFIX)) { + final var superType = ValueWithComment + .parse(line.substring(ExternalAnnotationProvider.SUPER_PREFIX.length())); + line = lines.peekFirst(); + if (line == null || line.isBlank() + || !line.startsWith(" <" /* ExternalAnnotationProvider.TYPE_PARAMETER_PREFIX */ )) { + continue; + } + lines.removeFirst(); + lineNumber++; + final var superTypeParamsOriginal = ValueWithComment.parse(line); + + // read optional annotated signature + line = lines.peekFirst(); + if (line != null && !line.isBlank() + && line.startsWith(" <" /* ExternalAnnotationProvider.TYPE_PARAMETER_PREFIX */ )) { + lines.removeFirst(); + lineNumber++; + final var superTypeParamsAnnotated = ValueWithComment.parse(line); + if (!superTypeParamsOriginal.value.equals(superTypeParamsAnnotated.value) // + && !superTypeParamsOriginal.value + .equals(removeNullAnnotations(superTypeParamsAnnotated.value))) + throw new IOException("Signature mismatch at " + path + ":" + lineNumber + "\n" // + + " Original: " + superTypeParamsAnnotated + "\n" // + + "Annotated Stripped: " + removeNullAnnotations(superTypeParamsAnnotated.value) + "\n" // + + " Annotated: " + superTypeParamsAnnotated + "\n"); + eeaFile.superTypes + .add(new ClassMember(superType, superTypeParamsOriginal, superTypeParamsAnnotated)); + } else { + eeaFile.superTypes.add(new ClassMember(superType, superTypeParamsOriginal)); + } + + /* + * read and validate class member, i.e. field or method name + */ + } else { + final var memberName = ValueWithComment.parse(line); + + // read mandatory original signature + line = lines.pollFirst(); + lineNumber++; + if (line == null || line.isBlank() || !line.startsWith(" ")) + throw new IOException("Illegal format for original signature at " + path + ":" + lineNumber); + + final var originalSignature = ValueWithComment.parse(line); + if (!originalSignature.value.equals(removeNullAnnotations(originalSignature.value))) + throw new IOException("Original signature contains null annotations at " + path + ":" + lineNumber); + + final var member = new ClassMember(memberName, originalSignature); + if (eeaFile.members.contains(member)) + throw new IOException("Duplicate entry \"" + memberName.value + " " + originalSignature.value + + "\" found at " + path + ":" + lineNumber); + + // read optional annotated signature + line = lines.peekFirst(); + if (line != null && !line.isBlank() && line.startsWith(" ")) { + lines.removeFirst(); + lineNumber++; + final var annotatedSignature = ValueWithComment.parse(line); + if (!originalSignature.value.equals(annotatedSignature.value) // + && !originalSignature.value.equals(removeNullAnnotations(annotatedSignature.value))) + throw new IOException("Signature mismatch at " + path + ":" + lineNumber + "\n" // + + " Original: " + originalSignature + "\n" // + + "Annotated Stripped: " + removeNullAnnotations(annotatedSignature.value) + "\n" // + + " Annotated: " + annotatedSignature + "\n"); + if (!originalSignature.value.equals(annotatedSignature.value) || annotatedSignature.hasComment()) { + member.annotatedSignature = annotatedSignature; + } + } + + // store the parsed member entry + eeaFile.members.add(member); + } + } + return eeaFile; + } + + private static Path classNameToRelativePath(final String className) { + return Path.of(className.replace('.', File.separatorChar) + ExternalAnnotationProvider.ANNOTATION_FILE_SUFFIX); + } + + public EEAFile(final String className) { + this(className, classNameToRelativePath(className)); + } + + private EEAFile(final String className, final Path relativePath) { + classHeader = new ClassMember(new ValueWithComment(className), new ValueWithComment("")); + this.relativePath = relativePath; + } + + public void addEmptyLine() { + final ClassMember lastMember = MiscUtils.findLastElement(members); + if (lastMember != null) { + lastMember.isFollowedByEmptyLine = true; + } + } + + /** + * Adds a new member declaration to the end of the file + */ + public void addMember(final ClassMember member) { + members.add(member); + } + + /** + * Adds a new member declaration to the end of the file + */ + public ClassMember addMember(final String name, final String originalSignature) { + final var member = new ClassMember(name, originalSignature); + members.add(member); + return member; + } + + /** + * @return a class member with the same name and the same original signature + */ + public @Nullable ClassMember findMatchingClassMember(final ClassMember member) { + return findMatchingClassMember(member.name.value, member.originalSignature.value); + } + + /** + * @return a class member with the same name and the same original signature + */ + public @Nullable ClassMember findMatchingClassMember(final String name, final String originalSignature) { + return members.stream() // + .filter(m -> m.name.value.equals(name) // + && m.originalSignature.value.equals(originalSignature)) // + .findFirst() // + .orElse(null); + } + + /** + * Copies annotated signatures for compatible class members from the given EEA + * file + * + * @param overrideOnConflict if true existing annotated signatures are + * overridden + */ + public void applyAnnotationsAndCommentsFrom(final EEAFile their, final boolean overrideOnConflict, + final boolean addNewMembers) { + LOG.log(Level.DEBUG, "Applying annotations from [{0}]...", their.relativePath); + + classHeader.applyAnnotationsAndCommentsFrom(their.classHeader, overrideOnConflict); + + for (final ClassMember superType : superTypes) { + for (final ClassMember theirSuperType : their.superTypes) { + if (superType.originalSignature.value.equals(theirSuperType.originalSignature.value)) { + superType.applyAnnotationsAndCommentsFrom(theirSuperType, overrideOnConflict); + break; + } + } + } + + for (final ClassMember theirMember : their.members) { + final ClassMember ourMember = findMatchingClassMember(theirMember); + if (ourMember == null) { + if (addNewMembers) { + addMember(theirMember.clone()); + } + } else { + ourMember.applyAnnotationsAndCommentsFrom(theirMember, overrideOnConflict); + } + } + } + + /** + * @return true if a corresponding EEAFile exists on the local file system + */ + public boolean exists(final Path rootPath) { + return Files.exists(rootPath.resolve(relativePath)); + } + + public Collection getClassMembers() { + return members; + } + + private void renderLine(final List lines, final Object... newLineContent) { + final var sb = new StringBuilder(); + for (final Object obj : newLineContent) { + sb.append(Objects.toString(obj)); + } + lines.add(sb.toString()); + } + + protected List renderFileContent(final Set opts) { + + final boolean omitComments = opts.contains(SaveOption.OMIT_COMMENTS); + final boolean omitEmptyLines = opts.contains(SaveOption.OMIT_EMPTY_LINES); + final boolean omitMembersWithInheritedAnnotatedSignature = opts + .contains(SaveOption.OMIT_MEMBERS_WITH_INHERITED_ANNOTATED_SIGNATURES); + final boolean omitMembersWithoutAnnotatedSignature = opts + .contains(SaveOption.OMIT_MEMBERS_WITHOUT_ANNOTATED_SIGNATURE); + final boolean omitRedundantAnnotatedSignatures = opts.contains(SaveOption.OMIT_REDUNDANT_ANNOTATED_SIGNATURES); + + final var lines = new ArrayList(); + + /* + * render class signature + */ + renderLine(lines, ExternalAnnotationProvider.CLASS_PREFIX, // + new ValueWithComment(classHeader.name.value.replace('.', '/'), + omitComments ? "" : classHeader.name.comment)); + final ValueWithComment classSignatureOriginal = classHeader.originalSignature; + if (!classSignatureOriginal.value.isEmpty()) { + renderLine(lines, " ", classSignatureOriginal.toString(omitComments)); + if (classHeader.hasNullAnnotations()) { + renderLine(lines, " ", classHeader.annotatedSignature.toString(omitComments)); + } else { + if (!omitRedundantAnnotatedSignatures) { + renderLine(lines, " ", classSignatureOriginal.toString(omitComments)); + } + } + } + + if (!omitEmptyLines) { + renderLine(lines); + } + + /* + * render super signature + */ + if (!superTypes.isEmpty()) { + for (final ClassMember superType : superTypes) { + if (omitMembersWithoutAnnotatedSignature && !superType.hasNullAnnotations()) { + continue; + } + renderLine(lines, ExternalAnnotationProvider.SUPER_PREFIX, superType.name.toString(omitComments)); + if (!superType.originalSignature.value.isEmpty()) { + renderLine(lines, " ", superType.originalSignature.toString(omitComments)); + if (superType.hasNullAnnotations()) { + renderLine(lines, " ", superType.annotatedSignature.toString(omitComments)); + } else { + if (!omitRedundantAnnotatedSignatures) { + renderLine(lines, " ", superType.originalSignature.toString(omitComments)); + } + } + } + } + if (!omitEmptyLines) { + renderLine(lines); + } + } + + /* + * render fields/methods + */ + final ClassMember lastMember = findLastElement(members); + for (final ClassMember member : members) { + final boolean keep = member.name.comment.contains(MARKER_KEEP) // + || member.originalSignature.comment.contains(MARKER_KEEP) // + || member.annotatedSignature.comment.contains(MARKER_KEEP); + + if (omitMembersWithoutAnnotatedSignature // + && !keep // + && !member.hasNullAnnotations()) { + continue; + } + if (omitMembersWithInheritedAnnotatedSignature // + && !keep // + && member.hasNullAnnotations() // + && contains(member.annotatedSignature.comment, MARKER_OVERRIDES)) { + continue; + } + + renderLine(lines, member.name.toString(omitComments)); + renderLine(lines, " ", member.originalSignature.toString(omitComments)); + + if (!omitRedundantAnnotatedSignatures || member.hasNullAnnotations()) { + renderLine(lines, " ", member.annotatedSignature.toString(omitComments)); + } + + if (member != lastMember && member.isFollowedByEmptyLine && !omitEmptyLines) { + renderLine(lines); + } + } + + removeTrailingBlanks(lines); + return lines; + } + + /** + * @return true if modifications where written to disk, false was already + * up-to-date + */ + public boolean save(final Path rootPath, final @Nullable SaveOption... opts) throws IOException { + return save(rootPath, Arrays.stream(opts).filter(Objects::nonNull).collect(Collectors.toSet())); + } + + /** + * @return true if modifications where written to disk, false was already + * up-to-date + */ + public boolean save(final Path rootPath, final Set opts) throws IOException { + final Path path = rootPath.resolve(relativePath); + + final boolean replaceExisting = opts.contains(SaveOption.REPLACE_EXISTING); + final boolean deleteIfEmpty = opts.contains(SaveOption.DELETE_IF_EMPTY); + final boolean quiet = opts.contains(SaveOption.QUIET); + + final List content = renderFileContent(opts); + + if (exists(rootPath)) { + + if (replaceExisting) { + + if (deleteIfEmpty && members.isEmpty()) { + LOG.log(Level.WARNING, "Deleting [{0}] (reason: no members)...", path.toAbsolutePath()); + Files.deleteIfExists(path); + return true; + } + + if (deleteIfEmpty && content.size() < 3) { + LOG.log(Level.WARNING, "Deleting [{0}] (reason: no annotated signatures)...", + path.toAbsolutePath()); + Files.deleteIfExists(path); + return true; + } + + final boolean needsUpdate = !content.equals(Files.readAllLines(rootPath.resolve(relativePath))); + if (!needsUpdate) { + LOG.log(Level.DEBUG, "Skipped saving [{0}] (reason: unchanged).", path.toAbsolutePath()); + return false; + } + + if (!quiet) { + LOG.log(Level.INFO, "Updating [{0}]...", path.toAbsolutePath()); + } + + } else { // !replaceExisting + + final boolean needsUpdate = !content.equals(Files.readAllLines(rootPath.resolve(relativePath))); + if (!needsUpdate) { + LOG.log(Level.DEBUG, "Skipped saving [{0}] (reason: unchanged).", path.toAbsolutePath()); + return false; + } + throw new IOException("File [" + path + "] already exists!"); + } + + } else { // !exists(rootPath) + + if (deleteIfEmpty && members.isEmpty()) { + LOG.log(Level.DEBUG, "Skipped creating [{0}] (reason: no members).", path.toAbsolutePath()); + return false; + } + + if (deleteIfEmpty && content.size() < 3) { + LOG.log(Level.DEBUG, "Skipped creating [{0}] (reason: no annotated signatures).", + path.toAbsolutePath()); + return false; + } + + if (!quiet) { + LOG.log(Level.INFO, "Creating [{0}]...", path.toAbsolutePath()); + } + + final Path parentDir = path.getParent(); + assert parentDir != null; + Files.createDirectories(parentDir); + } + + final var openOpts = replaceExisting // + ? List.of(StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING) // + : List.of(StandardOpenOption.CREATE_NEW); + Files.write(path, content, openOpts.toArray(OpenOption[]::new)); + return true; + } + + @Override + public String toString() { + return super.toString() + " [" + relativePath + "]"; + } +} diff --git a/generator/src/main/java/org/lastnpe/eea/generator/EEAGenerator.java b/generator/src/main/java/org/lastnpe/eea/generator/EEAGenerator.java new file mode 100644 index 000000000..c4fda9a52 --- /dev/null +++ b/generator/src/main/java/org/lastnpe/eea/generator/EEAGenerator.java @@ -0,0 +1,862 @@ +/* + * SPDX-FileCopyrightText: © Vegard IT GmbH (https://vegardit.com) and others. + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * - Sebastian Thomschke (Vegard IT GmbH) - initial API and implementation + */ +package org.lastnpe.eea.generator; + +import static org.lastnpe.eea.generator.internal.ClassGraphUtils.*; +import static org.lastnpe.eea.generator.internal.MiscUtils.*; + +import java.io.File; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.lang.System.Logger; +import java.lang.System.Logger.Level; +import java.lang.reflect.Modifier; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.SortedMap; +import java.util.TreeMap; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.LongAdder; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.jdt.internal.compiler.classfmt.ExternalAnnotationProvider; +import org.lastnpe.eea.generator.EEAFile.ClassMember; +import org.lastnpe.eea.generator.EEAFile.SaveOption; +import org.lastnpe.eea.generator.EEAFile.ValueWithComment; +import org.lastnpe.eea.generator.internal.Props; + +import io.github.classgraph.ClassGraph; +import io.github.classgraph.ClassInfo; +import io.github.classgraph.ClassMemberInfo; +import io.github.classgraph.ClassRefTypeSignature; +import io.github.classgraph.FieldInfo; +import io.github.classgraph.MethodInfo; +import io.github.classgraph.ScanResult; + +/** + * @author Sebastian Thomschke (Vegard IT GmbH) + */ +public abstract class EEAGenerator { + + private static final Logger LOG = System.getLogger(EEAGenerator.class.getName()); + + public static final Path DEFAULT_PROPERTES_FILE = Path.of("eea-generator.properties"); + + public static final String JVM_PROPERTY_PREFIX = "eea-generator."; + + public static final String PROPERTY_ACTION = "action"; + public static final String PROPERTY_INPUT_DIRS = "input.dirs"; + public static final String PROPERTY_INPUT_DIRS_EXTRA = PROPERTY_INPUT_DIRS + ".extra"; + public static final String PROPERTY_OUTPUT_DIR = "output.dir"; + public static final String PROPERTY_OUTPUT_DIR_DEFAULT = PROPERTY_OUTPUT_DIR + ".default"; + public static final String PROPERTY_PACKAGES_INCLUDE = "packages.include"; + public static final String PROPERTY_CLASSES_EXCLUDE = "classes.exclude"; + public static final String PROPERTY_DELETE_IF_EMPTY = "deleteIfEmpty"; + public static final String PROPERTY_OMIT_REDUNDAND_ANNOTATED_SIGNATURES = "omitRedundantAnnotatedSignatures"; + public static final String PROPERTY_OMIT_CLASS_MEMBERS_WITHOUT_NULL_ANNOTATION = "omitClassMembersWithoutNullAnnotation"; + + private static final EEAFile TEMPLATE_EXTERNALIZABLE; + private static final EEAFile TEMPLATE_SERIALIZABLE; + private static final EEAFile TEMPLATE_OBJECT; + private static final EEAFile TEMPLATE_THROWABLE; + + private static final ClassInfo OBJECT_CLASS_INFO = new ClassInfo("java.lang.Object", Modifier.PUBLIC, null) { + }; + + static { + try (var reader = getUTF8ResourceAsReader(EEAFile.class, "Externalizable.eea")) { + TEMPLATE_EXTERNALIZABLE = EEAFile.load(reader, "classpath:java/io/Externalizable.eea"); + } catch (final Exception ex) { + throw new IllegalStateException(ex); + } + + try (var reader = getUTF8ResourceAsReader(EEAFile.class, "Serializable.eea")) { + TEMPLATE_SERIALIZABLE = EEAFile.load(reader, "classpath:java/io/Serializable.eea"); + } catch (final Exception ex) { + throw new IllegalStateException(ex); + } + + try (var reader = getUTF8ResourceAsReader(EEAFile.class, "Object.eea")) { + TEMPLATE_OBJECT = EEAFile.load(reader, "classpath:java/lang/Object.eea"); + } catch (final Exception ex) { + throw new IllegalStateException(ex); + } + + try (var reader = getUTF8ResourceAsReader(EEAFile.class, "Throwable.eea")) { + TEMPLATE_THROWABLE = EEAFile.load(reader, "classpath:java/lang/Throwable.eea"); + } catch (final Exception ex) { + throw new IllegalStateException(ex); + } + } + + public static class Config { + public final String[] packages; + public final List inputDirs = new ArrayList<>(); + public final Path outputDir; + public Predicate classFilter = clazz -> true; + public boolean deleteIfEmpty = true; + public boolean omitClassMembersWithoutNullAnnotations; + public boolean omitRedundantAnnotatedSignatures; + + public Config(final Path outputDir, final String... packages) { + this.outputDir = outputDir; + this.packages = packages; + } + } + + /** + * args[0]: optional path to properties file + */ + public static void main(final String... args) throws Exception { + try { + configureJUL(); + + // load properties from file if specified + Path filePropsPath = null; + if (args.length > 0) { + filePropsPath = Path.of(args[0]); + } else if (Files.exists(DEFAULT_PROPERTES_FILE)) { + filePropsPath = DEFAULT_PROPERTES_FILE; + } + final var props = new Props(JVM_PROPERTY_PREFIX, filePropsPath); + + final String action = props.get(PROPERTY_ACTION, null).value; + + final String[] packages = "minimize".equals(action) // + ? new @NonNull String[0] // + : props.get(PROPERTY_PACKAGES_INCLUDE, null).value.split(","); + + final var classExclusionsStr = props.get(PROPERTY_CLASSES_EXCLUDE, ""); + final Pattern[] classExclusions = classExclusionsStr.value.isBlank() // + ? new Pattern[0] // + : Arrays.stream(classExclusionsStr.value.split(",")).map(Pattern::compile).toArray(Pattern[]::new); + + final var outputDirPropDefault = props.get(PROPERTY_OUTPUT_DIR_DEFAULT, "").value; + final var outputDirProp = props.get(PROPERTY_OUTPUT_DIR, + outputDirPropDefault.isEmpty() ? null : outputDirPropDefault); + Path outputDir = Path.of(outputDirProp.value); + if (outputDirProp.source instanceof final Path outputDirsPropSource && !outputDir.isAbsolute()) { + // if the specified outputDir value is relative and was source from properties + // file, then make it relative to the properties file + outputDir = outputDirsPropSource.getParent().resolve(outputDir); + } + outputDir = outputDir.normalize().toAbsolutePath(); + + final var config = new Config(outputDir, packages); + + config.deleteIfEmpty = Boolean.parseBoolean(props.get(PROPERTY_DELETE_IF_EMPTY, "true").value); + config.omitClassMembersWithoutNullAnnotations = Boolean + .parseBoolean(props.get(PROPERTY_OMIT_CLASS_MEMBERS_WITHOUT_NULL_ANNOTATION, "false").value); + config.omitRedundantAnnotatedSignatures = Boolean + .parseBoolean(props.get(PROPERTY_OMIT_REDUNDAND_ANNOTATED_SIGNATURES, "false").value); + config.classFilter = clazz -> { + for (final Pattern classExclusion : classExclusions) { + if (classExclusion.matcher(clazz.getName()).find()) + return false; + } + return true; + }; + + final var inputDirsProp = props.get(PROPERTY_INPUT_DIRS, ""); + final var inputDirsExtraProp = props.get(PROPERTY_INPUT_DIRS_EXTRA, ""); + for (final String inputDirStr : (inputDirsProp.value + ',' + inputDirsExtraProp.value).split(",")) { + if (inputDirStr.isBlank()) { + continue; + } + Path inputDir = Path.of(inputDirStr); + if (inputDirsProp.source instanceof Path && !inputDir.isAbsolute()) { + // if the specified inputDir value is relative and was source from properties + // file, + // then make it relative to the properties file + inputDir = ((Path) inputDirsProp.source).getParent().resolve(inputDir); + } + inputDir = inputDir.toAbsolutePath().normalize(); + if (!config.inputDirs.contains(inputDir)) { + config.inputDirs.add(inputDir); + if (!Files.exists(inputDir)) { + LOG.log(Level.WARNING, "Input directory: " + inputDir + " does not exist!"); + } + } + } + + LOG.log(Level.INFO, "Effective input directories: " + config.inputDirs); + LOG.log(Level.INFO, "Effective output directory: " + outputDir); + + switch (action) { + case "generate": + generateEEAFiles(config); + break; + case "minimize": + minimizeEEAFiles(config); + break; + case "validate": + validateEEAFiles(config); + break; + default: + throw new IllegalArgumentException("Unsupported value for [action] parameter: " + action); + } + } catch (final UncheckedIOException ex) { + final Exception iox = ex.getCause(); + sanitizeStackTraces(iox); + throw iox; + } catch (final Exception ex) { + sanitizeStackTraces(ex); + throw ex; + } + } + + protected static ValueWithComment computeAnnotatedSignature(final EEAFile.ClassMember member, + final ClassInfo classInfo, final ClassMemberInfo memberInfo) { + + final var templates = new ArrayList(); + if (isThrowable(classInfo)) { + templates.add(TEMPLATE_THROWABLE); // to inherit constructor parameter annotations + } + templates.add(TEMPLATE_EXTERNALIZABLE); + templates.add(TEMPLATE_SERIALIZABLE); + templates.add(TEMPLATE_OBJECT); + + for (final EEAFile template : templates) { + final ClassMember matchingMember = template.findMatchingClassMember(member); + if (matchingMember != null && matchingMember.hasNullAnnotations()) + return matchingMember.annotatedSignature; + } + + // analyzing a method + if (memberInfo instanceof final MethodInfo methodInfo) { + /* + * mark the return value of builder methods as @NonNull. + */ + if (classInfo.getName().endsWith("Builder") // + && !methodInfo.isStatic() // non-static + && methodInfo.isPublic() // + && methodInfo.getTypeDescriptor() + .getResultType() instanceof final ClassRefTypeSignature returnTypeSig // + && (methodInfo.getName().equals("build") && methodInfo.getParameterInfo().length == 0 // + || Objects.equals(returnTypeSig.getClassInfo(), classInfo))) + // (...)Lcom/example/MyBuilder -> (...)L1com/example/MyBuilder; + return new ValueWithComment(insert(member.originalSignature.value, + member.originalSignature.value.lastIndexOf(")") + 2, "1"), ""); + + /* + * mark the parameter of Comparable#compareTo(Object) as @NonNull. + */ + if (classInfo.implementsInterface("java.lang.Comparable") // + && !methodInfo.isStatic() // non-static + && member.originalSignature.value.endsWith(")I") // returns Integer + && methodInfo.isPublic() // + && methodInfo.getParameterInfo().length == 1 // only 1 parameter + && methodInfo.getParameterInfo()[0].getTypeDescriptor() instanceof ClassRefTypeSignature) + // (Lcom/example/Entity;)I -> (L1com/example/Entity;)I + return new ValueWithComment(insert(member.originalSignature.value, 2, "1"), ""); + + /* + * mark the parameter of single-parameter void methods as @NonNull, if the class + * name matches "*Listener" and the parameter type name matches "*Event" + */ + if (classInfo.isInterface() // + && classInfo.getName().endsWith("Listener") // + && !methodInfo.isStatic() // non-static + && member.originalSignature.value.endsWith(")V") // returns void + && methodInfo.getParameterInfo().length == 1 // only 1 parameter + && methodInfo.getParameterInfo()[0].getTypeDescriptor().toString().endsWith("Event")) + // (Ljava/lang/String;)V -> (L1java/lang/String;)V + return new ValueWithComment(insert(member.originalSignature.value, 2, "1"), ""); + + /* + * mark the parameter of single-parameter methods as @NonNull with signature + * matching: void (add|remove)*Listener(*Listener) + */ + if (!methodInfo.isStatic() // non-static + && (methodInfo.getName().startsWith("add") || methodInfo.getName().startsWith("remove")) // + && methodInfo.getName().endsWith("Listener") // + && member.originalSignature.value.endsWith(")V") // returns void + && methodInfo.getParameterInfo().length == 1 // only 1 parameter + && methodInfo.getParameterInfo()[0].getTypeDescriptor().toString().endsWith("Listener")) + return new ValueWithComment( // + member.originalSignature.value.startsWith("(") // + // (Lcom/example/MyListener;)V -> (L1com/example/MyListener;)V + // (TT;)V -> (T1T;)V + ? insert(member.originalSignature.value, 2, "1") // + // (TT;)V --> <1T::Lcom/example/MyListener;>(TT;)V + : insert(member.originalSignature.value, 1, "1"), // + ""); + + if (hasObjectReturnType(member)) { // returns non-void + if (hasNullableAnnotation(methodInfo.getAnnotationInfo())) + // ()Ljava/lang/String -> ()L0java/lang/String; + return new ValueWithComment(insert(member.originalSignature.value, + member.originalSignature.value.lastIndexOf(")") + 2, "0"), ""); + + if (hasNonNullAnnotation(methodInfo.getAnnotationInfo())) + // ()Ljava/lang/String -> ()L1java/lang/String; + return new ValueWithComment(insert(member.originalSignature.value, + member.originalSignature.value.lastIndexOf(")") + 2, "1"), ""); + } + } + + // analyzing a field + if (memberInfo instanceof final FieldInfo fieldInfo) { + if (hasNullableAnnotation(fieldInfo.getAnnotationInfo())) + return new ValueWithComment(insert(member.originalSignature.value, 1, "0")); + + // if the field is static and final we by default expect it to be non-null + if (fieldInfo.isStatic() && fieldInfo.isFinal() || hasNonNullAnnotation(fieldInfo.getAnnotationInfo()) // + ) + // Ljava/lang/String; -> L1java/lang/String; + return new ValueWithComment(insert(member.originalSignature.value, 1, "1")); + } + + return new ValueWithComment(member.originalSignature.value); + } + + protected static boolean hasObjectReturnType(final EEAFile.ClassMember member) { + final String sig = member.originalSignature.value; + // object return type: (Ljava/lang/String;)Ljava/lang/String; or + // (Ljava/lang/String;)TT; + // void return type: (Ljava/lang/String;)V + // primitive return type: (Ljava/lang/String;)B + return sig.charAt(sig.length() - 2) != ')'; + } + + protected static EEAFile computeEEAFile(final ClassInfo classInfo) { + LOG.log(Level.DEBUG, "Scanning class [{0}]...", classInfo.getName()); + + final var eeaFile = new EEAFile(classInfo.getName()); + + final var fields = classInfo.getDeclaredFieldInfo(); + final var methods = classInfo.getDeclaredMethodAndConstructorInfo(); + + final String typeSigStr = classInfo.getTypeSignatureStr(); + if (typeSigStr != null) { + + // class signature + final String superTypesSigStr; + if (typeSigStr.startsWith("<")) { + final String typeParams = substringBetweenBalanced(typeSigStr, '<', '>'); + if (typeParams != null) { + eeaFile.classHeader.originalSignature.value = '<' + typeParams + '>'; + eeaFile.classHeader.annotatedSignature.value = eeaFile.classHeader.originalSignature.value; + + superTypesSigStr = typeSigStr.substring(typeParams.length() + 2); + } else { + superTypesSigStr = typeSigStr; + } + } else { + superTypesSigStr = typeSigStr; + } + + final Function> superTypesSigSplitter = signature -> { + final String[] chunks = signature.split(";"); + final var result = new ArrayList(); + final var sb = new StringBuilder(); + for (final String chunk : chunks) { + sb.append(chunk); + + if (sb.length() > 0 && countOccurrences(sb, '<') == countOccurrences(sb, '>')) { + sb.deleteCharAt(0); // remove the leading L of e.g. Ljava/lang/Object; + result.add(sb.toString()); + sb.setLength(0); + } else { + sb.append(';'); + } + } + return result; + }; + + // super signatures + for (final String superTypeSig : superTypesSigSplitter.apply(superTypesSigStr)) { + if (!superTypeSig.contains("<")) { + continue; + } + final String superTypeName = superTypeSig.split("<", 2)[0]; + final String superTypeParams = '<' + substringBetweenBalanced(superTypeSig, '<', '>') + '>'; + assert superTypeParams != null; + eeaFile.superTypes.add( + new ClassMember(new ValueWithComment(superTypeName), new ValueWithComment(superTypeParams))); + } + } + eeaFile.addEmptyLine(); + + // static fields + for (final FieldInfo f : getStaticFields(fields)) { + if (classInfo.isEnum()) { + // omit enum values as they are always treated as non-null by Eclipse compiler + if (f.isFinal() && startsWith(classInfo.getTypeSignatureStr(), + "Ljava/lang/Enum<" + f.getTypeDescriptorStr() + ">;")) { + continue; + } + } + + final var member = eeaFile.addMember(f.getName(), f.getTypeSignatureOrTypeDescriptorStr()); + member.annotatedSignature = computeAnnotatedSignature(member, classInfo, f); + } + eeaFile.addEmptyLine(); + + // static methods + for (final MethodInfo m : getStaticMethods(methods)) { + final var member = eeaFile.addMember(m.getName(), m.getTypeSignatureOrTypeDescriptorStr()); + member.annotatedSignature = computeAnnotatedSignature(member, classInfo, m); + } + eeaFile.addEmptyLine(); + + // instance fields + for (final FieldInfo f : getInstanceFields(fields)) { + final var member = eeaFile.addMember(f.getName(), f.getTypeSignatureOrTypeDescriptorStr()); + member.annotatedSignature = computeAnnotatedSignature(member, classInfo, f); + } + eeaFile.addEmptyLine(); + + // instance methods + for (final MethodInfo m : getInstanceMethods(methods)) { + final var member = eeaFile.addMember(m.getName(), m.getTypeSignatureOrTypeDescriptorStr()); + member.annotatedSignature = computeAnnotatedSignature(member, classInfo, m); + } + return eeaFile; + } + + /** + * Instantiates {@link EEAFile} instances for all classes found in classpath in + * the given package or sub-packages. + * + * @param rootPackageName name the of root package to scan for classes + * @throws IllegalArgumentException if no class was found + */ + protected static SortedMap computeEEAFiles(final String rootPackageName, + final Predicate filter) { + final var result = new TreeMap(); + + try (ScanResult scanResult = new ClassGraph() // + .enableAllInfo() // + .enableSystemJarsAndModules() // + .acceptPackages(rootPackageName) // + .scan() // + ) { + final List classes = scanResult.getAllClasses(); + if (classes.isEmpty()) + throw new IllegalArgumentException( + "No classes found for package [" + rootPackageName + "] on classpath"); + + for (final ClassInfo classInfo : classes) { + if (classInfo.getName().equals("java.lang.AbstractStringBuilder")) { // https://github.com/vegardit/no-npe/issues/257 + LOG.log(Level.DEBUG, "Scanning class [{0}]...", classInfo.getName()); + final var eeaFile = computeEEAFile(classInfo); + result.put(classInfo, eeaFile); + continue; + } + + // skip uninteresting classes + if (hasPackageVisibility(classInfo) || classInfo.isPrivate() || classInfo.isAnonymousInnerClass()) { + LOG.log(Level.DEBUG, "Ignoring non-accessible classes [{0}]...", classInfo.getName()); + continue; + } + + if (!filter.test(classInfo)) { + LOG.log(Level.DEBUG, "Ignoring class excluded by filter [{0}]...", classInfo.getName()); + continue; + } + + LOG.log(Level.DEBUG, "Scanning class [{0}]...", classInfo.getName()); + final var eeaFile = computeEEAFile(classInfo); + result.put(classInfo, eeaFile); + } + } + + // TODO workaround for https://github.com/classgraph/classgraph/issues/703 + if ("java".equals(rootPackageName) || rootPackageName.startsWith("java.lang")) { + result.putIfAbsent(OBJECT_CLASS_INFO, TEMPLATE_OBJECT); + } + return result; + } + + /** + * Scans the classpath for classes of {@link Config#packages}, applies EEAs from + * files in {@link Config#inputDirs} and creates updated EEA files in + * {@link Config#outputDir}. + * + * @return number of updated and removed files + * @throws IllegalArgumentException if no class was found + */ + public static long generateEEAFiles(final Config cfg) throws IOException { + final var saveOptions = Arrays.stream(new @Nullable SaveOption[] { // + SaveOption.REPLACE_EXISTING, // + cfg.deleteIfEmpty ? SaveOption.DELETE_IF_EMPTY : null, // + cfg.omitRedundantAnnotatedSignatures ? SaveOption.OMIT_REDUNDANT_ANNOTATED_SIGNATURES : null, // + cfg.omitClassMembersWithoutNullAnnotations ? SaveOption.OMIT_MEMBERS_WITHOUT_ANNOTATED_SIGNATURE : null // + }).filter(Objects::nonNull).collect(Collectors.toSet()); + + final var eeaFiles = new HashMap(); + + long totalModifications = 0; + for (final String packageName : cfg.packages) { + LOG.log(Level.INFO, "Scanning EEA files of package [{0}]...", packageName); + + // create EEAFile instances based on class signatures found on classpath + final Map eeaFilesOfPackage = computeEEAFiles(packageName, cfg.classFilter); + LOG.log(Level.INFO, "Found {0} types on classpath.", eeaFilesOfPackage.size()); + + // extend computed EEAFiles with annotations found on matching *.eea files in + // input dirs + for (final var computedEEAFile : eeaFilesOfPackage.values()) { + for (final Path inputDir : cfg.inputDirs) { + final var existingEEAFile = EEAFile.loadIfExists(inputDir, computedEEAFile.classHeader.name.value); + if (existingEEAFile != null) { + computedEEAFile.applyAnnotationsAndCommentsFrom(existingEEAFile, true, false); + } + } + } + + eeaFiles.putAll(eeaFilesOfPackage); + + // remove obsolete files + final var pkgDeletions = new LongAdder(); + final var eeaFilesByPath = new HashMap(); + eeaFilesOfPackage.values().forEach(f -> eeaFilesByPath.put(f.relativePath, f)); + forEachFileWithExtension(cfg.outputDir.resolve(packageName.replace('.', File.separatorChar)), + ExternalAnnotationProvider.ANNOTATION_FILE_SUFFIX, path -> { + final Path relativePath = cfg.outputDir.relativize(path); + if (!eeaFilesByPath.containsKey(relativePath)) { + LOG.log(Level.WARNING, "Removing obsolete annotation file [{0}]...", path.toAbsolutePath()); + Files.delete(path); + pkgDeletions.increment(); + } + }); + + LOG.log(Level.INFO, "{0} EEA file(s) of package [{1}] updated or removed.", pkgDeletions.sum(), + packageName); + totalModifications += pkgDeletions.sum(); + } + + // will hold additional EEA files found in input dirs that are not part of the + // packages defined in {@link Config#packages} + final var superEEAFiles = new HashMap(); + final Function getSuperEEAFile = classInfo -> { + EEAFile eeaFile = eeaFiles.get(classInfo); + if (eeaFile != null) + return eeaFile; + eeaFile = superEEAFiles.get(classInfo); + if (eeaFile != null) + return eeaFile; + + for (final Path inputDir : cfg.inputDirs) { + try { + eeaFile = EEAFile.loadIfExists(inputDir, classInfo.getName().replace('.', '/')); + if (eeaFile != null) { + superEEAFiles.put(classInfo, eeaFile); + return eeaFile; + } + } catch (final IOException ex) { + throw new UncheckedIOException(ex); + } + } + return null; + }; + + // determine inherited annotated signatures + final var recomputeInheritance = new AtomicBoolean(true); + while (recomputeInheritance.get()) { + recomputeInheritance.set(false); + eeaFiles.forEach((classInfo, eeaFile) -> { + if (classInfo == OBJECT_CLASS_INFO) + return; + + final var superClasses = new ArrayList<>(classInfo.getSuperclasses()); + superClasses.add(OBJECT_CLASS_INFO); + final var interfaces = classInfo.getInterfaces(); + + for (final ClassMember member : eeaFile.getClassMembers()) { + switch (member.getType()) { + case CONSTRUCTOR: + continue; // exclude constructors + case FIELD: + if (isStaticField(classInfo, member.name.value)) { + continue; // exclude static fields + } + break; + case METHOD: + if (isStaticMethod(classInfo, member.name.value, member.originalSignature.value)) { + continue; // exclude static methods + } + break; + } + + ValueWithComment inheritableAnnotatedSignature = null; + ClassInfo inheritedFrom = null; + + /* + * 1) scan super classes (which have precedence) for inheritable annotated + * signature + */ + for (final ClassInfo superClass : superClasses) { + final EEAFile superClassEEA = superClass == OBJECT_CLASS_INFO // + ? TEMPLATE_OBJECT + : getSuperEEAFile.apply(superClass); + if (superClassEEA == null) { + continue; + } + + final var superClassMember = superClassEEA.findMatchingClassMember(member.name.value, + member.originalSignature.value); + if (superClassMember != null && superClassMember.hasNullAnnotations()) { + inheritableAnnotatedSignature = superClassMember.annotatedSignature; + inheritedFrom = superClass; + break; + } + } + + /* + * 2) scan interfaces if no inheritable annotated signature was found in any + * super class + */ + boolean hasConflictingIFaceAnnotatedSignatures = false; + if (inheritableAnnotatedSignature == null) { + for (final ClassInfo iface : interfaces) { + final EEAFile ifaceEEA = getSuperEEAFile.apply(iface); + if (ifaceEEA == null) { + continue; + } + + final var ifaceMember = ifaceEEA.findMatchingClassMember(member.name.value, + member.originalSignature.value); + if (ifaceMember == null) { + continue; + } + + if (ifaceMember.hasNullAnnotations()) { + if (inheritableAnnotatedSignature == null) { + inheritableAnnotatedSignature = ifaceMember.annotatedSignature; + inheritedFrom = iface; + } else if (!inheritableAnnotatedSignature.value + .equals(ifaceMember.annotatedSignature.value)) { + hasConflictingIFaceAnnotatedSignatures = true; + inheritableAnnotatedSignature = null; + break; + } + } + } + } + + /* + * 3) apply inheritable annotated signature if applicable + */ + // handle case when currently no annotated signature is defined + if (!member.hasNullAnnotations()) { + if (inheritableAnnotatedSignature != null) { // apply the inherited annotated signature + assert inheritedFrom != null; + if (setInheritedAnnotatedSignature(member, inheritableAnnotatedSignature, + inheritedFrom.getName())) { + recomputeInheritance.set(true); + } + } + + // handle case when an annotated signature is present already + } else { + if (hasConflictingIFaceAnnotatedSignatures || inheritableAnnotatedSignature == null) { + // do nothing + } else { + assert inheritedFrom != null; + if (inheritableAnnotatedSignature.value.equals(member.annotatedSignature.value)) { + if (setInheritedAnnotatedSignature(member, inheritableAnnotatedSignature, + inheritedFrom.getName())) { + recomputeInheritance.set(true); + } + } else if (contains(member.annotatedSignature.comment, EEAFile.MARKER_INHERITED)) { + // if the current annotated signature states it was inherited but + // a different inheritable annotated signature was found -> update the signature + if (setInheritedAnnotatedSignature(member, inheritableAnnotatedSignature, + inheritedFrom.getName())) { + recomputeInheritance.set(true); + } + } else { + // if the current annotated signature is different from the inheritable + // annotated signature + // -> add a comment that the annotated signature is overridden on purpose + if (setOverridingAnnotatedSignatureComment(member.annotatedSignature, + inheritedFrom.getName())) { + recomputeInheritance.set(true); + } + } + } + } + } + }); + } + + // save updated EEA files + long updates = 0; + for (final var computedEEAFile : eeaFiles.values()) { + if (computedEEAFile.save(cfg.outputDir, saveOptions)) { + updates++; + } + } + LOG.log(Level.INFO, "{0} EEA file(s) updated.", updates); + totalModifications += updates; + + return totalModifications; + } + + /** + * @return true if executing this method changes the value or comment of the + * target's annotated signature + */ + private static boolean setInheritedAnnotatedSignature(final ClassMember target, + final ValueWithComment inheritableAnnotatedSignature, final String parentType) { + final var oldAnnotatedSignature = target.annotatedSignature; + final var newAnnotatedSignature = new ValueWithComment(inheritableAnnotatedSignature.value); + newAnnotatedSignature.comment = "# " + EEAFile.MARKER_INHERITED + "(" + parentType + ")"; + target.annotatedSignature = newAnnotatedSignature; + return !Objects.equals(oldAnnotatedSignature.value, newAnnotatedSignature.value) // + || !Objects.equals(oldAnnotatedSignature.comment, newAnnotatedSignature.comment); + } + + /** + * @return true if executing this method changes the value or comment of the + * target's annotated signature + */ + private static boolean setOverridingAnnotatedSignatureComment(final ValueWithComment annotatedSignature, + final String parentType) { + final String oldComment = annotatedSignature.comment; + annotatedSignature.comment = "# " + EEAFile.MARKER_OVERRIDES + "(" + parentType + ")"; + return !Objects.equals(oldComment, annotatedSignature.comment); + } + + /** + * Merges and minimizes EEA files. + * + * @return number of updated and removed files + */ + public static long minimizeEEAFiles(final Config cfg) throws IOException { + final var saveOptions = Set.of( // + SaveOption.REPLACE_EXISTING, // + SaveOption.DELETE_IF_EMPTY, // + SaveOption.OMIT_COMMENTS, // + SaveOption.OMIT_EMPTY_LINES, // + SaveOption.OMIT_REDUNDANT_ANNOTATED_SIGNATURES, // + + // currently does not work reliable, see + // https://github.com/eclipse-jdt/eclipse.jdt.core/issues/2512 + // SaveOption.OMIT_MEMBERS_WITH_INHERITED_ANNOTATED_SIGNATURES, // + + SaveOption.OMIT_MEMBERS_WITHOUT_ANNOTATED_SIGNATURE, // + SaveOption.QUIET); + + if (cfg.inputDirs.isEmpty()) + throw new IllegalArgumentException("No input.dirs specified!"); + + LOG.log(Level.INFO, "Minimizing EEA files..."); + + final var mergedEEAFiles = new TreeMap(); + for (final Path inputDir : cfg.inputDirs) { + LOG.log(Level.INFO, "Loading EEA files from [{0}]...", inputDir); + forEachFileWithExtension(inputDir, ExternalAnnotationProvider.ANNOTATION_FILE_SUFFIX, // + path -> { + final Path relativePath = inputDir.relativize(path); + final EEAFile mergedEEAFile = mergedEEAFiles.get(relativePath); + final String expectedClassName = relativePathToClassName(relativePath); + + final EEAFile sourceEEAFile = EEAFile.load(inputDir, expectedClassName); + if (mergedEEAFile == null) { + mergedEEAFiles.put(relativePath, sourceEEAFile); + } else { + mergedEEAFile.applyAnnotationsAndCommentsFrom(sourceEEAFile, false, true); + } + }); + } + LOG.log(Level.INFO, "Found {0} types.", mergedEEAFiles.size()); + + final var totalModifications = new LongAdder(); + for (final EEAFile eeaFile : mergedEEAFiles.values()) { + if (eeaFile.save(cfg.outputDir, saveOptions)) { + totalModifications.increment(); + } + } + + // remove obsolete files + forEachFileWithExtension(cfg.outputDir, ExternalAnnotationProvider.ANNOTATION_FILE_SUFFIX, // + path -> { + final Path relativePath = cfg.outputDir.relativize(path); + if (!mergedEEAFiles.containsKey(relativePath)) { + LOG.log(Level.DEBUG, "Removing obsolete annotation file [{0}]...", path.toAbsolutePath()); + Files.delete(path); + totalModifications.increment(); + } + }); + + LOG.log(Level.INFO, "{0} EEA file(s) minimized or removed.", totalModifications.sum()); + return totalModifications.sum(); + } + + private static String relativePathToClassName(final Path relativePath) { + return removeSuffix(relativePath.toString(), ExternalAnnotationProvider.ANNOTATION_FILE_SUFFIX) + .replace(File.separatorChar, '.'); + } + + /** + * Recursively validates all EEA files for the given {@link Config#packages} in + * {@link Config#outputDir}. + * + * @return number of validated files + * @throws IllegalArgumentException if no class was found + */ + public static long validateEEAFiles(final Config config) throws IOException { + long totalValidations = 0; + + for (final String packageName : config.packages) { + LOG.log(Level.INFO, "Validating EEA files of package [{0}]...", packageName); + + final Map eeaFilesOfPkg = remap(computeEEAFiles(packageName, config.classFilter), + v -> v.relativePath); + LOG.log(Level.INFO, "Found {0} types on classpath.", eeaFilesOfPkg.size()); + + final Path packagePath = config.outputDir.resolve(packageName.replace('.', File.separatorChar)); + final long count = forEachFileWithExtension(packagePath, ExternalAnnotationProvider.ANNOTATION_FILE_SUFFIX, // + path -> { + final Path relativePath = config.outputDir.relativize(path); + final String expectedClassName = relativePathToClassName(relativePath); + + // ensure if the type actually exists on the class path + final var computedEEAFile = eeaFilesOfPkg.get(relativePath); + if (computedEEAFile == null) + throw new IllegalStateException("Type [" + expectedClassName + "] defined in [" + path + + "] no found on classpath."); + + // try to parse the EEA file + final var parsedEEAFile = EEAFile.load(path); + + // ensure the EEA file does not contain declarations of non-existing + // fields/methods + for (final ClassMember parsedMember : parsedEEAFile.getClassMembers()) { + if (computedEEAFile.findMatchingClassMember(parsedMember) == null) { + final var candidates = computedEEAFile.getClassMembers().stream() // + .filter(m -> m.name.equals(parsedMember.name)) // + .map(m -> m.name + "\n" + " " + m.originalSignature) // + .collect(Collectors.joining("\n")); + throw new IllegalStateException("Unknown member declaration found in [" + path + "]:\n" + + parsedMember + + (candidates.length() > 0 ? "\nPotential candidates: \n" + candidates : "")); + } + } + }); + LOG.log(Level.INFO, "{0} EEA file(s) of package [{1}] validated.", count, packageName); + totalValidations += count; + } + return totalValidations; + } +} diff --git a/generator/src/main/java/org/lastnpe/eea/generator/internal/ClassGraphUtils.java b/generator/src/main/java/org/lastnpe/eea/generator/internal/ClassGraphUtils.java new file mode 100644 index 000000000..264cb252c --- /dev/null +++ b/generator/src/main/java/org/lastnpe/eea/generator/internal/ClassGraphUtils.java @@ -0,0 +1,223 @@ +/* + * SPDX-FileCopyrightText: © Vegard IT GmbH (https://vegardit.com) and others. + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * - Sebastian Thomschke (Vegard IT GmbH) - initial API and implementation + */ +package org.lastnpe.eea.generator.internal; + +import java.util.HashSet; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; + +import io.github.classgraph.AnnotationInfoList; +import io.github.classgraph.ClassInfo; +import io.github.classgraph.FieldInfo; +import io.github.classgraph.FieldInfoList; +import io.github.classgraph.MethodInfo; +import io.github.classgraph.MethodInfoList; + +/** + * @author Sebastian Thomschke (Vegard IT GmbH) + */ +public final class ClassGraphUtils { + + private static final Set NULLABLE_ANNOTATIONS = Set.of( // + "android.annotation.Nullable", // + "android.support.annotation.Nullable", // + "androidx.annotation.Nullable", // + "com.mongodb.lang.Nullable", // + "com.sun.istack.internal.Nullable", // + "edu.umd.cs.findbugs.annotations.Nullable", // + "io.reactivex.annotations.Nullable", // + "io.reactivex.rxjava3.annotations.Nullable", // + "io.smallrye.common.constraint.Nullable", // + "io.vertx.codegen.annotations.Nullable", // + "jakarta.annotation.CheckForNull", // + "jakarta.annotation.Nullable", // + "javax.annotation.CheckForNull", // + "javax.annotation.Nullable", // + "net.bytebuddy.utility.nullability.AlwaysNull", // + "net.bytebuddy.utility.nullability.MaybeNull", // + "org.checkerframework.checker.nullness.compatqual.NullableDecl", // + "org.checkerframework.checker.nullness.compatqual.NullableType", // + "org.checkerframework.checker.nullness.qual.Nullable", // + "org.eclipse.jdt.annotation.Nullable", // + "org.eclipse.sisu.Nullable", // + "org.jetbrains.annotations.Nullable", // + "org.jmlspecs.annotation.Nullable", // + "org.netbeans.api.annotations.common.CheckForNull", // + "org.netbeans.api.annotations.common.NullAllowed", // + "org.netbeans.api.annotations.common.NullUnknown", // + "org.springframework.lang.Nullable", // + "org.sonatype.inject.Nullable", // + "org.wildfly.common.annotation.Nullable", // + "reactor.util.annotation.Nullable"); + + private static final Set NONNULL_ANNOTATIONS = Set.of( // + "android.annotation.NonNull", // + "android.support.annotation.NonNull", // + "androidx.annotation.NonNull", // + "com.sun.istack.internal.NotNull", // + "com.mongodb.lang.NonNull", // + "edu.umd.cs.findbugs.annotations.NonNull", // + "io.reactivex.annotations.NonNull", // + "io.reactivex.rxjava3.annotations.NonNull", // + "javax.annotation.Nonnull", // + "javax.validation.constraints.NotNull", // + "jakarta.annotation.Nonnull", // + "jakarta.validation.constraints.NotNull", // + "lombok.NonNull", // + "net.bytebuddy.utility.nullability.NeverNull", // + "org.checkerframework.checker.nullness.compatqual.NonNullDecl", // + "org.checkerframework.checker.nullness.compatqual.NonNullType", // + "org.checkerframework.checker.nullness.qual.NonNull", // + "org.eclipse.jdt.annotation.NonNull", // + "org.jetbrains.annotations.NotNull", // + "org.jmlspecs.annotation.NonNull", // + "org.netbeans.api.annotations.common.NonNull", // + "org.springframework.lang.NonNull", // + "org.wildfly.common.annotation.NotNull", // + "reactor.util.annotation.NonNull"); + + public static Set getDirectInterfaces(final ClassInfo classInfo) { + final var directInterfaces = new HashSet<>(classInfo.getInterfaces()); + if (classInfo.isInterface()) { + classInfo.getInterfaces().forEach(superIFace -> directInterfaces.removeAll(superIFace.getInterfaces())); + } else { + ClassInfo superclassInfo = classInfo.getSuperclass(); + while (superclassInfo != null) { + directInterfaces.removeAll(superclassInfo.getInterfaces()); + superclassInfo = superclassInfo.getSuperclass(); + } + } + return directInterfaces; + } + + /** + * @param selectStatic if true static fields are returned otherwise instance + * fields + * @return a sorted set of {@link FieldInfo} instances for all public or + * protected non-synthetic non-primitive fields + */ + private static SortedSet getFilteredAndSortedFields(final FieldInfoList fields, + final boolean selectStatic) { + final var result = new TreeSet((f1, f2) -> { + final int rc = f1.getName().compareTo(f2.getName()); + return rc == 0 + ? f1.getTypeSignatureOrTypeDescriptorStr().compareTo(f2.getTypeSignatureOrTypeDescriptorStr()) + : rc; + }); + + for (final var f : fields) { + if (!f.isSynthetic() // + && (selectStatic ? f.isStatic() : !f.isStatic()) // + && (f.isProtected() || f.isPublic()) // + && (f.getTypeSignatureOrTypeDescriptorStr().contains(";") + || f.getTypeSignatureOrTypeDescriptorStr().contains("["))) { + result.add(f); + } + } + return result; + } + + /** + * @param selectStatic if true static methods are returned otherwise instance + * methods + * @return a sorted set of {@link MethodInfo} instances for all public or + * protected non-synthetic methods with a non-primitive return value or + * at least one non-primitive method parameter + */ + private static SortedSet getFilteredAndSortedMethods(final MethodInfoList methods, + final boolean selectStatic) { + final var result = new TreeSet((m1, m2) -> { + final int rc = m1.getName().compareTo(m2.getName()); + return rc == 0 + ? m1.getTypeSignatureOrTypeDescriptorStr().compareTo(m2.getTypeSignatureOrTypeDescriptorStr()) + : rc; + }); + + for (final var m : methods) { + // omit auto-generated methods of enums as they are always treated as non-null + // by eclipse compiler + if (m.getClassInfo().isEnum()) { + switch (m.getName()) { + case "values": + if (m.getParameterInfo().length == 0) { + continue; + } + break; + case "valueOf": + if (m.getParameterInfo().length == 1 + && String.class.getName().equals(m.getParameterInfo()[0].getTypeDescriptor().toString())) { + continue; + } + break; + } + } + if (!m.isSynthetic() // + && (selectStatic ? m.isStatic() : !m.isStatic()) // + && (m.isProtected() || m.isPublic()) // + && (m.getTypeSignatureOrTypeDescriptorStr().contains(";") + || m.getTypeSignatureOrTypeDescriptorStr().contains("["))) { + result.add(m); + } + } + return result; + } + + public static SortedSet getInstanceFields(final FieldInfoList fields) { + return getFilteredAndSortedFields(fields, false); + } + + public static SortedSet getInstanceMethods(final MethodInfoList methods) { + return getFilteredAndSortedMethods(methods, false); + } + + public static SortedSet getStaticFields(final FieldInfoList fields) { + return getFilteredAndSortedFields(fields, true); + } + + public static SortedSet getStaticMethods(final MethodInfoList methods) { + return getFilteredAndSortedMethods(methods, true); + } + + public static boolean hasNonNullAnnotation(final AnnotationInfoList annos) { + return annos.stream().anyMatch(a -> NONNULL_ANNOTATIONS.contains(a.getName())); + } + + public static boolean hasNullableAnnotation(final AnnotationInfoList annos) { + return annos.stream().anyMatch(a -> NULLABLE_ANNOTATIONS.contains(a.getName())); + } + + public static boolean hasSuperclass(final ClassInfo classInfo, final String superClassName) { + return !classInfo.getSuperclasses().filter(c -> c.getName().equals(superClassName)).isEmpty(); + } + + public static boolean hasPackageVisibility(final ClassInfo classInfo) { + return !classInfo.isPublic() && !classInfo.isPrivate() && !classInfo.isProtected(); + } + + public static boolean isStaticField(final ClassInfo classInfo, final String fieldName) { + final var fieldInfo = classInfo.getDeclaredFieldInfo(fieldName); + if (fieldInfo == null) + return false; + return fieldInfo.isStatic(); + } + + public static boolean isStaticMethod(final ClassInfo classInfo, final String methodName, + final String methodSignature) { + return classInfo.getDeclaredMethodInfo(methodName).stream() // + .anyMatch(methodInfo -> methodInfo.isStatic() // + && methodSignature.equals(methodInfo.getTypeSignatureOrTypeDescriptorStr())); + } + + public static boolean isThrowable(final ClassInfo classInfo) { + return hasSuperclass(classInfo, "java.lang.Throwable"); + } + + private ClassGraphUtils() { + } +} diff --git a/generator/src/main/java/org/lastnpe/eea/generator/internal/CompositeKey.java b/generator/src/main/java/org/lastnpe/eea/generator/internal/CompositeKey.java new file mode 100644 index 000000000..77b37a754 --- /dev/null +++ b/generator/src/main/java/org/lastnpe/eea/generator/internal/CompositeKey.java @@ -0,0 +1,47 @@ +/* + * SPDX-FileCopyrightText: © Vegard IT GmbH (https://vegardit.com) and others. + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * - Sebastian Thomschke (Vegard IT GmbH) - initial API and implementation + */ +package org.lastnpe.eea.generator.internal; + +import java.util.Arrays; + +import org.eclipse.jdt.annotation.Nullable; + +/** + * @author Sebastian Thomschke (Vegard IT GmbH) + */ +public final class CompositeKey { + + private final @Nullable Object[] keys; + + public CompositeKey(final @Nullable Object... keys) { + this.keys = keys; + } + + @Override + public boolean equals(final @Nullable Object obj) { + if (this == obj) + return true; + if (obj == null || getClass() != obj.getClass()) + return false; + final CompositeKey other = (CompositeKey) obj; + return Arrays.deepEquals(keys, other.keys); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + Arrays.deepHashCode(keys); + return result; + } + + @Override + public String toString() { + return "CompositeKey [keys=" + Arrays.toString(keys) + "]"; + } +} diff --git a/generator/src/main/java/org/lastnpe/eea/generator/internal/MiscUtils.java b/generator/src/main/java/org/lastnpe/eea/generator/internal/MiscUtils.java new file mode 100644 index 000000000..61ff8eabf --- /dev/null +++ b/generator/src/main/java/org/lastnpe/eea/generator/internal/MiscUtils.java @@ -0,0 +1,263 @@ +/* + * SPDX-FileCopyrightText: © Vegard IT GmbH (https://vegardit.com) and others. + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * - Sebastian Thomschke (Vegard IT GmbH) - initial API and implementation + */ +package org.lastnpe.eea.generator.internal; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.UncheckedIOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.function.UnaryOperator; +import java.util.logging.ConsoleHandler; +import java.util.logging.LogRecord; +import java.util.logging.Logger; +import java.util.logging.SimpleFormatter; +import java.util.regex.Pattern; +import java.util.stream.Stream; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; + +/** + * @author Sebastian Thomschke (Vegard IT GmbH) + */ +public final class MiscUtils { + + @FunctionalInterface + public interface ThrowingConsumer { + void accept(V v) throws T; + } + + public static boolean arrayContains(final Object @Nullable [] searchIn, final Object searchFor) { + if (searchIn == null || searchIn.length == 0) + return false; + for (final var e : searchIn) { + if (Objects.equals(e, searchFor)) + return true; + } + return false; + } + + private static boolean isJULConfigured = false; + + public static boolean contains(final @Nullable String searchIn, final String searchFor) { + return searchIn != null && searchIn.contains(searchFor); + } + + public static void configureJUL() { + if (isJULConfigured) + return; + final var mainLogger = Logger.getLogger("com.vegardit.no_npe"); + mainLogger.setUseParentHandlers(false); + final var handler = new ConsoleHandler(); + handler.setFormatter(new SimpleFormatter() { + @Override + public synchronized String format(final LogRecord lr) { + var sourceClassName = lr.getSourceClassName(); + if (sourceClassName != null) { + sourceClassName = sourceClassName.substring(sourceClassName.lastIndexOf('.') + 1); + } + var msg = lr.getMessage(); + if (msg != null) { + msg = MessageFormat.format(msg, lr.getParameters()); + } + return String.format("[%1$s] %2$s | %3$s %n", lr.getLevel().getLocalizedName(), sourceClassName, msg); + } + }); + mainLogger.addHandler(handler); + isJULConfigured = true; + } + + public static BufferedReader getUTF8ResourceAsReader(final Class clazz, final String resourceName) { + final var is = clazz.getResourceAsStream(resourceName); + if (is == null) + throw new IllegalArgumentException("Resource not found: " + resourceName); + return new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8)); + } + + public static @Nullable E findLastElement(final List list) { + if (list.isEmpty()) + return null; + return list.get(list.size() - 1); + } + + /** + * @return total number of matching files + */ + public static long forEachFileWithExtension(final Path startPath, final String fileExtension, + final ThrowingConsumer onFile) throws IOException { + if (!Files.exists(startPath)) + return 0; + + final long[] count = { 0 }; + try (Stream paths = Files.walk(startPath)) { + paths // + .filter(Files::isRegularFile) // + .filter(path -> path.getFileName().toString().endsWith(fileExtension)) // + .forEach(path -> { + try { + count[0]++; + onFile.accept(path); + } catch (final IOException ex) { + throw new UncheckedIOException(ex); + } + }); + } catch (final UncheckedIOException ex) { + throw ex.getCause(); + } + return count[0]; + } + + /** + * Replaces the given capturing group of all matches. + */ + public static String replaceAll(final String searchIn, final Pattern searchFor, final int groupToReplace, + final UnaryOperator replaceWith) { + if (searchIn.isEmpty()) + return searchIn; + final var matcher = searchFor.matcher(searchIn); + int lastPos = 0; + final var sb = new StringBuilder(); + while (matcher.find()) { + final var start = matcher.start(groupToReplace); + sb.append(searchIn.substring(lastPos, start)); + final var textToReplace = matcher.group(groupToReplace); + assert textToReplace != null; + sb.append(replaceWith.apply(textToReplace)); + lastPos = matcher.end(groupToReplace); + } + if (lastPos == 0) + return searchIn; + + sb.append(searchIn.substring(lastPos)); + return sb.toString(); + } + + public static String removeSuffix(final String searchIn, final String remove) { + return !remove.isEmpty() && searchIn.endsWith(remove) // + ? searchIn.substring(0, searchIn.length() - remove.length()) + : searchIn; + } + + public static boolean startsWith(@Nullable final String searchIn, final String searchFor) { + if (searchIn == null) + return false; + return searchIn.startsWith(searchFor); + } + + public static @Nullable String substringBetweenBalanced(final String searchIn, final char startDelimiter, + final char endDelimiter) { + int depth = 0; + int lastStartDelimIdx = -1; + for (int i = 0, l = searchIn.length(); i < l; i++) { + final char c = searchIn.charAt(i); + if (c == startDelimiter) { + depth++; + if (depth == 1) { + lastStartDelimIdx = i + 1; + } + } else if (c == endDelimiter) { + if (depth == 1) + return searchIn.substring(lastStartDelimIdx, i); + if (depth > 0) { + depth--; + } + } + } + return null; + } + + public static int countOccurrences(final CharSequence searchIn, final char searchFor) { + return (int) searchIn.chars() // + .filter(ch -> ch == searchFor) // + .count(); + } + + public static @Nullable T sanitizeStackTraces(final @Nullable T ex) { + if (ex == null) + return null; + + final var stacktrace = ex.getStackTrace(); + if (stacktrace.length < 3) + return ex; + + final var sanitized = new ArrayList(stacktrace.length - 2); + // we leave the first two elements untouched to keep the context + sanitized.add(stacktrace[0]); + sanitized.add(stacktrace[1]); + for (int i = 2, l = stacktrace.length; i < l; i++) { + final StackTraceElement ste = stacktrace[i]; + final String className = ste.getClassName(); + if ("java.lang.reflect.Method".equals(className) // + || className.startsWith("java.util.stream.") // + || "java.util.Iterator".equals(className) && "forEachRemaining".equals(ste.getMethodName())// + || "java.util.Spliterators$IteratorSpliterator".equals(className) + && "forEachRemaining".equals(ste.getMethodName())// + || className.startsWith("sun.reflect.") // + || className.startsWith("sun.proxy.$Proxy", 4) // + || className.startsWith("org.codehaus.groovy.runtime.") // + || className.startsWith("org.codehaus.groovy.reflection.") // + || className.startsWith("groovy.lang.Meta") // + || className.startsWith("groovy.lang.Closure") // + ) { + continue; + } + sanitized.add(ste); + } + + @SuppressWarnings("null") + final @NonNull StackTraceElement[] arr = sanitized.toArray(StackTraceElement[]::new); + ex.setStackTrace(arr); + if (ex.getCause() != null) { + sanitizeStackTraces(ex.getCause()); + } + return ex; + } + + public static String insert(final String str, final int pos, final String insertion) { + return str.substring(0, pos) + insertion + str.substring(pos); + } + + public static Map remap(final Map map, final Function keyMapper) { + final var newMap = new HashMap(); + for (final V v : map.values()) { + newMap.put(keyMapper.apply(v), v); + } + return newMap; + } + + public static Map remap(final Map map, final BiFunction keyMapper, + final BiFunction valueMapper) { + final var newMap = new HashMap(); + for (final var e : map.entrySet()) { + newMap.put(keyMapper.apply(e.getKey(), e.getValue()), valueMapper.apply(e.getKey(), e.getValue())); + } + return newMap; + } + + public static void removeTrailingBlanks(final List strings) { + int i = strings.size() - 1; + while (i >= 0 && strings.get(i).isBlank()) { + strings.remove(i); + i--; + } + } + + private MiscUtils() { + } +} diff --git a/generator/src/main/java/org/lastnpe/eea/generator/internal/Props.java b/generator/src/main/java/org/lastnpe/eea/generator/internal/Props.java new file mode 100644 index 000000000..2ee2f46af --- /dev/null +++ b/generator/src/main/java/org/lastnpe/eea/generator/internal/Props.java @@ -0,0 +1,104 @@ +/* + * SPDX-FileCopyrightText: © Vegard IT GmbH (https://vegardit.com) and others. + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * - Sebastian Thomschke (Vegard IT GmbH) - initial API and implementation + */ +package org.lastnpe.eea.generator.internal; + +import java.io.IOException; +import java.lang.System.Logger; +import java.lang.System.Logger.Level; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Properties; + +import org.eclipse.jdt.annotation.Nullable; + +/** + * @author Sebastian Thomschke (Vegard IT GmbH) + */ +public final class Props { + + private static final Logger LOG = System.getLogger(Props.class.getName()); + + public static class Prop { + public static final String SOURCE_JVM_SYSTEM_ROPERTY = "JVM system property"; + public static final String SOURCE_DEFAULT_VALUE = "default value"; + + /** + * Either a reference to {@link Props#propertiesFile} or + * {@link Prop#SOURCE_JVM_SYSTEM_ROPERTY} or {@link Prop#SOURCE_DEFAULT_VALUE} + */ + public final Object source; + public final String name; + public final T value; + + public Prop(final Object source, final String name, final T value) { + this.source = source; + this.name = name; + this.value = value; + } + + @Override + public String toString() { + return "Prop [" // + + "name=" + name + ", " // + + "value=" + value + ", " // + + "source=" + source // + + "]"; + } + } + + public final String jvmPropertyPrefix; + public final @Nullable Path propertiesFile; + private final @Nullable Properties properties; + + public Props(final String jvmPropertyPrefix, final @Nullable Path propertiesFilePath) throws IOException { + this.jvmPropertyPrefix = jvmPropertyPrefix; + propertiesFile = propertiesFilePath; + + if (propertiesFilePath == null) { + properties = null; + } else { + final var properties = this.properties = new Properties(); + try (var r = Files.newBufferedReader(propertiesFilePath)) { + properties.load(r); + } + } + } + + public Prop get(final String propName, final @Nullable String defaultValue) { + var propValue = System.getProperty(jvmPropertyPrefix + propName); + Prop prop = null; + if (propValue != null) { + prop = new Prop<>(Prop.SOURCE_JVM_SYSTEM_ROPERTY, propName, propValue); + } + + final var properties = this.properties; + if (prop == null && properties != null) { + propValue = properties.getProperty(propName); + if (propValue != null) { + assert propertiesFile != null; + prop = new Prop<>(propertiesFile, propName, propValue); + } + } + + if (prop == null && defaultValue != null) { + prop = new Prop<>(Prop.SOURCE_DEFAULT_VALUE, propName, defaultValue); + } + + if (prop != null) { + LOG.log(Level.INFO, "Resolved property [{0}] \"{1}\" << {2}", prop.name, prop.value, prop.source); + return prop; + } + + if (propertiesFile != null) + throw new IllegalArgumentException( + "Required property [" + propName + "] not found in [" + propertiesFile + "]!"); + + throw new IllegalArgumentException( + "Required " + Prop.SOURCE_JVM_SYSTEM_ROPERTY + " [" + propName + "] not found!"); + } +} diff --git a/generator/src/main/java/org/lastnpe/eea/generator/internal/package-info.java b/generator/src/main/java/org/lastnpe/eea/generator/internal/package-info.java new file mode 100644 index 000000000..c866dbfcb --- /dev/null +++ b/generator/src/main/java/org/lastnpe/eea/generator/internal/package-info.java @@ -0,0 +1,6 @@ +@NonNullByDefault({ ARRAY_CONTENTS, FIELD, PARAMETER, RETURN_TYPE, TYPE_ARGUMENT, TYPE_BOUND, TYPE_PARAMETER }) +package org.lastnpe.eea.generator.internal; + +import static org.eclipse.jdt.annotation.DefaultLocation.*; + +import org.eclipse.jdt.annotation.NonNullByDefault; diff --git a/generator/src/main/java/org/lastnpe/eea/generator/package-info.java b/generator/src/main/java/org/lastnpe/eea/generator/package-info.java new file mode 100644 index 000000000..b8a74f413 --- /dev/null +++ b/generator/src/main/java/org/lastnpe/eea/generator/package-info.java @@ -0,0 +1,6 @@ +@NonNullByDefault({ ARRAY_CONTENTS, FIELD, PARAMETER, RETURN_TYPE, TYPE_ARGUMENT, TYPE_BOUND, TYPE_PARAMETER }) +package org.lastnpe.eea.generator; + +import static org.eclipse.jdt.annotation.DefaultLocation.*; + +import org.eclipse.jdt.annotation.NonNullByDefault; diff --git a/generator/src/main/resources/org/lastnpe/eea/generator/Externalizable.eea b/generator/src/main/resources/org/lastnpe/eea/generator/Externalizable.eea new file mode 100644 index 000000000..066524bb4 --- /dev/null +++ b/generator/src/main/resources/org/lastnpe/eea/generator/Externalizable.eea @@ -0,0 +1,8 @@ +class java/io/Externalizable + +readExternal + (Ljava/io/ObjectInput;)V + (L1java/io/ObjectInput;)V +writeExternal + (Ljava/io/ObjectOutput;)V + (L1java/io/ObjectOutput;)V diff --git a/generator/src/main/resources/org/lastnpe/eea/generator/Object.eea b/generator/src/main/resources/org/lastnpe/eea/generator/Object.eea new file mode 100644 index 000000000..04066550b --- /dev/null +++ b/generator/src/main/resources/org/lastnpe/eea/generator/Object.eea @@ -0,0 +1,14 @@ +class java/lang/Object + +clone + ()Ljava/lang/Object; + ()L1java/lang/Object; +equals + (Ljava/lang/Object;)Z + (L0java/lang/Object;)Z +getClass + ()Ljava/lang/Class<*>; + ()L1java/lang/Class<*>; +toString + ()Ljava/lang/String; + ()L1java/lang/String; diff --git a/generator/src/main/resources/org/lastnpe/eea/generator/Serializable.eea b/generator/src/main/resources/org/lastnpe/eea/generator/Serializable.eea new file mode 100644 index 000000000..a4b3a37de --- /dev/null +++ b/generator/src/main/resources/org/lastnpe/eea/generator/Serializable.eea @@ -0,0 +1,14 @@ +class java/io/Serializable + +readObject + ()Ljava/lang/Object; + ()L1java/lang/Object; +readResolve + ()Ljava/lang/Object; + ()L1java/lang/Object; +writeObject + (Ljava/lang/Object;)V + (L1java/lang/Object;)V +writeReplace + ()Ljava/lang/Object; + ()L1java/lang/Object; diff --git a/generator/src/main/resources/org/lastnpe/eea/generator/Throwable.eea b/generator/src/main/resources/org/lastnpe/eea/generator/Throwable.eea new file mode 100644 index 000000000..0ebe04425 --- /dev/null +++ b/generator/src/main/resources/org/lastnpe/eea/generator/Throwable.eea @@ -0,0 +1,14 @@ +class java/lang/Throwable + + + (Ljava/lang/String;)V + (L0java/lang/String;)V + + (Ljava/lang/String;Ljava/lang/Throwable;)V + (L0java/lang/String;L0java/lang/Throwable;)V + + (Ljava/lang/String;Ljava/lang/Throwable;ZZ)V + (L0java/lang/String;L0java/lang/Throwable;ZZ)V + + (Ljava/lang/Throwable;)V + (L0java/lang/Throwable;)V diff --git a/generator/src/test/java/org/lastnpe/eea/generator/EEAFileInheritanceTest.java b/generator/src/test/java/org/lastnpe/eea/generator/EEAFileInheritanceTest.java new file mode 100644 index 000000000..7196dd022 --- /dev/null +++ b/generator/src/test/java/org/lastnpe/eea/generator/EEAFileInheritanceTest.java @@ -0,0 +1,177 @@ +/* + * SPDX-FileCopyrightText: © Vegard IT GmbH (https://vegardit.com) and contributors. + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * - Sebastian Thomschke (Vegard IT GmbH) - initial API and implementation + */ +package org.lastnpe.eea.generator; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.lastnpe.eea.generator.internal.MiscUtils.remap; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentMap; +import java.util.stream.Collectors; + +import org.junit.jupiter.api.Test; + +/** + * @author Sebastian Thomschke (Vegard IT GmbH) + */ +class EEAFileInheritanceTest { + + public static class A0 { + } + + public static class A> { + } + + public static class B extends A> { + } + + public static class C extends A> { + } + + public static class D> extends A { + } + + public interface I> { + } + + public class J implements I> { + } + + public abstract class K extends Throwable implements I>, Comparable { + private static final long serialVersionUID = 1L; + } + + @Test + void testGenericInheritance() { + final var computedEEAFiles = EEAGenerator.computeEEAFiles(EEAFileInheritanceTest.class.getPackageName(), + c -> true); + final var classInfoByClassName = remap(computedEEAFiles, (k, v) -> v.classHeader.name.value, (k, v) -> k); + final var computedEEAFilesByClassName = remap(computedEEAFiles, v -> v.classHeader.name.value); + + final var classInfoA = classInfoByClassName.get(A.class.getName()); + final var classInfoB = classInfoByClassName.get(B.class.getName()); + final var classInfoC = classInfoByClassName.get(C.class.getName()); + final var classInfoD = classInfoByClassName.get(D.class.getName()); + final var classInfoI = classInfoByClassName.get(I.class.getName()); + final var classInfoJ = classInfoByClassName.get(J.class.getName()); + final var classInfoK = classInfoByClassName.get(K.class.getName()); + assert classInfoA != null; + assert classInfoB != null; + assert classInfoC != null; + assert classInfoD != null; + assert classInfoI != null; + assert classInfoJ != null; + assert classInfoK != null; + + assertThat(classInfoA.getTypeSignatureStr()) // + .isEqualTo(";>Ljava/lang/Object;"); + assertThat(classInfoB.getTypeSignatureStr()) // + .isEqualTo("Lorg/lastnpe/eea/generator/EEAFileInheritanceTest$A;>;"); + assertThat(classInfoC.getTypeSignatureStr()) // + .isEqualTo( + "Lorg/lastnpe/eea/generator/EEAFileInheritanceTest$A;>;"); + assertThat(classInfoD.getTypeSignatureStr()) // + .isEqualTo( + ";>Lorg/lastnpe/eea/generator/EEAFileInheritanceTest$A;"); + assertThat(classInfoI.getTypeSignatureStr()) // + .isEqualTo(";>Ljava/lang/Object;"); + assertThat(classInfoJ.getTypeSignatureStr()) // + .isEqualTo( + "Ljava/lang/Object;Lorg/lastnpe/eea/generator/EEAFileInheritanceTest$I;>;"); + assertThat(classInfoK.getTypeSignatureStr()) // + .isEqualTo( + "Ljava/lang/Throwable;Lorg/lastnpe/eea/generator/EEAFileInheritanceTest$I;>;" + + "Ljava/lang/Comparable;"); + + final var eeaFileA = computedEEAFilesByClassName.get(A.class.getName()); + final var eeaFileB = computedEEAFilesByClassName.get(B.class.getName()); + final var eeaFileC = computedEEAFilesByClassName.get(C.class.getName()); + final var eeaFileD = computedEEAFilesByClassName.get(D.class.getName()); + final var eeaFileI = computedEEAFilesByClassName.get(I.class.getName()); + final var eeaFileJ = computedEEAFilesByClassName.get(J.class.getName()); + final var eeaFileK = computedEEAFilesByClassName.get(K.class.getName()); + assert eeaFileA != null; + assert eeaFileB != null; + assert eeaFileC != null; + assert eeaFileD != null; + assert eeaFileI != null; + assert eeaFileJ != null; + assert eeaFileK != null; + + final var linesA = eeaFileA.renderFileContent(Set.of()).stream().collect(Collectors.joining("\n")); + final var linesB = eeaFileB.renderFileContent(Set.of()).stream().collect(Collectors.joining("\n")); + final var linesC = eeaFileC.renderFileContent(Set.of()).stream().collect(Collectors.joining("\n")); + final var linesD = eeaFileD.renderFileContent(Set.of()).stream().collect(Collectors.joining("\n")); + final var linesI = eeaFileI.renderFileContent(Set.of()).stream().collect(Collectors.joining("\n")); + final var linesJ = eeaFileJ.renderFileContent(Set.of()).stream().collect(Collectors.joining("\n")); + final var linesK = eeaFileK.renderFileContent(Set.of()).stream().collect(Collectors.joining("\n")); + + assertThat(linesA).isEqualTo(List.of( // + "class org/lastnpe/eea/generator/EEAFileInheritanceTest$A", // + " ;>", // + " ;>" // + ).stream().collect(Collectors.joining("\n"))); + + assertThat(linesB).isEqualTo(List.of( // + "class org/lastnpe/eea/generator/EEAFileInheritanceTest$B", // + "", // + "super org/lastnpe/eea/generator/EEAFileInheritanceTest$A", // + " ;>", // + " ;>" // + ).stream().collect(Collectors.joining("\n"))); + + assertThat(linesC).isEqualTo(List.of( // + "class org/lastnpe/eea/generator/EEAFileInheritanceTest$C", // + " ", // + " ", // + "", // + "super org/lastnpe/eea/generator/EEAFileInheritanceTest$A", // + " ;>", // + " ;>" // + ).stream().collect(Collectors.joining("\n"))); + + assertThat(linesD).isEqualTo(List.of( // + "class org/lastnpe/eea/generator/EEAFileInheritanceTest$D", // + " ;>", // + " ;>", // + "", // + "super org/lastnpe/eea/generator/EEAFileInheritanceTest$A", // + " ", // + " " // + ).stream().collect(Collectors.joining("\n"))); + + assertThat(linesI).isEqualTo(List.of( // + "class org/lastnpe/eea/generator/EEAFileInheritanceTest$I", // + " ;>", // + " ;>" // + ).stream().collect(Collectors.joining("\n"))); + + assertThat(linesJ).startsWith(List.of( // + "class org/lastnpe/eea/generator/EEAFileInheritanceTest$J", // + "", // + "super org/lastnpe/eea/generator/EEAFileInheritanceTest$I", // + " ;>", // + " ;>" // + ).stream().collect(Collectors.joining("\n"))); + + assertThat(linesK).startsWith(List.of( // + "class org/lastnpe/eea/generator/EEAFileInheritanceTest$K", // + "", // + "super org/lastnpe/eea/generator/EEAFileInheritanceTest$I", // + " ;>", // + " ;>", // + "super java/lang/Comparable", // + " ", // + " " // + ).stream().collect(Collectors.joining("\n"))); + } +} diff --git a/generator/src/test/java/org/lastnpe/eea/generator/EEAFileTest.java b/generator/src/test/java/org/lastnpe/eea/generator/EEAFileTest.java new file mode 100644 index 000000000..0743336e8 --- /dev/null +++ b/generator/src/test/java/org/lastnpe/eea/generator/EEAFileTest.java @@ -0,0 +1,121 @@ +/* + * SPDX-FileCopyrightText: © Vegard IT GmbH (https://vegardit.com) and contributors. + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * - Sebastian Thomschke (Vegard IT GmbH) - initial API and implementation + */ +package org.lastnpe.eea.generator; + +import static org.assertj.core.api.Assertions.*; +import static org.lastnpe.eea.generator.EEAFile.*; +import static org.lastnpe.eea.generator.internal.MiscUtils.remap; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Set; + +import org.junit.jupiter.api.Test; +import org.lastnpe.eea.generator.EEAFile.SaveOption; + +/** + * @author Sebastian Thomschke (Vegard IT GmbH) + */ +@SuppressWarnings("null") +class EEAFileTest { + + public static final class TestEntity { + public static final String STATIC_STRING = "MyStaticString"; + + public String name; + + public TestEntity(final String name) { // CHECKSTYLE:IGNORE RedundantModifier + this.name = name; + } + } + + public static final class TestEntity2 { + public static final String STATIC_STRING = "MyStaticString"; + } + + static final String TEST_ENTITY_NAME_WITH_SLASHES = TestEntity.class.getName().replace('.', '/'); + static final String WRONG_TYPE_NAME = EEAFileTest.class.getName() + "$WrongType"; + static final String WRONG_TYPE_NAME_WITH_SLASHES = WRONG_TYPE_NAME.replace('.', '/'); + + @Test + void testEEAFile() throws IOException { + final var eeaFile = load(Path.of("src/test/resources/valid"), TestEntity.class.getName()); + + assertThat(eeaFile.classHeader.name.value).isEqualTo(TestEntity.class.getName()); + assertThat(eeaFile.classHeader.name.comment).isEqualTo("# a class comment"); + assertThat(eeaFile.classHeader.name).hasToString(TestEntity.class.getName() + " # a class comment"); + assertThat(eeaFile.relativePath).isEqualTo(Path.of(TEST_ENTITY_NAME_WITH_SLASHES + ".eea")); + + assertThat(eeaFile.getClassMembers()).isNotEmpty(); + final var field = eeaFile.findMatchingClassMember("STATIC_STRING", "Ljava/lang/String;"); + assert field != null; + assertThat(field.name.comment).isEqualTo("# a field comment"); + assertThat(field.originalSignature.value).isEqualTo("Ljava/lang/String;"); + assertThat(field.originalSignature.comment).isEqualTo("# an original signature comment"); + + final var annotatedSignature = field.annotatedSignature; + assertThat(annotatedSignature).isNotNull(); + assert annotatedSignature != null; + + assertThat(annotatedSignature.value).isEqualTo("L1java/lang/String;"); + assertThat(annotatedSignature.comment).isEqualTo("# an annotated signature comment"); + + assertThat(eeaFile.renderFileContent(Set.of())) // + .isEqualTo(Files.readAllLines(Path.of("src/test/resources/valid").resolve(eeaFile.relativePath))); + + assertThat(eeaFile.renderFileContent(Set.of(SaveOption.OMIT_REDUNDANT_ANNOTATED_SIGNATURES))) // + .isNotEqualTo(Files.readAllLines(Path.of("src/test/resources/valid").resolve(eeaFile.relativePath))); + } + + @Test + void testWrongTypeHeader() { + final var wrongTypePath = Path.of("src/test/resources/invalid/" + WRONG_TYPE_NAME_WITH_SLASHES + ".eea"); + assertThatThrownBy(() -> { // + load(wrongTypePath); + }) // + .isInstanceOf(java.io.IOException.class) // + .hasMessage("Mismatch between file path of [" + wrongTypePath + + "] and contained class name definition [" + TestEntity.class.getName() + "]"); + } + + @Test + void testApplyAnnotationsAndCommentsFrom() throws IOException { + final var computedEEAFiles = remap(EEAGenerator.computeEEAFiles(EEAFileTest.class.getPackageName(), c -> true), + v -> v.relativePath); + final var computedEEAFile = computedEEAFiles.get(Path.of(TEST_ENTITY_NAME_WITH_SLASHES + ".eea")); + assertThat(computedEEAFile).isNotNull(); + assert computedEEAFile != null; + + final var method = computedEEAFile.findMatchingClassMember("name", "Ljava/lang/String;"); + assert method != null; + assertThat(method.hasNullAnnotations()).isFalse(); + assertThat(method.name.comment).isEmpty(); + + final var loadedEEAFile = load(Path.of("src/test/resources/valid"), computedEEAFile.classHeader.name.value); + computedEEAFile.applyAnnotationsAndCommentsFrom(loadedEEAFile, false, false); + final var annotatedSignature = method.annotatedSignature; + assert annotatedSignature != null; + assertThat(annotatedSignature.value).isEqualTo("L1java/lang/String;"); + assertThat(method.name.comment).isEqualTo("# a method comment"); + } + + @Test + void testRemoveNullAnnotations() { + assertThat(removeNullAnnotations("L0java/lang/Object;")).isEqualTo("Ljava/lang/Object;"); + assertThat(removeNullAnnotations("L1java/lang/Class<*>;L1java/lang/Class<*>;)L1java/lang/invoke/MethodType;")) + .isEqualTo("Ljava/lang/Class<*>;Ljava/lang/Class<*>;)Ljava/lang/invoke/MethodType;"); + assertThat(removeNullAnnotations("(L1java/lang/Class;)[1T1T;")) + .isEqualTo("(Ljava/lang/Class;)[TT;"); + assertThat(removeNullAnnotations("<1T::Ljava/util/EventListener;>(TT;)V")) + .isEqualTo("(TT;)V"); + + // T1 is the name of the generic variable + assertThat(removeNullAnnotations("")).isEqualTo(""); + } +} diff --git a/generator/src/test/java/org/lastnpe/eea/generator/EEAGeneratorTest.java b/generator/src/test/java/org/lastnpe/eea/generator/EEAGeneratorTest.java new file mode 100644 index 000000000..8d1ea972b --- /dev/null +++ b/generator/src/test/java/org/lastnpe/eea/generator/EEAGeneratorTest.java @@ -0,0 +1,59 @@ +/* + * SPDX-FileCopyrightText: © Vegard IT GmbH (https://vegardit.com) and contributors. + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * - Sebastian Thomschke (Vegard IT GmbH) - initial API and implementation + */ +package org.lastnpe.eea.generator; + +import static org.assertj.core.api.Assertions.*; + +import java.io.IOException; +import java.nio.file.Path; + +import org.junit.jupiter.api.Test; + +/** + * @author Sebastian Thomschke (Vegard IT GmbH) + */ +@SuppressWarnings("null") +class EEAGeneratorTest { + + @Test + void testVadilateValidEEAFiles() throws IOException { + final var rootPath = Path.of("src/test/resources/valid"); + final var config = new EEAGenerator.Config(rootPath, EEAGeneratorTest.class.getPackageName()); + config.inputDirs.add(rootPath); + + assertThat(EEAGenerator.validateEEAFiles(config)).isEqualTo(2); + } + + @Test + void testVadilateInvalidEEAFiles() { + final var rootPath = Path.of("src/test/resources/invalid"); + final var config = new EEAGenerator.Config(rootPath, EEAGeneratorTest.class.getPackageName()); + config.inputDirs.add(rootPath); + + final var wrongTypePath = rootPath.resolve(EEAFileTest.WRONG_TYPE_NAME_WITH_SLASHES + ".eea"); + assertThatThrownBy(() -> { + EEAGenerator.validateEEAFiles(config); + }) // + .isInstanceOf(IllegalStateException.class) // + .hasMessage("Type [org.lastnpe.eea.generator.EEAFileTest$WrongType] defined in [" + wrongTypePath + + "] no found on classpath."); + } + + @Test + void testPackageMissingOnClasspath() { + final var rootPath = Path.of("src/test/resources/invalid"); + final var config = new EEAGenerator.Config(rootPath, "org.no_npe.foobar"); + config.inputDirs.add(rootPath); + + assertThatThrownBy(() -> { + EEAGenerator.validateEEAFiles(config); + }) // + .isInstanceOf(IllegalArgumentException.class) // + .hasMessage("No classes found for package [org.no_npe.foobar] on classpath"); + } +} diff --git a/generator/src/test/java/org/lastnpe/eea/generator/EEAGeneratorTester.java b/generator/src/test/java/org/lastnpe/eea/generator/EEAGeneratorTester.java new file mode 100644 index 000000000..df1b8a995 --- /dev/null +++ b/generator/src/test/java/org/lastnpe/eea/generator/EEAGeneratorTester.java @@ -0,0 +1,34 @@ +/* + * SPDX-FileCopyrightText: © Vegard IT GmbH (https://vegardit.com) and contributors. + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * - Sebastian Thomschke (Vegard IT GmbH) - initial API and implementation + */ +package org.lastnpe.eea.generator; + +/** + * Utility class to be executed from within the IDE for convenient debugging of + * the EEAGenerator. + * + * @author Sebastian Thomschke (Vegard IT GmbH) + */ +public final class EEAGeneratorTester { + + public static void main(final String[] args) throws Exception { + + final String lib = "../libs/eea-java-17"; + System.setProperty("eea-generator.input.dirs", lib + "/src/main/resources"); + + System.setProperty("eea-generator.action", "generate"); + System.setProperty("eea-generator.output.dir", lib + "/src/main/resources"); + + // System.setProperty("eea-generator.action", "minimize"); + // System.setProperty("eea-generator.output.dir", lib + "/target/classes"); + + EEAGenerator.main(lib + "/eea-generator.properties"); + } + + private EEAGeneratorTester() { + } +} diff --git a/generator/src/test/java/org/lastnpe/eea/generator/internal/MiscUtilsTest.java b/generator/src/test/java/org/lastnpe/eea/generator/internal/MiscUtilsTest.java new file mode 100644 index 000000000..4492c6a72 --- /dev/null +++ b/generator/src/test/java/org/lastnpe/eea/generator/internal/MiscUtilsTest.java @@ -0,0 +1,33 @@ +/* + * SPDX-FileCopyrightText: © Vegard IT GmbH (https://vegardit.com) and contributors. + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * - Sebastian Thomschke (Vegard IT GmbH) - initial API and implementation + */ +package org.lastnpe.eea.generator.internal; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.lastnpe.eea.generator.internal.MiscUtils.replaceAll; + +import java.util.regex.Pattern; + +import org.junit.jupiter.api.Test; + +/** + * @author Sebastian Thomschke (Vegard IT GmbH) + */ +class MiscUtilsTest { + + @Test + void testReplaceAll() { + assertThat(replaceAll("", Pattern.compile("o"), 0, w -> "a")).isEmpty(); + assertThat(replaceAll("o", Pattern.compile("o"), 0, w -> "a")).isEqualTo("a"); + assertThat(replaceAll("ooo", Pattern.compile("o"), 0, w -> "a")).isEqualTo("aaa"); + assertThat(replaceAll("oX", Pattern.compile("o"), 0, w -> "a")).isEqualTo("aX"); + assertThat(replaceAll("oooX", Pattern.compile("o"), 0, w -> "a")).isEqualTo("aaaX"); + assertThat(replaceAll("Xo", Pattern.compile("o"), 0, w -> "a")).isEqualTo("Xa"); + assertThat(replaceAll("Xooo", Pattern.compile("o"), 0, w -> "a")).isEqualTo("Xaaa"); + assertThat(replaceAll("aXcaXc", Pattern.compile("a(X)c"), 1, w -> "b")).isEqualTo("abcabc"); + } +} diff --git a/generator/src/test/resources/invalid/org/lastnpe/eea/generator/EEAFileTest$WrongType.eea b/generator/src/test/resources/invalid/org/lastnpe/eea/generator/EEAFileTest$WrongType.eea new file mode 100644 index 000000000..3a87efd09 --- /dev/null +++ b/generator/src/test/resources/invalid/org/lastnpe/eea/generator/EEAFileTest$WrongType.eea @@ -0,0 +1,5 @@ +class org/lastnpe/eea/generator/EEAFileTest$TestEntity + +STATIC_STRING + Ljava/lang/String; + L1java/lang/String; diff --git a/generator/src/test/resources/valid/org/lastnpe/eea/generator/EEAFileTest$TestEntity.eea b/generator/src/test/resources/valid/org/lastnpe/eea/generator/EEAFileTest$TestEntity.eea new file mode 100644 index 000000000..b92f0571e --- /dev/null +++ b/generator/src/test/resources/valid/org/lastnpe/eea/generator/EEAFileTest$TestEntity.eea @@ -0,0 +1,13 @@ +class org/lastnpe/eea/generator/EEAFileTest$TestEntity # a class comment + +STATIC_STRING # a field comment + Ljava/lang/String; # an original signature comment + L1java/lang/String; # an annotated signature comment + +name # a method comment + Ljava/lang/String; + L1java/lang/String; + + + (Ljava/lang/String;)V + (Ljava/lang/String;)V diff --git a/generator/src/test/resources/valid/org/lastnpe/eea/generator/EEAFileTest$TestEntity2.eea b/generator/src/test/resources/valid/org/lastnpe/eea/generator/EEAFileTest$TestEntity2.eea new file mode 100644 index 000000000..5ac5e6a5f --- /dev/null +++ b/generator/src/test/resources/valid/org/lastnpe/eea/generator/EEAFileTest$TestEntity2.eea @@ -0,0 +1,5 @@ +class org/lastnpe/eea/generator/EEAFileTest$TestEntity2 + +STATIC_STRING + Ljava/lang/String; + L1java/lang/String; diff --git a/libraries/eea-all/pom.xml b/libraries/eea-all/pom.xml deleted file mode 100644 index a64306d9f..000000000 --- a/libraries/eea-all/pom.xml +++ /dev/null @@ -1,226 +0,0 @@ - - - 4.0.0 - - - org.lastnpe.eea - eea-parent - 3.0.0-SNAPSHOT - - - eea-all - - jar - EEA :: All-in-one - - - - org.lastnpe.eea - javamail-eea - ${project.version} - - - org.lastnpe.eea - jdk-eea - ${project.version} - - - org.lastnpe.eea - jetty-eea - ${project.version} - - - org.lastnpe.eea - gson-eea - ${project.version} - - - org.lastnpe.eea - guava-eea - ${project.version} - - - org.lastnpe.eea - mockito-eea - ${project.version} - - - org.lastnpe.eea - junit5-eea - ${project.version} - - - org.lastnpe.eea - servlet-api-eea - ${project.version} - - - org.lastnpe.eea - slf4j-api-eea - ${project.version} - - - org.lastnpe.eea - spring-eea - ${project.version} - - - org.lastnpe.eea - osgi-core-eea - ${project.version} - - - org.lastnpe.eea - xstream-eea - ${project.version} - - - - - org.junit.jupiter - junit-jupiter-api - 5.7.0 - test - - - org.ow2.asm - asm - 7.1 - test - - - - com.google.code.gson - gson - 2.8.6 - test - - - - com.google.guava - guava - 25.1-jre - test - - - - com.sun.mail - javax.mail - 1.6.2 - test - - - - com.thoughtworks.xstream - xstream - 1.4.16 - test - - - - javax.servlet - javax.servlet-api - 3.1.0 - test - - - - org.springframework - spring-beans - 4.3.17.RELEASE - test - - - - org.mockito - mockito-core - 1.10.19 - test - - - - org.eclipse.jetty - jetty-client - 9.4.20.v20190813 - test - - - - org.slf4j - slf4j-api - 1.7.25 - test - - - - org.osgi - org.osgi.core - 6.0.0 - test - - - - javax.xml.bind - jaxb-api - 2.3.1 - test - - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.5.1 - - ${eea.java.version} - ${eea.java.version} - - - - default-testCompile - test-compile - - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.19.1 - - - default-test - test - - - - - org.apache.maven.plugins - maven-shade-plugin - 3.1.0 - - - - shade - - package - - - - *:* - - eea-for-gav - dependency-reduced-pom.xml - - - - - - - - - - - diff --git a/libraries/eea-all/src/test/java/org/lastnpe/eea/test/EeaFile.java b/libraries/eea-all/src/test/java/org/lastnpe/eea/test/EeaFile.java deleted file mode 100644 index c67e74524..000000000 --- a/libraries/eea-all/src/test/java/org/lastnpe/eea/test/EeaFile.java +++ /dev/null @@ -1,233 +0,0 @@ -package org.lastnpe.eea.test; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; - -import org.objectweb.asm.ClassReader; -import org.objectweb.asm.ClassVisitor; -import org.objectweb.asm.FieldVisitor; -import org.objectweb.asm.MethodVisitor; -import org.objectweb.asm.Opcodes; - -/** - * Represents the EEA file. The EEA file could either be parsed by name - */ -public class EeaFile { - - enum State { - READ_CLASS, READ_ENTRY, READ_SIGNATURE1, READ_SIGNATURE2 - } - - /** - * This represents an entry - a definition of a method/constant with old and new - * signature. - */ - public static class Entry { - public Entry(String name) { - this.name = name; - } - - private final String name; - private String signature1; - private String signature2; - private boolean important; - - @Override - public String toString() { - return name + "\n " + signature1 + "\n " + signature2; - } - - public String getName() { - return name; - } - - public String getSignature1() { - return signature1; - } - - public String getSignature2() { - return signature2; - } - - public boolean isImportant() { - return important; - } - } - - private String className; - - private Map entries = new TreeMap<>(); - - /** - * Parses the eea from eea-file. Specify a resourcename in classpath. Note, that - * the resource name should start with '/' - */ - public static EeaFile parseEeaFile(String resourceName) throws IOException { - EeaFile result = new EeaFile(); - State state = State.READ_CLASS; - int i = 0; - Entry entry = null; - try (InputStream is = EeaFile.class.getResourceAsStream(resourceName); - BufferedReader reader = new BufferedReader(new InputStreamReader(is))) { - String line; - while ((line = reader.readLine()) != null) { - i++; - if (line.trim().length() == 0) { - continue; - } - switch (state) { - - case READ_CLASS: - if (!line.startsWith("class ")) { - throw new IllegalStateException("expected that line starts with 'class'"); - } - result.className = line.substring(6); - state = State.READ_ENTRY; - break; - - case READ_ENTRY: - if (line.startsWith(" ")) { - throw new IllegalStateException("expected that line starts with entry"); - } - if (entry != null) { - result.addEntry(entry); - } - entry = new Entry(line); - state = State.READ_SIGNATURE1; - break; - - case READ_SIGNATURE1: - if (!line.startsWith(" ")) { - throw new IllegalStateException("expected that line contains signature"); - } - entry.signature1 = line.substring(1); - state = State.READ_SIGNATURE2; - break; - - case READ_SIGNATURE2: - if (!line.startsWith(" ")) { - throw new IllegalStateException("expected that line contains signature"); - } - entry.signature2 = line.substring(1); - ; - state = State.READ_ENTRY; - break; - } - - } - } catch (IllegalStateException ie) { - throw new IllegalStateException("Error in file " + resourceName + " line " + i + ": " + ie.getMessage(), ie); - } - if (entry != null) { - result.addEntry(entry); - } - return result; - } - - /** - * Parses the EEA file by reading the bytecode using asm. Specify a resourcename - * in classpath. Note, that the resource name should start with '/' - */ - public static EeaFile parseClassFile(String resourceName) throws IOException { - EeaFile result = new EeaFile(); - - try (InputStream is = EeaFile.class.getResourceAsStream(resourceName)) { - ClassReader cr = new ClassReader(is); - cr.accept(new ClassVisitor(Opcodes.ASM7) { - - @Override - public void visit(int version, int access, String name, String signature, String superName, - String[] interfaces) { - result.className = name; - super.visit(version, access, name, signature, superName, interfaces); - } - - @Override - public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) { - result.visit(access, name, desc, signature); - return super.visitField(access, name, desc, signature, value); - } - - public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { - result.visit(access, name, desc, signature); - return super.visitMethod(access, name, desc, signature, exceptions); - } - }, 0); - } - return result; - } - - private void visit(int access, String name, String desc, String signature) { - // CHECKME: There is no need to declare private methods in eea file. - // if ((Opcodes.ACC_PRIVATE & access) == 0) { - Entry entry = new Entry(name); - entry.signature1 = signature != null ? signature : desc; - entry.signature2 = entry.signature1; - - // detect if method is public and object or arrays are involved - entry.important = (Opcodes.ACC_PUBLIC & access) > 0 - && (entry.signature1.contains(";") || entry.signature1.contains("[")); - addEntry(entry); - // } - } - - /** - * Returns the parsed information as eea-compatible string. this is a good place to work on. - */ - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class ").append(className).append('\n'); - for (Entry entry : entries.values()) { - if (entry.isImportant()) { - sb.append(entry).append('\n'); - } - } - return sb.toString(); - } - - public String getClassName() { - return className; - } - - private void addEntry(Entry entry) { - String key = entry.getName() + entry.getSignature1(); - if (entries.put(key, entry) != null) { - throw new IllegalStateException(entry + " defined twice"); - } - } - - /** - * Return the exact entry - */ - public Entry getEntry(String name, String signature) { - return entries.get(name + signature); - } - - /** - * Return all entries. - */ - public Collection getEntries() { - return entries.values(); - } - - /** - * Returns all entries matching to this name. - */ - public List getEntries(String name) { - List ret = new ArrayList<>(); - for (Entry entry : entries.values()) { - if (entry.getName().equals(name)) { - ret.add(entry); - } - } - return ret; - } -} diff --git a/libraries/eea-all/src/test/java/org/lastnpe/eea/test/EeaScanner.java b/libraries/eea-all/src/test/java/org/lastnpe/eea/test/EeaScanner.java deleted file mode 100644 index f87176a66..000000000 --- a/libraries/eea-all/src/test/java/org/lastnpe/eea/test/EeaScanner.java +++ /dev/null @@ -1,83 +0,0 @@ -package org.lastnpe.eea.test; - -import java.io.File; -import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLDecoder; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Enumeration; -import java.util.List; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; - -/** - * Scans for eea-files in classpath. The classpath components are idenfified by their eea-for-gav file. - * So only projects/jars are inspected that contains such a file. - * @author Roland Praml, FOCONIS AG - * - */ -public class EeaScanner { - - List eeaFiles; - - /** - * Returns all eea file names that are found in classpath. The files are - * returned relatively. e.g. 'java/lang/Object.eea'. - */ - public List getEeaFiles() throws IOException { - if (eeaFiles == null) { - List ret = new ArrayList<>(); - Enumeration res = SelfTest.class.getClassLoader().getResources("eea-for-gav"); - while (res.hasMoreElements()) { - URL url = res.nextElement(); - if ("file".equals(url.getProtocol())) { - File file = new File(URLDecoder.decode(url.getPath().replace("+", "%2b"), "UTF-8")); - scanDirectory(ret, file.getParentFile()); - } else if ("jar".equals(url.getProtocol())) { - String path = url.getPath(); - path = path.substring(5, path.length() - 13); // cuts out "jar:" ... "!/eea-for-gav" - File file = new File(URLDecoder.decode(path.replace("+", "%2b"), "UTF-8")); - scanJar(ret, file); - } - } - eeaFiles = Collections.unmodifiableList(ret); - } - return eeaFiles; - } - - /** - * Scans a directory for .eea files. This code path is used when the test is - * invoked from IDE - */ - protected void scanDirectory(List ret, File dir) throws MalformedURLException { - String rootDiskFolder = dir.getAbsolutePath(); - if (!rootDiskFolder.endsWith(File.separator)) { - rootDiskFolder = rootDiskFolder + File.separator; - } - scanDirectory(ret, dir, rootDiskFolder); - } - - private void scanDirectory(List ret, File dir, String rootDiskFolder) throws MalformedURLException { - for (File file : dir.listFiles()) { - if (file.isDirectory()) { - scanDirectory(ret, file, rootDiskFolder); - } else if (file.getName().endsWith(".eea")) { - ret.add(file.getAbsolutePath().substring(rootDiskFolder.length()).replace(File.separatorChar, '/')); - } - } - } - - protected void scanJar(List ret, File file) throws IOException { - try (JarFile jarFile = new JarFile(file)) { - Enumeration entries = jarFile.entries(); - while (entries.hasMoreElements()) { - JarEntry entry = entries.nextElement(); - if (entry.getName().endsWith(".eea")) { - ret.add(entry.getName()); - } - } - } - } -} diff --git a/libraries/eea-all/src/test/java/org/lastnpe/eea/test/Main.java b/libraries/eea-all/src/test/java/org/lastnpe/eea/test/Main.java deleted file mode 100644 index 25fe6a7b6..000000000 --- a/libraries/eea-all/src/test/java/org/lastnpe/eea/test/Main.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.lastnpe.eea.test; - -import java.io.IOException; -import java.time.OffsetDateTime; - -public class Main { - - // modify this line and run the class in eclipse (right click/run java application) - private static final Class CLASS_TO_TEST = OffsetDateTime.class; - - public static void main(String[] args) throws IOException { - EeaFile eea = EeaFile.parseClassFile("/" + CLASS_TO_TEST.getName().replace('.','/') + ".class"); - System.out.println(eea); - } - -} diff --git a/libraries/eea-all/src/test/java/org/lastnpe/eea/test/SelfTest.java b/libraries/eea-all/src/test/java/org/lastnpe/eea/test/SelfTest.java deleted file mode 100644 index 60429e417..000000000 --- a/libraries/eea-all/src/test/java/org/lastnpe/eea/test/SelfTest.java +++ /dev/null @@ -1,83 +0,0 @@ -package org.lastnpe.eea.test; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -import java.util.List; - -/** - * This is a 'self test'. It checks if the .eea files will match to the .class files. - * - * (it only validates the first line of signature, not the second line, which contains null information) - * @author Roland Praml, FOCONIS AG - * - */ -public class SelfTest { - - /** - * Should we list missing methods. - */ - private static boolean LIST_MISSING = false; - private final EeaScanner scanner = new EeaScanner(); - - @Test - public void testEeaConsistency() throws Exception { - boolean ok = true; - for (String eea : scanner.getEeaFiles()) { - ok &= checkEea(eea); - } - if (!ok) { - Assertions.fail("There were eea inconsistences detected"); - } - } - - protected boolean checkEea(String eeaPath) { - boolean ok = true; - ; - try { - EeaFile eea = EeaFile.parseEeaFile("/" + eeaPath); - EeaFile cls = EeaFile.parseClassFile("/" + eeaPath.replace(".eea", ".class")); - - if (!cls.getClassName().equals(eea.getClassName())) { - ok = false; - System.out.println("[FAIL] " + eeaPath + ": Class name does not match"); - } - - for (EeaFile.Entry eeaEntry : eea.getEntries()) { - // check if we find each corresponding entry in the class - EeaFile.Entry clsEntry = cls.getEntry(eeaEntry.getName(), eeaEntry.getSignature1()); - - if (clsEntry == null) { - System.out.println("[FAIL] " + eeaPath + ": Did not find: " + eeaEntry.getName() + " " + eeaEntry.getSignature1()); - ok = false; - - List candidates = cls.getEntries(eeaEntry.getName()); - if (candidates.isEmpty()) { - System.out.println("No Candidates found"); - } else { - System.out.println("Candidates:"); - for (EeaFile.Entry candidate : candidates) { - System.out.println(candidate); - } - } - } - } - - if (ok && LIST_MISSING) { - for (EeaFile.Entry entry : cls.getEntries()) { - if (entry.isImportant()) { - if (eea.getEntry(entry.getName(), entry.getSignature1()) == null) { - System.out.println("[WARN] " + eeaPath + ": Should be checked:"); - System.out.println(entry); - } - } - } - } - return ok; - } catch (Exception e) { - System.out.println("[FAIL] " + eeaPath + ": " + e.getMessage()); - return false; - } - } - -} diff --git a/libraries/gson/com/google/gson/GsonBuilder.eea b/libraries/gson/com/google/gson/GsonBuilder.eea index 9c9b5d0ad..e2b7e6ed1 100644 --- a/libraries/gson/com/google/gson/GsonBuilder.eea +++ b/libraries/gson/com/google/gson/GsonBuilder.eea @@ -5,9 +5,6 @@ addDeserializationExclusionStrategy addSerializationExclusionStrategy (Lcom/google/gson/ExclusionStrategy;)Lcom/google/gson/GsonBuilder; (L1com/google/gson/ExclusionStrategy;)L1com/google/gson/GsonBuilder; -addTypeAdaptersForDate - (Ljava/lang/String;IILjava/util/List;)V - (L0java/lang/String;IILjava/util/List;)V create ()Lcom/google/gson/Gson; ()L1com/google/gson/Gson; diff --git a/libraries/gson/com/google/gson/reflect/TypeToken.eea b/libraries/gson/com/google/gson/reflect/TypeToken.eea index 5c26757c9..bfdbfaf24 100644 --- a/libraries/gson/com/google/gson/reflect/TypeToken.eea +++ b/libraries/gson/com/google/gson/reflect/TypeToken.eea @@ -1,7 +1,4 @@ class com/google/gson/reflect/TypeToken - - (Ljava/lang/reflect/Type;)V - (L1java/lang/reflect/Type;)V get (Ljava/lang/reflect/Type;)Lcom/google/gson/reflect/TypeToken<*>; (L1java/lang/reflect/Type;)L1com/google/gson/reflect/TypeToken<*>; diff --git a/libraries/gson/eea-for-gav b/libraries/gson/eea-for-gav deleted file mode 100644 index b6f6c428e..000000000 --- a/libraries/gson/eea-for-gav +++ /dev/null @@ -1,2 +0,0 @@ -com.google.code.gson:gson - diff --git a/libraries/gson/eea-generator.properties b/libraries/gson/eea-generator.properties new file mode 100644 index 000000000..e0a2ea412 --- /dev/null +++ b/libraries/gson/eea-generator.properties @@ -0,0 +1,2 @@ +packages.include=com.google.gson +classes.exclude=[.]internal[.] \ No newline at end of file diff --git a/libraries/gson/pom.xml b/libraries/gson/pom.xml index cfd4d6e08..7eba85a8d 100644 --- a/libraries/gson/pom.xml +++ b/libraries/gson/pom.xml @@ -1,9 +1,9 @@ - + 4.0.0 - - org.lastnpe.eea eea-parent @@ -17,4 +17,12 @@ but version the EEA itself. Put the version of the lib into the EEA's name, if at all.--> + + + com.google.code.gson + gson + 2.11.0 + provided + + diff --git a/libraries/guava/com/google/common/base/Strings.eea b/libraries/guava/com/google/common/base/Strings.eea index 5dc37a669..4ee9ca7ea 100644 --- a/libraries/guava/com/google/common/base/Strings.eea +++ b/libraries/guava/com/google/common/base/Strings.eea @@ -23,6 +23,3 @@ padStart repeat (Ljava/lang/String;I)Ljava/lang/String; (L1java/lang/String;I)L1java/lang/String; -validSurrogatePairAt - (Ljava/lang/CharSequence;I)Z - (L1java/lang/CharSequence;I)Z diff --git a/libraries/guava/com/google/common/cache/Cache.eea b/libraries/guava/com/google/common/cache/Cache.eea index dab3ef801..624e4027e 100644 --- a/libraries/guava/com/google/common/cache/Cache.eea +++ b/libraries/guava/com/google/common/cache/Cache.eea @@ -6,8 +6,8 @@ get (TK;Ljava/util/concurrent/Callable<+TV;>;)TV; (TK;Ljava/util/concurrent/Callable<+1TV;>;)T1V; getAllPresent - (Ljava/lang/Iterable<*>;)Lcom/google/common/collect/ImmutableMap; - (Ljava/lang/Iterable<*>;)L1com/google/common/collect/ImmutableMap; + (Ljava/lang/Iterable<+Ljava/lang/Object;>;)Lcom/google/common/collect/ImmutableMap; + (Ljava/lang/Iterable<+Ljava/lang/Object;>;)L1com/google/common/collect/ImmutableMap; getIfPresent (Ljava/lang/Object;)TV; (Ljava/lang/Object;)T0V; diff --git a/libraries/guava/com/google/common/util/concurrent/Futures.eea b/libraries/guava/com/google/common/util/concurrent/Futures.eea index f9739ba7e..7a7865daa 100644 --- a/libraries/guava/com/google/common/util/concurrent/Futures.eea +++ b/libraries/guava/com/google/common/util/concurrent/Futures.eea @@ -5,24 +5,18 @@ allAsList allAsList ([Lcom/google/common/util/concurrent/ListenableFuture<+TV;>;)Lcom/google/common/util/concurrent/ListenableFuture;>; ([Lcom/google/common/util/concurrent/ListenableFuture<+TV;>;)L1com/google/common/util/concurrent/ListenableFuture;>; -catching - (Lcom/google/common/util/concurrent/ListenableFuture<+TV;>;Ljava/lang/Class;Lcom/google/common/base/Function<-TX;+TV;>;)Lcom/google/common/util/concurrent/ListenableFuture; - (Lcom/google/common/util/concurrent/ListenableFuture<+TV;>;Ljava/lang/Class;Lcom/google/common/base/Function<-TX;+TV;>;)L1com/google/common/util/concurrent/ListenableFuture; catching (Lcom/google/common/util/concurrent/ListenableFuture<+TV;>;Ljava/lang/Class;Lcom/google/common/base/Function<-TX;+TV;>;Ljava/util/concurrent/Executor;)Lcom/google/common/util/concurrent/ListenableFuture; (Lcom/google/common/util/concurrent/ListenableFuture<+TV;>;Ljava/lang/Class;Lcom/google/common/base/Function<-TX;+TV;>;Ljava/util/concurrent/Executor;)L1com/google/common/util/concurrent/ListenableFuture; -catchingAsync - (Lcom/google/common/util/concurrent/ListenableFuture<+TV;>;Ljava/lang/Class;Lcom/google/common/util/concurrent/AsyncFunction<-TX;+TV;>;)Lcom/google/common/util/concurrent/ListenableFuture; - (Lcom/google/common/util/concurrent/ListenableFuture<+TV;>;Ljava/lang/Class;Lcom/google/common/util/concurrent/AsyncFunction<-TX;+TV;>;)L1com/google/common/util/concurrent/ListenableFuture; catchingAsync (Lcom/google/common/util/concurrent/ListenableFuture<+TV;>;Ljava/lang/Class;Lcom/google/common/util/concurrent/AsyncFunction<-TX;+TV;>;Ljava/util/concurrent/Executor;)Lcom/google/common/util/concurrent/ListenableFuture; (Lcom/google/common/util/concurrent/ListenableFuture<+TV;>;Ljava/lang/Class;Lcom/google/common/util/concurrent/AsyncFunction<-TX;+TV;>;Ljava/util/concurrent/Executor;)L1com/google/common/util/concurrent/ListenableFuture; getChecked (Ljava/util/concurrent/Future;Ljava/lang/Class;)TV;^TX; - (Ljava/util/concurrent/Future;Ljava/lang/Class;)T1V; + (Ljava/util/concurrent/Future;Ljava/lang/Class;)T1V;^TX; getChecked (Ljava/util/concurrent/Future;Ljava/lang/Class;JLjava/util/concurrent/TimeUnit;)TV;^TX; - (Ljava/util/concurrent/Future;Ljava/lang/Class;JLjava/util/concurrent/TimeUnit;)T1V; + (Ljava/util/concurrent/Future;Ljava/lang/Class;JLjava/util/concurrent/TimeUnit;)T1V;^TX; getDone (Ljava/util/concurrent/Future;)TV; (Ljava/util/concurrent/Future;)T1V; @@ -32,12 +26,6 @@ getUnchecked immediateCancelledFuture ()Lcom/google/common/util/concurrent/ListenableFuture; ()L1com/google/common/util/concurrent/ListenableFuture; -immediateCheckedFuture - (TV;)Lcom/google/common/util/concurrent/CheckedFuture; - (TV;)L1com/google/common/util/concurrent/CheckedFuture; -immediateFailedCheckedFuture - (TX;)Lcom/google/common/util/concurrent/CheckedFuture; - (TX;)L1com/google/common/util/concurrent/CheckedFuture; immediateFailedFuture (Ljava/lang/Throwable;)Lcom/google/common/util/concurrent/ListenableFuture; (Ljava/lang/Throwable;)L1com/google/common/util/concurrent/ListenableFuture; @@ -50,9 +38,6 @@ inCompletionOrder lazyTransform (Ljava/util/concurrent/Future;Lcom/google/common/base/Function<-TI;+TO;>;)Ljava/util/concurrent/Future; (Ljava/util/concurrent/Future;Lcom/google/common/base/Function<-TI;+TO;>;)Ljava/util/concurrent/Future; -makeChecked - (Lcom/google/common/util/concurrent/ListenableFuture;Lcom/google/common/base/Function<-Ljava/lang/Exception;TX;>;)Lcom/google/common/util/concurrent/CheckedFuture; - (Lcom/google/common/util/concurrent/ListenableFuture;Lcom/google/common/base/Function<-Ljava/lang/Exception;TX;>;)L1com/google/common/util/concurrent/CheckedFuture; nonCancellationPropagating (Lcom/google/common/util/concurrent/ListenableFuture;)Lcom/google/common/util/concurrent/ListenableFuture; (Lcom/google/common/util/concurrent/ListenableFuture;)L1com/google/common/util/concurrent/ListenableFuture; @@ -68,15 +53,9 @@ successfulAsList successfulAsList ([Lcom/google/common/util/concurrent/ListenableFuture<+TV;>;)Lcom/google/common/util/concurrent/ListenableFuture;>; ([Lcom/google/common/util/concurrent/ListenableFuture<+TV;>;)L1com/google/common/util/concurrent/ListenableFuture;>; -transform - (Lcom/google/common/util/concurrent/ListenableFuture;Lcom/google/common/base/Function<-TI;+TO;>;)Lcom/google/common/util/concurrent/ListenableFuture; - (Lcom/google/common/util/concurrent/ListenableFuture;Lcom/google/common/base/Function<-TI;+TO;>;)L1com/google/common/util/concurrent/ListenableFuture; transform (Lcom/google/common/util/concurrent/ListenableFuture;Lcom/google/common/base/Function<-TI;+TO;>;Ljava/util/concurrent/Executor;)Lcom/google/common/util/concurrent/ListenableFuture; (Lcom/google/common/util/concurrent/ListenableFuture;Lcom/google/common/base/Function<-TI;+TO;>;Ljava/util/concurrent/Executor;)L1com/google/common/util/concurrent/ListenableFuture; -transformAsync - (Lcom/google/common/util/concurrent/ListenableFuture;Lcom/google/common/util/concurrent/AsyncFunction<-TI;+TO;>;)Lcom/google/common/util/concurrent/ListenableFuture; - (Lcom/google/common/util/concurrent/ListenableFuture;Lcom/google/common/util/concurrent/AsyncFunction<-TI;+TO;>;)L1com/google/common/util/concurrent/ListenableFuture; transformAsync (Lcom/google/common/util/concurrent/ListenableFuture;Lcom/google/common/util/concurrent/AsyncFunction<-TI;+TO;>;Ljava/util/concurrent/Executor;)Lcom/google/common/util/concurrent/ListenableFuture; (Lcom/google/common/util/concurrent/ListenableFuture;Lcom/google/common/util/concurrent/AsyncFunction<-TI;+TO;>;Ljava/util/concurrent/Executor;)L1com/google/common/util/concurrent/ListenableFuture; diff --git a/libraries/guava/eea-for-gav b/libraries/guava/eea-for-gav deleted file mode 100644 index 3c85c0b55..000000000 --- a/libraries/guava/eea-for-gav +++ /dev/null @@ -1,2 +0,0 @@ -com.google.guava:guava - diff --git a/libraries/guava/eea-generator.properties b/libraries/guava/eea-generator.properties new file mode 100644 index 000000000..44d68b17e --- /dev/null +++ b/libraries/guava/eea-generator.properties @@ -0,0 +1,2 @@ +packages.include=com.google.common +classes.exclude=[.]internal[.] \ No newline at end of file diff --git a/libraries/guava/pom.xml b/libraries/guava/pom.xml index 44fbc1d9f..a8834368e 100644 --- a/libraries/guava/pom.xml +++ b/libraries/guava/pom.xml @@ -1,9 +1,9 @@ - + 4.0.0 - - org.lastnpe.eea eea-parent @@ -17,4 +17,13 @@ but version the EEA itself. Put the version of the lib into the EEA's name, if at all.--> + + + com.google.guava + guava + 33.3.0-jre + provided + + + diff --git a/libraries/java-17/eea-for-gav b/libraries/java-17/eea-for-gav deleted file mode 100644 index b167f2ea3..000000000 --- a/libraries/java-17/eea-for-gav +++ /dev/null @@ -1,2 +0,0 @@ -# This isn't a real Maven GAV, but a convention to mean Java JDK rt.jar -java:java diff --git a/libraries/java-17/eea-generator.properties b/libraries/java-17/eea-generator.properties new file mode 100644 index 000000000..f03236590 --- /dev/null +++ b/libraries/java-17/eea-generator.properties @@ -0,0 +1,2 @@ +packages.include=java,javax,org.w3c.dom,org.xml.sax + diff --git a/libraries/java-17/java/lang/ClassNotFoundException.eea b/libraries/java-17/java/lang/ClassNotFoundException.eea index e997c8cba..1b58e22d1 100644 --- a/libraries/java-17/java/lang/ClassNotFoundException.eea +++ b/libraries/java-17/java/lang/ClassNotFoundException.eea @@ -5,9 +5,6 @@ class java/lang/ClassNotFoundException (Ljava/lang/String;Ljava/lang/Throwable;)V (L0java/lang/String;L0java/lang/Throwable;)V -getCause - ()Ljava/lang/Throwable; - ()L0java/lang/Throwable; getException ()Ljava/lang/Throwable; ()L0java/lang/Throwable; diff --git a/libraries/java-17/java/lang/ThreadGroup.eea b/libraries/java-17/java/lang/ThreadGroup.eea index cb1b54180..e5a1d86c8 100644 --- a/libraries/java-17/java/lang/ThreadGroup.eea +++ b/libraries/java-17/java/lang/ThreadGroup.eea @@ -14,9 +14,6 @@ enumerate enumerate ([Ljava/lang/ThreadGroup;)I ([1L1java/lang/ThreadGroup;)I -enumerate - ([Ljava/lang/ThreadGroup;IZ)I - ([1L1java/lang/ThreadGroup;IZ)I enumerate ([Ljava/lang/ThreadGroup;Z)I ([1L1java/lang/ThreadGroup;Z)I diff --git a/libraries/java-17/java/math/BigDecimal.eea b/libraries/java-17/java/math/BigDecimal.eea index 01e7b84a1..fc8e81e55 100644 --- a/libraries/java-17/java/math/BigDecimal.eea +++ b/libraries/java-17/java/math/BigDecimal.eea @@ -38,9 +38,6 @@ valueOf (Ljava/math/BigInteger;ILjava/math/MathContext;)V (L1java/math/BigInteger;IL1java/math/MathContext;)V - - (Ljava/math/BigInteger;JII)V - (L1java/math/BigInteger;JII)V (Ljava/math/BigInteger;Ljava/math/MathContext;)V (L1java/math/BigInteger;L1java/math/MathContext;)V diff --git a/libraries/java-17/java/math/BigInteger.eea b/libraries/java-17/java/math/BigInteger.eea index 04e641399..a0699f84d 100644 --- a/libraries/java-17/java/math/BigInteger.eea +++ b/libraries/java-17/java/math/BigInteger.eea @@ -15,17 +15,17 @@ valueOf (J)Ljava/math/BigInteger; (J)L1java/math/BigInteger; - ([B)V - ([B1)V + (I[B)V + (I[1B)V - ([BII)V - ([B1II)V + (I[BII)V + (I[1BII)V (I[B)V - (I[B1)V + (I[1B)V (I[BII)V - (I[B1II)V + (I[1BII)V (IILjava/util/Random;)V (IIL1java/util/Random;)V diff --git a/libraries/java-17/java/security/acl/Permission.eea b/libraries/java-17/java/security/acl/Permission.eea deleted file mode 100644 index 8f549fddb..000000000 --- a/libraries/java-17/java/security/acl/Permission.eea +++ /dev/null @@ -1,7 +0,0 @@ -class java/security/acl/Permission -equals - (Ljava/lang/Object;)Z - (L0java/lang/Object;)Z -toString - ()Ljava/lang/String; - ()L1java/lang/String; diff --git a/libraries/java-17/java/time/Instant.eea b/libraries/java-17/java/time/Instant.eea index e886c9df0..120cca269 100644 --- a/libraries/java-17/java/time/Instant.eea +++ b/libraries/java-17/java/time/Instant.eea @@ -68,9 +68,6 @@ ofEpochSecond parse (Ljava/lang/CharSequence;)Ljava/time/Instant; (L1java/lang/CharSequence;)L1java/time/Instant; -plus - (JJ)Ljava/time/Instant; - (JJ)L1java/time/Instant; plus (JLjava/time/temporal/TemporalUnit;)Ljava/time/Instant; (JL1java/time/temporal/TemporalUnit;)L1java/time/Instant; diff --git a/libraries/java-17/java/time/LocalDate.eea b/libraries/java-17/java/time/LocalDate.eea index d33c9b03f..08cf13640 100644 --- a/libraries/java-17/java/time/LocalDate.eea +++ b/libraries/java-17/java/time/LocalDate.eea @@ -26,15 +26,9 @@ atTime atTime (Ljava/time/LocalTime;)Ljava/time/LocalDateTime; (L1java/time/LocalTime;)L1java/time/LocalDateTime; -atTime - (Ljava/time/LocalTime;)Ljava/time/chrono/ChronoLocalDateTime; - (L1java/time/LocalTime;)L1java/time/chrono/ChronoLocalDateTime; atTime (Ljava/time/OffsetTime;)Ljava/time/OffsetDateTime; (L1java/time/OffsetTime;)L1java/time/OffsetDateTime; -compareTo - (Ljava/lang/Object;)I - (L1java/lang/Object;)I compareTo (Ljava/time/chrono/ChronoLocalDate;)I (L1java/time/chrono/ChronoLocalDate;)I @@ -50,9 +44,6 @@ from get (Ljava/time/temporal/TemporalField;)I (L1java/time/temporal/TemporalField;)I -getChronology - ()Ljava/time/chrono/Chronology; - ()L1java/time/chrono/Chronology; getChronology ()Ljava/time/chrono/IsoChronology; ()L1java/time/chrono/IsoChronology; @@ -60,8 +51,8 @@ getDayOfWeek ()Ljava/time/DayOfWeek; ()L1java/time/DayOfWeek; getEra - ()Ljava/time/chrono/Era; - ()L1java/time/chrono/Era; + ()Ljava/time/chrono/IsoEra; + ()L1java/time/chrono/IsoEra; getLong (Ljava/time/temporal/TemporalField;)J (L1java/time/temporal/TemporalField;)J @@ -86,21 +77,9 @@ isSupported minus (JLjava/time/temporal/TemporalUnit;)Ljava/time/LocalDate; (JL1java/time/temporal/TemporalUnit;)L1java/time/LocalDate; -minus - (JLjava/time/temporal/TemporalUnit;)Ljava/time/chrono/ChronoLocalDate; - (JL1java/time/temporal/TemporalUnit;)L1java/time/chrono/ChronoLocalDate; -minus - (JLjava/time/temporal/TemporalUnit;)Ljava/time/temporal/Temporal; - (JL1java/time/temporal/TemporalUnit;)L1java/time/temporal/Temporal; minus (Ljava/time/temporal/TemporalAmount;)Ljava/time/LocalDate; - (L1java/time/temporal/TemporalAmount;)Lj1ava/time/LocalDate; -minus - (Ljava/time/temporal/TemporalAmount;)Ljava/time/chrono/ChronoLocalDate; - (L1java/time/temporal/TemporalAmount;)L1java/time/chrono/ChronoLocalDate; -minus - (Ljava/time/temporal/TemporalAmount;)Ljava/time/temporal/Temporal; - (L1java/time/temporal/TemporalAmount;)L1java/time/temporal/Temporal; + (L1java/time/temporal/TemporalAmount;)L1java/time/LocalDate; minusDays (J)Ljava/time/LocalDate; (J)L1java/time/LocalDate; @@ -143,21 +122,9 @@ parse plus (JLjava/time/temporal/TemporalUnit;)Ljava/time/LocalDate; (JL1java/time/temporal/TemporalUnit;)L1java/time/LocalDate; -plus - (JLjava/time/temporal/TemporalUnit;)Ljava/time/chrono/ChronoLocalDate; - (JL1java/time/temporal/TemporalUnit;)L1java/time/chrono/ChronoLocalDate; -plus - (JLjava/time/temporal/TemporalUnit;)Ljava/time/temporal/Temporal; - (JL1java/time/temporal/TemporalUnit;)L1java/time/temporal/Temporal; plus (Ljava/time/temporal/TemporalAmount;)Ljava/time/LocalDate; (L1java/time/temporal/TemporalAmount;)L1java/time/LocalDate; -plus - (Ljava/time/temporal/TemporalAmount;)Ljava/time/chrono/ChronoLocalDate; - (L1java/time/temporal/TemporalAmount;)L1java/time/chrono/ChronoLocalDate; -plus - (Ljava/time/temporal/TemporalAmount;)Ljava/time/temporal/Temporal; - (L1java/time/temporal/TemporalAmount;)L1java/time/temporal/Temporal; plusDays (J)Ljava/time/LocalDate; (J)L1java/time/LocalDate; @@ -182,30 +149,15 @@ toString until (Ljava/time/chrono/ChronoLocalDate;)Ljava/time/Period; (L1java/time/chrono/ChronoLocalDate;)L1java/time/Period; -until - (Ljava/time/chrono/ChronoLocalDate;)Ljava/time/chrono/ChronoPeriod; - (L1java/time/chrono/ChronoLocalDate;)L1java/time/chrono/ChronoPeriod; until (Ljava/time/temporal/Temporal;Ljava/time/temporal/TemporalUnit;)J (L1java/time/temporal/Temporal;L1java/time/temporal/TemporalUnit;)J with (Ljava/time/temporal/TemporalAdjuster;)Ljava/time/LocalDate; (L1java/time/temporal/TemporalAdjuster;)L1java/time/LocalDate; -with - (Ljava/time/temporal/TemporalAdjuster;)Ljava/time/chrono/ChronoLocalDate; - (L1java/time/temporal/TemporalAdjuster;)L1java/time/chrono/ChronoLocalDate; -with - (Ljava/time/temporal/TemporalAdjuster;)Ljava/time/temporal/Temporal; - (L1java/time/temporal/TemporalAdjuster;)Lj1ava/time/temporal/Temporal; with (Ljava/time/temporal/TemporalField;J)Ljava/time/LocalDate; (L1java/time/temporal/TemporalField;J)L1java/time/LocalDate; -with - (Ljava/time/temporal/TemporalField;J)Ljava/time/chrono/ChronoLocalDate; - (L1java/time/temporal/TemporalField;J)L1java/time/chrono/ChronoLocalDate; -with - (Ljava/time/temporal/TemporalField;J)Ljava/time/temporal/Temporal; - (L1java/time/temporal/TemporalField;J)L1java/time/temporal/Temporal; withDayOfMonth (I)Ljava/time/LocalDate; (I)L1java/time/LocalDate; diff --git a/libraries/java-17/java/time/LocalDateTime.eea b/libraries/java-17/java/time/LocalDateTime.eea index b97404c06..1489153c0 100644 --- a/libraries/java-17/java/time/LocalDateTime.eea +++ b/libraries/java-17/java/time/LocalDateTime.eea @@ -14,12 +14,6 @@ atOffset atZone (Ljava/time/ZoneId;)Ljava/time/ZonedDateTime; (L1java/time/ZoneId;)L1java/time/ZonedDateTime; -atZone - (Ljava/time/ZoneId;)Ljava/time/chrono/ChronoZonedDateTime; - (L1java/time/ZoneId;)L1java/time/chrono/ChronoZonedDateTime; -compareTo - (Ljava/lang/Object;)I - (L1java/lang/Object;)I compareTo (Ljava/time/chrono/ChronoLocalDateTime<*>;)I (L1java/time/chrono/ChronoLocalDateTime<*>;)I @@ -62,21 +56,9 @@ isSupported minus (JLjava/time/temporal/TemporalUnit;)Ljava/time/LocalDateTime; (JL1java/time/temporal/TemporalUnit;)L1java/time/LocalDateTime; -minus - (JLjava/time/temporal/TemporalUnit;)Ljava/time/chrono/ChronoLocalDateTime; - (JL1java/time/temporal/TemporalUnit;)L1java/time/chrono/ChronoLocalDateTime; -minus - (JLjava/time/temporal/TemporalUnit;)Ljava/time/temporal/Temporal; - (JL1java/time/temporal/TemporalUnit;)L1java/time/temporal/Temporal; minus (Ljava/time/temporal/TemporalAmount;)Ljava/time/LocalDateTime; (L1java/time/temporal/TemporalAmount;)L1java/time/LocalDateTime; -minus - (Ljava/time/temporal/TemporalAmount;)Ljava/time/chrono/ChronoLocalDateTime; - (L1java/time/temporal/TemporalAmount;)L1java/time/chrono/ChronoLocalDateTime; -minus - (Ljava/time/temporal/TemporalAmount;)Ljava/time/temporal/Temporal; - (L1java/time/temporal/TemporalAmount;)L1java/time/temporal/Temporal; minusDays (J)Ljava/time/LocalDateTime; (J)L1java/time/LocalDateTime; @@ -146,21 +128,9 @@ parse plus (JLjava/time/temporal/TemporalUnit;)Ljava/time/LocalDateTime; (JL1java/time/temporal/TemporalUnit;)L1java/time/LocalDateTime; -plus - (JLjava/time/temporal/TemporalUnit;)Ljava/time/chrono/ChronoLocalDateTime; - (JL1java/time/temporal/TemporalUnit;)L1java/time/chrono/ChronoLocalDateTime; -plus - (JLjava/time/temporal/TemporalUnit;)Ljava/time/temporal/Temporal; - (JL1java/time/temporal/TemporalUnit;)L1java/time/temporal/Temporal; plus (Ljava/time/temporal/TemporalAmount;)Ljava/time/LocalDateTime; (L1java/time/temporal/TemporalAmount;)L1java/time/LocalDateTime; -plus - (Ljava/time/temporal/TemporalAmount;)Ljava/time/chrono/ChronoLocalDateTime; - (L1java/time/temporal/TemporalAmount;)L1java/time/chrono/ChronoLocalDateTime; -plus - (Ljava/time/temporal/TemporalAmount;)Ljava/time/temporal/Temporal; - (L1java/time/temporal/TemporalAmount;)L1java/time/temporal/Temporal; plusDays (J)Ljava/time/LocalDateTime; (J)L1java/time/LocalDateTime; @@ -194,9 +164,6 @@ range toLocalDate ()Ljava/time/LocalDate; ()L1java/time/LocalDate; -toLocalDate - ()Ljava/time/chrono/ChronoLocalDate; - ()L1java/time/chrono/ChronoLocalDate; toLocalTime ()Ljava/time/LocalTime; ()L1java/time/LocalTime; @@ -212,21 +179,9 @@ until with (Ljava/time/temporal/TemporalAdjuster;)Ljava/time/LocalDateTime; (Ljava/time/temporal/TemporalAdjuster;)L1java/time/LocalDateTime; -with - (Ljava/time/temporal/TemporalAdjuster;)Ljava/time/chrono/ChronoLocalDateTime; - (L1java/time/temporal/TemporalAdjuster;)L1java/time/chrono/ChronoLocalDateTime; -with - (Ljava/time/temporal/TemporalAdjuster;)Ljava/time/temporal/Temporal; - (L1java/time/temporal/TemporalAdjuster;)L1java/time/temporal/Temporal; with (Ljava/time/temporal/TemporalField;J)Ljava/time/LocalDateTime; (L1java/time/temporal/TemporalField;J)L1java/time/LocalDateTime; -with - (Ljava/time/temporal/TemporalField;J)Ljava/time/chrono/ChronoLocalDateTime; - (L1java/time/temporal/TemporalField;J)L1java/time/chrono/ChronoLocalDateTime; -with - (Ljava/time/temporal/TemporalField;J)Ljava/time/temporal/Temporal; - (L1java/time/temporal/TemporalField;J)L1java/time/temporal/Temporal; withDayOfMonth (I)Ljava/time/LocalDateTime; (I)L1java/time/LocalDateTime; diff --git a/libraries/java-17/java/time/LocalTime.eea b/libraries/java-17/java/time/LocalTime.eea index 91367407e..6d908de5d 100644 --- a/libraries/java-17/java/time/LocalTime.eea +++ b/libraries/java-17/java/time/LocalTime.eea @@ -20,9 +20,6 @@ atDate atOffset (Ljava/time/ZoneOffset;)Ljava/time/OffsetTime; (L1java/time/ZoneOffset;)L1java/time/OffsetTime; -compareTo - (Ljava/lang/Object;)I - (L1java/lang/Object;)I compareTo (Ljava/time/LocalTime;)I (L1java/time/LocalTime;)I @@ -56,15 +53,9 @@ isSupported minus (JLjava/time/temporal/TemporalUnit;)Ljava/time/LocalTime; (JL1java/time/temporal/TemporalUnit;)L1java/time/LocalTime; -minus - (JLjava/time/temporal/TemporalUnit;)Ljava/time/temporal/Temporal; - (JL1java/time/temporal/TemporalUnit;)L1java/time/temporal/Temporal; minus (Ljava/time/temporal/TemporalAmount;)Ljava/time/LocalTime; (L1java/time/temporal/TemporalAmount;)L1java/time/LocalTime; -minus - (Ljava/time/temporal/TemporalAmount;)Ljava/time/temporal/Temporal; - (L1java/time/temporal/TemporalAmount;)L1java/time/temporal/Temporal; minusHours (J)Ljava/time/LocalTime; (J)L1java/time/LocalTime; @@ -110,15 +101,9 @@ parse plus (JLjava/time/temporal/TemporalUnit;)Ljava/time/LocalTime; (JL1java/time/temporal/TemporalUnit;)L1java/time/LocalTime; -plus - (JLjava/time/temporal/TemporalUnit;)Ljava/time/temporal/Temporal; - (JL1java/time/temporal/TemporalUnit;)L1java/time/temporal/Temporal; plus (Ljava/time/temporal/TemporalAmount;)Ljava/time/LocalTime; (L1java/time/temporal/TemporalAmount;)L1java/time/LocalTime; -plus - (Ljava/time/temporal/TemporalAmount;)Ljava/time/temporal/Temporal; - (L1java/time/temporal/TemporalAmount;)L1java/time/temporal/Temporal; plusHours (J)Ljava/time/LocalTime; (J)L1java/time/LocalTime; @@ -149,15 +134,9 @@ until with (Ljava/time/temporal/TemporalAdjuster;)Ljava/time/LocalTime; (L1java/time/temporal/TemporalAdjuster;)L1java/time/LocalTime; -with - (Ljava/time/temporal/TemporalAdjuster;)Ljava/time/temporal/Temporal; - (L1java/time/temporal/TemporalAdjuster;)L1java/time/temporal/Temporal; with (Ljava/time/temporal/TemporalField;J)Ljava/time/LocalTime; (L1java/time/temporal/TemporalField;J)L1java/time/LocalTime; -with - (Ljava/time/temporal/TemporalField;J)Ljava/time/temporal/Temporal; - (L1java/time/temporal/TemporalField;J)L1java/time/temporal/Temporal; withHour (I)Ljava/time/LocalTime; (I)L1java/time/LocalTime; diff --git a/libraries/java-17/java/time/OffsetDateTime.eea b/libraries/java-17/java/time/OffsetDateTime.eea index 306a87462..59d6864cf 100644 --- a/libraries/java-17/java/time/OffsetDateTime.eea +++ b/libraries/java-17/java/time/OffsetDateTime.eea @@ -14,9 +14,6 @@ atZoneSameInstant atZoneSimilarLocal (Ljava/time/ZoneId;)Ljava/time/ZonedDateTime; (Ljava/time/ZoneId;)Ljava/time/ZonedDateTime; -compareTo - (Ljava/lang/Object;)I - (L1java/lang/Object;)I compareTo (Ljava/time/OffsetDateTime;)I (L1java/time/OffsetDateTime;)I @@ -62,15 +59,9 @@ isSupported minus (JLjava/time/temporal/TemporalUnit;)Ljava/time/OffsetDateTime; (JL1java/time/temporal/TemporalUnit;)Ljava/time/OffsetDateTime; -minus - (JLjava/time/temporal/TemporalUnit;)Ljava/time/temporal/Temporal; - (JL1java/time/temporal/TemporalUnit;)Ljava/time/temporal/Temporal; minus (Ljava/time/temporal/TemporalAmount;)Ljava/time/OffsetDateTime; (L1java/time/temporal/TemporalAmount;)Ljava/time/OffsetDateTime; -minus - (Ljava/time/temporal/TemporalAmount;)Ljava/time/temporal/Temporal; - (L1java/time/temporal/TemporalAmount;)Ljava/time/temporal/Temporal; minusDays (J)Ljava/time/OffsetDateTime; (J)L1java/time/OffsetDateTime; @@ -125,15 +116,9 @@ parse plus (JLjava/time/temporal/TemporalUnit;)Ljava/time/OffsetDateTime; (JL1java/time/temporal/TemporalUnit;)L1java/time/OffsetDateTime; -plus - (JLjava/time/temporal/TemporalUnit;)Ljava/time/temporal/Temporal; - (JL1java/time/temporal/TemporalUnit;)L1java/time/temporal/Temporal; plus (Ljava/time/temporal/TemporalAmount;)Ljava/time/OffsetDateTime; (L1java/time/temporal/TemporalAmount;)L1java/time/OffsetDateTime; -plus - (Ljava/time/temporal/TemporalAmount;)Ljava/time/temporal/Temporal; - (L1java/time/temporal/TemporalAmount;)L1java/time/temporal/Temporal; plusDays (J)Ljava/time/OffsetDateTime; (J)L1java/time/OffsetDateTime; @@ -197,15 +182,9 @@ until with (Ljava/time/temporal/TemporalAdjuster;)Ljava/time/OffsetDateTime; (L1java/time/temporal/TemporalAdjuster;)L1java/time/OffsetDateTime; -with - (Ljava/time/temporal/TemporalAdjuster;)Ljava/time/temporal/Temporal; - (L1java/time/temporal/TemporalAdjuster;)L1java/time/temporal/Temporal; with (Ljava/time/temporal/TemporalField;J)Ljava/time/OffsetDateTime; (L1java/time/temporal/TemporalField;J)L1java/time/OffsetDateTime; -with - (Ljava/time/temporal/TemporalField;J)Ljava/time/temporal/Temporal; - (L1java/time/temporal/TemporalField;J)L1java/time/temporal/Temporal; withDayOfMonth (I)Ljava/time/OffsetDateTime; (I)L1java/time/OffsetDateTime; diff --git a/libraries/java-17/java/time/ZonedDateTime.eea b/libraries/java-17/java/time/ZonedDateTime.eea index 3872a2a0e..16908a31c 100644 --- a/libraries/java-17/java/time/ZonedDateTime.eea +++ b/libraries/java-17/java/time/ZonedDateTime.eea @@ -35,21 +35,9 @@ isSupported minus (JLjava/time/temporal/TemporalUnit;)Ljava/time/ZonedDateTime; (JL1java/time/temporal/TemporalUnit;)Ljava/time/ZonedDateTime; -minus - (JLjava/time/temporal/TemporalUnit;)Ljava/time/chrono/ChronoZonedDateTime; - (JL1java/time/temporal/TemporalUnit;)Ljava/time/chrono/ChronoZonedDateTime; -minus - (JLjava/time/temporal/TemporalUnit;)Ljava/time/temporal/Temporal; - (JL1java/time/temporal/TemporalUnit;)Ljava/time/temporal/Temporal; minus (Ljava/time/temporal/TemporalAmount;)Ljava/time/ZonedDateTime; (L1java/time/temporal/TemporalAmount;)Ljava/time/ZonedDateTime; -minus - (Ljava/time/temporal/TemporalAmount;)Ljava/time/chrono/ChronoZonedDateTime; - (L1java/time/temporal/TemporalAmount;)Ljava/time/chrono/ChronoZonedDateTime; -minus - (Ljava/time/temporal/TemporalAmount;)Ljava/time/temporal/Temporal; - (L1java/time/temporal/TemporalAmount;)Ljava/time/temporal/Temporal; minusDays (J)Ljava/time/ZonedDateTime; (J)L1java/time/ZonedDateTime; @@ -113,21 +101,9 @@ parse plus (JLjava/time/temporal/TemporalUnit;)Ljava/time/ZonedDateTime; (JL1java/time/temporal/TemporalUnit;)L1java/time/ZonedDateTime; -plus - (JLjava/time/temporal/TemporalUnit;)Ljava/time/chrono/ChronoZonedDateTime; - (JL1java/time/temporal/TemporalUnit;)L1java/time/chrono/ChronoZonedDateTime; -plus - (JLjava/time/temporal/TemporalUnit;)Ljava/time/temporal/Temporal; - (JL1java/time/temporal/TemporalUnit;)L1java/time/temporal/Temporal; plus (Ljava/time/temporal/TemporalAmount;)Ljava/time/ZonedDateTime; (L1java/time/temporal/TemporalAmount;)L1java/time/ZonedDateTime; -plus - (Ljava/time/temporal/TemporalAmount;)Ljava/time/chrono/ChronoZonedDateTime; - (L1java/time/temporal/TemporalAmount;)L1java/time/chrono/ChronoZonedDateTime; -plus - (Ljava/time/temporal/TemporalAmount;)Ljava/time/temporal/Temporal; - (L1java/time/temporal/TemporalAmount;)L1java/time/temporal/Temporal; plusDays (J)Ljava/time/ZonedDateTime; (J)L1java/time/ZonedDateTime; @@ -164,9 +140,6 @@ toLocalDate toLocalDateTime ()Ljava/time/LocalDateTime; ()L1java/time/LocalDateTime; -toLocalDateTime - ()Ljava/time/chrono/ChronoLocalDateTime; - ()L1java/time/chrono/ChronoLocalDateTime; toLocalTime ()Ljava/time/LocalTime; ()L1java/time/LocalTime; @@ -185,21 +158,9 @@ until with (Ljava/time/temporal/TemporalAdjuster;)Ljava/time/ZonedDateTime; (L1java/time/temporal/TemporalAdjuster;)L1java/time/ZonedDateTime; -with - (Ljava/time/temporal/TemporalAdjuster;)Ljava/time/chrono/ChronoZonedDateTime; - (L1java/time/temporal/TemporalAdjuster;)L1java/time/chrono/ChronoZonedDateTime; -with - (Ljava/time/temporal/TemporalAdjuster;)Ljava/time/temporal/Temporal; - (L1java/time/temporal/TemporalAdjuster;)L1java/time/temporal/Temporal; with (Ljava/time/temporal/TemporalField;J)Ljava/time/ZonedDateTime; (L1java/time/temporal/TemporalField;J)L1java/time/ZonedDateTime; -with - (Ljava/time/temporal/TemporalField;J)Ljava/time/chrono/ChronoZonedDateTime; - (L1java/time/temporal/TemporalField;J)L1java/time/chrono/ChronoZonedDateTime; -with - (Ljava/time/temporal/TemporalField;J)Ljava/time/temporal/Temporal; - (L1java/time/temporal/TemporalField;J)L1java/time/temporal/Temporal; withDayOfMonth (I)Ljava/time/ZonedDateTime; (I)L1java/time/ZonedDateTime; @@ -209,9 +170,6 @@ withDayOfYear withEarlierOffsetAtOverlap ()Ljava/time/ZonedDateTime; ()L1java/time/ZonedDateTime; -withEarlierOffsetAtOverlap - ()Ljava/time/chrono/ChronoZonedDateTime; - ()L1java/time/chrono/ChronoZonedDateTime; withFixedOffsetZone ()Ljava/time/ZonedDateTime; ()L1java/time/ZonedDateTime; @@ -221,9 +179,6 @@ withHour withLaterOffsetAtOverlap ()Ljava/time/ZonedDateTime; ()L1java/time/ZonedDateTime; -withLaterOffsetAtOverlap - ()Ljava/time/chrono/ChronoZonedDateTime; - ()L1java/time/chrono/ChronoZonedDateTime; withMinute (I)Ljava/time/ZonedDateTime; (I)L1java/time/ZonedDateTime; @@ -242,13 +197,7 @@ withYear withZoneSameInstant (Ljava/time/ZoneId;)Ljava/time/ZonedDateTime; (L1java/time/ZoneId;)L1java/time/ZonedDateTime; -withZoneSameInstant - (Ljava/time/ZoneId;)Ljava/time/chrono/ChronoZonedDateTime; - (L1java/time/ZoneId;)L1java/time/chrono/ChronoZonedDateTime; withZoneSameLocal (Ljava/time/ZoneId;)Ljava/time/ZonedDateTime; (L1java/time/ZoneId;)L1java/time/ZonedDateTime; -withZoneSameLocal - (Ljava/time/ZoneId;)Ljava/time/chrono/ChronoZonedDateTime; - (L1java/time/ZoneId;)L1java/time/chrono/ChronoZonedDateTime; diff --git a/libraries/java-17/java/time/format/DateTimeFormatter.eea b/libraries/java-17/java/time/format/DateTimeFormatter.eea index b2c2575ad..696a356ab 100644 --- a/libraries/java-17/java/time/format/DateTimeFormatter.eea +++ b/libraries/java-17/java/time/format/DateTimeFormatter.eea @@ -49,7 +49,7 @@ format (L1java/time/temporal/TemporalAccessor;)L1java/lang/String; formatTo (Ljava/time/temporal/TemporalAccessor;Ljava/lang/Appendable;)V - (L1java/time/temporal/TemporalAccessor;1Ljava/lang/Appendable;)V + (L1java/time/temporal/TemporalAccessor;L1java/lang/Appendable;)V getChronology ()Ljava/time/chrono/Chronology; ()L0java/time/chrono/Chronology; diff --git a/libraries/java-17/java/util/ArrayList.eea b/libraries/java-17/java/util/ArrayList.eea index 706a60610..8545fd2c9 100644 --- a/libraries/java-17/java/util/ArrayList.eea +++ b/libraries/java-17/java/util/ArrayList.eea @@ -8,42 +8,27 @@ addAll addAll (Ljava/util/Collection<+TE;>;)Z (L1java/util/Collection<+TE;>;)Z -batchRemove - (Ljava/util/Collection<*>;ZII)Z - (L1java/util/Collection<*>;ZII)Z clone ()Ljava/lang/Object; ()L1java/lang/Object; contains (Ljava/lang/Object;)Z (L0java/lang/Object;)Z -elementAt - ([Ljava/lang/Object;I)TE; - ([L1java/lang/Object;I)TE; equals (Ljava/lang/Object;)Z (L0java/lang/Object;)Z -equalsRange - (Ljava/util/List<*>;II)Z - (L1java/util/List<*>;II)Z forEach (Ljava/util/function/Consumer<-TE;>;)V (L1java/util/function/Consumer<-TE;>;)V indexOf (Ljava/lang/Object;)I (L0java/lang/Object;)I -indexOfRange - (Ljava/lang/Object;II)I - (L0java/lang/Object;II)I iterator ()Ljava/util/Iterator; ()L1java/util/Iterator; lastIndexOf (Ljava/lang/Object;)I (L0java/lang/Object;)I -lastIndexOfRange - (Ljava/lang/Object;II)I - (L0java/lang/Object;II)I listIterator ()Ljava/util/ListIterator; ()L1java/util/ListIterator; @@ -59,15 +44,9 @@ removeAll removeIf (Ljava/util/function/Predicate<-TE;>;)Z (L1java/util/function/Predicate<-TE;>;)Z -removeIf - (Ljava/util/function/Predicate<-TE;>;II)Z - (L1java/util/function/Predicate<-TE;>;II)Z replaceAll (Ljava/util/function/UnaryOperator;)V (L1java/util/function/UnaryOperator;)V -replaceAllRange - (Ljava/util/function/UnaryOperator;II)V - (L1java/util/function/UnaryOperator;II)V retainAll (Ljava/util/Collection<*>;)Z (L1java/util/Collection<*>;)Z diff --git a/libraries/java-17/java/util/Collections.eea b/libraries/java-17/java/util/Collections.eea index bce6d3bdf..18e157572 100644 --- a/libraries/java-17/java/util/Collections.eea +++ b/libraries/java-17/java/util/Collections.eea @@ -44,30 +44,18 @@ reverseOrder singleton (TT;)Ljava/util/Set; (TT;)L1java/util/Set; -singletonIterator - (TE;)Ljava/util/Iterator; - (TE;)L1java/util/Iterator; singletonList (TT;)Ljava/util/List; (TT;)L1java/util/List; singletonMap (TK;TV;)Ljava/util/Map; (TK;TV;)L1java/util/Map; -singletonSpliterator - (TT;)Ljava/util/Spliterator; - (TT;)L1java/util/Spliterator; synchronizedCollection (Ljava/util/Collection;)Ljava/util/Collection; (Ljava/util/Collection;)L1java/util/Collection; -synchronizedCollection - (Ljava/util/Collection;Ljava/lang/Object;)Ljava/util/Collection; - (Ljava/util/Collection;Ljava/lang/Object;)L1java/util/Collection; synchronizedList (Ljava/util/List;)Ljava/util/List; (Ljava/util/List;)L1java/util/List; -synchronizedList - (Ljava/util/List;Ljava/lang/Object;)Ljava/util/List; - (Ljava/util/List;Ljava/lang/Object;)L1java/util/List; synchronizedMap (Ljava/util/Map;)Ljava/util/Map; (Ljava/util/Map;)L1java/util/Map; @@ -80,9 +68,6 @@ synchronizedNavigableSet synchronizedSet (Ljava/util/Set;)Ljava/util/Set; (Ljava/util/Set;)L1java/util/Set; -synchronizedSet - (Ljava/util/Set;Ljava/lang/Object;)Ljava/util/Set; - (Ljava/util/Set;Ljava/lang/Object;)L1java/util/Set; synchronizedSortedMap (Ljava/util/SortedMap;)Ljava/util/SortedMap; (Ljava/util/SortedMap;)L1java/util/SortedMap; diff --git a/libraries/java-17/java/util/HashMap.eea b/libraries/java-17/java/util/HashMap.eea index 40e570678..0790f8ea0 100644 --- a/libraries/java-17/java/util/HashMap.eea +++ b/libraries/java-17/java/util/HashMap.eea @@ -29,12 +29,6 @@ forEach get (Ljava/lang/Object;)TV; (L0java/lang/Object;)T0V; -getNode - (ILjava/lang/Object;)Ljava/util/HashMap$Node; - (IL0java/lang/Object;)L0java/util/HashMap$Node; -hash - (Ljava/lang/Object;)I - (L0java/lang/Object;)I keySet ()Ljava/util/Set; ()L1java/util/Set; @@ -50,21 +44,12 @@ putAll putIfAbsent (TK;TV;)TV; (T0K;T0V;)T0V; -putMapEntries - (Ljava/util/Map<+TK;+TV;>;Z)V - (L1java/util/Map<+TK;+TV;>;Z)V -putVal - (ITK;TV;ZZ)TV; - (IT0K;T0V;ZZ)T0V; remove (Ljava/lang/Object;)TV; (L0java/lang/Object;)T0V; remove (Ljava/lang/Object;Ljava/lang/Object;)Z (L0java/lang/Object;L0java/lang/Object;)Z -removeNode - (ILjava/lang/Object;Ljava/lang/Object;ZZ)Ljava/util/HashMap$Node; - (IL0java/lang/Object;L0java/lang/Object;ZZ)L0java/util/HashMap$Node; replace (TK;TV;)TV; (T0K;T0V;)T0V; @@ -74,12 +59,6 @@ replace replaceAll (Ljava/util/function/BiFunction<-TK;-TV;+TV;>;)V (L1java/util/function/BiFunction<-TK;-TV;+TV;>;)V -resize - ()[Ljava/util/HashMap$Node; - ()[L1java/util/HashMap$Node; -treeifyBin - ([Ljava/util/HashMap$Node;I)V - ([L0java/util/HashMap$Node;I)V values ()Ljava/util/Collection; ()L1java/util/Collection; diff --git a/libraries/java-17/java/util/Iterator.eea b/libraries/java-17/java/util/Iterator.eea index e86a1a6c9..95cce07e6 100644 --- a/libraries/java-17/java/util/Iterator.eea +++ b/libraries/java-17/java/util/Iterator.eea @@ -4,4 +4,4 @@ forEachRemaining (L1java/util/function/Consumer<-TE;>;)V next ()TE; - ()T+E; + ()TE; diff --git a/libraries/java-17/java/util/LinkedList.eea b/libraries/java-17/java/util/LinkedList.eea index d463816ab..f1ebae3d5 100644 --- a/libraries/java-17/java/util/LinkedList.eea +++ b/libraries/java-17/java/util/LinkedList.eea @@ -26,9 +26,6 @@ indexOf lastIndexOf (Ljava/lang/Object;)I (L0java/lang/Object;)I -linkBefore - (TE;Ljava/util/LinkedList$Node;)V - (TE;L1java/util/LinkedList$Node;)V listIterator (I)Ljava/util/ListIterator; (I)L1java/util/ListIterator; @@ -67,7 +64,4 @@ toArray ()[L1java/lang/Object; toArray ([TT;)[TT; - ([1TT;)[1TT; -unlink - (Ljava/util/LinkedList$Node;)TE; - (L1java/util/LinkedList$Node;)TE; + ([1TT;)[1TT; \ No newline at end of file diff --git a/libraries/java-17/java/util/List.eea b/libraries/java-17/java/util/List.eea index 3656a80b5..2164f63f6 100644 --- a/libraries/java-17/java/util/List.eea +++ b/libraries/java-17/java/util/List.eea @@ -19,7 +19,7 @@ equals (L0java/lang/Object;)Z get (I)TE; - (I)T+E; + (I)TE; indexOf (Ljava/lang/Object;)I (L0java/lang/Object;)I diff --git a/libraries/java-17/java/util/Map$Entry.eea b/libraries/java-17/java/util/Map$Entry.eea index ac6652e87..2ee483d53 100644 --- a/libraries/java-17/java/util/Map$Entry.eea +++ b/libraries/java-17/java/util/Map$Entry.eea @@ -16,7 +16,7 @@ equals (L0java/lang/Object;)Z getKey ()TK; - ()T+K; + ()TK; getValue ()TV; - ()T+V; + ()TV; diff --git a/libraries/java-17/java/util/Map.eea b/libraries/java-17/java/util/Map.eea index a7aa6025e..616bfc8c4 100644 --- a/libraries/java-17/java/util/Map.eea +++ b/libraries/java-17/java/util/Map.eea @@ -61,7 +61,7 @@ of (T1K;T1V;T1K;T1V;T1K;T1V;T1K;T1V;T1K;T1V;T1K;T1V;T1K;T1V;)L1java/util/Map; of (TK;TV;TK;TV;TK;TV;TK;TV;TK;TV;TK;TV;TK;TV;TK;TV;)Ljava/util/Map; - (T1K;T1V;T1K;T1V;T1K;T1V;T1K;T1V;T1K;T1V;T1K;T1V;T1K;T1V;T1K;TV1;)L1java/util/Map; + (T1K;T1V;T1K;T1V;T1K;T1V;T1K;T1V;T1K;T1V;T1K;T1V;T1K;T1V;T1K;T1V;)L1java/util/Map; of (TK;TV;TK;TV;TK;TV;TK;TV;TK;TV;TK;TV;TK;TV;TK;TV;TK;TV;)Ljava/util/Map; (T1K;T1V;T1K;T1V;T1K;T1V;T1K;T1V;T1K;T1V;T1K;T1V;T1K;T1V;T1K;T1V;T1K;T1V;)L1java/util/Map; @@ -91,4 +91,4 @@ replaceAll (L1java/util/function/BiFunction<-TK;-TV;+TV;>;)V values ()Ljava/util/Collection; - ()L1java/util/Collection; + ()L1java/util/Collection; diff --git a/libraries/java-17/java/util/Optional.eea b/libraries/java-17/java/util/Optional.eea index 102f04ed9..0f23fefa1 100644 --- a/libraries/java-17/java/util/Optional.eea +++ b/libraries/java-17/java/util/Optional.eea @@ -43,7 +43,7 @@ orElseThrow ()T1T; orElseThrow (Ljava/util/function/Supplier<+TX;>;)TT;^TX; - (L1java/util/function/Supplier<+TX;>;)T1T; + (L1java/util/function/Supplier<+TX;>;)T1T;^TX; stream ()Ljava/util/stream/Stream; ()L1java/util/stream/Stream; diff --git a/libraries/java-17/java/util/Properties.eea b/libraries/java-17/java/util/Properties.eea index 0a5a3a8cf..4e3fef58a 100644 --- a/libraries/java-17/java/util/Properties.eea +++ b/libraries/java-17/java/util/Properties.eea @@ -29,12 +29,6 @@ elements entrySet ()Ljava/util/Set;>; ()L1java/util/Set;>; -enumerate - (Ljava/util/Map;)V - (L1java/util/Map;)V -enumerateStringProperties - (Ljava/util/Map;)V - (L1java/util/Map;)V equals (Ljava/lang/Object;)Z (L0java/lang/Object;)Z diff --git a/libraries/java-17/java/util/UUID.eea b/libraries/java-17/java/util/UUID.eea index e105f5e09..b503a86ca 100644 --- a/libraries/java-17/java/util/UUID.eea +++ b/libraries/java-17/java/util/UUID.eea @@ -1,7 +1,4 @@ class java/util/UUID - - ([B)V - ([1B)V fromString (Ljava/lang/String;)Ljava/util/UUID; (L1java/lang/String;)L1java/util/UUID; diff --git a/libraries/java-17/java/util/Vector.eea b/libraries/java-17/java/util/Vector.eea index d61ca935e..54391d64a 100644 --- a/libraries/java-17/java/util/Vector.eea +++ b/libraries/java-17/java/util/Vector.eea @@ -1,4 +1,4 @@ class java/util/Vector get (I)TE; - (I)T+E; + (I)TE; diff --git a/libraries/java-17/java/util/concurrent/ConcurrentHashMap.eea b/libraries/java-17/java/util/concurrent/ConcurrentHashMap.eea index d337205e5..1787ffb7e 100644 --- a/libraries/java-17/java/util/concurrent/ConcurrentHashMap.eea +++ b/libraries/java-17/java/util/concurrent/ConcurrentHashMap.eea @@ -2,12 +2,6 @@ class java/util/concurrent/ConcurrentHashMap (Ljava/util/Map<+TK;+TV;>;)V (L1java/util/Map<+TK;+TV;>;)V -comparableClassFor - (Ljava/lang/Object;)Ljava/lang/Class<*>; - (L0java/lang/Object;)L0java/lang/Class<*>; -compareComparables - (Ljava/lang/Class<*>;Ljava/lang/Object;Ljava/lang/Object;)I - (L0java/lang/Class<*>;L1java/lang/Object;L1java/lang/Object;)I compute (TK;Ljava/util/function/BiFunction<-TK;-TV;+TV;>;)TV; (T1K;L1java/util/function/BiFunction<-TK;-TV;+TV;>;)T0V; @@ -95,9 +89,6 @@ putAll putIfAbsent (TK;TV;)TV; (T1K;T1V;)T0V; -putVal - (TK;TV;Z)TV; - (T1K;T1V;Z)T0V; reduce (JLjava/util/function/BiFunction<-TK;-TV;+TU;>;Ljava/util/function/BiFunction<-TU;-TU;+TU;>;)TU; (JL1java/util/function/BiFunction<-TK;-TV;+TU;>;L1java/util/function/BiFunction<-TU;-TU;+TU;>;)TU; @@ -161,12 +152,6 @@ remove remove (Ljava/lang/Object;Ljava/lang/Object;)Z (L1java/lang/Object;L0java/lang/Object;)Z -removeEntryIf - (Ljava/util/function/Predicate<-Ljava/util/Map$Entry;>;)Z - (L1java/util/function/Predicate<-Ljava/util/Map$Entry;>;)Z -removeValueIf - (Ljava/util/function/Predicate<-TV;>;)Z - (L1java/util/function/Predicate<-TV;>;)Z replace (TK;TV;)TV; (T1K;T1V;)T0V; @@ -176,9 +161,6 @@ replace replaceAll (Ljava/util/function/BiFunction<-TK;-TV;+TV;>;)V (L1java/util/function/BiFunction<-TK;-TV;+TV;>;)V -replaceNode - (Ljava/lang/Object;TV;Ljava/lang/Object;)TV; - (L1java/lang/Object;T0V;L0java/lang/Object;)T0V; search (JLjava/util/function/BiFunction<-TK;-TV;+TU;>;)TU; (JL1java/util/function/BiFunction<-TK;-TV;+TU;>;)TU; diff --git a/libraries/java-17/java/util/jar/Attributes$Name.eea b/libraries/java-17/java/util/jar/Attributes$Name.eea index b4f833f1d..e29fc7bf5 100644 --- a/libraries/java-17/java/util/jar/Attributes$Name.eea +++ b/libraries/java-17/java/util/jar/Attributes$Name.eea @@ -59,12 +59,6 @@ SPECIFICATION_VERSION equals (Ljava/lang/Object;)Z (L0java/lang/Object;)Z -hash - (Ljava/lang/String;)I - (L1java/lang/String;)I -of - (Ljava/lang/String;)Ljava/util/jar/Attributes$Name; - (L1java/lang/String;)L1java/util/jar/Attributes$Name; toString ()Ljava/lang/String; ()L1java/lang/String; diff --git a/libraries/java-17/java/util/jar/Attributes.eea b/libraries/java-17/java/util/jar/Attributes.eea index ee8899459..55c211811 100644 --- a/libraries/java-17/java/util/jar/Attributes.eea +++ b/libraries/java-17/java/util/jar/Attributes.eea @@ -38,18 +38,9 @@ putAll putValue (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; (L1java/lang/String;L1java/lang/String;)L0java/lang/String; -read - (Ljava/util/jar/Manifest$FastInputStream;[B)V - (L1java/util/jar/Manifest$FastInputStream;[1B)V remove (Ljava/lang/Object;)Ljava/lang/Object; (L1java/lang/Object;)L0java/lang/Object; values ()Ljava/util/Collection; ()L1java/util/Collection; -write - (Ljava/io/DataOutputStream;)V - (L1java/io/DataOutputStream;)V -writeMain - (Ljava/io/DataOutputStream;)V - (L1java/io/DataOutputStream;)V diff --git a/libraries/java-17/java/util/jar/JarFile.eea b/libraries/java-17/java/util/jar/JarFile.eea index 663c37b61..13708d847 100644 --- a/libraries/java-17/java/util/jar/JarFile.eea +++ b/libraries/java-17/java/util/jar/JarFile.eea @@ -35,12 +35,6 @@ getJarEntry getManifest ()Ljava/util/jar/Manifest; ()L0java/util/jar/Manifest; -getManifestFromReference - ()Ljava/util/jar/Manifest; - ()Ljava/util/jar/Manifest; -getMetaInfEntryNames - ()[Ljava/lang/String; - ()[0Ljava/lang/String; getVersion ()Ljava/lang/Runtime$Version; ()L1java/lang/Runtime$Version; @@ -50,9 +44,6 @@ runtimeVersion stream ()Ljava/util/stream/Stream; ()L1java/util/stream/Stream; -verifiableEntry - (Ljava/util/zip/ZipEntry;)Ljava/util/jar/JarEntry; - (L1java/util/zip/ZipEntry;)L1java/util/jar/JarEntry; versionedStream ()Ljava/util/stream/Stream; ()L1java/util/stream/Stream; diff --git a/libraries/java-17/java/util/jar/JarInputStream.eea b/libraries/java-17/java/util/jar/JarInputStream.eea index 6c213e3a2..15e7ec656 100644 --- a/libraries/java-17/java/util/jar/JarInputStream.eea +++ b/libraries/java-17/java/util/jar/JarInputStream.eea @@ -5,15 +5,9 @@ class java/util/jar/JarInputStream (Ljava/io/InputStream;Z)V (L1java/io/InputStream;Z)V -checkManifest - (Ljava/util/jar/JarEntry;)Ljava/util/jar/JarEntry; - (L0java/util/jar/JarEntry;)L0java/util/jar/JarEntry; createZipEntry (Ljava/lang/String;)Ljava/util/zip/ZipEntry; (L1java/lang/String;)L1java/util/zip/ZipEntry; -getBytes - (Ljava/io/InputStream;)[B - (L1java/io/InputStream;)[1B getManifest ()Ljava/util/jar/Manifest; ()L0java/util/jar/Manifest; diff --git a/libraries/java-17/javax/xml/bind/DatatypeConverter.eea b/libraries/java-17/javax/xml/bind/DatatypeConverter.eea deleted file mode 100644 index 36c7f5e85..000000000 --- a/libraries/java-17/javax/xml/bind/DatatypeConverter.eea +++ /dev/null @@ -1,10 +0,0 @@ -class javax/xml/bind/DatatypeConverter -parseDate - (Ljava/lang/String;)Ljava/util/Calendar; - (L1java/lang/String;)L1java/util/Calendar; -printDateTime - (Ljava/util/Calendar;)Ljava/lang/String; - (L1java/util/Calendar;)L1java/lang/String; -printBase64Binary - ([B)Ljava/lang/String; - ([B)L1java/lang/String; diff --git a/libraries/java-17/pom.xml b/libraries/java-17/pom.xml index 8f8c6812a..c812f6743 100644 --- a/libraries/java-17/pom.xml +++ b/libraries/java-17/pom.xml @@ -1,13 +1,14 @@ - + 4.0.0 - - org.lastnpe.eea eea-parent 3.0.0-SNAPSHOT + ../pom.xml java-17-eea @@ -17,4 +18,8 @@ but version the EEA itself. Put the version of the lib into the EEA's name, if at all.--> + + 17 + + diff --git a/libraries/jetty/eea-generator.properties b/libraries/jetty/eea-generator.properties new file mode 100644 index 000000000..c7edcee36 --- /dev/null +++ b/libraries/jetty/eea-generator.properties @@ -0,0 +1 @@ +packages.include=org.eclipse.jetty.client \ No newline at end of file diff --git a/libraries/jetty/org/eclipse/jetty/client/util/BufferingResponseListener.eea b/libraries/jetty/org/eclipse/jetty/client/BufferingResponseListener.eea similarity index 57% rename from libraries/jetty/org/eclipse/jetty/client/util/BufferingResponseListener.eea rename to libraries/jetty/org/eclipse/jetty/client/BufferingResponseListener.eea index c43754e38..c7acdc64f 100644 --- a/libraries/jetty/org/eclipse/jetty/client/util/BufferingResponseListener.eea +++ b/libraries/jetty/org/eclipse/jetty/client/BufferingResponseListener.eea @@ -1,4 +1,4 @@ -class org/eclipse/jetty/client/util/BufferingResponseListener +class org/eclipse/jetty/client/BufferingResponseListener getContentAsInputStream ()Ljava/io/InputStream; ()L1java/io/InputStream; @@ -18,11 +18,11 @@ getMediaType ()Ljava/lang/String; ()L0java/lang/String; onComplete - (Lorg/eclipse/jetty/client/api/Result;)V - (L1org/eclipse/jetty/client/api/Result;)V + (Lorg/eclipse/jetty/client/Result;)V + (L1org/eclipse/jetty/client/Result;)V onContent - (Lorg/eclipse/jetty/client/api/Response;Ljava/nio/ByteBuffer;)V - (L1org/eclipse/jetty/client/api/Response;L1java/nio/ByteBuffer;)V + (Lorg/eclipse/jetty/client/Response;Ljava/nio/ByteBuffer;)V + (L1org/eclipse/jetty/client/Response;L1java/nio/ByteBuffer;)V onHeaders - (Lorg/eclipse/jetty/client/api/Response;)V - (L1org/eclipse/jetty/client/api/Response;)V + (Lorg/eclipse/jetty/client/Response;)V + (L1org/eclipse/jetty/client/Response;)V diff --git a/libraries/jetty/org/eclipse/jetty/client/Response$BeginListener.eea b/libraries/jetty/org/eclipse/jetty/client/Response$BeginListener.eea new file mode 100644 index 000000000..b6f957480 --- /dev/null +++ b/libraries/jetty/org/eclipse/jetty/client/Response$BeginListener.eea @@ -0,0 +1,4 @@ +class org/eclipse/jetty/client/Response$BeginListener +onBegin + (Lorg/eclipse/jetty/client/Response;)V + (L1org/eclipse/jetty/client/Response;)V diff --git a/libraries/jetty/org/eclipse/jetty/client/Response$CompleteListener.eea b/libraries/jetty/org/eclipse/jetty/client/Response$CompleteListener.eea new file mode 100644 index 000000000..a5c9a8317 --- /dev/null +++ b/libraries/jetty/org/eclipse/jetty/client/Response$CompleteListener.eea @@ -0,0 +1,4 @@ +class org/eclipse/jetty/client/Response$CompleteListener +onComplete + (Lorg/eclipse/jetty/client/Result;)V + (L1org/eclipse/jetty/client/Result;)V diff --git a/libraries/jetty/org/eclipse/jetty/client/Response$ContentListener.eea b/libraries/jetty/org/eclipse/jetty/client/Response$ContentListener.eea new file mode 100644 index 000000000..36b56b96c --- /dev/null +++ b/libraries/jetty/org/eclipse/jetty/client/Response$ContentListener.eea @@ -0,0 +1,4 @@ +class org/eclipse/jetty/client/Response$ContentListener +onContent + (Lorg/eclipse/jetty/client/Response;Ljava/nio/ByteBuffer;)V + (L1org/eclipse/jetty/client/Response;L1java/nio/ByteBuffer;)V diff --git a/libraries/jetty/org/eclipse/jetty/client/Response$FailureListener.eea b/libraries/jetty/org/eclipse/jetty/client/Response$FailureListener.eea new file mode 100644 index 000000000..443f0c2b2 --- /dev/null +++ b/libraries/jetty/org/eclipse/jetty/client/Response$FailureListener.eea @@ -0,0 +1,4 @@ +class org/eclipse/jetty/client/Response$FailureListener +onFailure + (Lorg/eclipse/jetty/client/Response;Ljava/lang/Throwable;)V + (L1org/eclipse/jetty/client/Response;L1java/lang/Throwable;)V diff --git a/libraries/jetty/org/eclipse/jetty/client/Response$HeaderListener.eea b/libraries/jetty/org/eclipse/jetty/client/Response$HeaderListener.eea new file mode 100644 index 000000000..17da57123 --- /dev/null +++ b/libraries/jetty/org/eclipse/jetty/client/Response$HeaderListener.eea @@ -0,0 +1,4 @@ +class org/eclipse/jetty/client/Response$HeaderListener +onHeader + (Lorg/eclipse/jetty/client/Response;Lorg/eclipse/jetty/http/HttpField;)Z + (L1org/eclipse/jetty/client/Response;L1org/eclipse/jetty/http/HttpField;)Z diff --git a/libraries/jetty/org/eclipse/jetty/client/Response$HeadersListener.eea b/libraries/jetty/org/eclipse/jetty/client/Response$HeadersListener.eea new file mode 100644 index 000000000..e10f7f66c --- /dev/null +++ b/libraries/jetty/org/eclipse/jetty/client/Response$HeadersListener.eea @@ -0,0 +1,4 @@ +class org/eclipse/jetty/client/Response$HeadersListener +onHeaders + (Lorg/eclipse/jetty/client/Response;)V + (L1org/eclipse/jetty/client/Response;)V diff --git a/libraries/jetty/org/eclipse/jetty/client/Response$SuccessListener.eea b/libraries/jetty/org/eclipse/jetty/client/Response$SuccessListener.eea new file mode 100644 index 000000000..2006d428d --- /dev/null +++ b/libraries/jetty/org/eclipse/jetty/client/Response$SuccessListener.eea @@ -0,0 +1,4 @@ +class org/eclipse/jetty/client/Response$SuccessListener +onSuccess + (Lorg/eclipse/jetty/client/Response;)V + (L1org/eclipse/jetty/client/Response;)V diff --git a/libraries/jetty/org/eclipse/jetty/client/Response.eea b/libraries/jetty/org/eclipse/jetty/client/Response.eea new file mode 100644 index 000000000..e0238736c --- /dev/null +++ b/libraries/jetty/org/eclipse/jetty/client/Response.eea @@ -0,0 +1,16 @@ +class org/eclipse/jetty/client/Response +abort + (Ljava/lang/Throwable;)Ljava/util/concurrent/CompletableFuture; + (L1java/lang/Throwable;)L1java/util/concurrent/CompletableFuture; +getHeaders + ()Lorg/eclipse/jetty/http/HttpFields; + ()L1org/eclipse/jetty/http/HttpFields; +getReason + ()Ljava/lang/String; + ()L1java/lang/String; +getRequest + ()Lorg/eclipse/jetty/client/Request; + ()L1org/eclipse/jetty/client/Request; +getVersion + ()Lorg/eclipse/jetty/http/HttpVersion; + ()L1org/eclipse/jetty/http/HttpVersion; diff --git a/libraries/jetty/org/eclipse/jetty/client/api/Response$AsyncContentListener.eea b/libraries/jetty/org/eclipse/jetty/client/api/Response$AsyncContentListener.eea deleted file mode 100644 index 9e0fc08ea..000000000 --- a/libraries/jetty/org/eclipse/jetty/client/api/Response$AsyncContentListener.eea +++ /dev/null @@ -1,4 +0,0 @@ -class org/eclipse/jetty/client/api/Response$AsyncContentListener -onContent - (Lorg/eclipse/jetty/client/api/Response;Ljava/nio/ByteBuffer;Lorg/eclipse/jetty/util/Callback;)V - (L1org/eclipse/jetty/client/api/Response;L1java/nio/ByteBuffer;L1org/eclipse/jetty/util/Callback;)V diff --git a/libraries/jetty/org/eclipse/jetty/client/api/Response$BeginListener.eea b/libraries/jetty/org/eclipse/jetty/client/api/Response$BeginListener.eea deleted file mode 100644 index f3e0e4ffe..000000000 --- a/libraries/jetty/org/eclipse/jetty/client/api/Response$BeginListener.eea +++ /dev/null @@ -1,4 +0,0 @@ -class org/eclipse/jetty/client/api/Response$BeginListener -onBegin - (Lorg/eclipse/jetty/client/api/Response;)V - (L1org/eclipse/jetty/client/api/Response;)V diff --git a/libraries/jetty/org/eclipse/jetty/client/api/Response$CompleteListener.eea b/libraries/jetty/org/eclipse/jetty/client/api/Response$CompleteListener.eea deleted file mode 100644 index 00611bb8c..000000000 --- a/libraries/jetty/org/eclipse/jetty/client/api/Response$CompleteListener.eea +++ /dev/null @@ -1,4 +0,0 @@ -class org/eclipse/jetty/client/api/Response$CompleteListener -onComplete - (Lorg/eclipse/jetty/client/api/Result;)V - (L1org/eclipse/jetty/client/api/Result;)V diff --git a/libraries/jetty/org/eclipse/jetty/client/api/Response$ContentListener.eea b/libraries/jetty/org/eclipse/jetty/client/api/Response$ContentListener.eea deleted file mode 100644 index 7ddc1a920..000000000 --- a/libraries/jetty/org/eclipse/jetty/client/api/Response$ContentListener.eea +++ /dev/null @@ -1,4 +0,0 @@ -class org/eclipse/jetty/client/api/Response$ContentListener -onContent - (Lorg/eclipse/jetty/client/api/Response;Ljava/nio/ByteBuffer;)V - (L1org/eclipse/jetty/client/api/Response;L1java/nio/ByteBuffer;)V diff --git a/libraries/jetty/org/eclipse/jetty/client/api/Response$FailureListener.eea b/libraries/jetty/org/eclipse/jetty/client/api/Response$FailureListener.eea deleted file mode 100644 index ac991de36..000000000 --- a/libraries/jetty/org/eclipse/jetty/client/api/Response$FailureListener.eea +++ /dev/null @@ -1,4 +0,0 @@ -class org/eclipse/jetty/client/api/Response$FailureListener -onFailure - (Lorg/eclipse/jetty/client/api/Response;Ljava/lang/Throwable;)V - (L1org/eclipse/jetty/client/api/Response;L1java/lang/Throwable;)V diff --git a/libraries/jetty/org/eclipse/jetty/client/api/Response$HeaderListener.eea b/libraries/jetty/org/eclipse/jetty/client/api/Response$HeaderListener.eea deleted file mode 100644 index 3d09e9a31..000000000 --- a/libraries/jetty/org/eclipse/jetty/client/api/Response$HeaderListener.eea +++ /dev/null @@ -1,4 +0,0 @@ -class org/eclipse/jetty/client/api/Response$HeaderListener -onHeader - (Lorg/eclipse/jetty/client/api/Response;Lorg/eclipse/jetty/http/HttpField;)Z - (L1org/eclipse/jetty/client/api/Response;L1org/eclipse/jetty/http/HttpField;)Z diff --git a/libraries/jetty/org/eclipse/jetty/client/api/Response$HeadersListener.eea b/libraries/jetty/org/eclipse/jetty/client/api/Response$HeadersListener.eea deleted file mode 100644 index 5f50a441e..000000000 --- a/libraries/jetty/org/eclipse/jetty/client/api/Response$HeadersListener.eea +++ /dev/null @@ -1,4 +0,0 @@ -class org/eclipse/jetty/client/api/Response$HeadersListener -onHeaders - (Lorg/eclipse/jetty/client/api/Response;)V - (L1org/eclipse/jetty/client/api/Response;)V diff --git a/libraries/jetty/org/eclipse/jetty/client/api/Response$Listener$Adapter.eea b/libraries/jetty/org/eclipse/jetty/client/api/Response$Listener$Adapter.eea deleted file mode 100644 index ec4e3657c..000000000 --- a/libraries/jetty/org/eclipse/jetty/client/api/Response$Listener$Adapter.eea +++ /dev/null @@ -1,25 +0,0 @@ -class org/eclipse/jetty/client/api/Response$Listener$Adapter -onBegin - (Lorg/eclipse/jetty/client/api/Response;)V - (L1org/eclipse/jetty/client/api/Response;)V -onComplete - (Lorg/eclipse/jetty/client/api/Result;)V - (L1org/eclipse/jetty/client/api/Result;)V -onContent - (Lorg/eclipse/jetty/client/api/Response;Ljava/nio/ByteBuffer;)V - (L1org/eclipse/jetty/client/api/Response;L1java/nio/ByteBuffer;)V -onContent - (Lorg/eclipse/jetty/client/api/Response;Ljava/nio/ByteBuffer;Lorg/eclipse/jetty/util/Callback;)V - (L1org/eclipse/jetty/client/api/Response;L1java/nio/ByteBuffer;L1org/eclipse/jetty/util/Callback;)V -onFailure - (Lorg/eclipse/jetty/client/api/Response;Ljava/lang/Throwable;)V - (L1org/eclipse/jetty/client/api/Response;L1java/lang/Throwable;)V -onHeader - (Lorg/eclipse/jetty/client/api/Response;Lorg/eclipse/jetty/http/HttpField;)Z - (L1org/eclipse/jetty/client/api/Response;L1org/eclipse/jetty/http/HttpField;)Z -onHeaders - (Lorg/eclipse/jetty/client/api/Response;)V - (L1org/eclipse/jetty/client/api/Response;)V -onSuccess - (Lorg/eclipse/jetty/client/api/Response;)V - (L1org/eclipse/jetty/client/api/Response;)V diff --git a/libraries/jetty/org/eclipse/jetty/client/api/Response$SuccessListener.eea b/libraries/jetty/org/eclipse/jetty/client/api/Response$SuccessListener.eea deleted file mode 100644 index 767b97a8b..000000000 --- a/libraries/jetty/org/eclipse/jetty/client/api/Response$SuccessListener.eea +++ /dev/null @@ -1,4 +0,0 @@ -class org/eclipse/jetty/client/api/Response$SuccessListener -onSuccess - (Lorg/eclipse/jetty/client/api/Response;)V - (L1org/eclipse/jetty/client/api/Response;)V diff --git a/libraries/jetty/org/eclipse/jetty/client/api/Response.eea b/libraries/jetty/org/eclipse/jetty/client/api/Response.eea deleted file mode 100644 index 90579d5f7..000000000 --- a/libraries/jetty/org/eclipse/jetty/client/api/Response.eea +++ /dev/null @@ -1,16 +0,0 @@ -class org/eclipse/jetty/client/api/Response -abort - (Ljava/lang/Throwable;)Z - (L1java/lang/Throwable;)Z -getHeaders - ()Lorg/eclipse/jetty/http/HttpFields; - ()L1org/eclipse/jetty/http/HttpFields; -getReason - ()Ljava/lang/String; - ()L1java/lang/String; -getRequest - ()Lorg/eclipse/jetty/client/api/Request; - ()L1org/eclipse/jetty/client/api/Request; -getVersion - ()Lorg/eclipse/jetty/http/HttpVersion; - ()L1org/eclipse/jetty/http/HttpVersion; diff --git a/libraries/jetty/pom.xml b/libraries/jetty/pom.xml index 0fda137b5..cacd70871 100644 --- a/libraries/jetty/pom.xml +++ b/libraries/jetty/pom.xml @@ -1,20 +1,27 @@ - + 4.0.0 - - org.lastnpe.eea eea-parent 3.0.0-SNAPSHOT - jetty-eea - EEA :: jetty + jetty-client-eea + EEA :: jetty-client + + + org.eclipse.jetty + jetty-client + 12.0.12 + + diff --git a/libraries/junit-5/eea-generator.properties b/libraries/junit-5/eea-generator.properties new file mode 100644 index 000000000..3098aa53b --- /dev/null +++ b/libraries/junit-5/eea-generator.properties @@ -0,0 +1 @@ +packages.include=org.junit.jupiter.api \ No newline at end of file diff --git a/libraries/junit5/org/junit/jupiter/api/Assertions.eea b/libraries/junit-5/org/junit/jupiter/api/Assertions.eea similarity index 100% rename from libraries/junit5/org/junit/jupiter/api/Assertions.eea rename to libraries/junit-5/org/junit/jupiter/api/Assertions.eea diff --git a/libraries/junit5/pom.xml b/libraries/junit-5/pom.xml similarity index 70% rename from libraries/junit5/pom.xml rename to libraries/junit-5/pom.xml index 4478eef4a..b9a30cb8d 100644 --- a/libraries/junit5/pom.xml +++ b/libraries/junit-5/pom.xml @@ -2,19 +2,25 @@ 4.0.0 - - org.lastnpe.eea eea-parent 3.0.0-SNAPSHOT - junit5-eea + junit-5-eea EEA :: junit5 + + + org.junit.jupiter + junit-jupiter-api + 5.11.0 + provided + + diff --git a/libraries/mockito/eea-for-gav b/libraries/mockito/eea-for-gav deleted file mode 100644 index 153f74b4b..000000000 --- a/libraries/mockito/eea-for-gav +++ /dev/null @@ -1,3 +0,0 @@ -org.mockito:mockito-all -org.mockito:mockito-core - diff --git a/libraries/mockito/eea-generator.properties b/libraries/mockito/eea-generator.properties new file mode 100644 index 000000000..bdd4f1019 --- /dev/null +++ b/libraries/mockito/eea-generator.properties @@ -0,0 +1 @@ +packages.include=org.mockito \ No newline at end of file diff --git a/libraries/mockito/pom.xml b/libraries/mockito/pom.xml index cd302c329..06d69a320 100644 --- a/libraries/mockito/pom.xml +++ b/libraries/mockito/pom.xml @@ -1,9 +1,9 @@ - + 4.0.0 - - org.lastnpe.eea eea-parent @@ -17,4 +17,12 @@ but version the EEA itself. Put the version of the lib into the EEA's name, if at all.--> + + + org.mockito + mockito-core + 5.12.0 + true + + diff --git a/libraries/osgi-core/eea-for-gav b/libraries/osgi-core/eea-for-gav deleted file mode 100644 index 6d22eb21b..000000000 --- a/libraries/osgi-core/eea-for-gav +++ /dev/null @@ -1 +0,0 @@ -org.osgi:org.osgi.core diff --git a/libraries/osgi-core/eea-generator.properties b/libraries/osgi-core/eea-generator.properties new file mode 100644 index 000000000..e0745f49a --- /dev/null +++ b/libraries/osgi-core/eea-generator.properties @@ -0,0 +1 @@ +packages.include=org.osgi \ No newline at end of file diff --git a/libraries/osgi-core/pom.xml b/libraries/osgi-core/pom.xml index 8fa574f7c..0737eccc1 100644 --- a/libraries/osgi-core/pom.xml +++ b/libraries/osgi-core/pom.xml @@ -1,9 +1,9 @@ - + 4.0.0 - - org.lastnpe.eea eea-parent @@ -17,4 +17,12 @@ but version the EEA itself. Put the version of the lib into the EEA's name, if at all.--> + + + org.osgi + osgi.core + 8.0.0 + provided + + diff --git a/libraries/pom.xml b/libraries/pom.xml index 67299cee7..a859dc6d2 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -1,5 +1,7 @@ - + 4.0.0 @@ -13,76 +15,199 @@ pom EEA :: Reactor - JARs of *.eea for the JDK and common Java libraries + Parent for JARs of *.eea for the JDK and common Java libraries + + + + validate + - eea-all + java-17 gson guava - java-17 - javamail + jetty - junit5 + junit-5 mockito osgi-core slf4j-api - servlet-api + spring xstream - - - - - false - ${project.basedir} - - **/* - eea-*.* - - - .* - pom.xml - target/ - .settings/ - - - - - - org.apache.maven.plugins - maven-resources-plugin - 3.0.1 - - - - default-testResources - none - - - - - org.apache.maven.plugins - maven-jar-plugin - 3.0.2 - - - org.apache.maven.plugins - maven-surefire-plugin - 2.19.1 - - - - default-test - none - - - - - - + + + eea-library-module + + + ${project.basedir}/eea-generator.properties + + + + + + + + false + ${project.basedir} + + **/* + eea-*.* + + + .* + pom.xml + target/ + .settings/ + + + + + + + + org.codehaus.mojo + exec-maven-plugin + 3.4.1 + + + + ${eea-generator.action}-eeas + generate-resources + + exec + + + provided + true + java + + -Deea-generator.action=${eea-generator.action} + + + -Deea-generator.input.dirs.default=${project.basedir},${project.basedir}/../eea-java-17 + + + + -Deea-generator.output.dir=${project.basedir} + + -classpath + + org.lastnpe.eea.generator.EEAGenerator + ${project.basedir}/eea-generator.properties + + + + + + generate-minimized-eeas + process-resources + + exec + + + provided + true + java + + -Deea-generator.action=minimize + -Deea-generator.input.dirs=${project.basedir} + + -Deea-generator.output.dir.default=${project.build.outputDirectory} + -classpath + + org.lastnpe.eea.generator.EEAGenerator + ${project.basedir}/eea-generator.properties + + + + + + + org.lastnpe.eea + lastnpe-eea-generator + ${project.version} + + + + + + + org.apache.felix + maven-bundle-plugin + 5.1.9 + + + manifest@process-classes + process-classes + + manifest + + + + + true + + + + + + + + + maven-resources-plugin + + + + default-resources + none + + + default-testResources + none + + + + + maven-surefire-plugin + + + + default-test + none + + + + + maven-source-plugin + + + + attach-sources + none + + jar + + + + + + + + not-m2e @@ -93,9 +218,7 @@ - org.apache.maven.plugins maven-compiler-plugin - 3.8.1 - org.lastnpe.eea eea-parent @@ -17,4 +17,12 @@ but version the EEA itself. Put the version of the lib into the EEA's name, if at all.--> + + + org.slf4j + slf4j-api + 2.0.13 + provided + + diff --git a/libraries/spring/eea-for-gav b/libraries/spring/eea-for-gav deleted file mode 100644 index 8ea1490b3..000000000 --- a/libraries/spring/eea-for-gav +++ /dev/null @@ -1,2 +0,0 @@ -org.springframework:spring-beans -org.springframework:spring-core diff --git a/libraries/spring/eea-generator.properties b/libraries/spring/eea-generator.properties new file mode 100644 index 000000000..81ca0fdd2 --- /dev/null +++ b/libraries/spring/eea-generator.properties @@ -0,0 +1 @@ +packages.include=org.springframework \ No newline at end of file diff --git a/libraries/spring/pom.xml b/libraries/spring/pom.xml index 69804aaaa..ed878644e 100644 --- a/libraries/spring/pom.xml +++ b/libraries/spring/pom.xml @@ -1,9 +1,9 @@ - + 4.0.0 - - org.lastnpe.eea eea-parent @@ -17,4 +17,24 @@ but version the EEA itself. Put the version of the lib into the EEA's name, if at all.--> + + + + org.springframework + spring-framework-bom + 6.1.12 + pom + import + + + + + + + org.springframework + spring-beans + provided + + + diff --git a/libraries/xstream/eea-for-gav b/libraries/xstream/eea-for-gav deleted file mode 100644 index 130ff3617..000000000 --- a/libraries/xstream/eea-for-gav +++ /dev/null @@ -1 +0,0 @@ -com.thoughtworks.xstream:xstream diff --git a/libraries/xstream/eea-generator.properties b/libraries/xstream/eea-generator.properties new file mode 100644 index 000000000..2a16e8b1f --- /dev/null +++ b/libraries/xstream/eea-generator.properties @@ -0,0 +1 @@ +packages.include=com.thoughtworks.xstream \ No newline at end of file diff --git a/libraries/xstream/pom.xml b/libraries/xstream/pom.xml index d8eeb9ce2..3b53b2a46 100644 --- a/libraries/xstream/pom.xml +++ b/libraries/xstream/pom.xml @@ -1,9 +1,9 @@ - + 4.0.0 - - org.lastnpe.eea eea-parent @@ -17,4 +17,12 @@ but version the EEA itself. Put the version of the lib into the EEA's name, if at all.--> + + + com.thoughtworks.xstream + xstream + 1.4.20 + provided + + diff --git a/pom.xml b/pom.xml index 7c6678961..f05303235 100644 --- a/pom.xml +++ b/pom.xml @@ -1,5 +1,7 @@ - + 4.0.0 org.lastnpe.eea @@ -10,10 +12,8 @@ Eclipse External null Annotations (EEA) This is the root POM of the EEA project - https://lastnpe.org 2016 - LastNPE.org http://www.lastnpe.org @@ -37,6 +37,7 @@ sebthom Sebastian Thomschke + https://sebthom.de Vegard IT GmbH https://vegardit.com @@ -54,6 +55,16 @@ https://github.com/lastnpe/eclipse-null-eea-augments + + github.com + https://github.com/lastnpe/eclipse-null-eea-augments/issues + + + + github.com + https://github.com/lastnpe/eclipse-null-eea-augments/actions + + ossrh @@ -66,13 +77,74 @@ - 11 UTF-8 + 17 + + + + maven-toolchains-plugin + 3.2.0 + + + toolchain@validate + validate + + toolchain + + + + + ${java.version} + + + + + + + + + + + + maven-compiler-plugin + 3.13.0 + + ${java.version} + ${java.version} + ${java.version} + + + + maven-resources-plugin + 3.3.1 + + + maven-jar-plugin + 3.4.2 + + + maven-source-plugin + 3.3.1 + + + maven-surefire-plugin + 3.4.0 + + + maven-deploy-plugin + 3.1.2 + + + + + + generator libraries - examples/maven + eea-all + @@ -81,9 +153,8 @@ - org.apache.maven.plugins maven-gpg-plugin - 1.6 + 3.2.5 sign-artifacts @@ -101,9 +172,8 @@ - org.apache.maven.plugins maven-release-plugin - 3.0.0-M1 + 3.1.1 clean install v@{project.version} @@ -112,6 +182,7 @@ +