diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 3b9d2d3917..fd7900e799 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -1,13 +1,15 @@
name: Build and release
on:
+ workflow_dispatch:
+
push:
branches:
- '**'
env:
native_image_opts: --verbose -H:Log=registerResource:verbose -H:+PrintClassInitialization
- graal_version: 22.3.1
- graal_java_version: 11
+ graal_distribution: graalvm-community
+ graal_java_version: 17
jobs:
build:
@@ -16,6 +18,10 @@ jobs:
steps:
- name: Check-out source code
uses: actions/checkout@v3
+ - uses: actions/setup-java@v3
+ with:
+ distribution: 'temurin'
+ java-version: '17'
- name: PROD - Prepare GitHub release
id: create_prod_release
@@ -24,8 +30,8 @@ jobs:
with:
command: github-release
release-type: simple
- package-name: ${{ github.event.repository.name }}
- default-branch: main
+ package-name: ${{ github.event.repository.name }}
+ default-branch: main
- name: PROD - Define release info
if: steps.create_prod_release.outputs.release_created
@@ -62,7 +68,7 @@ jobs:
- name: Build release ${{env.RELEASE_VERSION}}
if: env.DO_BUILD
- run: ./gradlew clean build dist distThirdParty -Pversion=${{env.RELEASE_VERSION}}
+ run: ./gradlew clean build dist distThirdPartyReleaseAsset distFtest -Pversion=${{env.RELEASE_VERSION}}
- name: Check fcli version
if: env.DO_BUILD
@@ -71,7 +77,7 @@ jobs:
- name: Publish build artifacts
uses: actions/upload-artifact@v3
with:
- path: build/dist/*
+ path: build/dist/**/*
outputs:
do_release: ${{ env.DO_RELEASE }}
@@ -92,7 +98,7 @@ jobs:
- uses: graalvm/setup-graalvm@v1
with:
- version: ${{ env.graal_version }}
+ distribution: ${{ env.graal_distribution }}
java-version: ${{ env.graal_java_version }}
components: 'native-image'
native-image-musl: true
@@ -110,7 +116,7 @@ jobs:
# at build time (see https://www.graalvm.org/22.1/reference-manual/native-image/Properties/).
# We also exclude the native Jansi library resources, as these are now no longer needed.
- name: Create native fcli
- run: native-image ${{ env.native_image_opts }} --static --libc=musl -Djansi.disable=true --initialize-at-build-time=com.fortify.cli.app.FortifyCLI -H:ExcludeResources="org/fusesource/jansi/internal/native/.*" -jar ./artifact/fcli.jar fcli
+ run: native-image ${{ env.native_image_opts }} --static --libc=musl -Djansi.disable=true --initialize-at-build-time=com.fortify.cli.app.FortifyCLI -H:ExcludeResources="org/fusesource/jansi/internal/native/.*" -jar ./artifact/release-assets/fcli.jar fcli
- name: Compress native fcli
uses: svenstaro/upx-action@v2
@@ -124,23 +130,23 @@ jobs:
run: ./fcli --version | tee /dev/stderr | grep -E '[0-9]+\.[0-9]+\.[0-9]+' >/dev/null || (echo "fcli --version doesn't output proper version number"; exit 1)
- name: Package native fcli
- run: tar -zcvf fcli-linux.tgz fcli -C ./artifact fcli_completion
+ run: tar -zcvf artifact/release-assets/fcli-linux.tgz fcli -C ./artifact fcli_completion
- uses: actions/upload-artifact@v3
with:
- path: ./fcli-linux.tgz
+ path: ./artifact/**/fcli-linux.tgz
native_mac:
name: native-image-mac
needs: build
- runs-on: macos-12
+ runs-on: macos-latest
steps:
- name: Check-out source code
uses: actions/checkout@v3
- uses: graalvm/setup-graalvm@v1
with:
- version: ${{ env.graal_version }}
+ distribution: ${{ env.graal_distribution }}
java-version: ${{ env.graal_java_version }}
components: 'native-image'
github-token: ${{ secrets.GITHUB_TOKEN }}
@@ -153,7 +159,7 @@ jobs:
# file to include native libraries for all platforms; we override this to include only the MacOS
# libraries
- name: Create native fcli
- run: native-image ${{ env.native_image_opts }} -H:ExcludeResources="org/fusesource/jansi/internal/native/Windows/.*" -H:ExcludeResources="org/fusesource/jansi/internal/native/Linux/.*" -H:ExcludeResources="org/fusesource/jansi/internal/native/FreeBSD/.*" -jar ./artifact/fcli.jar fcli
+ run: native-image ${{ env.native_image_opts }} -march=compatibility -H:ExcludeResources="org/fusesource/jansi/internal/native/Windows/.*" -H:ExcludeResources="org/fusesource/jansi/internal/native/Linux/.*" -H:ExcludeResources="org/fusesource/jansi/internal/native/FreeBSD/.*" -jar ./artifact/release-assets/fcli.jar fcli
- name: Compress native fcli
uses: svenstaro/upx-action@v2
@@ -164,11 +170,11 @@ jobs:
run: ./fcli --help && ./fcli get --help
- name: Package native fcli
- run: tar -zcvf fcli-mac.tgz fcli -C ./artifact fcli_completion
+ run: tar -zcvf ./artifact/release-assets/fcli-mac.tgz fcli -C ./artifact fcli_completion
- uses: actions/upload-artifact@v3
with:
- path: ./fcli-mac.tgz
+ path: ./artifact/**/fcli-mac.tgz
native_win:
name: native-image-win
@@ -177,7 +183,7 @@ jobs:
steps:
- uses: graalvm/setup-graalvm@v1
with:
- version: ${{ env.graal_version }}
+ distribution: ${{ env.graal_distribution }}
java-version: ${{ env.graal_java_version }}
components: 'native-image'
github-token: ${{ secrets.GITHUB_TOKEN }}
@@ -192,7 +198,7 @@ jobs:
- name: Create native fcli
run: >-
"C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" &&
- ${{ env.JAVA_HOME }}\bin\native-image.cmd ${{ env.native_image_opts }} -H:ExcludeResources="org/fusesource/jansi/internal/native/Mac/.*" -H:ExcludeResources="org/fusesource/jansi/internal/native/Linux/.*" -H:ExcludeResources="org/fusesource/jansi/internal/native/FreeBSD/.*" -jar .\artifact\fcli.jar fcli
+ ${{ env.JAVA_HOME }}\bin\native-image.cmd ${{ env.native_image_opts }} -H:ExcludeResources="org/fusesource/jansi/internal/native/Mac/.*" -H:ExcludeResources="org/fusesource/jansi/internal/native/Linux/.*" -H:ExcludeResources="org/fusesource/jansi/internal/native/FreeBSD/.*" -jar .\artifact\release-assets\fcli.jar fcli
shell: cmd
# We don't compress the Windows binary for now as this is incompatible with current Graal version.
@@ -208,11 +214,11 @@ jobs:
.\fcli.exe get --help
- name: Package native fcli
- run: 7z a fcli-windows.zip fcli*.exe
+ run: 7z a artifact\release-assets\fcli-windows.zip fcli*.exe
- uses: actions/upload-artifact@v3
with:
- path: ./fcli-windows.zip
+ path: ./artifact/**/fcli-windows.zip
release:
name: release
@@ -228,9 +234,6 @@ jobs:
with:
path: ./
- - name: Remove fcli_completion script
- run: rm -f artifact/fcli_completion
-
- name: PROD - Prepare release PR
if: github.ref == 'refs/heads/main'
uses: GoogleCloudPlatform/release-please-action@v3
@@ -259,7 +262,7 @@ jobs:
- name: Upload assets to release
if: needs.build.outputs.do_release
run: |
- files=$(find "./artifact" -type f -printf "%p ")
+ files=$(find "./artifact/release-assets" -type f -printf "%p ")
gh release upload "${{ needs.build.outputs.release_tag }}" $files --clobber
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -315,15 +318,3 @@ jobs:
publish_dir: ./docs
enable_jekyll: true
-
- cleanup:
- name: cleanup
- if: needs.build.outputs.do_release
- needs: [release, publishPages]
- runs-on: ubuntu-latest
- steps:
- - name: Delete artifacts if uploaded to release
- uses: geekyeggo/delete-artifact@v1
- with:
- name: artifact
- failOnError: false
diff --git a/.github/workflows/fortify-analysis.yml b/.github/workflows/fortify-analysis.yml
index ef129a1d99..b90ebf76fe 100644
--- a/.github/workflows/fortify-analysis.yml
+++ b/.github/workflows/fortify-analysis.yml
@@ -22,7 +22,7 @@ name: Fortify on Demand Scan
on:
workflow_dispatch:
push:
- branches: [ main ]
+ branches: [ develop ]
schedule:
- cron: '16 0 * * 5'
@@ -39,14 +39,17 @@ jobs:
steps:
# Check out source code
- name: Check Out Source Code
- uses: actions/checkout@v2
+ uses: actions/checkout@v4
+ with:
+ ref: develop
# Java is required to run the various Fortify utilities.
# When scanning a Java application, please use the appropriate Java version for building your application.
- name: Setup Java
- uses: actions/setup-java@v1
+ uses: actions/setup-java@v3
with:
- java-version: 11
+ distribution: 'temurin'
+ java-version: '17'
# Prepare source+dependencies for upload. The default example is for a Maven project that uses pom.xml.
# TODO: Update PACKAGE_OPTS based on the ScanCentral Client documentation for your project's included tech stack(s). Helpful hints:
@@ -56,20 +59,18 @@ jobs:
# For other build tools, add your build commands to download necessary dependencies and prepare according to Fortify on Demand Packaging documentation.
# ScanCentral Client documentation is located at https://www.microfocus.com/documentation/fortify-software-security-center/
- name: Download Fortify ScanCentral Client
- uses: fortify/gha-setup-scancentral-client@5b7382f8234fb9840958c49d5f32ae854115f9f3
- with:
- version: 21.2.0-prerelease # Required as Gradle 7.2 not supported by earlier versions
+ uses: fortify/gha-setup-scancentral-client@v2
- name: Package Code + Dependencies
run: scancentral package $PACKAGE_OPTS -o package.zip
env:
- PACKAGE_OPTS: "-bt gradle"
+ PACKAGE_OPTS: "-bt gradle -oss"
# Start Fortify on Demand SAST scan and wait until results complete. For more information on FoDUploader commands, see https://github.com/fod-dev/fod-uploader-java
# TODO: Update ENV variables for your application and create the necessary GitHub Secrets. Helpful hints:
# Credentials and release ID should be obtained from your FoD tenant (either Personal Access Token or API Key can be used).
# Automated Audit preference should be configured for the release's Static Scan Settings in the Fortify on Demand portal.
- name: Download Fortify on Demand Universal CI Tool
- uses: fortify/gha-setup-fod-uploader@6e6bb8a33cb476e240929fa8ebc739ff110e7433
+ uses: fortify/gha-setup-fod-uploader@v1
- name: Perform SAST Scan
run: java -jar $FOD_UPLOAD_JAR -z package.zip -aurl $FOD_API_URL -purl $FOD_URL -rid "$FOD_RELEASE_ID" -tc "$FOD_TENANT" -uc "$FOD_USER" "$FOD_PAT" $FOD_UPLOADER_OPTS -n "$FOD_UPLOADER_NOTES"
env:
@@ -84,7 +85,7 @@ jobs:
# Once scan completes, pull SAST issues from Fortify on Demand and generate SARIF output.
- name: Export results to GitHub-optimized SARIF
- uses: fortify/gha-export-vulnerabilities@fcb374411cff9809028c911dabb8b57dbdae623b
+ uses: fortify/gha-export-vulnerabilities@v1
with:
fod_base_url: "https://ams.fortify.com/"
fod_tenant: ${{ secrets.OSS_FOD_TENANT }}
@@ -94,6 +95,6 @@ jobs:
# Import Fortify on Demand results to GitHub Security Code Scanning
- name: Import Results
- uses: github/codeql-action/upload-sarif@v1
+ uses: github/codeql-action/upload-sarif@v2
with:
- sarif_file: ./gh-fortify-sast.sarif
\ No newline at end of file
+ sarif_file: ./gh-fortify-sast.sarif
diff --git a/.github/workflows/functional-tests.yml b/.github/workflows/functional-tests.yml
new file mode 100644
index 0000000000..a95203c228
--- /dev/null
+++ b/.github/workflows/functional-tests.yml
@@ -0,0 +1,156 @@
+name: Functional Tests
+
+on:
+ workflow_dispatch:
+ inputs:
+ runNumber: # Accessible through ${{ inputs.runNumber }}
+ description: 'Required "Build and release"" workflow run number from which to get artifacts to be tested'
+ required: true
+ type: number
+ workflow_run:
+ workflows: [Build and release]
+ types: [completed]
+
+
+jobs:
+ ft-core:
+ if: github.event.workflow_run.conclusion == 'success' || github.event_name == 'workflow_dispatch'
+ strategy:
+ fail-fast: false
+ matrix:
+ os: [ubuntu-latest, windows-latest, macos-latest]
+ type: [java, jar, native]
+
+ runs-on: ${{ matrix.os }}
+
+ steps:
+ # Java is required for running the functional tests
+ - name: Setup Java
+ uses: actions/setup-java@v3
+ with:
+ distribution: 'temurin'
+ java-version: '17'
+
+ - name: Get artifacts from triggering workflow
+ if: github.event_name == 'workflow_run'
+ uses: dawidd6/action-download-artifact@v2
+ with:
+ run_id: ${{ github.event.workflow_run.id }}
+ - name: Get artifacts from specified workflow
+ if: github.event_name == 'workflow_dispatch'
+ uses: dawidd6/action-download-artifact@v2
+ with:
+ run_number: ${{ inputs.runNumber }}
+ workflow: ci.yml
+
+ - name: List artifact contents
+ shell: bash
+ run: ls -lR
+
+ - name: Run Tests
+ shell: bash
+ run: |
+ mv artifact/release-assets/* .
+ mv artifact/fcli-ftest.jar .
+ case "${{ matrix.type }}" in
+ "java" )
+ java -jar fcli-ftest.jar -Dft.fcli=build -Dft.run=core,config ;;
+ "jar" )
+ java -jar fcli-ftest.jar -Dft.fcli=fcli.jar -Dft.run=core,config ;;
+ "native" )
+ case "${{ matrix.os }}" in
+ "ubuntu-latest" )
+ tar -zxvf fcli-linux.tgz
+ java -jar fcli-ftest.jar -Dft.fcli=./fcli -Dft.run=core,config ;;
+ "windows-latest" )
+ 7z e fcli-windows.zip
+ java -jar fcli-ftest.jar -Dft.fcli=fcli.exe -Dft.run=core,config ;;
+ "macos-latest" )
+ tar -zxvf fcli-mac.tgz
+ java -jar fcli-ftest.jar -Dft.fcli=./fcli -Dft.run=core,config ;;
+ esac ;;
+ esac
+
+ - name: Rename test log
+ if: always()
+ shell: bash
+ run: mv test.log "test-${{ matrix.os }}-${{ matrix.type }}.log"
+
+ - name: Publish test logs
+ if: failure()
+ uses: actions/upload-artifact@v3
+ with:
+ name: test-log
+ path: test-*.log
+
+ ft-product:
+ if: github.event.workflow_run.conclusion == 'success' || github.event_name == 'workflow_dispatch'
+ strategy:
+ fail-fast: false
+ matrix:
+ type: [fod, ssc, sc-sast, sc-dast, report]
+
+ runs-on: ubuntu-latest
+
+ steps:
+ # Java is required for running the functional tests
+ - name: Setup Java
+ uses: actions/setup-java@v3
+ with:
+ distribution: 'temurin'
+ java-version: '17'
+
+ - name: Get artifacts from triggering workflow
+ if: github.event_name == 'workflow_run'
+ uses: dawidd6/action-download-artifact@v2
+ with:
+ run_id: ${{ github.event.workflow_run.id }}
+ - name: Get artifacts from specified workflow
+ if: github.event_name == 'workflow_dispatch'
+ uses: dawidd6/action-download-artifact@v2
+ with:
+ run_number: ${{ inputs.runNumber }}
+ workflow: ci.yml
+
+ - name: Run Tests
+ shell: bash
+ run: |
+ mv artifact/release-assets/* .
+ mv artifact/fcli-ftest.jar .
+ tar -zxvf fcli-linux.tgz
+ # Although we only run the current matrix entry type, we pass connection
+ # options for all session types, as some SC-SAST/SC-DAST tests may also
+ # require an SSC session.
+ java -jar fcli-ftest.jar -Dft.fcli=./fcli -Dft.run=$type \
+ -Dft.fod.url=$fod_url -Dft.fod.tenant=$fod_tenant -Dft.fod.user=$fod_user -Dft.fod.password=$fod_pwd \
+ -Dft.ssc.url=$ssc_url -Dft.ssc.user=$ssc_user -Dft.ssc.password=$ssc_pwd \
+ -Dft.sc-sast.ssc-url=$ssc_url -Dft.sc-sast.ssc-user=$ssc_user -Dft.sc-sast.ssc-password=$ssc_pwd \
+ -Dft.sc-dast.ssc-url=$ssc_url -Dft.sc-dast.ssc-user=$ssc_user -Dft.sc-dast.ssc-password=$ssc_pwd \
+ -Dft.sc-sast.client-auth-token=$scsast_token
+ env:
+ type: ${{ matrix.type }}
+ fod_url: ${{ secrets.FCLI_FT_FOD_URL }}
+ fod_tenant: ${{ secrets.FCLI_FT_FOD_TENANT }}
+ fod_user: ${{ secrets.FCLI_FT_FOD_USER }}
+ fod_pwd: ${{ secrets.FCLI_FT_FOD_PWD }}
+ ssc_url: ${{ secrets.FCLI_FT_SSC_URL }}
+ ssc_user: ${{ secrets.FCLI_FT_SSC_USER }}
+ ssc_pwd: ${{ secrets.FCLI_FT_SSC_PWD }}
+ scsast_token: ${{ secrets.FCLI_FT_SCSAST_TOKEN }}
+ # Pass GitHub and GitLab tokens for use by NCD license report tests
+ FCLI_FT_GITHUB_TOKEN: ${{ secrets.FCLI_FT_GITHUB_TOKEN }}
+ FCLI_FT_GITLAB_TOKEN: ${{ secrets.FCLI_FT_GITLAB_TOKEN }}
+
+ - name: Rename test log
+ if: always()
+ shell: bash
+ run: mv test.log "test-${{ matrix.os }}-${{ matrix.type }}.log"
+
+ - name: Publish test logs
+ if: always()
+ uses: actions/upload-artifact@v3
+ with:
+ name: test-log
+ path: test-*.log
+
+
\ No newline at end of file
diff --git a/.github/workflows/update-repo-docs.yml b/.github/workflows/update-repo-docs.yml
index 3706cb96a1..c3c74f9e1f 100644
--- a/.github/workflows/update-repo-docs.yml
+++ b/.github/workflows/update-repo-docs.yml
@@ -6,7 +6,7 @@ on:
- cron: '5 4 * * *'
push:
branches:
- - main
+ - develop
jobs:
update-repo-docs:
diff --git a/.gitignore b/.gitignore
index b8b326213e..e6d472f6e5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,9 @@
*.csv
*.json
*.sarif
+*.zip
+NcdReportConfig.yml
+MspReportConfig.yml
# Files generated by native-image when run locally
/fcli
@@ -14,6 +17,9 @@ build/
!**/src/test/**
!**/resource-config.json
+# We want to include everything in our functional test resources
+!**/ftest/resources/runtime/**/*
+
### STS ###
.apt_generated
.classpath
@@ -45,7 +51,7 @@ bin/
samples/**/scans/**
samples/**/logs/**
-*.fpr
+#*.fpr
FortifyImportExportUtility-common/lombok.config FortifyImportExportUtility-common-from/lombok.config FortifyImportExportUtility-common-to/lombok.config FortifyImportExportUtility-from-fod-plugin/lombok.config FortifyImportExportUtility-from-mock-plugin/lombok.config FortifyImportExportUtility-from-ssc-plugin/lombok.config FortifyImportExportUtility-to-file-plugin/lombok.config FortifyImportExportUtility-to-mock-plugin/lombok.config
lombok.config
fcli.log
@@ -53,3 +59,4 @@ fcli.log
/ReportTemplateDefAnswerTemplate.json*
/ReportTemplateDefAnswerTemplate.y*ml*
/*.rptdesign
+*.log
diff --git a/LICENSE.txt b/LICENSE.txt
index 4637524dd4..0282e86da3 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -1,6 +1,6 @@
MIT License
-Copyright 2023 Open Text or one of its affiliates
+Copyright 2021 - 2023 Open Text or one of its affiliates
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/build.gradle b/build.gradle
index 60cd8fc18b..f5e8d93602 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,368 +1,63 @@
-// the buildscript section is temporary until the missing dependency issue is resolved.
-buildscript {
- repositories {
- jcenter()
- mavenCentral()
- gradlePluginPortal()
- }
-
- dependencies {
- classpath ("org.ysb33r.gradle:grolifant:0.16.2") {
- force = true
- }
- }
-}
-
plugins {
- id('com.github.jk1.dependency-license-report') version '2.1'
- id "org.kordamp.gradle.markdown" version "2.2.0"
- id("com.github.johnrengelman.shadow") version "7.1.2"
- id("io.micronaut.application") version "3.6.4" apply false
- id("io.micronaut.library") version "3.6.4" apply false
- id 'eclipse'
- id "com.github.ben-manes.versions" version "0.44.0"
- id "org.asciidoctor.jvm.convert" version "3.3.2"
+ id('com.github.jk1.dependency-license-report') version '2.5' apply false
+ id("com.github.johnrengelman.shadow") version "8.1.1" apply false
+ id "org.asciidoctor.jvm.convert" version "3.3.2" apply false
+ id "io.freefair.lombok" version "8.1.0" apply false
}
group = "com.fortify.cli"
-ext.buildTime = LocalDateTime.now()
-ext.getVersion = {
- def result = project.findProperty('version');
- return !result || result=='unspecified' ? buildTime.format('0.yyyyMMdd.HHmmss') : result;
-}
-version = ext.getVersion();
-
-apply plugin: "io.micronaut.application"
-subprojects {
- apply plugin: "io.micronaut.library"
- apply plugin: 'eclipse'
-}
-
-application {
- mainClass.set("com.fortify.cli.app.FortifyCLI")
-}
-shadowJar {
- archiveBaseName.set('fcli')
- archiveClassifier.set('')
- archiveVersion.set('')
+ext {
+ buildTime = LocalDateTime.now()
+ getVersion = {
+ def result = project.findProperty('version');
+ return !result || result=='unspecified' ? buildTime.format('0.yyyyMMdd.HHmmss') : result;
+ }
}
allprojects {
- java {
- sourceCompatibility = JavaVersion.toVersion("11")
- targetCompatibility = JavaVersion.toVersion("11")
- }
- micronaut {
- testRuntime("junit5")
- processing {
- incremental(true)
- annotations("com.fortify.cli.*")
- }
- }
-
- repositories {
- mavenCentral()
- }
-
- dependencies {
- // Lombok dependency & annotation processor
- compileOnly 'org.projectlombok:lombok:1.18.24'
- annotationProcessor 'org.projectlombok:lombok:1.18.24'
-
- // TODO Re-enable this line (with appropriate version) once new picocli is released
- //implementation("info.picocli:picocli:4.6.3")
-
- implementation("org.fusesource.jansi:jansi:2.4.0");
-
- annotationProcessor("io.micronaut:micronaut-inject-java:3.4.2")
- annotationProcessor("io.micronaut:micronaut-graal:3.4.2")
-
- // Micronaut dependencies
- implementation("io.micronaut:micronaut-runtime:3.4.2")
- implementation("io.micronaut.picocli:micronaut-picocli:4.1.0") {
- exclude group: 'info.picocli'
- }
- implementation("javax.annotation:javax.annotation-api")
-
- // Logback dependency to allow us to configure logging programmatically
- implementation("ch.qos.logback:logback-classic:1.2.11")
-
- implementation('com.konghq:unirest-java:3.13.11') {
- exclude group: 'com.google.code.gson', module: 'gson' // We use Jackson, so no need for Gson
- exclude group: 'commons-logging', module: 'commons-logging' // We use jcl-over-slf4j
- }
- implementation('com.konghq:unirest-objectmapper-jackson:3.13.11')
-
- implementation('com.jayway.jsonpath:json-path:2.7.0') {
- //exclude group: 'net.minidev', module: 'json-smart'
- }
-
- // for yaml support and generating trees/tables
- implementation('com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.13.2')
- implementation('com.fasterxml.jackson.dataformat:jackson-dataformat-csv:2.13.2')
- implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.13.2")
- implementation('hu.webarticum:tree-printer:2.0.0')
- implementation('com.github.freva:ascii-table:1.2.0')
-
- // Encryption library
- implementation('org.jasypt:jasypt:1.9.3:lite')
- }
-}
-
-// TODO Remove this block once new picocli is released
-configure(allprojects.findAll {it.name == 'fcli-picocli-codegen-patches'}) {
- dependencies {
- implementation project(':fcli-picocli-patches')
- }
-}
-
-// TODO Remove this block once new picocli is released
-configure(allprojects.findAll {it.name != 'fcli-picocli-patches' && it.name != 'fcli-picocli-codegen-patches'}) {
- dependencies {
- implementation project(':fcli-picocli-patches')
- // Picocli dependency and annotation processor. Note that for now, we cannot use 4.7.0 due to https://github.com/remkop/picocli/issues/1876
- //annotationProcessor("info.picocli:picocli-codegen:4.6.3")
- annotationProcessor(project(":fcli-picocli-codegen-patches"))
- }
-}
-
-// TODO Move to allprojects block once we no longer require picocli patches
-configure(allprojects.findAll {it.name != 'fcli-picocli-patches' && it.name != 'fcli-picocli-codegen-patches'}) {
- // Set picocli annotation processor options
- compileJava {
- options.compilerArgs += ["-Averbose=true"]
- }
+ apply plugin: 'eclipse'
+ version = rootProject.ext.getVersion();
+ ext {
+ distDir = "${rootProject.buildDir}/dist"
+ releaseAssetsDir = "${distDir}/release-assets"
+ sharedGradleScriptsDir = "${rootDir}/$sharedGradleScriptsRelativeDir"
+ gradleHelpersLocation = "https://raw.githubusercontent.com/fortify/shared-gradle-helpers/1.8"
+ }
+ // Define *RefDir properties for each *Ref property defined in gradle.properties,
+ // based on the refPatterns property defined in the same gradle.properties
+ properties.each { p->
+ if ( "$refPatterns".split(',').any { p.key.matches(it) } ) {
+ ext[p.key+"Dir"] = "$rootDir" + p.value.replaceAll(':', '/')
+ }
+ }
+
+ // Define Maven Central repository
+ repositories {
+ mavenCentral()
+ maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
+ }
- // Micronaut is supposed to generate a resource-config.json file that includes all resources,
- // but for some reason this doesn't work, so we generate our own resource-config.json file for
- // each module
- ext.generatedResourceConfigDir = "${buildDir}/generated-resource-config"
- tasks.register('generateResourceConfig') {
- doLast {
- def outputDir = "${generatedResourceConfigDir}/META-INF/native-image/fcli-generated/${project.name}";
- mkdir "${outputDir}"
- def entries = [];
- fileTree(dir: 'src/main/resources', excludes: ['**/i18n/**', 'META-INF/**'])
- .visit {e -> if ( !e.isDirectory() ) {entries << '\n {"pattern":"'+e.relativePath+'"}'}};
- if ( entries.size>0 ) {
- def contents = '{"resources":[' + entries.join(",") + '\n]}';
- file("${outputDir}/resource-config.json").text = contents;
- println contents
- }
- }
- }
- sourceSets.main.output.dir generatedResourceConfigDir, builtBy: generateResourceConfig
-}
-
-// TODO Remove fcli-picocli-patches condition once new picocli is released
-configure(allprojects.findAll {it.name != 'fcli-common' && it.name != 'fcli-picocli-patches' && it.name != 'fcli-picocli-codegen-patches'}) {
- dependencies {
- implementation project(':fcli-common')
- }
-}
-
-dependencies {
- implementation project(':fcli-config')
- implementation project(':fcli-ssc')
- implementation project(':fcli-fod')
- implementation project(':fcli-sc-sast')
- implementation project(':fcli-sc-dast')
- implementation project(':fcli-tool')
- implementation project(':fcli-util')
-
- // Logging dependencies
- runtimeOnly('ch.qos.logback:logback-classic:1.2.11')
- runtimeOnly('org.slf4j:jcl-over-slf4j:1.7.36')
-
- // GraalVM dependency
- compileOnly("org.graalvm.nativeimage:svm")
-}
-
-ext {
- gradleHelpersLocation = "https://raw.githubusercontent.com/fortify/shared-gradle-helpers/1.8"
- thirdPartyBaseName = "${rootProject.name}"
- autoCompleteDir = "${project.buildDir}/autocomplete"
-}
-apply from: "${gradleHelpersLocation}/thirdparty-helper.gradle"
-apply from: "${gradleHelpersLocation}/readme2html.gradle"
-
-mainClassName = "com.fortify.cli.app.FCLIRootCommands"
-
-ext.buildPropertiesDir = "${buildDir}/generated-build-properties"
-task generateFcliBuildProperties {
- doLast {
- def outputDir = "${buildPropertiesDir}/com/fortify/cli/app"
- mkdir "${outputDir}"
- ant.propertyfile(file: "${outputDir}/fcli-build.properties") {
- entry(key: "projectName", value: project.name)
- entry(key: "projectVersion", value: project.version)
- entry(key: "buildDate", value: buildTime.format('yyyy-MM-dd HH:mm:ss'))
+ task createDistDir {
+ doFirst {
+ mkdir "${distDir}"
+ mkdir "${releaseAssetsDir}"
}
- def resourceConfigOutputDir = "${buildPropertiesDir}/META-INF/native-image/fcli-build-properties"
- mkdir "${resourceConfigOutputDir}"
- def contents =
- '{"resources":[\n' +
- ' {"pattern":"com/fortify/cli/app/fcli-build.properties"}\n' +
- ']}\n'
- file("${resourceConfigOutputDir}/resource-config.json").text = contents;
- println contents
- }
-}
-sourceSets.main.output.dir buildPropertiesDir, builtBy: generateFcliBuildProperties
-
-tasks.register('generateAutoCompleteDir') {
- doLast {
- mkdir "${autoCompleteDir}"
}
}
-task generateAutoComplete(type: JavaExec) {
- dependsOn(classes, generateAutoCompleteDir)
- group = "Documentation"
- description = "Generate autocomplete"
- classpath(configurations.runtimeClasspath, configurations.annotationProcessor, sourceSets.main.runtimeClasspath)
- main 'picocli.AutoComplete'
- args mainClassName, "-f", "--completionScript=${autoCompleteDir}/fcli_completion"
-}
-
-task generateManpageAsciiDoc(type: JavaExec) {
- dependsOn(classes)
- group = "Documentation"
- description = "Generate AsciiDoc manpage"
- classpath(configurations.runtimeClasspath, configurations.annotationProcessor, sourceSets.main.runtimeClasspath)
- main 'picocli.codegen.docgen.manpage.ManPageGenerator'
- args mainClassName, "--outdir=${project.buildDir}/generated-docs/src/manpage", "-v"
+task clean(type: Delete) {
+ delete "build"
}
-
-task copyStaticAsciiDoc(type: Copy) {
- into "${project.buildDir}/generated-docs/src"
- from("${projectDir}/doc-resources/asciidoc/versioned") {
- include "*.adoc"
- }
+task build(type: Copy) {
+ dependsOn("${fcliAppRef}:build")
+ from "${fcliAppRefDir}/build/libs/fcli.jar"
+ into "build/libs"
}
-
-task prepareAsciiDoc {
- dependsOn 'generateManpageAsciiDoc', 'copyStaticAsciiDoc'
-}
-
-task asciiDoctorManPage(type: org.asciidoctor.gradle.jvm.AsciidoctorTask) {
- dependsOn(prepareAsciiDoc)
- sourceDir = file("${project.buildDir}/generated-docs/src/manpage")
- outputDir = file("${project.buildDir}/generated-docs/manpage")
- logDocuments = true
- outputOptions {
- backends = ['manpage']
- }
-}
-
-task asciiDoctorHtml(type: org.asciidoctor.gradle.jvm.AsciidoctorTask) {
- dependsOn(prepareAsciiDoc)
- sourceDir = file("${project.buildDir}/generated-docs/src")
- outputDir = file("${project.buildDir}/generated-docs/html5")
- logDocuments = true
- outputOptions {
- backends = ['html5']
- }
- attributes = [
- 'toc' : 'left',
- 'sectanchors' : 'true',
- 'docinfo' : 'shared',
- 'jekyll' : false,
- 'bannertitle' : 'FCLI: The Universal Fortify CLI',
- 'docversion' : "${project.version}"
- ]
- options = [
- 'template_dirs': [new File("${project.rootDir}/doc-resources/asciidoc/templates").absolutePath]
- ]
-}
-
-task asciidoctorJekyll(type: org.asciidoctor.gradle.jvm.AsciidoctorTask) {
- dependsOn(prepareAsciiDoc)
- sourceDir = file("${project.buildDir}/generated-docs/src")
- outputDir = file("${project.buildDir}/generated-docs/jekyll")
- logDocuments = true
- outputOptions {
- backends = ['html5']
- }
- attributes = [
- 'toc' : 'left',
- 'sectanchors' : 'true',
- 'docinfo' : 'shared',
- 'jekyll' : true,
- 'stylesheet' : false,
- 'bannertitle' : 'FCLI: The Universal Fortify CLI',
- 'docversion' : "${project.version}"
- ]
- options = [
- 'template_dirs': [new File("${project.rootDir}/doc-resources/asciidoc/templates").absolutePath]
- ]
-}
-
-task asciidoctorGHPages(type: org.asciidoctor.gradle.jvm.AsciidoctorTask) {
- sourceDir = file("${project.rootDir}/doc-resources/asciidoc/gh-pages")
- outputDir = file("${project.buildDir}/generated-docs/gh-pages")
- logDocuments = true
- outputOptions {
- backends = ['html5']
- }
- attributes = [
- 'toc' : 'left',
- 'sectanchors' : 'true',
- 'docinfo' : 'shared',
- 'jekyll' : true,
- 'stylesheet' : false,
- 'bannertitle' : 'FCLI: The Universal Fortify CLI',
- 'docversion' : "[select]",
- 'revnumber' : null
- ]
- options = [
- 'template_dirs': [new File("${project.rootDir}/doc-resources/asciidoc/templates").absolutePath]
- ]
-}
-
-tasks.register('distDocsHtml5', Zip) {
- dependsOn 'asciiDoctorHtml'
- archiveFileName = "docs-html.zip"
- destinationDirectory = layout.buildDirectory.dir('dist')
- from layout.buildDirectory.dir("generated-docs/html5")
-}
-
-tasks.register('distDocsManPage', Zip) {
- dependsOn 'asciiDoctorManPage'
- archiveFileName = "docs-manpage.zip"
- destinationDirectory = layout.buildDirectory.dir('dist')
- from layout.buildDirectory.dir("generated-docs/manpage")
-}
-
-tasks.register('distDocsJekyll', Zip) {
- dependsOn 'asciidoctorJekyll'
- archiveFileName = "docs-jekyll.zip"
- destinationDirectory = layout.buildDirectory.dir('dist')
- from layout.buildDirectory.dir("generated-docs/jekyll")
-}
-
-tasks.register('distDocsGHPages', Zip) {
- dependsOn 'asciidoctorGHPages'
- archiveFileName = "docs-gh-pages.zip"
- destinationDirectory = layout.buildDirectory.dir('dist')
- from layout.buildDirectory.dir("generated-docs/gh-pages")
-}
-
-task distDocs {
- dependsOn 'distDocsHtml5', 'distDocsManPage', 'distDocsJekyll', 'distDocsGHPages'
-}
-
task dist(type: Copy) {
- dependsOn 'build', 'readme2html', 'distDocs', 'generateAutoComplete'
- from "${buildDir}/html"
- from "${autoCompleteDir}"
+ dependsOn(createDistDir)
from("${projectDir}") {
- include "config/**/*"
- include "LICENSE.TXT"
+ include "LICENSE.txt"
}
- from("${buildDir}/${libsDirName}") {
- include "${rootProject.name}.jar"
- }
- into "$buildDir/dist"
-}
+ into "${releaseAssetsDir}"
+}
\ No newline at end of file
diff --git a/doc-resources/asciidoc/gh-pages/dev-info.adoc b/doc-resources/asciidoc/gh-pages/dev-info.adoc
deleted file mode 100644
index ca68201719..0000000000
--- a/doc-resources/asciidoc/gh-pages/dev-info.adoc
+++ /dev/null
@@ -1,176 +0,0 @@
-= Fortify CLI (fcli) Developer Information
-
-The following sections provide information that may be useful for developers of this utility.
-
-== Conventional Commits & Versioning
-
-Versioning is handled automatically by https://github.com/google-github-actions/release-please-action[release-please-action] based on https://www.conventionalcommits.org/[Conventional Commits]. Every commit to the `+main+` branch should follow the Conventional Commits convention. Following are some examples; these can be combined in a single commit message (separated by empty lines), or you can have commit messages describing just a single fix or feature.
-
-....
-chore: Won't show up in changelog
-
-ci: Change to GitHub Actions workflow; won't show up in changelog
-
-docs: Change to documentation; won't show up in changelog
-
-fix: Some fix (#2)
-
-feat: New feature (#3)
-
-feat!: Some feature that breaks backward compatibility
-
-feat: Some feature
- BREAKING-CHANGE: No longer supports xyz
-....
-
-See the output of `+git log+` to view some sample commit messages.
-
-`+release-please-action+` invoked from the GitHub CI workflow generates pull requests containing updated `+CHANGELOG.md+` and `+version.txt+` files based on these commit messages. Merging the pull request will
-result in a new release version being published; this includes publishing the image to Docker Hub, and creating a GitHub release describing the changes.
-
-== Technologies & Frameworks
-
-Following is a list of the main frameworks and technologies used by fcli:
-
-* https://picocli.info/[picocli]: Process command line options, generate usage information, …
-* https://micronaut.io/[Micronaut]: Dependency injection, features for GraalVM native image generation
-* https://github.com/FasterXML/jackson[Jackson]: Parse and generate data in JSON and other formats
-* https://www.graalvm.org/[GraalVM]: Generate native images (native executables)
-
-== Prerequisites & Considerations
-
-As can be seen in the link:#_technologies_frameworks[Technologies & frameworks] section, this is no ordinary Java project. Some of these technologies and frameworks require special prerequisites, precautions and other considerations to be taken into account to prevent compilation issues and runtime errors, as described below.
-
-=== IDE Setup
-
-This project uses the following frameworks that may require some special setup in order to have your IDE compile this project without errors:
-
-* Lombok: Please see https://projectlombok.org/setup/overview for more information on how to add Lombok support to your IDE
-* Micronaut & picocli: These frameworks require annotation processors to be run during builds; please see your IDE documentation on how to enable annotation processing
-
-=== Incremental Compilation
-
-Incremental compilation (for example in IDE or when doing a `+gradle build+` without `+clean+`) may leave behind old AOT artifacts causing exceptions when trying to run `+fcli+`. This is especially the case when renaming or moving classes, which may result in exceptions like the below:
-
-....
-Message: Error loading bean [com.fortify.cli.ssc.rest.unirest.SSCUnirestRunner]: com/fortify/cli/rest/unirest/AbstractUnirestRunner
-...
-Caused by: java.lang.NoClassDefFoundError: com/fortify/cli/rest/unirest/AbstractUnirestRunner
-...
-....
-
-In this example, the AbstractUnirestRunner class was moved to a different package, but the now obsolete AOT-generated classes were still present. So, if at any time you see unexpected exceptions, please try to do a full clean/rebuild and run `+fcli+` again.
-
-=== Reflection
-
-GraalVM Native Image needs to know ahead-of-time the reflectively accessed program elements; see https://www.graalvm.org/reference-manual/native-image/Reflection/[GraalVM Native Image & Reflection] for details. Micronaut allows for generating the necessary GraalVM reflection configuration using the `+@ReflectiveAccess+` annotation if necessary.
-
-If a command runs fine on a regular JVM but not when running as a native image, then quite likely this is caused by missing reflection configuration which may be fixed by adding the `+@ReflectiveAccess+` annotation to the appropriate classes. Also see below for some reflection-related considerations specific to picocli and Jackson.
-
-=== Picocli
-
-Picocli and it’s annotation processor should in theory generate the necessary reflection configuration as described above. However, the annotation processor doesn’t seem to take class hierarchies into account; see https://github.com/remkop/picocli/issues/1444[GraalVM: Options from superclass not visible]. As a work-around, we can complement the picocli-generated reflection configuration by using Micronaut’s `+@ReflectiveAccess+` annotation. In general the following classes should probably be annotated with `+@ReflectiveAccess+`:
-
-* All classes annotated with `+@Command+` (this likely duplicates the reflection configuration generated by picocli, but doesn’t hurt)
-* All super-classes of all classes annotated with `+@Command+`, in particular if they contain any picocli annotations like `+@Mixin+`, `+@ArgGroup+`, or `+@Option+`
-* All classes used as an `+@Mixin+` or `+@ArgGroup+`, and their super-classes
-
-The following native image runtime behavior may indicate a missing `+@ReflectiveAccess+` annotation:
-
-* Options and sub-commands not listed in help output, and not recognized when entered on the command line
-* Exceptions related to picocli trying to access classes, methods and fields using reflection
-
-=== Jackson
-
-Jackson is heavily based on reflection to perform object serialization and deserialization. All classes that need to be (de-)serialized with Jackson therefore need to be annotated with `+@ReflectiveAccess+` to allow reflection-based (de-)serialization.
-
-Note that Micronaut provides the `+@Introspected+` annotation that should allow for reflection-free (de-)serialization. However experience learns that there are just too many differences between reflection-based
-and introspection-based (de-)serialization. When running in a normal JVM these differences are often not visible as Jackson can easily fall back to reflection-based (de-)serialization. In native images, Jackson cannot fall back to reflection-based (de-)serialization unless properly configured, and even when properly configured there are still some differences in behavior.
-
-As such, it has been decided to disable Jackson introspection-based (de-)serialization using the `+jackson.bean-introspection-module+` configuration property in `+application.yml+`. This also means that we will not be using the `+@Introspected+` annotation on classes that need to be (de-)serialized with Jackson (unless of course introspection-based access is used for non Jackson-related purposes).
-
-== Gradle Wrapper
-
-It is strongly recommended to build this project using the included Gradle Wrapper scripts; using other Gradle versions may result in build errors and other issues.
-
-The Gradle build uses various helper scripts from https://github.com/fortify/shared-gradle-helpers; please refer to the documentation and comments in included scripts for more information.
-
-== Common Commands
-
-All commands listed below use Linux/bash notation; adjust accordingly if you are running on a different platform. All commands are to be executed from the main project directory.
-
-* `+./gradlew tasks --all+`: List all available tasks
-* Build: (plugin binary will be stored in `+build/libs+`)
-** `+./gradlew clean build+`: Clean and build the project
-** `+./gradlew build+`: Build the project without cleaning
-** `+./gradlew dist distThirdParty+`: Build distribution zip and third-party information bundle
-
-== Documentation
-
-Two types of documentation are automatically being generated; the standard repository documentation like `+README.md+` and `+CONTRIBUTING.md+`, and fcli user documentation (including manual pages). The following two sections describe the generation process in more detail.
-
-=== Repository Documentation
-
-Most or all of the `+*.md+` and `LICENSE.txt` files located in the repository root are generated automatically. Generation of `+CHANGELOG.md+` is done by `+release-please-action+` as described in the link:#_conventional_commits_versioning[Conventional Commits & Versioning] section. Generation of the other files is done by the `+doc-resources/update-repo-docs.sh+` scripts, based on the templates provided in https://github.com/fortify/shared-doc-resources, combined with the repo-specific MarkDown files in the repository `+doc-resources+` directory. For more information about this generation process, please see https://github.com/fortify/shared-doc-resources/blob/main/USAGE.md.
-
-=== User Documentation
-
-User documentation is generated automatically from the following three locations:
-
-* AsciiDoc located in the repository `+doc-resources/asciidoc/gh-pages+` directory
-** Published to the root directory of the GitHub Pages site
-* AsciiDoc located in the repository `+doc-resources/asciidoc/versioned+` directory
-** Published to a version-specific directory on the GitHub Pages site
-** Published to docs-html.zip in release assets
-* Manual pages generated from the fcli code
-** Published to a version-specific directory on the GitHub Pages site
-** Published to docs-html.zip in release assets
-** Published to docs-manpage.zip in release assets
-
-The Gradle build includes various tasks for generating this documentation, following are the main tasks:
-
-* `+generateManpageAsciiDoc+`: Generate man-page style AsciiDoc documentation from fcli code
-* `+asciiDoctorManPage+`: Convert man-page style AsciiDoc to Linux man-page format
-* `+asciiDoctorHtml+`: Convert both man-page style AsciiDoc and versioned user documentation to offline HTML format
-* `+asciidoctorJekyll+`: Convert both man-page style AsciiDoc and versioned user documentation to Jekyll HTML format for publishing on the GitHub Pages site
-* `+asciidoctorGHPages+`: Convert AsciiDoc files from `+doc-resources/asciidoc/gh-pages+` to Jekyll HTML format for publishing on the GitHub Pages site
-* `+distDocs+`: Calls of the tasks above and packages the output from these tasks into separate `+docs-*.zip+` files in the `+build/dist+` directory
-
-The GitHub Actions workflow defined in `+.github/workflows/ci.yml+` is responsible for publishing the documentation:
-
-* The `+build+` job builds the documentation artifacts and archives them as artifacts
-* The `+release+` job publishes `+docs-html.zip+` and `+docs-manpage.zip+` to the release artifacts (when building a release or development version)
-* The `+publishPages+` job published the output of the `+asciidoctorJekyll+` and `+asciidoctorGHPages+` to the appropriate directories on the GitHub Pages site, and updates the version index in the Jekyll `+_data+` directory (when building a release or development version)
-
-All HTML-formatted documentation described above is generated using the `+doc-resources/templates/html5/document.html.erb+` template. This template is based on the link:https://github.com/asciidoctor/asciidoctor-backends/blob/master/erb/html5/document.html.erb[official AsciiDoctor template] with various modifications. Based on the attributes provided in the relevant Gradle tasks:
-
-* For Jekyll output:
-** Add Jekyll front matter
-** Add a Jekyll include to include additional content in the HTML `+
+` section; mostly used for applying stylesheets
-** Add a Jekyll include to include the site-wide banner and (version) navigation bar
-* For offline HTML output:
-** Add hardcoded custom styling
-** Add hardcoded banner and version bar
-
-The offline HTML documentation is supposed to be self-contained, i.e., users can open any HTML file from `+docs-html.zip+` without extracting the full contents, and the page will render correctly. Of course, links to other documentation files will not work unless the full zip-file is extracted.
-
-For now, the hardcoded banner and navigation bar in the offline documentation is similar to the banner included by Jekyll. However:
-
-* Stylesheets and images are linked rather than being included in the HTML page, allowing for better browser cache utilization
-* The navigation bar in the offline documentation contains just a static version number, whereas the navigation bar in the online documentation allows for navigating to different versions
-* We can potentially add more advanced (navigation) functionalities in the online documentation
-* We can easily update the banner for the online documentation to have a new layout/styling, for example to apply OpenText styling; this will be automatically applied to all existing online documentation pages
-
-Usually it shouldn't be necessary to update the documentation contents for existing release versions. However, if necessary, and assuming the build.gradle file is compatible with older versions, potentially a command like the following can be used to regenerate the documentation for the given versions:
-
-....
-for v in 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.1.0 1.2.0 1.2.1 1.2.2; do (git restore . && git clean -fd && git checkout v$v && cp -r ../fcli-fork/doc-resources ../fcli-fork/build.gradle . && ./gradlew clean distDocs -Pversion=$v && mkdir -p ~/Downloads/fcli-docs/$v && cp build/dist/docs-html.zip ~/Downloads/fcli-docs/$v && cd ../fcli-pages/v$v && echo $pwd && rm -rf * && unzip ../../fcli/build/dist/docs-jekyll.zip && cd - && git restore . && git clean -fd); done
-....
-
-This command iterates over the given version numbers, regenerates the documentation for each version (using latest `+build.gradle+` and `+doc-resources+`), copies the `docs-html.zip` to a separate directory for later upload to the corresponding release assets, and updates the GitHub Pages site, based on the following assumptions:
-
-* Current directory is a clone of the fcli repository
-* `+../fcli-fork+` would contain the latest version of `+doc-resources+` and `+build.gradle+`
-* `+../fcli-pages+` would be a clone of the fcli repository with the gh-pages branch checked out
-
-
diff --git a/doc-resources/asciidoc/gh-pages/index.adoc b/doc-resources/asciidoc/gh-pages/index.adoc
deleted file mode 100644
index b4070f3784..0000000000
--- a/doc-resources/asciidoc/gh-pages/index.adoc
+++ /dev/null
@@ -1,7 +0,0 @@
-= Fortify CLI (fcli) Documentation
-
-The fcli utility can be used to interact with various Fortify products, like Fortify on Demand (FoD), Software Security Center (SSC), ScanCentral SAST and ScanCentral DAST. Please select a version from the menu on the top-right to view detailed usage documentation and manual pages for that version.
-
-== Developer Documentation
-
-Information useful for developers can be found in the link:./dev-info.html[developer documentation].
\ No newline at end of file
diff --git a/doc-resources/asciidoc/versioned/index.adoc b/doc-resources/asciidoc/versioned/index.adoc
deleted file mode 100644
index 3c78dbc427..0000000000
--- a/doc-resources/asciidoc/versioned/index.adoc
+++ /dev/null
@@ -1,294 +0,0 @@
-= Fortify CLI (fcli) Installation & Usage
-
-The fcli utility can be used to interact with various Fortify products, like Fortify on Demand (FoD), Software Security Center (SSC), ScanCentral SAST and ScanCentral DAST. This document describes installation and general usage of fcli. For a full listing of fcli commands and corresponding command line options, please see the
-man-pages as listed in the link:#_manual_pages[Manual Pages] section.
-
-Some of the fcli highlights:
-
-* Interact with many different Fortify products with just a single command-line utility
-* link:#_installation[Both plain Java and native platform binaries for Windows, Linux and Mac available]
-* link:#_command_structure[Modular command structure], making it easy to focus on particular tasks
-* link:#_o_output[Rich output formats]; save command output in JSON, CSV, XML or plain-text formats
-* link:#_session_management[Session-based]; no need to pass URL’s and credentials on every individual fcli invocation
-* Support for configuring option values through link:#_environment_variables[environment variables]
-* Support for link:#_fcli_variables[fcli variables]; pass data between fcli commands
-
-The following Fortify products are currently supported by fcli:
-
-* Software Security Center (SSC)
-** Includes virtually all functionality provided by the legacy FortifyClient utility
-** Includes virtually all functionality provided by the ssc-client sample shipped with SSC
-** Adds a wide range of other functionalities not previously included in any Fortify client-side utilities
-* ScanCentral SAST
-** Support for starting and managing ScanCentral SAST scans
-* ScanCentral DAST
-** Support for starting and managing ScanCentral DAST scans
-** Support for listing scan policies and settings
-** Support for listing and managing sensors
-* Fortify on Demand (FoD)
-** Currently in preview mode
-** No link:#_manual_pages[manual pages] available
-** `+fod+` command is hidden from `+fcli -h+` output
-** View available FoD commands by running `+fcli fod -h+`
-
-== Installation
-
-Download bundles for fcli are available on the https://github.com/fortify/fcli/releases[Releases] page, containing both development releases (named `+Development Release - branch+`) and final releases. In general, the use of a final release is recommended, unless you want to use any functionality that hasn’t made it into a final release yet.
-
-Each release comes with a list of assets:
-
-* `+docs-html.zip+` & `+docs-manpage.zip+`: Manual pages in either HTML or manpage format
-* `+fcli-linux.tgz+`, `+fcli-mac.tgz+` & `+fcli-windows.zip+`: Native binaries for each of the mentioned platforms
-** Note that some browsers by default will disallow downloading of `+fcli-windows.zip+`; please bypass the warning
-** Linux and Mac downloads include an `+auto-completion+` script that makes interactive fcli usage easier
-* `+fcli.jar+`: Java version of fcli, which should be runnable on any platform that has Java 11+ installed
-** Note that in general, the native binaries are easier to invoke, offer better performance, and have the benefit of auto-completion capabilities on Linux & Mac
-** If you experience any unexpected behavior with native binaries, like commands or command line options not being listed or recognized, or technical error messages about methods, constructors or serializers not being
-found, please try with the Java version a s it may be an issue specific to the native binaries. See the link:#_troubleshooting[Troubleshooting] section for details.
-* `+fcli-thirdparty.zip+`: Third-party licenses and sources for license purposes; usually no need to download
-* `+LICENSE.TXT+` & `+README.md+`: Some generic information and license for fcli
-
-Please note that when publishing a new release, it may take up to 30-60 minutes before release assets are posted. If the latest release doesn’t show any of the assets listed above, please check again in 30-60 minutes. If you encounter a release without these assets after waiting for 60 minutes, please consider submitting an issue on the https://github.com/fortify/fcli/issues[fcli issue tracker].
-
-To install one of the binary distributions of fcli:
-
-* Download the appropriate binary archive for your platform
-* Extract the archive contents to a directory of your choosing
-* For ease of use, add this directory to your operating system or shell PATH environment variable, or move the `+fcli+`/`+fcli.exe+` binary to a directory that is already on the PATH
-* Linux/Mac only: Run the following command to install fcli auto command completion, allowing for use of the `++` to get suggestions for fcli command and option names. You may want to add this to your shell startup script, such that fcli auto-completion is readily available in every shell. +
-`+source /fcli_completion+`
-
-To install the `+.jar+` version of fcli, simply download `+fcli.jar+` and put in in a directory of your choosing, after which it can be executed using `+java -jar path/to/fcli.jar+`. You may want to set up a
-simple wrapper script/batch file or shell alias to make it slightly easier to invoke `+fcli.jar+`.
-
-== Command Structure
-
-Fcli provides a product-oriented command structure, with each product represented by a separate tree of subcommands. For example, the `+fcli fod+` command tree can be used to interact with Fortify on Demand
-(FoD), and the `+fcli ssc+` command tree can be used to interact with Fortify Software Security Center (SSC). There are also some non product-related command trees, like the `+fcli config+` command tree to manage fcli configuration.
-
-To see what top-level fcli commands are available, you can use the `+fcli --help+` command. You can drill down into the command tree to see what sub-commands are available within a particular parent command, for example by running `+fcli ssc --help+` to see all `+fcli ssc+` sub-commands, or `+fcli ssc session --help+` to see all SSC session management commands.
-
-If you don’t have fcli up and running yet, you can also refer to the downloadable or online manual pages; refer to the link:#_manual_pages[Manual Pages] section for more information.
-
-== Common Options
-
-The following sections describe common options that are available on (most) fcli commands.
-
-=== -h | –help
-
-This option can be used on every fcli (sub-)command to view usage information for that command. Usage information usually shows the command synopsis, a description of the functionality provided by the command, and a description of each command line option or parameter accepted by the command.
-
-=== –env-prefix
-
-As described in the link:#_environment_variables[Environment Variables] section, default option and parameter values can be retrieved from environment variables starting with `+FCLI_DEFAULT+`. This option allows for configuring a different environment variable prefix. This may be useful if, for example, you want to login to multiple instances of the same system using environment variables. For example, when running `+fcli ssc session login --env-prefix PROD+`, fcli will look for environment variables like `+PROD_SSC_URL+` instead of `+FCLI_DEFAULT_SSC_URL+`.
-
-Note that a default value for the `+--env-prefix+` option itself can be specified through an `+FCLI_DEFAULT_ENV_PREFIX+` environment variable, for example if you want to globally override the `+FCLI_DEFAULT+` prefix.
-
-=== –log-level
-
-This option can be used on every fcli (sub-)command to specify the fcli log level; see the help output for a list of allowed levels. Note that this option also requires the `+--log-file+` option to be specified,
-otherwise no log will be written.
-
-=== –log-file
-
-This option can be used on every fcli (sub-)command to specify the file to which to output log data. If not specified, currently no log data will be written, although future versions may specify a default log file
-location in the fcli home folder.
-
-=== -o | –output
-
-Available on virtually all (leaf) commands that output data, this option can be used to specify the output format. Fcli supports a wide variety of output formats, like `+table+`, `+csv+`, `+json+`, `+xml+`, and `+tree+` formats, allowing for both human-readable output or output suitable for automations. The `+csv-plain+` and `+table-plain+` output formats produce CSV or table output without headers. The `+*-flat+`
-output formats produce a flattened view of the output data, potentially making it easier to process that data without having to navigate through an object tree. For a full list of output formats supported by your fcli
-version, please refer to the help output or link:#_manual_pages[Manual Pages].
-
-Most output formats allow for specifying the JSON properties to be included in the output, for example `+-o csv=id,name+`. If no JSON properties are specified, most output formats will output all available
-JSON properties, except for table output, which usually outputs a predefined set of JSON properties.
-
-There are two output formats that are somewhat special:
-
-* `+-o 'expr=Text with {property1} or {property2}\n'+` Formats the output data based on the given expression, which is a combination of (optional) plain text and JSON property placeholders. This can be used for a variety of purposes, for example generating output in a human-readable format, or for generating a list of commands to be run at a later stage. Note that by default, no newline character will be inserted after
-evaluating the given expression. If necessary, the expression should explicitly include `+\n+` to output a newline character. To demonstrate the power of this output format, following are two examples of how `+-o expr+` can be used to generate a script that purges all application versions matching certain criteria:
-** `+fcli ssc appversion list -q createdBy=admin -o 'expr=fcli ssc appversion-artifact purge --older-than 30d --appversion {id}\n'+`
-** for id in $(fcli ssc appversion list -q createdBy=admin -o '`expr=\{id}`'); do echo "`fcli ssc appversion-artifact purge –older-than 30d –appversion $\{id}`"; done
-* `+-o json-properties+` List all JSON properties returned by the current command, which can be used
-on options that take JSON propert ies as input, like output expressions (`+-o expr={prop}+`), properties to include in the output (`+-o table=prop1,prop2+`), queries (`+-q prop1=value1+`), and fcli variables (`+--store var:prop1,prop2+` & `+{?var:prop1}+`). Two important notes about this output format:
-** The command will be executed as specified, so be careful when using this output option on any command
-that changes state (delete/update/create/…) * On some commands, the list of available JSON properties may vary depending on command line options. For example, when a query returns no records, then `+-o json-properties+` will not output any properties. Likewise, a command may provide options for including additional data for each record; the corresponding JSON properties will only be shown if `+-o json-properties+` is used in combination with these options that load additional data.
-
-=== –output-to-file
-
-Available on virtually all (leaf) commands that output data, this option can be used to write the command output data to a file, in the format specified by the `+--output+` option listed above. In some cases, this may be more convenient than redirecting the output to a file. For example, although currently not implemented, fcli could potentially skip creating the output file if there is no output data or if an error occurs. Also, for commands that output status updates, like `+wait-for+` commands, the `+--output-to-file+` option allows for status updates to be written to standard output while the final output of the command will be written to the file specified.
-
-=== –store
-
-Available on virtually all (leaf) commands that output data, this option can be used to store command output data in an fcli variable. For more details, see the link:#_fcli_variables[Fcli Variables] section.
-
-=== -q | –query
-
-Available on most `+list+` commands and some other commands, this option allows for querying the output data, outputting only records that match the given query or queries. For now, only equals-based matching is supported; future fcli versions may provide additional matching options. General format is `+-q =+`; the list of JSON properties available for matching can be found by executing the same command with the `+-o json-properties+` option; see link:++#-o--output++[-o | –output] for details.
-
-=== –session
-
-Available on virtually all commands that interact with a target system, this option allows for specifying a session name. For more details, see the link:#_session_management[Session Management] section.
-
-== Session Management
-
-Most fcli product modules are session-based, meaning that you need to run a `+session login+` command before you can use most of the other commands provided by a product module, and run a `+session logout+` command when finished, for example:
-
-[source,bash]
-----
-fcli ssc session login --url https://my.ssc.org/ssc --user --password
-fcli ssc appversion list
-fcli ssc session logout --user --password
-----
-
-For interactive use, you can choose to keep the session open until it expires (expiration period depends on target system and login method). For pipeline use or other automation scenarios, it is highly recommended to issue a `+session logout+` command when no further interaction with the target system is required, to allow for any client-side and server-side cleanup to be performed. For example, upon logging in to SSC with user credentials, fcli will generate a `+UnifiedLoginToken+`, which will be invalidated when the `+ssc session logout+` is being run. If you have many (frequently executed) pipelines that interact with SSC, and you don’t run the `+ssc session logout+` command when the pipeline finishes, you risk exhausting SSC’s limit on active tokens. In addition, the `+logout+` commands will perform client-side cleanup, like removing session details like URL and authentication tokens from the client system.
-
-For product modules that support it, like SSC or ScanCentral DAST, it is also highly recommended to use token-based authentication rather than username/password-based authentication when incorporating fcli into pipelines or other automation tasks. This will avoid creation of a temporary token as described above, but also allows for better access control based on token permissions. Similarly, for systems that support Personal Access tokens, like FoD, it is highly recommended to utilize a Personal Access Token rather than user password. Note however that depending on (personal access) token permissions, not all fcli functionality may be available. In particular, even the least restrictive SSC `+CIToken+` may not provide access to all endpoints covered by fcli. If you need access to functionality not covered by `+CIToken+`, you may need to define a custom token definition, but this can only be done on self-hosted SSC environments, not on Fortify Hosted. If all else fails, you may need to revert to username/password-based authentication to utilize the short-lived `+UnifiedLoginToken+`.
-
-=== Named Sessions
-
-Fcli supports named sessions, allowing you to have multiple open sessions for a single product. When issuing a `+session login+` command, you can optionally provide a session name as in `+fcli ssc session login mySession ...+`, and then use that session in other commands using the `+--session mySession+` command line option. If no session name is specified, a session named `+default+` will be created/used. Named sessions allow for a variety of use cases, for example:
-
-* Run fcli commands against multiple instances of the same product, like DEV and PROD instances or an on-premise instance and a Fortify Hosted instance, without having to continuously login and logout from one instance to switch to another instance
-* Run fcli commands against a single instance of a product, but with alternating credentials, for example with one session providing admin rights and another session providing limited user rights
-* Run one session with username/password credentials to allow access to all fcli functionality (based on user permissions), and another session with token-based authentication with access to only a subset of fcli functionality
-* Run multiple pipelines or automation scripts simultaneously, each with their own session name, to reduce chances of these pipelines and scripts affecting each other (see link:#_fcli_home_folder[Fcli Home Folder] though for a potentially better solution for this scenario)
-
-=== Session Storage
-
-To keep session state between fcli invocations, fcli stores session data like URL and authentication tokens in the link:#_fcli_home_folder[Fcli Home Folder]. To reduce the risk of unauthorized access to this sensitive data, fcli encrypts the session data files. However, this is not bullet-proof, as the default encryption key and algorithm can be easily viewed in fcli source code. As such, it is recommended to ensure file permissions on the FCLI Home folder are properly configured to disallow access by other users. Being stored in the user’s home directory by default, the correct file permissions should usually already be in place. For enhanced security, you may also consider setting the `+FCLI_ENCRYPT_KEY+` environment variable; see the link:#_fcli_home_folder[Fcli Home Folder] section for details.
-
-== Fcli Home Folder
-
-Fcli stores various files in its home directory, like session files (see link:#_session_management[Session Management]) and fcli variable contents (see link:#_fcli_variables[Fcli Variables]). Future versions of fcli may
-also automatically generated log files in this home directory, if no `+--log-file+` option is provided.
-
-By default, the fcli home directory is located at `+/.fortify/fcli+`, but this can be overridden through the `+FORTIFY_HOME+` or `+FCLI_HOME+` environment variables. If the `+FCLI_HOME+` environment variable is set, then this will be used as the fcli home directory. If the `+FORTIFY_HOME+` environment variable is set (and `+FCLI_HOME+` is not set), then fcli will use `+/fcli+` as its home directory.
-
-When utilizing fcli in pipelines or automation scripts, especially when multiple pipelines or scripts may be running simultaneously on a single, non-containerized system, it is highly recommended to set the `+FCLI_HOME+` or `+FORTIFY_HOME+` environment variables to a dedicated directory for each individual pipeline/script run. Failure to do so may cause these runs to share session data, variables and other persistent fcli data, which will likely cause issues. For example, both pipelines may try to login with the same session name but with different URL’s or credentials, or even when using the same session configuration, one pipeline may log out of the session while the other pipeline is still using that session. Or, both pipelines may be updating the same fcli variable but with different contents, causing unexpected results when accessing those fcli variables. On containerized systems, like pipelines running in GitLab or GitHub, the fcli home folder will usually be stored inside the individual pipeline containers, so in this case it shouldn’t be necessary to set the `+FCLI_HOME+` or `+FORTIFY_HOME+` variables.
-
-Note that some files stored in the fcli home directory may contain sensitive data, like authentication tokens generated by login commands, or proxy credentials configured through the `+fcli config proxy+` commands. Fcli encrypts any sensitive files, but since the encryption key and algorithm are hardcoded, these files can be decrypted fairly easily. You should ensure proper file access permissions on the fcli home folder. In addition, you can consider setting the `+FCLI_ENCRYPT_KEY+` environment variable to configure an alternative encryption key. That way, the sensitive files can only be decrypted if someone has access to this customer encryption key.
-
-== Environment Variables
-
-Apart from the special-purpose environment variables described in other sections, like the link:#_fcli_home_folder[Fcli Home Folder] section, fcli allows for specifying default option and parameter values through environment variables. This is particularly useful for specifying product URL’s and credentials through pipeline secrets, but also allows for preventing having to manually supply command line options if you frequently invoke a particular command with the same option value(s). For example, you could define a default value for the `+fcli ssc appversion create --issue-template+` option, to avoid having to remember the issue template name every time you invoke this command.
-
-Fcli walks the command tree to find an environment variable that matches a particular option, starting with the most detailed command prefix first. For the issue-template example above, fcli would look for the following environment variable names, in this order:
-
-* `+FCLI_DEFAULT_SSC_APPVERSION_CREATE_ISSUE_TEMPLATE+`
-* `+FCLI_DEFAULT_SSC_APPVERSION_ISSUE_TEMPLATE+`
-* `+FCLI_DEFAULT_SSC_ISSUE_TEMPLATE+`
-* `+FCLI_DEFAULT_ISSUE_TEMPLATE+`
-
-Environment variable lookups are based on the following rules:
-
-* Command aliases are not taken into account when looking for environment variables; suppose we have a `+delete+` command with alias `+rm+`, you will need to use `+FCLI_DEFAULT_..._DELETE_...+` and not `+FCLI_DEFAULT_..._RM_...+`
-* For options, fcli will use the longest option name when looking for environment variables; suppose we have an option with names `+-a+`, `+--ab+` and `+--abc+`, you will need to use `+FCLI_DEFAULT_..._ABC+` and not `+FCLI_DEFAULT_..._AB+` or `+FCLI_DEFAULT_..._A+`
-* Currently, not all positional parameters support default values from environment variables; this will be improved over time. Please refer to the positional parameter description in help output or manual pages to identify what environment variable suffix should be used for a particular positional parameter.
-
-Although powerful, these environment variables for providing default option and parameter values should be used with some care to avoid unexpected results:
-
-1. Obviously command option requirements should be respected; supplying default values for exclusive options may result in errors or unexpected behavior
-2. Preferably, you should use the most specific environment variable name, like `+FCLI_DEFAULT_SSC_APPVERSION_CREATE_ISSUE_TEMPLATE+` from the example above, to avoid accidentally supplying default values to a similarly named option on other commands
-
-Despite #2 above, in some cases it may be useful to use less specific environment names, in particular if the same default values should be applied to multiple commands. As an example, consider an environment variable named `+FCLI_DEFAULT_SSC_URL+`:
-
-* This variable value will be used as a default value for all `+--url+` options in the SSC module
-* This variable value will be used as a default value for all `+--ssc-url+` options in other product modules
-
-This means that defining a single `+FCLI_DEFAULT_SSC_URL+` environment variable, together with for example `+FCLI_DEFAULT_SSC_USER+` and `+FCLI_DEFAULT_SSC_PASSWORD+` environment variables, allows for applying these default values to all of the `+fcli ssc session login+`, `+fcli sc-sast session login+`, `+fcli sc-dast session login+`, and corresponding `+logout+` commands.
-
-Note that as described in the link:#_env_prefix[–env-prefix] section, you can override the `+FCLI_DEFAULT+` prefix. For example, with `+--env-prefix MYPREFIX+`, fcli will look for `+MYPREFIX_*+` environment variables instead of `+FCLI_DEFAULT_*+` environment variables.
-
-== Fcli Variables
-
-Fcli allows for storing fcli output data in fcli variables for use by subsequent fcli commands. This is a powerful feature that prevents users from having to use shell features to parse fcli output when needing to provide output from one command as input to another command. For example, this feature allows for starting a scan, and then passing the scan id to a corresponding `+wait-for+` command, or for creating an SSC application version, and passing the SSC application version id to the `+appversion-artifact upload+` command.
-
-Fcli supports two types of variables:
-
-* Named variables
-** Stored using the `+--store myVarName[:prop1,prop2]+` option on data output commands
-** If no properties are provided with the `+--store+` option, all JSON properties will be stored
-** Referenced using the `+'{?myVarName:prop1}'+` syntax anywhere on the command line of subsequent fcli commands
-** As a best practice, variable references should be quoted to avoid the shell interpreting the curly braces
-** On most shells, you should be able to put the variable reference in single quotes, or use `+\{+`
-** If you have any suggestions for a better syntax, please comment here: https://github.com/fortify/fcli/issues/160
-** Variable names are global and can be referenced across products and sessions
-* Predefined variables:
-** Stored using the `+--store '?'+` option on a subset of data output commands
-** Stored under a command-specific predefined variable name
-** Referenced using the `+'?'+` syntax on specific options
-** As a best practice, question marks should be quoted to avoid the shell interpreting `+?+` as a file name wildcard (for example, if you have a file named `+x+` in the current directory, then `+--store ?+` would store a variable named `+x+` instead of the predefined variable name)
-** On most shells, you should be able to put the `+?+` in single or double quotes, or use `+\?+`
-** If you have any suggestions for a better syntax, please comment here: https://github.com/fortify/fcli/issues/160
-** Help output and manual pages may currently lack information about which commands and options support the `+'?'+` syntax, so for now you’ll need to look at examples or just try.
-
-Predefined variables are easier to use; they are more concise and you do not need to remember JSON property names. However, as indicated, they are more limited in use; they only store a predefined JSON property, and
-are only available on a subset of commands and options.
-
-Following are some examples, assuming the necessary login sessions are available:
-
-[source,bash]
-----
-fcli ssc appversion create myApp:1.0 --auto-required --skip-if-exists --store '?'
-fcli ssc appversion-artifact upload myScan.fpr --appversion '?'
-
-fcli ssc appversion create myApp:1.0 --auto-required --skip-if-exists --store myVersion:id,name
-fcli ssc appversion-artifact upload myScan.fpr --appversion {?myVersion:id}
-
-fcli sc-dast scan start MyScan -S 011daf6b-f2d0-4127-89ab-1d3cebab8784 --store '?'
-fcli sc-dast scan wait-for '?'
-
-fcli sc-dast scan start MyScan -S 011daf6b-f2d0-4127-89ab-1d3cebab8784 --store myScan
-fcli sc-dast scan wait-for {?myScan:id}
-----
-
-Fcli provides dedicated commands for managing variables and variable contents through the following commands; please see help output or manual pages for available sub-commands:
-
-* `+fcli config variable definition+` * `+fcli config variable contents+`
-
-Note that the `+fcli config variable contents+` `+get+` and `+list+` commands support the regular fcli output options, and the `+list+` command also provides query capabilities. This allows for advanced use
-cases, like retrieving server data once and then outputting it in multiple formats, potentially even applying separate filters. As an example:
-
-[source,bash]
-----
-fcli ssc appversion list --store myVersions
-fcli config variable contents list myVersions -o csv --output-to-file myVersions.csv
-fcli config variable contents list myVersions -o json -q createdBy=admin --output-to-file myAdminVersions.json
-fcli config variable contents list myVersions -o 'expr={id}\n' --output-to-file myVersionIds.txt
-----
-
-== Manual Pages
-
-The manual pages for this fcli release can be found here: link:manpage/fcli.html[fcli (1)]. If you are viewing this documentation offline, please make sure that you have fully extracted the docs-html.zip file to access the manual pages.
-
-Manual pages for each fcli release are automatically generated as new fcli releases are being built, and are available in HTML and Linux man-page formats. The manual pages in man-page format can be downloaded from the fcli releases page at https://github.com/fortify/fcli/releases. The HTML-formatted manual pages, including this documentation page, can also be downloaded from the fcli release page or viewed online at https://fortify.github.io/fcli.
-
-== Troubleshooting
-
-=== Native Binaries
-
-Native binaries require some special source code annotations for proper operation, which are not required for the plain Java `+.jar+` version of fcli. If fcli developers forgot to include any of these annotations, you
-may experience any of the following behavior:
-
-* Commands and/or option listed in manual pages are not listed by the help output of a native binary
-* Trying to use commands and/or options listed in the manual pages result in errors stating that the command or option is not recognized
-* Some commands and/or options result in technical error messages about classes, constructors or methods not being found or not being accessible
-
-If you encounter any of these issues, please submit a bug report as described in link:#_submitting_a_bug_report[Submitting a Bug Report]. As described in that section, please include information on whether the `+.jar+` version of fcli exhibits the same erroneous behavior. While fcli developers are working on fixing the issue, you can temporarily use the `+.jar+` version of fcli until the issue is resolved.
-
-=== Submitting a Bug Report
-
-After confirming that an issue cannot be resolved based on the information above, and is not caused by user error, please consider submitting a bug report on the https://github.com/fortify/fcli/issues[fcli issue tracker]. Before doing so, please verify that there is not already a bug report open for the issue that you are experiencing; in that case, feel free to leave a comment on the existing bug report to confirm the issue and/or provide additional details.
-
-When opening a bug report, please include the following information:
-
-* Fcli version, as shown by the `+fcli --version+` command
-* Which fcli variant you are using; one of the native binaries or the `+.jar+` variant invoked using `+java -jar fcli.jar+`
-* If you are experiencing an issue with the native binaries, please confirm whether the `+.jar+` version of fcli exhibits the same behavior
-* Operating system and any other relevant environment details, for example:
-** Interactive or pipeline/automation use
-** If pipeline use, what CI/CD system are you running fcli on (Jenkins, GitHub, GitLab, …)
-** What FCLI environment variables have been set
-* Steps to reproduce
-* Any other information that may be relevant
diff --git a/doc-resources/template-values.md b/doc-resources/template-values.md
index 7937fa4cae..3970133b8f 100644
--- a/doc-resources/template-values.md
+++ b/doc-resources/template-values.md
@@ -6,3 +6,7 @@ https://github.com/fortify/fcli
# gh-pages-url
https://fortify.github.io/fcli
+
+# copyright-years
+2021 - {{var:current-year}}
+
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/cli/cmd/AbstractFortifyCLICommand.java b/fcli-common/src/main/java/com/fortify/cli/common/cli/cmd/AbstractFortifyCLICommand.java
deleted file mode 100644
index 058ab73a04..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/cli/cmd/AbstractFortifyCLICommand.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package com.fortify.cli.common.cli.cmd;
-
-import ch.qos.logback.classic.Level;
-import io.micronaut.core.annotation.ReflectiveAccess;
-import lombok.Getter;
-import picocli.CommandLine.ArgGroup;
-import picocli.CommandLine.Option;
-
-@ReflectiveAccess
-public class AbstractFortifyCLICommand {
- @ArgGroup(exclusive = false, headingKey = "fcli.genericOptions.heading", order = 50)
- @Getter private GenericOptionsArgGroup genericOptions = new GenericOptionsArgGroup();
-
- public static enum LogLevel {
- TRACE(Level.TRACE),
- DEBUG(Level.DEBUG),
- INFO(Level.INFO),
- WARN(Level.WARN),
- ERROR(Level.ERROR);
-
- @Getter private final Level logbackLevel;
- LogLevel(Level logbackLevel) {
- this.logbackLevel = logbackLevel;
- }
- }
-
- @ReflectiveAccess
- public static final class GenericOptionsArgGroup {
- @Option(names = {"-h", "--help"}, usageHelp = true, description = "display this help message")
- private boolean usageHelpRequested;
-
- @Option(names = "--env-prefix", defaultValue = "FCLI_DEFAULT")
- @Getter private String envPrefix;
-
- @Option(names = "--log-file")
- @Getter private String logFile;
-
- @Option(names = "--log-level")
- @Getter private LogLevel logLevel;
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/cli/mixin/CommonOptionMixins.java b/fcli-common/src/main/java/com/fortify/cli/common/cli/mixin/CommonOptionMixins.java
deleted file mode 100644
index c3b6d23a19..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/cli/mixin/CommonOptionMixins.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.fortify.cli.common.cli.mixin;
-
-import io.micronaut.core.annotation.ReflectiveAccess;
-import lombok.Getter;
-import picocli.CommandLine.Option;
-
-public class CommonOptionMixins {
- private CommonOptionMixins() {}
-
- @ReflectiveAccess
- public static class OptionalDestinationFile {
- @Option(names = {"-f", "--dest"}, descriptionKey = "fcli.destination-file")
- @Getter private String destination;
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/cli/util/EnvPrefixInitializer.java b/fcli-common/src/main/java/com/fortify/cli/common/cli/util/EnvPrefixInitializer.java
deleted file mode 100644
index 52d88c3afb..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/cli/util/EnvPrefixInitializer.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.fortify.cli.common.cli.util;
-
-import com.fortify.cli.common.cli.util.FortifyCLIInitializerRunner.FortifyCLIInitializerCommand;
-
-import jakarta.inject.Singleton;
-
-@Singleton
-public class EnvPrefixInitializer implements IFortifyCLIInitializer {
- @Override
- public void initializeFortifyCLI(FortifyCLIInitializerCommand cmd) {
- String envPrefix = cmd.getGenericOptions().getEnvPrefix();
- System.setProperty("fcli.env.default.prefix", envPrefix);
- FortifyCLIDefaultValueProvider.setEnvPrefix(envPrefix);
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/cli/util/EnvSuffix.java b/fcli-common/src/main/java/com/fortify/cli/common/cli/util/EnvSuffix.java
deleted file mode 100644
index 9c6a1bbc26..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/cli/util/EnvSuffix.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.fortify.cli.common.cli.util;
-
-import static java.lang.annotation.RetentionPolicy.*;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * This annotation allows for defining an environment variable suffix
- * on options and positional parameters for resolving default values
- * from environment variables.
- *
- * @author rsenden
- *
- */
-@Retention(RUNTIME)
-@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
-public @interface EnvSuffix {
- String value();
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/cli/util/FortifyCLIDefaultValueProvider.java b/fcli-common/src/main/java/com/fortify/cli/common/cli/util/FortifyCLIDefaultValueProvider.java
deleted file mode 100644
index bb053f452a..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/cli/util/FortifyCLIDefaultValueProvider.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package com.fortify.cli.common.cli.util;
-
-import java.lang.reflect.AnnotatedElement;
-
-import com.fortify.cli.common.util.StringUtils;
-
-import lombok.Setter;
-import picocli.CommandLine;
-import picocli.CommandLine.Model.ArgSpec;
-import picocli.CommandLine.Model.CommandSpec;
-import picocli.CommandLine.Model.OptionSpec;
-
-public class FortifyCLIDefaultValueProvider implements CommandLine.IDefaultValueProvider {
- @Setter private static String envPrefix = "FCLI_DEFAULT";
-
- @Override
- public String defaultValue(ArgSpec argSpec) {
- String envVarSuffix;
- if (argSpec instanceof OptionSpec) {
- final var optionSpec = (OptionSpec) argSpec;
- envVarSuffix = getEnvVarSuffix(optionSpec.userObject(), optionSpec.longestName().replaceAll("^-+", ""));
- } else {
- envVarSuffix = getEnvVarSuffix(argSpec.userObject(), null);
- }
- return resolve(argSpec.command(), envVarSuffix);
- }
-
- private String resolve(CommandSpec command, String suffix) {
- if ( command!=null && suffix!=null ) {
- var envVarName = getEnvVarName(command, suffix);
- String value = System.getenv(envVarName);
- if ( StringUtils.isNotBlank(value) ) { return value; }
- return resolve(command.parent(), suffix);
- }
- return null;
- }
-
- private final String getEnvVarSuffix(Object userObject, String defaultValue) {
- if ( userObject!=null && userObject instanceof AnnotatedElement ) {
- EnvSuffix envSuffixAnnotation = ((AnnotatedElement)userObject).getAnnotation(EnvSuffix.class);
- if ( envSuffixAnnotation!=null ) { return envSuffixAnnotation.value(); }
- }
- return defaultValue;
- }
-
- private final String getEnvVarName(CommandSpec command, String suffix) {
- String qualifiedCommandName = command.qualifiedName("_");
- String combinedName = String.format("%s_%s", qualifiedCommandName, suffix);
- return combinedName.replace('-', '_').toUpperCase().replaceFirst("FCLI", envPrefix);
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/cli/util/FortifyCLIInitializerRunner.java b/fcli-common/src/main/java/com/fortify/cli/common/cli/util/FortifyCLIInitializerRunner.java
deleted file mode 100644
index 96997ef519..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/cli/util/FortifyCLIInitializerRunner.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.cli.util;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.stream.Stream;
-
-import com.fortify.cli.common.cli.cmd.AbstractFortifyCLICommand;
-import com.fortify.cli.common.util.FixInjection;
-
-import io.micronaut.configuration.picocli.MicronautFactory;
-import io.micronaut.core.annotation.ReflectiveAccess;
-import jakarta.inject.Inject;
-import lombok.Getter;
-import picocli.CommandLine;
-import picocli.CommandLine.Command;
-import picocli.CommandLine.Model.CommandSpec;
-import picocli.CommandLine.Spec;
-
-@Command(defaultValueProvider = FortifyCLIDefaultValueProvider.class)
-@FixInjection
-public class FortifyCLIInitializerRunner {
- private static final PrintWriter DUMMY_WRITER = new PrintWriter(new StringWriter());
-
- public static final void initialize(String[] args, MicronautFactory micronautFactory) {
- // Remove help options, as we want initialization always to occur
- String[] argsWithoutHelp = Stream.of(args).filter(a->!a.matches("-h|--help")).toArray(String[]::new);
- new CommandLine(FortifyCLIInitializerCommand.class, micronautFactory)
- .setOut(DUMMY_WRITER)
- .setErr(DUMMY_WRITER)
- .setUnmatchedArgumentsAllowed(true)
- .setUnmatchedOptionsArePositionalParams(true)
- .setExpandAtFiles(true)
- .execute(argsWithoutHelp);
- }
-
- @Command(name = "fcli", defaultValueProvider = FortifyCLIDefaultValueProvider.class)
- @FixInjection @ReflectiveAccess
- public static final class FortifyCLIInitializerCommand extends AbstractFortifyCLICommand implements Runnable {
- @Inject private IFortifyCLIInitializer[] initializers;
- @Getter @Spec private CommandSpec commandSpec;
-
- @Override
- public void run() {
- for ( var initializer : initializers ) {
- initializer.initializeFortifyCLI(this);
- }
- }
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/cli/util/IFortifyCLIInitializer.java b/fcli-common/src/main/java/com/fortify/cli/common/cli/util/IFortifyCLIInitializer.java
deleted file mode 100644
index 6bb4779b20..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/cli/util/IFortifyCLIInitializer.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.fortify.cli.common.cli.util;
-
-import com.fortify.cli.common.cli.util.FortifyCLIInitializerRunner.FortifyCLIInitializerCommand;
-
-public interface IFortifyCLIInitializer {
- void initializeFortifyCLI(FortifyCLIInitializerCommand initializerCommand);
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/http/proxy/helper/ProxyHelper.java b/fcli-common/src/main/java/com/fortify/cli/common/http/proxy/helper/ProxyHelper.java
deleted file mode 100644
index 9e67510254..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/http/proxy/helper/ProxyHelper.java
+++ /dev/null
@@ -1,81 +0,0 @@
-package com.fortify.cli.common.http.proxy.helper;
-
-import java.nio.file.Path;
-import java.util.Comparator;
-import java.util.stream.Stream;
-
-import com.fortify.cli.common.util.FcliHomeHelper;
-
-import kong.unirest.UnirestInstance;
-
-public final class ProxyHelper {
- private ProxyHelper() {}
-
- public static final void configureProxy(UnirestInstance unirest, String module, String url) {
- getProxiesStream()
- .sorted(Comparator.comparingInt(ProxyDescriptor::getPriority).reversed())
- .filter(d->d.matches(module, url))
- .findFirst()
- .ifPresent(d->
- unirest.config().proxy(d.getProxyHost(), d.getProxyPort(), d.getProxyUser(), d.getProxyPasswordAsString())
- );
- }
-
- public static final ProxyDescriptor getProxy(String name) {
- Path proxyConfigPath = getProxyConfigPath(name);
- if ( !FcliHomeHelper.exists(proxyConfigPath) ) {
- throw new IllegalArgumentException("No proxy configuration found with name: "+name);
- }
- return getProxy(proxyConfigPath);
- }
-
- public static final ProxyDescriptor addProxy(ProxyDescriptor descriptor) {
- Path proxyConfigPath = getProxyConfigPath(descriptor);
- if ( FcliHomeHelper.exists(proxyConfigPath) ) {
- throw new IllegalArgumentException("proxy configuration with name "+descriptor.getName()+" already exists");
- }
- FcliHomeHelper.saveSecuredFile(proxyConfigPath, descriptor, true);
- return descriptor;
- }
-
- public static final ProxyDescriptor updateProxy(ProxyDescriptor descriptor) {
- FcliHomeHelper.saveSecuredFile(getProxyConfigPath(descriptor), descriptor, true);
- return descriptor;
- }
-
- private static final ProxyDescriptor getProxy(Path proxyDescriptorPath) {
- return FcliHomeHelper.readSecuredFile(proxyDescriptorPath, ProxyDescriptor.class, true);
- }
-
- public static final ProxyDescriptor deleteProxy(ProxyDescriptor descriptor) {
- FcliHomeHelper.deleteFile(getProxyConfigPath(descriptor), true);
- return descriptor;
- }
-
- public static final Stream deleteAllProxies() {
- return getProxiesStream()
- .peek(ProxyHelper::deleteProxy);
- }
-
- public static final Stream getProxiesStream() {
- return FcliHomeHelper.exists(getProxiesConfigPath())
- ? FcliHomeHelper.listFilesInDir(getProxiesConfigPath(), true).map(ProxyHelper::getProxy)
- : Stream.empty();
- }
-
- private static final Path getProxiesConfigPath() {
- return Path.of("proxies");
- }
-
- private static final Path getProxyConfigPath(ProxyDescriptor descriptor) {
- return getProxyConfigPath(descriptor.getName());
- }
-
- private static final Path getProxyConfigPath(String name) {
- return getProxiesConfigPath().resolve(getProxyFileName(name));
- }
-
- private static final String getProxyFileName(String name) {
- return name.replaceAll("[^a-zA-Z0-9]", "_");
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/http/ssl/truststore/helper/TrustStoreConfigDescriptor.java b/fcli-common/src/main/java/com/fortify/cli/common/http/ssl/truststore/helper/TrustStoreConfigDescriptor.java
deleted file mode 100644
index 1d58465960..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/http/ssl/truststore/helper/TrustStoreConfigDescriptor.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.fortify.cli.common.http.ssl.truststore.helper;
-
-import com.fortify.cli.common.json.JsonNodeHolder;
-
-import io.micronaut.core.annotation.ReflectiveAccess;
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.NoArgsConstructor;
-
-@Data @EqualsAndHashCode(callSuper = false)
-@Builder @NoArgsConstructor @AllArgsConstructor @ReflectiveAccess
-public class TrustStoreConfigDescriptor extends JsonNodeHolder {
- private String path;
- private String type;
- private String password;
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/http/ssl/truststore/helper/TrustStoreConfigHelper.java b/fcli-common/src/main/java/com/fortify/cli/common/http/ssl/truststore/helper/TrustStoreConfigHelper.java
deleted file mode 100644
index 9bd1ea7bbd..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/http/ssl/truststore/helper/TrustStoreConfigHelper.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package com.fortify.cli.common.http.ssl.truststore.helper;
-
-import java.nio.file.Path;
-
-import com.fortify.cli.common.util.FcliHomeHelper;
-
-public final class TrustStoreConfigHelper {
- private TrustStoreConfigHelper() {}
-
- public static final TrustStoreConfigDescriptor getTrustStoreConfig() {
- Path trustStoreConfigPath = getTrustStoreConfigPath();
- return !FcliHomeHelper.exists(trustStoreConfigPath)
- ? new TrustStoreConfigDescriptor()
- : FcliHomeHelper.readSecuredFile(trustStoreConfigPath, TrustStoreConfigDescriptor.class, true);
- }
-
- public static final TrustStoreConfigDescriptor setTrustStoreConfig(TrustStoreConfigDescriptor descriptor) {
- Path trustStoreConfigPath = getTrustStoreConfigPath();
- FcliHomeHelper.saveSecuredFile(trustStoreConfigPath, descriptor, true);
- return descriptor;
- }
-
- public static final void clearTrustStoreConfig() {
- FcliHomeHelper.deleteFile(getTrustStoreConfigPath(), true);
- }
-
- private static final Path getTrustStoreConfigPath() {
- return FcliHomeHelper.getFcliConfigPath().resolve("ssl/truststore.json");
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/json/IJsonNodeHolder.java b/fcli-common/src/main/java/com/fortify/cli/common/json/IJsonNodeHolder.java
deleted file mode 100644
index 1502a12581..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/json/IJsonNodeHolder.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package com.fortify.cli.common.json;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-
-public interface IJsonNodeHolder {
- void setJsonNode(JsonNode jsonNode);
- JsonNode asJsonNode();
- ObjectNode asObjectNode();
- ArrayNode asArrayNode();
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/json/JsonHelper.java b/fcli-common/src/main/java/com/fortify/cli/common/json/JsonHelper.java
deleted file mode 100644
index 1bb48cf0b0..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/json/JsonHelper.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.json;
-
-import java.util.EnumSet;
-import java.util.Iterator;
-import java.util.Set;
-import java.util.function.BiConsumer;
-import java.util.function.BinaryOperator;
-import java.util.function.Function;
-import java.util.function.Supplier;
-import java.util.stream.Collector;
-import java.util.stream.Stream;
-import java.util.stream.StreamSupport;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.DeserializationFeature;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.fasterxml.jackson.databind.node.TextNode;
-import com.fortify.cli.common.util.StringUtils;
-import com.jayway.jsonpath.Configuration;
-import com.jayway.jsonpath.DocumentContext;
-import com.jayway.jsonpath.JsonPath;
-import com.jayway.jsonpath.Option;
-import com.jayway.jsonpath.ParseContext;
-import com.jayway.jsonpath.spi.json.JacksonJsonNodeJsonProvider;
-import com.jayway.jsonpath.spi.mapper.JacksonMappingProvider;
-
-import lombok.Getter;
-
-/**
- * This bean provides utility methods for working with Jackson JsonNode trees.
- *
- * @author Ruud Senden
- *
- */
-public class JsonHelper {
- @Getter private static final ObjectMapper objectMapper = _createObjectMapper();
- private final ParseContext parseContext;
- private static final JsonHelper INSTANCE = new JsonHelper();
-
- public JsonHelper() {
- this.parseContext = JsonPath.using(Configuration.builder()
- .jsonProvider(new JacksonJsonNodeJsonProvider(objectMapper))
- .mappingProvider(new JacksonMappingProvider(objectMapper))
- .options(EnumSet.noneOf(Option.class))
- .build());
- }
-
- private static final ObjectMapper _createObjectMapper() {
- ObjectMapper objectMapper = new ObjectMapper();
- objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
- objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
- objectMapper.configure(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS, true);
- return objectMapper;
- }
-
- @SuppressWarnings("unchecked")
- public static final R evaluateJsonPath(Object input, String path, Class returnClass) {
- DocumentContext context = INSTANCE.parseContext.parse(input);
- if ( !ObjectNode.class.isAssignableFrom(returnClass) ) {
- return context.read(path, returnClass);
- } else {
- JsonNode jsonNode = context.read(path, JsonNode.class);
- if ( jsonNode instanceof ObjectNode ) {
- return (R)jsonNode;
- } else if ( jsonNode==null || !jsonNode.isArray() || jsonNode.size()>1 ) {
- throw new IllegalStateException("Unable to get ObjectNode for JSONPath "+path+", json node: "+jsonNode);
- } else if ( jsonNode.size()==0 ) {
- // What to return here; null, empty ObjectNode, NullNode?
- return null;
- } else {
- return (R)jsonNode.get(0);
- }
- }
- }
-
- public static final ObjectNode getFirstObjectNode(JsonNode input) {
- if ( input instanceof ObjectNode ) {
- return (ObjectNode)input;
- } else if ( input instanceof ArrayNode ) {
- ArrayNode array = (ArrayNode)input;
- if ( array.size()==0 ) { return null; }
- JsonNode node = array.get(0);
- if ( node instanceof ObjectNode ) {
- return (ObjectNode)node;
- }
- }
- throw new IllegalArgumentException("Input must be an ObjectNode or array of ObjectNodes");
- }
-
- public static final Iterable iterable(ArrayNode arrayNode) {
- Iterator iterator = arrayNode.iterator();
- return () -> iterator;
- }
-
- public static final Stream stream(ArrayNode arrayNode) {
- return StreamSupport.stream(iterable(arrayNode).spliterator(), false);
- }
-
- public static final ArrayNodeCollector arrayNodeCollector() {
- return new ArrayNodeCollector();
- }
-
- public static final ArrayNode toArrayNode(String... objects) {
- return Stream.of(objects).map(TextNode::new).collect(arrayNodeCollector());
- }
-
- public static T treeToValue(JsonNode node, Class returnType) {
- if ( node==null ) { return null; }
- try {
- T result = objectMapper.treeToValue(node, returnType);
- if ( result instanceof IJsonNodeHolder ) {
- ((IJsonNodeHolder)result).setJsonNode(node);
- }
- return result;
- } catch (JsonProcessingException jpe ) {
- throw new RuntimeException("Error processing JSON data", jpe);
- }
- }
-
- public static T jsonStringToValue(String jsonString, Class returnType) {
- if ( StringUtils.isBlank(jsonString) ) { return null; }
- try {
- return treeToValue(objectMapper.readTree(jsonString), returnType);
- } catch (JsonProcessingException jpe) {
- throw new RuntimeException("Error processing JSON data", jpe);
- }
- }
-
- private static final class ArrayNodeCollector implements Collector {
- @Override
- public Supplier supplier() {
- return objectMapper::createArrayNode;
- }
-
- @Override
- public BiConsumer accumulator() {
- return ArrayNode::add;
- }
-
- @Override
- public BinaryOperator combiner() {
- return (x, y) -> {
- x.addAll(y);
- return x;
- };
- }
-
- @Override
- public Function finisher() {
- return accumulator -> accumulator;
- }
-
- @Override
- public Set characteristics() {
- return EnumSet.of(Characteristics.UNORDERED);
- }
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/json/JsonNodeHolder.java b/fcli-common/src/main/java/com/fortify/cli/common/json/JsonNodeHolder.java
deleted file mode 100644
index abcc99be0f..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/json/JsonNodeHolder.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.fortify.cli.common.json;
-
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-
-import lombok.EqualsAndHashCode;
-import lombok.ToString;
-
-@ToString @EqualsAndHashCode
-public class JsonNodeHolder implements IJsonNodeHolder {
- private JsonNode jsonNode;
- @Override
- public void setJsonNode(JsonNode jsonNode) {
- this.jsonNode = jsonNode;
- }
-
- @Override @JsonIgnore
- public JsonNode asJsonNode() {
- if ( jsonNode==null ) {
- jsonNode = JsonHelper.getObjectMapper().valueToTree(this);
- }
- return jsonNode;
- }
-
- @Override @JsonIgnore
- public ObjectNode asObjectNode() {
- if ( !(jsonNode instanceof ObjectNode) ) { throw new IllegalStateException("JsonNode is not an instance of ObjectNode"); }
- return (ObjectNode)jsonNode;
- }
-
- @Override @JsonIgnore
- public ArrayNode asArrayNode() {
- if ( !(jsonNode instanceof ArrayNode) ) { throw new IllegalStateException("JsonNode is not an instance of ArrayNode"); }
- return (ArrayNode)jsonNode;
- }
-
-
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/OutputFormat.java b/fcli-common/src/main/java/com/fortify/cli/common/output/OutputFormat.java
deleted file mode 100644
index d79987c5d7..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/OutputFormat.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.output;
-
-import com.fortify.cli.common.output.writer.record.IRecordWriterFactory;
-import com.fortify.cli.common.output.writer.record.csv.CsvRecordWriterFactory;
-import com.fortify.cli.common.output.writer.record.csv.CsvRecordWriter.CsvType;
-import com.fortify.cli.common.output.writer.record.expr.ExprRecordWriterFactory;
-import com.fortify.cli.common.output.writer.record.json.JsonRecordWriterFactory;
-import com.fortify.cli.common.output.writer.record.json_properties.JsonPropertiesRecordWriterFactory;
-import com.fortify.cli.common.output.writer.record.table.TableRecordWriterFactory;
-import com.fortify.cli.common.output.writer.record.table.TableRecordWriter.TableType;
-import com.fortify.cli.common.output.writer.record.tree.TreeRecordWriterFactory;
-import com.fortify.cli.common.output.writer.record.xml.XmlRecordWriterFactory;
-import com.fortify.cli.common.output.writer.record.yaml.YamlRecordWriterFactory;
-
-import lombok.Getter;
-import lombok.RequiredArgsConstructor;
-
-/**
- * @author rsenden
- */
-@RequiredArgsConstructor
-public enum OutputFormat {
- // These entries should be in alphabetical order, except for expr & json_properties as
- // these are 'special' formats.
- csv (OutputStructure.FLAT, "csv", new CsvRecordWriterFactory(CsvType.HEADERS)),
- csv_plain (OutputStructure.FLAT, "csv", new CsvRecordWriterFactory(CsvType.NO_HEADERS)),
- json (OutputStructure.TREE, "json", new JsonRecordWriterFactory()),
- json_flat (OutputStructure.FLAT, "json", new JsonRecordWriterFactory()),
- table (OutputStructure.FLAT, "table", new TableRecordWriterFactory(TableType.HEADERS)),
- table_plain (OutputStructure.FLAT, "table", new TableRecordWriterFactory(TableType.NO_HEADERS)),
- tree (OutputStructure.TREE, "tree", new TreeRecordWriterFactory()),
- tree_flat (OutputStructure.FLAT, "tree", new TreeRecordWriterFactory()),
- xml (OutputStructure.TREE, "xml", new XmlRecordWriterFactory()),
- xml_flat (OutputStructure.FLAT, "xml", new XmlRecordWriterFactory()),
- yaml (OutputStructure.TREE, "yaml", new YamlRecordWriterFactory()),
- yaml_flat (OutputStructure.FLAT, "yaml", new YamlRecordWriterFactory()),
- expr (OutputStructure.TREE, "expr", new ExprRecordWriterFactory()),
- json_properties (OutputStructure.TREE, "paths", new JsonPropertiesRecordWriterFactory());
-
- @Getter private final OutputStructure outputStructure;
- @Getter private final String messageKey;
- @Getter private final IRecordWriterFactory recordWriterFactory;
-
- public enum OutputStructure { TREE, FLAT }
-
- public final boolean isFlat() {
- return isFlat(this);
- }
-
- public static final boolean isFlat(OutputFormat outputFormat) {
- switch (outputFormat.getOutputStructure()) {
- case FLAT: return true;
- default: return false;
- }
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/cli/cmd/basic/AbstractBasicOutputCommand.java b/fcli-common/src/main/java/com/fortify/cli/common/output/cli/cmd/basic/AbstractBasicOutputCommand.java
deleted file mode 100644
index 86ae1a6e4f..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/cli/cmd/basic/AbstractBasicOutputCommand.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.output.cli.cmd.basic;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fortify.cli.common.cli.cmd.AbstractFortifyCLICommand;
-import com.fortify.cli.common.output.cli.mixin.spi.basic.IBasicOutputHelper;
-import com.fortify.cli.common.output.spi.ISingularSupplier;
-
-import io.micronaut.core.annotation.ReflectiveAccess;
-
-@ReflectiveAccess
-public abstract class AbstractBasicOutputCommand extends AbstractFortifyCLICommand implements Runnable, ISingularSupplier {
- @Override
- public final void run() {
- IBasicOutputHelper outputHelper = getOutputHelper();
- outputHelper.write(getJsonNode());
- }
-
- protected abstract JsonNode getJsonNode();
- protected abstract IBasicOutputHelper getOutputHelper();
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/cli/cmd/unirest/AbstractUnirestOutputCommand.java b/fcli-common/src/main/java/com/fortify/cli/common/output/cli/cmd/unirest/AbstractUnirestOutputCommand.java
deleted file mode 100644
index 478e6aedc9..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/cli/cmd/unirest/AbstractUnirestOutputCommand.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.output.cli.cmd.unirest;
-
-import java.util.Arrays;
-import java.util.List;
-
-import com.fortify.cli.common.output.cli.mixin.spi.unirest.IUnirestOutputHelper;
-import com.fortify.cli.common.output.spi.ISingularSupplier;
-import com.fortify.cli.common.rest.cli.cmd.AbstractUnirestRunnerCommand;
-import com.fortify.cli.common.session.manager.api.ISessionData;
-
-import io.micronaut.core.annotation.ReflectiveAccess;
-import kong.unirest.UnirestInstance;
-
-@ReflectiveAccess
-public abstract class AbstractUnirestOutputCommand extends AbstractUnirestRunnerCommand implements ISingularSupplier {
- private static final List> supportedInterfaces = Arrays.asList(
- IUnirestBaseRequestSupplier.class,
- IUnirestWithSessionDataBaseRequestSupplier.class,
- IUnirestJsonNodeSupplier.class,
- IUnirestWithSessionDataJsonNodeSupplier.class);
- @SuppressWarnings("unchecked")
- @Override
- protected final Void run(UnirestInstance unirest, D sessionData) {
- IUnirestOutputHelper outputHelper = getOutputHelper();
- if ( isInstance(IUnirestBaseRequestSupplier.class) ) {
- outputHelper.write(unirest, ((IUnirestBaseRequestSupplier)this).getBaseRequest(unirest));
- } else if ( isInstance(IUnirestWithSessionDataBaseRequestSupplier.class) ) {
- outputHelper.write(unirest, ((IUnirestWithSessionDataBaseRequestSupplier)this).getBaseRequest(unirest, sessionData));
- } else if ( isInstance(IUnirestJsonNodeSupplier.class) ) {
- outputHelper.write(unirest, ((IUnirestJsonNodeSupplier)this).getJsonNode(unirest));
- } else if ( isInstance(IUnirestWithSessionDataJsonNodeSupplier.class) ) {
- outputHelper.write(unirest, ((IUnirestWithSessionDataJsonNodeSupplier)this).getJsonNode(unirest, sessionData));
- } else {
- throw new IllegalStateException(this.getClass().getName()+" must implement exactly one of "+supportedInterfaces);
- }
- return null;
- }
-
- private boolean isInstance(Class> clazz) {
- return clazz.isAssignableFrom(this.getClass()) &&
- supportedInterfaces.stream()
- .filter(c->!c.equals(clazz))
- .noneMatch(c->c.isAssignableFrom(this.getClass()));
- }
-
- protected abstract IUnirestOutputHelper getOutputHelper();
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/cli/cmd/unirest/IUnirestBaseRequestSupplier.java b/fcli-common/src/main/java/com/fortify/cli/common/output/cli/cmd/unirest/IUnirestBaseRequestSupplier.java
deleted file mode 100644
index 448b687644..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/cli/cmd/unirest/IUnirestBaseRequestSupplier.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package com.fortify.cli.common.output.cli.cmd.unirest;
-
-import kong.unirest.HttpRequest;
-import kong.unirest.UnirestInstance;
-
-public interface IUnirestBaseRequestSupplier {
- HttpRequest> getBaseRequest(UnirestInstance unirest);
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/cli/cmd/unirest/IUnirestJsonNodeSupplier.java b/fcli-common/src/main/java/com/fortify/cli/common/output/cli/cmd/unirest/IUnirestJsonNodeSupplier.java
deleted file mode 100644
index d35fc2c08c..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/cli/cmd/unirest/IUnirestJsonNodeSupplier.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.fortify.cli.common.output.cli.cmd.unirest;
-
-import com.fasterxml.jackson.databind.JsonNode;
-
-import kong.unirest.UnirestInstance;
-
-public interface IUnirestJsonNodeSupplier {
- JsonNode getJsonNode(UnirestInstance unirest);
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/cli/cmd/unirest/IUnirestWithSessionDataBaseRequestSupplier.java b/fcli-common/src/main/java/com/fortify/cli/common/output/cli/cmd/unirest/IUnirestWithSessionDataBaseRequestSupplier.java
deleted file mode 100644
index b39037b6e4..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/cli/cmd/unirest/IUnirestWithSessionDataBaseRequestSupplier.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.fortify.cli.common.output.cli.cmd.unirest;
-
-import com.fortify.cli.common.session.manager.api.ISessionData;
-
-import kong.unirest.HttpRequest;
-import kong.unirest.UnirestInstance;
-
-public interface IUnirestWithSessionDataBaseRequestSupplier {
- HttpRequest> getBaseRequest(UnirestInstance unirest, D sessionData);
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/cli/cmd/unirest/IUnirestWithSessionDataJsonNodeSupplier.java b/fcli-common/src/main/java/com/fortify/cli/common/output/cli/cmd/unirest/IUnirestWithSessionDataJsonNodeSupplier.java
deleted file mode 100644
index 177bbaa1ec..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/cli/cmd/unirest/IUnirestWithSessionDataJsonNodeSupplier.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.fortify.cli.common.output.cli.cmd.unirest;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fortify.cli.common.session.manager.api.ISessionData;
-
-import kong.unirest.UnirestInstance;
-
-public interface IUnirestWithSessionDataJsonNodeSupplier {
- JsonNode getJsonNode(UnirestInstance unirest, D sessionData);
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/cli/mixin/BasicOutputHelperMixins.java b/fcli-common/src/main/java/com/fortify/cli/common/output/cli/mixin/BasicOutputHelperMixins.java
deleted file mode 100644
index c296c91e27..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/cli/mixin/BasicOutputHelperMixins.java
+++ /dev/null
@@ -1,209 +0,0 @@
-package com.fortify.cli.common.output.cli.mixin;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fortify.cli.common.output.cli.mixin.spi.basic.AbstractBasicOutputHelper;
-import com.fortify.cli.common.output.cli.mixin.spi.basic.IBasicOutputHelper;
-import com.fortify.cli.common.output.cli.mixin.writer.OutputWriterWithQueryFactoryMixin;
-import com.fortify.cli.common.output.cli.mixin.writer.StandardOutputWriterFactoryMixin;
-import com.fortify.cli.common.output.spi.product.IProductHelper;
-import com.fortify.cli.common.output.writer.output.standard.StandardOutputConfig;
-
-import io.micronaut.core.annotation.ReflectiveAccess;
-import kong.unirest.UnirestInstance;
-import lombok.Getter;
-import lombok.Setter;
-import picocli.CommandLine.Command;
-import picocli.CommandLine.Mixin;
-import picocli.CommandLine.Model.CommandSpec;
-import picocli.CommandLine.Spec;
-import picocli.CommandLine.Spec.Target;
-
-/**
- * This class provides standard, product-agnostic {@link IBasicOutputHelper} implementations.
- * The mixins provided in this class are equivalent to the mixins in {@link UnirestOutputHelperMixins},
- * but allows for writing {@link JsonNode} instances to be written when no {@link UnirestInstance}
- * and/or {@link IProductHelper} is available or required.
- */
-public class BasicOutputHelperMixins {
-
- @ReflectiveAccess
- public static class Login extends AbstractBasicOutputHelper {
- public static final String CMD_NAME = "login";
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- @Getter @Mixin private StandardOutputWriterFactoryMixin outputWriterFactory;
- @Getter private StandardOutputConfig basicOutputConfig = StandardOutputConfig.table();
- }
-
- @ReflectiveAccess
- public static class Logout extends AbstractBasicOutputHelper {
- public static final String CMD_NAME = "logout";
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- @Getter @Mixin private StandardOutputWriterFactoryMixin outputWriterFactory;
- @Getter private StandardOutputConfig basicOutputConfig = StandardOutputConfig.table();
- }
-
- @ReflectiveAccess
- public static class Add extends AbstractBasicOutputHelper {
- public static final String CMD_NAME = "add";
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- @Getter @Mixin private StandardOutputWriterFactoryMixin outputWriterFactory;
- @Getter private StandardOutputConfig basicOutputConfig = StandardOutputConfig.table();
- }
-
- @ReflectiveAccess
- public static class Create extends AbstractBasicOutputHelper {
- public static final String CMD_NAME = "create";
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- @Getter @Mixin private StandardOutputWriterFactoryMixin outputWriterFactory;
- @Getter private StandardOutputConfig basicOutputConfig = StandardOutputConfig.table();
- }
-
- @ReflectiveAccess @Command(aliases = {"rm"})
- public static class Delete extends AbstractBasicOutputHelper {
- public static final String CMD_NAME = "delete";
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- @Getter @Mixin private StandardOutputWriterFactoryMixin outputWriterFactory;
- @Getter private StandardOutputConfig basicOutputConfig = StandardOutputConfig.table();
- }
-
- @ReflectiveAccess
- public static class Revoke extends AbstractBasicOutputHelper {
- public static final String CMD_NAME = "revoke";
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- @Getter @Mixin private StandardOutputWriterFactoryMixin outputWriterFactory;
- @Getter private StandardOutputConfig basicOutputConfig = StandardOutputConfig.table();
- }
-
- @ReflectiveAccess
- public static class Clear extends AbstractBasicOutputHelper {
- public static final String CMD_NAME = "clear";
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- @Getter @Mixin private StandardOutputWriterFactoryMixin outputWriterFactory;
- @Getter private StandardOutputConfig basicOutputConfig = StandardOutputConfig.table();
- }
-
- @ReflectiveAccess @Command(name = "list", aliases = {"ls"})
- public static class List extends AbstractBasicOutputHelper {
- public static final String CMD_NAME = "list";
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- @Getter @Mixin private OutputWriterWithQueryFactoryMixin outputWriterFactory;
- @Getter private StandardOutputConfig basicOutputConfig = StandardOutputConfig.table();
- }
-
- @ReflectiveAccess
- public static class Get extends AbstractBasicOutputHelper {
- public static final String CMD_NAME = "get";
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- @Getter @Mixin private StandardOutputWriterFactoryMixin outputWriterFactory;
- @Getter private StandardOutputConfig basicOutputConfig = StandardOutputConfig.details();
- }
-
- @ReflectiveAccess
- public static class Set extends AbstractBasicOutputHelper {
- public static final String CMD_NAME = "set";
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- @Getter @Mixin private StandardOutputWriterFactoryMixin outputWriterFactory;
- @Getter private StandardOutputConfig basicOutputConfig = StandardOutputConfig.table();
- }
-
- @ReflectiveAccess
- public static class Update extends AbstractBasicOutputHelper {
- public static final String CMD_NAME = "update";
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- @Getter @Mixin private StandardOutputWriterFactoryMixin outputWriterFactory;
- @Getter private StandardOutputConfig basicOutputConfig = StandardOutputConfig.table();
- }
-
- @ReflectiveAccess
- public static class Enable extends AbstractBasicOutputHelper {
- public static final String CMD_NAME = "enable";
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- @Getter @Mixin private StandardOutputWriterFactoryMixin outputWriterFactory;
- @Getter private StandardOutputConfig basicOutputConfig = StandardOutputConfig.table();
- }
-
- @ReflectiveAccess
- public static class Disable extends AbstractBasicOutputHelper {
- public static final String CMD_NAME = "disable";
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- @Getter @Mixin private StandardOutputWriterFactoryMixin outputWriterFactory;
- @Getter private StandardOutputConfig basicOutputConfig = StandardOutputConfig.table();
- }
-
- @ReflectiveAccess
- public static class Start extends AbstractBasicOutputHelper {
- public static final String CMD_NAME = "start";
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- @Getter @Mixin private StandardOutputWriterFactoryMixin outputWriterFactory;
- @Getter private StandardOutputConfig basicOutputConfig = StandardOutputConfig.table();
- }
-
- @ReflectiveAccess
- public static class Pause extends AbstractBasicOutputHelper {
- public static final String CMD_NAME = "pause";
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- @Getter @Mixin private StandardOutputWriterFactoryMixin outputWriterFactory;
- @Getter private StandardOutputConfig basicOutputConfig = StandardOutputConfig.table();
- }
-
- @ReflectiveAccess
- public static class Resume extends AbstractBasicOutputHelper {
- public static final String CMD_NAME = "resume";
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- @Getter @Mixin private StandardOutputWriterFactoryMixin outputWriterFactory;
- @Getter private StandardOutputConfig basicOutputConfig = StandardOutputConfig.table();
- }
-
- @ReflectiveAccess
- public static class Cancel extends AbstractBasicOutputHelper {
- public static final String CMD_NAME = "cancel";
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- @Getter @Mixin private StandardOutputWriterFactoryMixin outputWriterFactory;
- @Getter private StandardOutputConfig basicOutputConfig = StandardOutputConfig.table();
- }
-
- @ReflectiveAccess
- public static class WaitFor extends AbstractBasicOutputHelper {
- public static final String CMD_NAME = "wait-for";
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- @Getter @Mixin private StandardOutputWriterFactoryMixin outputWriterFactory;
- @Getter private StandardOutputConfig basicOutputConfig = StandardOutputConfig.table();
- }
-
- @ReflectiveAccess
- public static class Upload extends AbstractBasicOutputHelper {
- public static final String CMD_NAME = "upload";
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- @Getter @Mixin private StandardOutputWriterFactoryMixin outputWriterFactory;
- @Getter private StandardOutputConfig basicOutputConfig = StandardOutputConfig.table();
- }
-
- @ReflectiveAccess
- public static class Download extends AbstractBasicOutputHelper {
- public static final String CMD_NAME = "download";
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- @Getter @Mixin private StandardOutputWriterFactoryMixin outputWriterFactory;
- @Getter private StandardOutputConfig basicOutputConfig = StandardOutputConfig.table();
- }
-
- @ReflectiveAccess
- public static class Install extends AbstractBasicOutputHelper {
- public static final String CMD_NAME = "install";
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- @Getter @Mixin private StandardOutputWriterFactoryMixin outputWriterFactory;
- @Getter private StandardOutputConfig basicOutputConfig = StandardOutputConfig.table();
- }
-
- @ReflectiveAccess
- public static class Uninstall extends AbstractBasicOutputHelper {
- public static final String CMD_NAME = "uninstall";
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- @Getter @Mixin private StandardOutputWriterFactoryMixin outputWriterFactory;
- @Getter private StandardOutputConfig basicOutputConfig = StandardOutputConfig.table();
- }
-
- @ReflectiveAccess @Command
- public static class Other extends AbstractBasicOutputHelper {
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/cli/mixin/UnirestOutputHelperMixins.java b/fcli-common/src/main/java/com/fortify/cli/common/output/cli/mixin/UnirestOutputHelperMixins.java
deleted file mode 100644
index d7f4fba4f3..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/cli/mixin/UnirestOutputHelperMixins.java
+++ /dev/null
@@ -1,253 +0,0 @@
-package com.fortify.cli.common.output.cli.mixin;
-
-import com.fortify.cli.common.output.cli.cmd.unirest.AbstractUnirestOutputCommand;
-import com.fortify.cli.common.output.cli.mixin.spi.unirest.AbstractUnirestOutputHelper;
-import com.fortify.cli.common.output.cli.mixin.spi.unirest.IUnirestOutputHelper;
-import com.fortify.cli.common.output.cli.mixin.writer.OutputWriterWithQueryFactoryMixin;
-import com.fortify.cli.common.output.cli.mixin.writer.StandardOutputWriterFactoryMixin;
-import com.fortify.cli.common.output.spi.product.IProductHelper;
-import com.fortify.cli.common.output.writer.output.standard.StandardOutputConfig;
-
-import io.micronaut.core.annotation.ReflectiveAccess;
-import lombok.Getter;
-import lombok.Setter;
-import picocli.CommandLine.Command;
-import picocli.CommandLine.Mixin;
-import picocli.CommandLine.Model.CommandSpec;
-import picocli.CommandLine.Spec;
-import picocli.CommandLine.Spec.Target;
-
-// TODO Rename this class to UnirestOutputHelperMixins
-/**
- * This class provides standard, product-agnostic {@link IUnirestOutputHelper} implementations.
- * Each product module should provide a {@code OutputHelperMixins} class that
- * provides similarly named inner classes that extend from the corresponding
- * {@link UnirestOutputHelperMixins} inner class, with a no-argument constructor that injects
- * the product-specific {@link IProductHelper} by calling the
- * {@link AbstractUnirestOutputHelper#setProductHelper(IProductHelper)} method. For example:
- *
- *
- * public class MyProductOutputHelperMixins {
- * ...
- *
- * @ReflectiveAccess
- * public static class List extends OutputHelperMixins.List {
- * public List() { setProductHelper(new MyProductProductHelper()); }
- * }
- *
- * ...
- * }
- *
- *
- * Note that the {@link IUnirestOutputHelper} instance is injected back into the provided
- * {@link IProductHelper}, so you should always create a new {@link IProductHelper}
- * instance, rather than reusing the same {@link IProductHelper} instance for all
- * {@link IUnirestOutputHelper} implementations.
- *
- * Each {@link Command} implementation can then use the appropriate product-specific
- * {@link IUnirestOutputHelper} implementation through the {@link Mixin} annotation, i.e.:
- *
- *
- * @ReflectiveAccess
- * @Command(name = MyProductOutputHelperMixins.List.CMD_NAME)
- * public class SomeListCommand extends AbstractMyProductOutputCommand implements IBaseHttpRequestSupplier {
- * @Getter @Mixin private MyProductOutputHelperMixins.List outputHelper;
- * ...
- * }
- *
- *
- * Here, {@code AbstractMyProductOutputCommand} would extend from {@link AbstractUnirestOutputCommand},
- * which takes care of displaying the output generated by the command, based on the configured
- * {@link IUnirestOutputHelper} {@link Mixin}.
- *
- * For consistency, command implementations should use the {@link IUnirestOutputHelper} implementation
- * that exactly matches the command. For example, you should only be using the {@link List}
- * implementation if you are actually implementing a 'list' command; {@link List} shouldn't be used
- * by commands that just generate some list of output but are not actually called 'list'. In other
- * words, the command name should match the {@code CMD_NAME} provided by the {@link IUnirestOutputHelper}
- * implementation (and you should always use that constant to define the {@link Command} name.
- *
- * If there is no matching standard {@link IUnirestOutputHelper} implementation, there are two options:
- *
- * - The {@code MyProductOutputHelperMixins} class can define additional, product-specific
- * {@link IUnirestOutputHelper} implementations, that extend from {@link Other} and provide
- * appropriate {@code CMD_NAME} constants and other output attributes
- * - The {@link Command} implementation can use the product-specific {@link Other} implementation
- *
- *
- * @author rsenden
- */
-public class UnirestOutputHelperMixins {
- @ReflectiveAccess
- public static class Add extends AbstractUnirestOutputHelper {
- public static final String CMD_NAME = "add";
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- @Getter @Mixin private StandardOutputWriterFactoryMixin outputWriterFactory;
- @Getter private StandardOutputConfig basicOutputConfig = StandardOutputConfig.table();
- }
-
- @ReflectiveAccess
- public static class Create extends AbstractUnirestOutputHelper {
- public static final String CMD_NAME = "create";
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- @Getter @Mixin private StandardOutputWriterFactoryMixin outputWriterFactory;
- @Getter private StandardOutputConfig basicOutputConfig = StandardOutputConfig.table();
- }
-
- @ReflectiveAccess @Command(aliases = {"rm"})
- public static class Delete extends AbstractUnirestOutputHelper {
- public static final String CMD_NAME = "delete";
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- @Getter @Mixin private StandardOutputWriterFactoryMixin outputWriterFactory;
- @Getter private StandardOutputConfig basicOutputConfig = StandardOutputConfig.table();
- }
-
- @ReflectiveAccess @Command(aliases = {"clear"})
- public static class DeleteAll extends AbstractUnirestOutputHelper {
- public static final String CMD_NAME = "delete-all";
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- @Getter @Mixin private StandardOutputWriterFactoryMixin outputWriterFactory;
- @Getter private StandardOutputConfig basicOutputConfig = StandardOutputConfig.table();
- }
-
- @ReflectiveAccess @Command(name = "list", aliases = {"ls"})
- public static class List extends AbstractUnirestOutputHelper {
- public static final String CMD_NAME = "list";
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- @Getter @Mixin private OutputWriterWithQueryFactoryMixin outputWriterFactory;
- @Getter private StandardOutputConfig basicOutputConfig = StandardOutputConfig.table();
- }
-
- @ReflectiveAccess
- public static class Get extends AbstractUnirestOutputHelper {
- public static final String CMD_NAME = "get";
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- @Getter @Mixin private StandardOutputWriterFactoryMixin outputWriterFactory;
- @Getter private StandardOutputConfig basicOutputConfig = StandardOutputConfig.details();
- }
-
- @ReflectiveAccess
- public static class Set extends AbstractUnirestOutputHelper {
- public static final String CMD_NAME = "set";
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- @Getter @Mixin private StandardOutputWriterFactoryMixin outputWriterFactory;
- @Getter private StandardOutputConfig basicOutputConfig = StandardOutputConfig.table();
- }
-
- @ReflectiveAccess
- public static class Update extends AbstractUnirestOutputHelper {
- public static final String CMD_NAME = "update";
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- @Getter @Mixin private StandardOutputWriterFactoryMixin outputWriterFactory;
- @Getter private StandardOutputConfig basicOutputConfig = StandardOutputConfig.table();
- }
-
- @ReflectiveAccess
- public static class Enable extends AbstractUnirestOutputHelper {
- public static final String CMD_NAME = "enable";
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- @Getter @Mixin private StandardOutputWriterFactoryMixin outputWriterFactory;
- @Getter private StandardOutputConfig basicOutputConfig = StandardOutputConfig.table();
- }
-
- @ReflectiveAccess
- public static class Disable extends AbstractUnirestOutputHelper {
- public static final String CMD_NAME = "disable";
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- @Getter @Mixin private StandardOutputWriterFactoryMixin outputWriterFactory;
- @Getter private StandardOutputConfig basicOutputConfig = StandardOutputConfig.table();
- }
-
- @ReflectiveAccess
- public static class Start extends AbstractUnirestOutputHelper {
- public static final String CMD_NAME = "start";
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- @Getter @Mixin private StandardOutputWriterFactoryMixin outputWriterFactory;
- @Getter private StandardOutputConfig basicOutputConfig = StandardOutputConfig.table();
- }
-
- @ReflectiveAccess
- public static class Pause extends AbstractUnirestOutputHelper {
- public static final String CMD_NAME = "pause";
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- @Getter @Mixin private StandardOutputWriterFactoryMixin outputWriterFactory;
- @Getter private StandardOutputConfig basicOutputConfig = StandardOutputConfig.table();
- }
-
- @ReflectiveAccess
- public static class Resume extends AbstractUnirestOutputHelper {
- public static final String CMD_NAME = "resume";
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- @Getter @Mixin private StandardOutputWriterFactoryMixin outputWriterFactory;
- @Getter private StandardOutputConfig basicOutputConfig = StandardOutputConfig.table();
- }
-
- @ReflectiveAccess
- public static class Cancel extends AbstractUnirestOutputHelper {
- public static final String CMD_NAME = "cancel";
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- @Getter @Mixin private StandardOutputWriterFactoryMixin outputWriterFactory;
- @Getter private StandardOutputConfig basicOutputConfig = StandardOutputConfig.table();
- }
-
- @ReflectiveAccess
- public static class Upload extends AbstractUnirestOutputHelper {
- public static final String CMD_NAME = "upload";
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- @Getter @Mixin private StandardOutputWriterFactoryMixin outputWriterFactory;
- @Getter private StandardOutputConfig basicOutputConfig = StandardOutputConfig.table();
- }
-
- @ReflectiveAccess
- public static class Download extends AbstractUnirestOutputHelper {
- public static final String CMD_NAME = "download";
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- @Getter @Mixin private StandardOutputWriterFactoryMixin outputWriterFactory;
- @Getter private StandardOutputConfig basicOutputConfig = StandardOutputConfig.table();
- }
-
- @ReflectiveAccess
- public static class Install extends AbstractUnirestOutputHelper {
- public static final String CMD_NAME = "install";
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- @Getter @Mixin private StandardOutputWriterFactoryMixin outputWriterFactory;
- @Getter private StandardOutputConfig basicOutputConfig = StandardOutputConfig.table();
- }
-
- @ReflectiveAccess
- public static class Uninstall extends AbstractUnirestOutputHelper {
- public static final String CMD_NAME = "uninstall";
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- @Getter @Mixin private StandardOutputWriterFactoryMixin outputWriterFactory;
- @Getter private StandardOutputConfig basicOutputConfig = StandardOutputConfig.table();
- }
-
- @ReflectiveAccess
- public static class Import extends AbstractUnirestOutputHelper {
- public static final String CMD_NAME = "import";
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- @Getter @Mixin private StandardOutputWriterFactoryMixin outputWriterFactory;
- @Getter private StandardOutputConfig basicOutputConfig = StandardOutputConfig.table();
- }
-
- @ReflectiveAccess
- public static class Export extends AbstractUnirestOutputHelper {
- public static final String CMD_NAME = "export";
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- @Getter @Mixin private StandardOutputWriterFactoryMixin outputWriterFactory;
- @Getter private StandardOutputConfig basicOutputConfig = StandardOutputConfig.table();
- }
-
- @ReflectiveAccess
- public static class Setup extends AbstractUnirestOutputHelper {
- public static final String CMD_NAME = "setup";
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- @Getter @Mixin private StandardOutputWriterFactoryMixin outputWriterFactory;
- @Getter private StandardOutputConfig basicOutputConfig = StandardOutputConfig.table();
- }
-
- @ReflectiveAccess @Command
- public static class Other extends AbstractUnirestOutputHelper {
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/cli/mixin/impl/OutputOptionsArgGroup.java b/fcli-common/src/main/java/com/fortify/cli/common/output/cli/mixin/impl/OutputOptionsArgGroup.java
deleted file mode 100644
index 03d22c4ae0..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/cli/mixin/impl/OutputOptionsArgGroup.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.fortify.cli.common.output.cli.mixin.impl;
-
-import com.fortify.cli.common.output.writer.output.standard.IOutputOptions;
-import com.fortify.cli.common.output.writer.output.standard.OutputFormatConfig;
-import com.fortify.cli.common.output.writer.output.standard.OutputFormatConfigConverter;
-import com.fortify.cli.common.output.writer.output.standard.VariableStoreConfig;
-import com.fortify.cli.common.output.writer.output.standard.VariableStoreConfigConverter;
-import com.fortify.cli.common.output.writer.output.standard.OutputFormatConfigConverter.OutputFormatIterable;
-
-import lombok.Getter;
-import picocli.CommandLine.Option;
-
-public final class OutputOptionsArgGroup implements IOutputOptions {
- @Option(names = {"-o", "--output"}, order=1, converter = OutputFormatConfigConverter.class, completionCandidates = OutputFormatIterable.class, paramLabel = "format[=]")
- @Getter private OutputFormatConfig outputFormatConfig;
-
- @Option(names = {"--store"}, order=1, converter = VariableStoreConfigConverter.class, paramLabel = "variableName[=]")
- @Getter private VariableStoreConfig variableStoreConfig;
-
- @Option(names = {"--output-to-file"}, order=7)
-
- @Getter private String outputFile;
-}
\ No newline at end of file
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/cli/mixin/impl/QueryOptionsArgGroup.java b/fcli-common/src/main/java/com/fortify/cli/common/output/cli/mixin/impl/QueryOptionsArgGroup.java
deleted file mode 100644
index deb266007f..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/cli/mixin/impl/QueryOptionsArgGroup.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package com.fortify.cli.common.output.cli.mixin.impl;
-
-import java.util.Collections;
-import java.util.List;
-
-import com.fortify.cli.common.output.query.IOutputQueriesSupplier;
-import com.fortify.cli.common.output.query.OutputQuery;
-import com.fortify.cli.common.output.query.OutputQueryConverter;
-
-import lombok.Getter;
-import picocli.CommandLine;
-
-public final class QueryOptionsArgGroup implements IOutputQueriesSupplier {
- @CommandLine.Option(names = {"-q", "--query"}, order=1, converter = OutputQueryConverter.class, paramLabel = "")
- @Getter private List outputQueries = Collections.emptyList();
-}
\ No newline at end of file
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/cli/mixin/package-info.java b/fcli-common/src/main/java/com/fortify/cli/common/output/cli/mixin/package-info.java
deleted file mode 100644
index 59902bba4c..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/cli/mixin/package-info.java
+++ /dev/null
@@ -1,5 +0,0 @@
-/**
- * This package contains classes used to configure command output options and associated functionality.
- */
-package com.fortify.cli.common.output.cli.mixin;
-
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/cli/mixin/spi/AbstractOutputHelper.java b/fcli-common/src/main/java/com/fortify/cli/common/output/cli/mixin/spi/AbstractOutputHelper.java
deleted file mode 100644
index 5bfe8b3f48..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/cli/mixin/spi/AbstractOutputHelper.java
+++ /dev/null
@@ -1,265 +0,0 @@
-package com.fortify.cli.common.output.cli.mixin.spi;
-
-import java.util.function.Consumer;
-import java.util.function.Function;
-import java.util.function.Supplier;
-import java.util.function.UnaryOperator;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fortify.cli.common.output.cli.mixin.UnirestOutputHelperMixins;
-import com.fortify.cli.common.output.cli.mixin.spi.unirest.IUnirestOutputHelper;
-import com.fortify.cli.common.output.spi.IBasicOutputConfigSupplier;
-import com.fortify.cli.common.output.spi.IOutputWriterFactorySupplier;
-import com.fortify.cli.common.output.spi.transform.IActionCommandResultSupplier;
-import com.fortify.cli.common.output.spi.transform.IInputTransformer;
-import com.fortify.cli.common.output.spi.transform.IInputTransformerSupplier;
-import com.fortify.cli.common.output.spi.transform.IRecordTransformer;
-import com.fortify.cli.common.output.spi.transform.IRecordTransformerSupplier;
-import com.fortify.cli.common.output.transform.fields.AddFieldsTransformer;
-import com.fortify.cli.common.output.writer.output.IOutputWriter;
-import com.fortify.cli.common.output.writer.output.IOutputWriterFactory;
-import com.fortify.cli.common.output.writer.output.standard.StandardOutputConfig;
-
-import io.micronaut.core.annotation.ReflectiveAccess;
-import picocli.CommandLine.Model.CommandSpec;
-
-@ReflectiveAccess
-public abstract class AbstractOutputHelper implements IOutputHelperBase {
-
- /**
- * Utility method for retrieving the command being invoked as the given
- * type, returning null if the command is not an instance of the given
- * type.
- */
- @Override
- public final T getCommandAs(Class asType) {
- return getAs(getCommand(), asType);
- }
-
- /**
- * Get the {@link CommandSpec} for the command being invoked.
- */
- @Override
- public final CommandSpec getCommandSpec() {
- CommandSpec mixee = getMixee();
- // mixee may represent an intermediate mixin rather than representing the actual command
- // so we use mixee.commandLine() if available to retrieve the CommandSpec for the actual
- // command.
- return mixee.commandLine()==null ? mixee : mixee.commandLine().getCommandSpec();
- }
-
- /**
- * This default implementation of {@link IUnirestOutputHelper#getBasicOutputConfig()}
- * tries to retrieve a basic output configuration from the command being invoked,
- * if it implements the {@link IBasicOutputConfigSupplier} interface. If the
- * command doesn't implement this interface, or if the
- * {@link IBasicOutputConfigSupplier#getBasicOutputConfig()} method returns null,
- * this method throws an exception. Note that most concrete {@link IUnirestOutputHelper}
- * implementations will override this method; this default implementation is
- * mostly used for {@link UnirestOutputHelperMixins.Other}.
- */
- @Override
- public StandardOutputConfig getBasicOutputConfig() {
- Object cmd = getCommand();
- return applyWithDefaultSupplier(cmd,
- IBasicOutputConfigSupplier.class, IBasicOutputConfigSupplier::getBasicOutputConfig,
- ()->{throw new IllegalStateException(cmd.getClass().getName()+" must implement IBasicOutputConfigSupplier, or use an IOutputHelper implementation that provides a basic output configuration");});
- }
-
- /**
- * This default implementation of {@link IUnirestOutputHelper#getOutputWriterFactory()}
- * tries to retrieve an {@link IOutputWriterFactory} instance from the command
- * being invoked, if it implements the {@link IOutputWriterFactorySupplier} interface.
- * If the command doesn't implement this interface, or if the
- * {@link IOutputWriterFactorySupplier#getOutputWriterFactory()} method returns null,
- * this method throws an exception. Note that most concrete {@link IUnirestOutputHelper}
- * implementations will override this method; this default implementation is
- * mostly used for {@link UnirestOutputHelperMixins.Other}.
- */
- @Override
- public IOutputWriterFactory getOutputWriterFactory() {
- Object cmd = getCommand();
- return applyWithDefaultSupplier(cmd,
- IOutputWriterFactorySupplier.class, IOutputWriterFactorySupplier::getOutputWriterFactory,
- ()->{throw new IllegalStateException(cmd.getClass().getName()+" must implement IOutputWriterFactorySupplier, or use an IOutputHelper implementation that provides an output factory");});
- }
-
- /**
- * This method retrieves an {@link IOutputWriterFactory} by calling the
- * {@link #getOutputWriterFactory()} method, then returns the {@link IOutputWriter}
- * returned by the {@link IOutputWriterFactory#createOutputWriter(StandardOutputConfig)}
- * method.
- * @return {@link IOutputWriter} instance retrieved from an {@link IOutputWriterFactory} instance
- */
- protected final IOutputWriter createOutputWriter() {
- return getOutputWriterFactory().createOutputWriter(getOutputConfig());
- }
-
- /**
- * Utility method for retrieving the command currently being invoked.
- * @return
- */
- protected final Object getCommand() {
- return getCommandSpec().userObject();
- }
-
- /**
- * This method returns an {@link StandardOutputConfig} instance that is
- * based on the basic output configuration returned by the
- * {@link #getBasicOutputConfig()} method, with input and record
- * transformers added by the {@link #addInputTransformersForCommand(StandardOutputConfig, Object)}
- * and {@link #addRecordTransformersForCommand(StandardOutputConfig, Object)} methods.
- * @return
- */
- protected final StandardOutputConfig getOutputConfig() {
- Object cmd = getCommand();
- StandardOutputConfig standardOutputConfig = getBasicOutputConfig(cmd);
- addInputTransformersForCommand(standardOutputConfig, cmd);
- addRecordTransformersForCommand(standardOutputConfig, cmd);
- addCommandActionResultRecordTransformer(standardOutputConfig, cmd);
- return standardOutputConfig;
- }
-
- protected abstract void addRecordTransformersForCommand(StandardOutputConfig standardOutputConfig, Object cmd);
-
- protected abstract void addInputTransformersForCommand(StandardOutputConfig standardOutputConfig, Object cmd);
-
- protected abstract CommandSpec getMixee();
-
- /**
- * If the command being invoked implements {@link IBasicOutputConfigSupplier}, the
- * {@link IBasicOutputConfigSupplier#getBasicOutputConfig()} method is called on the
- * command to retrieve the command-specific basic output configuration. If the
- * command doesn't implement {@link IBasicOutputConfigSupplier}, or if the
- * {@link IBasicOutputConfigSupplier#getBasicOutputConfig()} method provided by the
- * command returns null, the {@link #getBasicOutputConfig()} method in this class
- * will be called to retrieve the basic output configuration.
- * @param cmd
- * @return
- */
- private final StandardOutputConfig getBasicOutputConfig(Object cmd) {
- return applyWithDefaultSupplier(cmd, IBasicOutputConfigSupplier.class, IBasicOutputConfigSupplier::getBasicOutputConfig, this::getBasicOutputConfig);
- }
-
- /**
- * Utility method for getting the given object as the given type,
- * returning null if the given object is not an instance of the
- * given type.
- * @param
- * @param obj
- * @param asType
- * @return
- */
- @SuppressWarnings("unchecked")
- protected static final T getAs(Object obj, Class asType) {
- if ( obj!=null && asType.isAssignableFrom(obj.getClass()) ) {
- return (T)obj;
- }
- return null;
- }
-
- /**
- * Utility method for calling the given consumer if the given object is
- * an instance of the given type.
- * @param
- * @param obj
- * @param type
- * @param consumer
- */
- protected static final void accept(Object obj, Class type, Consumer consumer) {
- T target = getAs(obj, type);
- if ( target!=null ) { consumer.accept(target); }
- }
-
- /**
- * Utility method for applying the given function on the given object and
- * returning the result, if the given object is an instance of the given
- * type. If the given object is not of the given type, or if the provided
- * function returns null, this method returns the value returned by the
- * given defaultValueSupplier if it is not null. Otherwise, this method
- * returns null.
- * @param
- * @param
- * @param obj
- * @param type
- * @param function
- * @param defaultValueSupplier
- * @return
- */
- protected static final R applyWithDefaultSupplier(Object obj, Class type, Function function, Supplier defaultValueSupplier) {
- T target = getAs(obj, type);
- R result = target==null ? null : function.apply(target);
- if ( result==null && defaultValueSupplier!=null ) {
- result = defaultValueSupplier.get();
- }
- return result;
- }
-
- /**
- * Utility method for applying the given function on the given object and
- * returning the result, if the given object is an instance of the given
- * type. If the given object is not of the given type, or if the provided
- * function returns null, this method returns the provided default value.
- * @param
- * @param
- * @param obj
- * @param type
- * @param function
- * @param defaultValue
- * @return
- */
- protected static final R applyWithDefault(Object obj, Class type, Function function, R defaultValue) {
- return applyWithDefaultSupplier(obj, type, function, ()->defaultValue);
- }
-
- /**
- * Utility method for applying the given function on the given object and
- * returning the result, if the given object is an instance of the given
- * type. If the given object is not of the given type, or if the provided
- * function returns null, this method returns null.
- * @param
- * @param
- * @param obj
- * @param type
- * @param function
- * @return
- */
- protected static final R apply(Object obj, Class type, Function function) {
- return applyWithDefaultSupplier(obj, type, function, null);
- }
-
- /**
- * This method adds record transformers from the given object if it implements {@link IRecordTransformerSupplier}
- * or {@link IRecordTransformer}. Usually an object would implement only one of those interfaces,
- * but if both interfaces are implemented, {@link IRecordTransformerSupplier}-based transformations
- * will run before {@link IRecordTransformer}-based transformations.
- * @param standardOutputConfig
- * @param obj
- */
- protected static final void addRecordTransformersFromObject(StandardOutputConfig standardOutputConfig, Object obj) {
- apply(obj, IRecordTransformerSupplier.class, s->standardOutputConfig.recordTransformer(s.getRecordTransformer()));
- apply(obj, IRecordTransformer.class, s->standardOutputConfig.recordTransformer(s::transformRecord));
- }
-
- /**
- * This method adds input transformers from the given object if it implements {@link IInputTransformerSupplier}
- * or {@link IInputTransformer}. Usually an object would implement only one of those interfaces,
- * but if both interfaces are implemented, {@link IInputTransformerSupplier}-based transformations
- * will run before {@link IInputTransformer}-based transformations.
- * @param standardOutputConfig
- * @param obj
- */
- protected static final void addInputTransformersFromObject(StandardOutputConfig standardOutputConfig, Object obj) {
- apply(obj, IInputTransformerSupplier.class, s->standardOutputConfig.inputTransformer(s.getInputTransformer()));
- apply(obj, IInputTransformer.class, s->standardOutputConfig.inputTransformer(s::transformInput));
- }
-
- protected static final void addCommandActionResultRecordTransformer(StandardOutputConfig standardOutputConfig, Object cmd) {
- apply(cmd, IActionCommandResultSupplier.class, s->standardOutputConfig.recordTransformer(createCommandActionResultRecordTransformer(s)));
- }
-
- private static final UnaryOperator createCommandActionResultRecordTransformer(IActionCommandResultSupplier supplier) {
- return new AddFieldsTransformer(IActionCommandResultSupplier.actionFieldName, supplier.getActionCommandResult()).overwiteExisting(false)::transform;
- }
-
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/cli/mixin/spi/IOutputHelperBase.java b/fcli-common/src/main/java/com/fortify/cli/common/output/cli/mixin/spi/IOutputHelperBase.java
deleted file mode 100644
index 8742d1d57d..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/cli/mixin/spi/IOutputHelperBase.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.fortify.cli.common.output.cli.mixin.spi;
-
-import com.fortify.cli.common.output.spi.IBasicOutputConfigSupplier;
-import com.fortify.cli.common.output.spi.IOutputWriterFactorySupplier;
-
-import picocli.CommandLine.Model.CommandSpec;
-
-public interface IOutputHelperBase extends IBasicOutputConfigSupplier, IOutputWriterFactorySupplier {
- CommandSpec getCommandSpec();
- T getCommandAs(Class asType);
-}
\ No newline at end of file
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/cli/mixin/spi/basic/AbstractBasicOutputHelper.java b/fcli-common/src/main/java/com/fortify/cli/common/output/cli/mixin/spi/basic/AbstractBasicOutputHelper.java
deleted file mode 100644
index b3280af241..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/cli/mixin/spi/basic/AbstractBasicOutputHelper.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package com.fortify.cli.common.output.cli.mixin.spi.basic;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fortify.cli.common.output.cli.mixin.spi.AbstractOutputHelper;
-import com.fortify.cli.common.output.spi.IBasicOutputConfigSupplier;
-import com.fortify.cli.common.output.spi.product.IProductHelper;
-import com.fortify.cli.common.output.writer.output.standard.StandardOutputConfig;
-
-import io.micronaut.core.annotation.ReflectiveAccess;
-
-@ReflectiveAccess
-public abstract class AbstractBasicOutputHelper extends AbstractOutputHelper implements IBasicOutputHelper {
- /**
- * Write the given {@link JsonNode} using the output writer created by the
- * {@link #createOutputWriter()} method.
- */
- @Override
- public final void write(JsonNode jsonNode) {
- createOutputWriter().write(jsonNode);
- }
-
- /**
- * This method adds record transformers to the given {@link StandardOutputConfig} by
- * calling the following methods, in this order:
- *
- * - {@link #addRecordTransformersFromObject(StandardOutputConfig, Object)} with the command being invoked
- * - {@link #addCommandActionResultRecordTransformer(StandardOutputConfig, Object)} with the command being invoked
- *
- * If a command needs to run any record transformations before the record transformations provided by
- * {@link IProductHelper}, the command should implement the {@link IBasicOutputConfigSupplier} interface
- * to add those record transformations to the basic output configuration.
- * @param standardOutputConfig
- * @param cmd
- */
- protected final void addRecordTransformersForCommand(StandardOutputConfig standardOutputConfig, Object cmd) {
- addRecordTransformersFromObject(standardOutputConfig, cmd);
- addCommandActionResultRecordTransformer(standardOutputConfig, cmd);
- }
-
- /**
- * This method adds input transformers to the given {@link StandardOutputConfig} by
- * calling the following methods, in this order:
- *
- * - {@link #addInputTransformersFromObject(StandardOutputConfig, Object)} with the command being invoked
- *
- * If a command needs to run any input transformations before the input transformations provided by
- * {@link IProductHelper}, the command should implement the {@link IBasicOutputConfigSupplier} interface
- * to add those input transformations to the basic output configuration.
- * @param standardOutputConfig
- * @param cmd
- */
- protected final void addInputTransformersForCommand(StandardOutputConfig standardOutputConfig, Object cmd) {
- addInputTransformersFromObject(standardOutputConfig, cmd);
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/cli/mixin/spi/basic/IBasicOutputHelper.java b/fcli-common/src/main/java/com/fortify/cli/common/output/cli/mixin/spi/basic/IBasicOutputHelper.java
deleted file mode 100644
index d79147dd79..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/cli/mixin/spi/basic/IBasicOutputHelper.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package com.fortify.cli.common.output.cli.mixin.spi.basic;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fortify.cli.common.output.cli.mixin.spi.IOutputHelperBase;
-
-public interface IBasicOutputHelper extends IOutputHelperBase {
- void write(JsonNode jsonNode);
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/cli/mixin/spi/unirest/AbstractUnirestOutputHelper.java b/fcli-common/src/main/java/com/fortify/cli/common/output/cli/mixin/spi/unirest/AbstractUnirestOutputHelper.java
deleted file mode 100644
index 3ba097ec6c..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/cli/mixin/spi/unirest/AbstractUnirestOutputHelper.java
+++ /dev/null
@@ -1,189 +0,0 @@
-package com.fortify.cli.common.output.cli.mixin.spi.unirest;
-
-import java.lang.reflect.InvocationTargetException;
-import java.util.Objects;
-import java.util.function.Function;
-import java.util.stream.Stream;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fortify.cli.common.json.JsonNodeHolder;
-import com.fortify.cli.common.output.cli.mixin.spi.AbstractOutputHelper;
-import com.fortify.cli.common.output.spi.IBasicOutputConfigSupplier;
-import com.fortify.cli.common.output.spi.product.IProductHelper;
-import com.fortify.cli.common.output.spi.product.ProductHelperClass;
-import com.fortify.cli.common.output.spi.request.IHttpRequestUpdater;
-import com.fortify.cli.common.output.spi.request.INextPageUrlProducerSupplier;
-import com.fortify.cli.common.output.writer.output.IOutputWriter;
-import com.fortify.cli.common.output.writer.output.standard.StandardOutputConfig;
-import com.fortify.cli.common.rest.paging.INextPageUrlProducer;
-
-import io.micronaut.core.annotation.ReflectiveAccess;
-import kong.unirest.HttpRequest;
-import kong.unirest.UnirestInstance;
-import lombok.Getter;
-
-@ReflectiveAccess
-public abstract class AbstractUnirestOutputHelper extends AbstractOutputHelper implements IUnirestOutputHelper {
- @Getter private final IProductHelper productHelper;
-
- /**
- * This constructor creates an {@link IProductHelper} instance based on
- * the {@link ProductHelperClass} annotation on either the concrete
- * subclass of {@link AbstractUnirestOutputHelper}, or its enclosing class.
- * The {@link IProductHelper} instance is then configured with this
- * {@link IUnirestOutputHelper} instance.
- */
- public AbstractUnirestOutputHelper() {
- Class> clazz = this.getClass();
- Class> enclosingClass = clazz.getEnclosingClass();
- ProductHelperClass productHelperClassAnnotation = clazz.getAnnotation(ProductHelperClass.class);
- if ( productHelperClassAnnotation==null && enclosingClass!=null ) {
- productHelperClassAnnotation = enclosingClass.getAnnotation(ProductHelperClass.class);
- }
- if ( productHelperClassAnnotation==null ) {
- throw new RuntimeException(this.getClass().getName()+" or its enclosing class must have the @ProductHelper annotation");
- }
- Class extends IProductHelper> productHelperClass = productHelperClassAnnotation.value();
- try {
- this.productHelper = productHelperClass.getDeclaredConstructor().newInstance();
- this.productHelper.setOutputHelper(this);
- } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) {
- throw new RuntimeException("Error instantiating product helper class "+productHelperClass.getName(), e);
- }
- }
-
- /**
- * Write output based on the given {@link UnirestInstance} and base {@link HttpRequest}.
- * This method updates the given base {@link HttpRequest} by calling the
- * {@link #updateRequest(UnirestInstance, HttpRequest)} method, and retrieves a next page
- * producer by calling the {@link #getNextPageUrlProducer(UnirestInstance, HttpRequest)}
- * method. The (potentially) updated request and next page producer are then passed to
- * the {@link IOutputWriter} created by the {@link #createOutputWriter()} method, which
- * in turn will execute the request, handling paging if necessary, and write the response
- * data.
- */
- @Override
- public final void write(UnirestInstance unirest, HttpRequest> baseRequest) {
- HttpRequest> request = updateRequest(unirest, baseRequest);
- INextPageUrlProducer nextPageUrlProducer = getNextPageUrlProducer(unirest, request);
- createOutputWriter().write(request, nextPageUrlProducer);
- }
-
- /**
- * Write the given {@link JsonNode} using the output writer created by the
- * {@link #createOutputWriter()} method. Obviously, this method will not
- * provide any of the {@link HttpRequest}-based functionality as provided
- * by the {@link #write(UnirestInstance, HttpRequest)} method, as there is
- * no {@link HttpRequest} to be updated or to apply paging on. Although not
- * currently used, this method accepts a {@link UnirestInstance} to be
- * consistent with {@link #write(UnirestInstance, HttpRequest)}, and just in
- * case we ever need it for future functionality.
- */
- @Override
- public final void write(UnirestInstance unirest, JsonNode jsonNode) {
- createOutputWriter().write(jsonNode);
- }
-
- /**
- * This method simply gets a {@link JsonNode} instance from the given {@link JsonNodeHolder},
- * then calls the {@link #write(UnirestInstance, JsonNode)} method to write this
- * {@link JsonNode} instance to the output.
- */
- @Override
- public final void write(UnirestInstance unirest, JsonNodeHolder jsonNodeHolder) {
- write(unirest, jsonNodeHolder.asJsonNode());
- }
-
- /**
- * This method updates the given base {@link HttpRequest} by calling the
- * {@link IHttpRequestUpdater#updateRequest(UnirestInstance, HttpRequest)} method
- * on the configured {@link IProductHelper} and on the command currently being
- * invoked, in this order, if they implement the {@link IHttpRequestUpdater} interface.
- * @param unirest
- * @param baseRequest
- * @return
- */
- protected final HttpRequest> updateRequest(UnirestInstance unirest, HttpRequest> request) {
- request = applyWithDefault(getProductHelper(), IHttpRequestUpdater.class, httpRequestUpdater(unirest, request), request);
- request = applyWithDefault(getCommand(), IHttpRequestUpdater.class, httpRequestUpdater(unirest, request), request);
- return request;
- }
-
- /**
- * This method returns a next page url producer retrieved from either the command
- * being invoked, or the configured {@link IProductHelper}, in this order, if
- * they implement the {@link INextPageUrlProducerSupplier} interface.
- * @param unirest
- * @param request
- * @return
- */
- protected final INextPageUrlProducer getNextPageUrlProducer(UnirestInstance unirest, HttpRequest> request) {
- return Stream.of(getCommand(), getProductHelper())
- .map(obj->getNextPageUrlProducerFromObject(obj, unirest, request))
- .filter(Objects::nonNull)
- .findFirst().orElse(null);
- }
-
- /**
- * This method adds record transformers to the given {@link StandardOutputConfig} by
- * calling the following methods, in this order:
- *
- * - {@link #addRecordTransformersFromObject(StandardOutputConfig, Object)} with the configured {@link IProductHelper}
- * - {@link #addRecordTransformersFromObject(StandardOutputConfig, Object)} with the command being invoked
- * - {@link #addCommandActionResultRecordTransformer(StandardOutputConfig, Object)} with the command being invoked
- *
- * If a command needs to run any record transformations before the record transformations provided by
- * {@link IProductHelper}, the command should implement the {@link IBasicOutputConfigSupplier} interface
- * to add those record transformations to the basic output configuration.
- * @param standardOutputConfig
- * @param cmd
- */
- protected final void addRecordTransformersForCommand(StandardOutputConfig standardOutputConfig, Object cmd) {
- addRecordTransformersFromObject(standardOutputConfig, getProductHelper());
- addRecordTransformersFromObject(standardOutputConfig, cmd);
- addCommandActionResultRecordTransformer(standardOutputConfig, cmd);
- }
-
- /**
- * This method adds input transformers to the given {@link StandardOutputConfig} by
- * calling the following methods, in this order:
- *
- * - {@link #addInputTransformersFromObject(StandardOutputConfig, Object)} with the configured {@link IProductHelper}
- * - {@link #addInputTransformersFromObject(StandardOutputConfig, Object)} with the command being invoked
- *
- * If a command needs to run any input transformations before the input transformations provided by
- * {@link IProductHelper}, the command should implement the {@link IBasicOutputConfigSupplier} interface
- * to add those input transformations to the basic output configuration.
- * @param standardOutputConfig
- * @param cmd
- */
- protected final void addInputTransformersForCommand(StandardOutputConfig standardOutputConfig, Object cmd) {
- addInputTransformersFromObject(standardOutputConfig, getProductHelper());
- addInputTransformersFromObject(standardOutputConfig, cmd);
- }
-
- /**
- * Utility method used by {@link #updateRequest(UnirestInstance, HttpRequest)}, returning a function
- * that takes an {@link IHttpRequestUpdater} instance and returning the result of
- * {@link IHttpRequestUpdater#updateRequest(UnirestInstance, HttpRequest)}.
- * @param unirest
- * @param request
- * @return
- */
- private static final Function> httpRequestUpdater(UnirestInstance unirest, final HttpRequest> request) {
- return requestUpdater -> requestUpdater.updateRequest(unirest, request);
- }
-
- /**
- * Utility method used by {@link #getNextPageUrlProducer(UnirestInstance, HttpRequest)}, returning a
- * next page producer retrieved from the given object if that object implements {@link INextPageUrlProducerSupplier},
- * or null otherwise.
- * @param obj
- * @param unirest
- * @param request
- * @return
- */
- private static final INextPageUrlProducer getNextPageUrlProducerFromObject(Object obj, UnirestInstance unirest, final HttpRequest> request) {
- return apply(obj, INextPageUrlProducerSupplier.class, supplier->supplier.getNextPageUrlProducer(unirest, request));
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/cli/mixin/spi/unirest/IUnirestOutputHelper.java b/fcli-common/src/main/java/com/fortify/cli/common/output/cli/mixin/spi/unirest/IUnirestOutputHelper.java
deleted file mode 100644
index 28c7436851..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/cli/mixin/spi/unirest/IUnirestOutputHelper.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package com.fortify.cli.common.output.cli.mixin.spi.unirest;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fortify.cli.common.json.JsonNodeHolder;
-import com.fortify.cli.common.output.cli.mixin.spi.IOutputHelperBase;
-import com.fortify.cli.common.output.spi.product.IProductHelper;
-
-import kong.unirest.HttpRequest;
-import kong.unirest.UnirestInstance;
-
-public interface IUnirestOutputHelper extends IOutputHelperBase {
- IProductHelper getProductHelper();
- void write(UnirestInstance unirest, HttpRequest> baseRequest);
- void write(UnirestInstance unirest, JsonNodeHolder jsonNodeHolder);
- void write(UnirestInstance unirest, JsonNode jsonNode);
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/cli/mixin/writer/OutputWriterWithQueryFactoryMixin.java b/fcli-common/src/main/java/com/fortify/cli/common/output/cli/mixin/writer/OutputWriterWithQueryFactoryMixin.java
deleted file mode 100644
index 9622f41f99..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/cli/mixin/writer/OutputWriterWithQueryFactoryMixin.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package com.fortify.cli.common.output.cli.mixin.writer;
-
-import java.util.List;
-
-import com.fortify.cli.common.output.cli.mixin.impl.OutputOptionsArgGroup;
-import com.fortify.cli.common.output.cli.mixin.impl.QueryOptionsArgGroup;
-import com.fortify.cli.common.output.query.IOutputQueriesSupplier;
-import com.fortify.cli.common.output.query.OutputQuery;
-import com.fortify.cli.common.output.writer.output.IOutputWriter;
-import com.fortify.cli.common.output.writer.output.IOutputWriterFactory;
-import com.fortify.cli.common.output.writer.output.query.OutputWriterWithQuery;
-import com.fortify.cli.common.output.writer.output.standard.StandardOutputConfig;
-
-import io.micronaut.core.annotation.ReflectiveAccess;
-import lombok.Getter;
-import lombok.Setter;
-import picocli.CommandLine.ArgGroup;
-import picocli.CommandLine.Model.CommandSpec;
-import picocli.CommandLine.Spec;
-import picocli.CommandLine.Spec.Target;
-
-@ReflectiveAccess
-public class OutputWriterWithQueryFactoryMixin implements IOutputWriterFactory, IOutputQueriesSupplier {
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- @ArgGroup(headingKey = "arggroup.output.heading", exclusive = false, order=30)
- private OutputOptionsArgGroup outputOptionsArgGroup = new OutputOptionsArgGroup();
- @ArgGroup(headingKey = "arggroup.query.heading", exclusive = false, order=40)
- private QueryOptionsArgGroup queryOptionsArgGroup = new QueryOptionsArgGroup();
-
- @Override
- public List getOutputQueries() {
- return queryOptionsArgGroup.getOutputQueries();
- }
-
- @Override
- public IOutputWriter createOutputWriter(StandardOutputConfig defaultOutputConfig) {
- return new OutputWriterWithQuery(mixee, outputOptionsArgGroup, queryOptionsArgGroup, defaultOutputConfig);
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/cli/mixin/writer/StandardOutputWriterFactoryMixin.java b/fcli-common/src/main/java/com/fortify/cli/common/output/cli/mixin/writer/StandardOutputWriterFactoryMixin.java
deleted file mode 100644
index 3eac64f074..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/cli/mixin/writer/StandardOutputWriterFactoryMixin.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package com.fortify.cli.common.output.cli.mixin.writer;
-
-import com.fortify.cli.common.output.cli.mixin.impl.OutputOptionsArgGroup;
-import com.fortify.cli.common.output.writer.output.IOutputWriter;
-import com.fortify.cli.common.output.writer.output.IOutputWriterFactory;
-import com.fortify.cli.common.output.writer.output.standard.StandardOutputConfig;
-import com.fortify.cli.common.output.writer.output.standard.StandardOutputWriter;
-
-import io.micronaut.core.annotation.ReflectiveAccess;
-import lombok.Getter;
-import lombok.Setter;
-import picocli.CommandLine.ArgGroup;
-import picocli.CommandLine.Model.CommandSpec;
-import picocli.CommandLine.Spec;
-import picocli.CommandLine.Spec.Target;
-
-@ReflectiveAccess
-public class StandardOutputWriterFactoryMixin implements IOutputWriterFactory {
- @Getter @Setter(onMethod=@__({@Spec(Target.MIXEE)})) private CommandSpec mixee;
- @ArgGroup(headingKey = "arggroup.output.heading", exclusive = false, order=30)
- private OutputOptionsArgGroup outputOptionsArgGroup = new OutputOptionsArgGroup();
-
- @Override
- public IOutputWriter createOutputWriter(StandardOutputConfig defaultOutputConfig) {
- return new StandardOutputWriter(mixee, outputOptionsArgGroup, defaultOutputConfig);
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/query/IJsonNodeMatcher.java b/fcli-common/src/main/java/com/fortify/cli/common/output/query/IJsonNodeMatcher.java
deleted file mode 100644
index 3dc3275f29..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/query/IJsonNodeMatcher.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package com.fortify.cli.common.output.query;
-
-import com.fasterxml.jackson.databind.JsonNode;
-
-@FunctionalInterface
-public interface IJsonNodeMatcher {
- public boolean matches(JsonNode input, String propertyPath, String valueToMatch);
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/query/IOutputQueriesSupplier.java b/fcli-common/src/main/java/com/fortify/cli/common/output/query/IOutputQueriesSupplier.java
deleted file mode 100644
index 63a020c950..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/query/IOutputQueriesSupplier.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.fortify.cli.common.output.query;
-
-import java.util.List;
-
-public interface IOutputQueriesSupplier {
- List getOutputQueries();
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/query/OutputQuery.java b/fcli-common/src/main/java/com/fortify/cli/common/output/query/OutputQuery.java
deleted file mode 100644
index 6eeacfc743..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/query/OutputQuery.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package com.fortify.cli.common.output.query;
-
-import com.fasterxml.jackson.databind.JsonNode;
-
-import lombok.Data;
-
-@Data
-public final class OutputQuery {
- private final String propertyPath;
- private final OutputQueryOperator operator;
- private final String valueToMatch;
-
- public final boolean matches(JsonNode node) {
- return operator.matches(node, propertyPath, valueToMatch);
- }
-}
\ No newline at end of file
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/query/OutputQueryConverter.java b/fcli-common/src/main/java/com/fortify/cli/common/output/query/OutputQueryConverter.java
deleted file mode 100644
index 0d0a7406a1..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/query/OutputQueryConverter.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package com.fortify.cli.common.output.query;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import picocli.CommandLine.ITypeConverter;
-
-public class OutputQueryConverter implements ITypeConverter {
- private static final Pattern QUERY_PATTERN = generateQueryPattern();
-
- @Override
- public OutputQuery convert(String value) throws Exception {
- Matcher m = QUERY_PATTERN.matcher(value);
- if ( !m.matches() ) {
- throw new IllegalArgumentException("Query expression '"+value+"' doesn't match pattern "+QUERY_PATTERN.pattern());
- } else {
- String propertyPath = m.group(1)!=null ? m.group(1) : m.group(2);
- OutputQueryOperator operator = OutputQueryOperator.valueOfOperator(m.group(3));
- String valueToMatch = m.group(4);
- return new OutputQuery(propertyPath, operator, valueToMatch);
- }
- }
-
- private static final Pattern generateQueryPattern() {
- // Match either any (JSON path) expression embedded in curly braces, or a simple (nested) property path,
- // followed by any of the available operators, followed by the value to be matched.
- String patternString = String.format("^(?:(?:\\{(.+?)\\})|([a-zA-Z0-9\\.]+?))(%s){1}+(.+?)$", generateOperatorsPattern());
- return Pattern.compile(patternString);
- }
-
- private static final String generateOperatorsPattern() {
- return String.join("|", OutputQueryOperator.operators());
- }
-
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/query/OutputQueryHelper.java b/fcli-common/src/main/java/com/fortify/cli/common/output/query/OutputQueryHelper.java
deleted file mode 100644
index 169b73691a..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/query/OutputQueryHelper.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package com.fortify.cli.common.output.query;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.stream.Collectors;
-
-import com.fortify.cli.common.output.cli.mixin.spi.unirest.IUnirestOutputHelper;
-import com.fortify.cli.common.output.cli.mixin.writer.OutputWriterWithQueryFactoryMixin;
-import com.fortify.cli.common.output.writer.output.IOutputWriterFactory;
-
-public class OutputQueryHelper {
- private final List outputQueries;
-
- public OutputQueryHelper(IUnirestOutputHelper unirestOutputHelper) {
- this(unirestOutputHelper.getOutputWriterFactory());
- }
-
- public OutputQueryHelper(IOutputWriterFactory outputWriterFactory) {
- if ( outputWriterFactory instanceof OutputWriterWithQueryFactoryMixin ) {
- this.outputQueries = ((OutputWriterWithQueryFactoryMixin)outputWriterFactory).getOutputQueries();
- } else {
- this.outputQueries = null;
- }
- }
-
- public List getOutputQueries() {
- return outputQueries==null ? Collections.emptyList() : Collections.unmodifiableList(outputQueries);
- }
-
- public List getOutputQueries(String propertyPath) {
- return getOutputQueries().stream()
- .filter(q->propertyPath.equals(q.getPropertyPath()))
- .collect(Collectors.toList());
- }
-
- public String getQueryValue(String propertyPath, OutputQueryOperator operator) {
- List result = getOutputQueries(propertyPath).stream()
- .filter(q->operator.equals(q.getOperator()))
- .map(OutputQuery::getValueToMatch)
- .collect(Collectors.toList());
- if ( result.size()>1 ) {
- throw new IllegalArgumentException("Multiple comparison values specified for property "+propertyPath+" and operator "+operator.getOperator());
- }
- return result.isEmpty() ? null : result.get(0);
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/query/OutputQueryOperator.java b/fcli-common/src/main/java/com/fortify/cli/common/output/query/OutputQueryOperator.java
deleted file mode 100644
index 74a56121eb..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/query/OutputQueryOperator.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package com.fortify.cli.common.output.query;
-
-import java.util.stream.Stream;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fortify.cli.common.json.JsonHelper;
-
-import lombok.Getter;
-import lombok.RequiredArgsConstructor;
-
-@RequiredArgsConstructor
-public enum OutputQueryOperator implements IJsonNodeMatcher {
- EQUALS("=", OutputQueryOperator::evaluateEquals);
-
- @Getter private final String operator;
- private final IJsonNodeMatcher matcher;
-
- @Override
- public boolean matches(JsonNode input, String propertyPath, String valueToMatch) {
- return matcher.matches(input, propertyPath, valueToMatch);
- }
-
- public static final String[] operators() {
- return Stream.of(OutputQueryOperator.values()).map(OutputQueryOperator::getOperator).toArray(String[]::new);
- }
-
- public static final OutputQueryOperator valueOfOperator(String operator) {
- return Stream.of(OutputQueryOperator.values())
- .filter(o->o.getOperator().equalsIgnoreCase(operator))
- .findFirst()
- .orElseThrow(()->new IllegalArgumentException("Unknown query operator '"+operator+"'"));
- }
-
- private static Boolean evaluateEquals(JsonNode node, String propertyPath, String valueToMatch) {
- return valueToMatch.equals(JsonHelper.evaluateJsonPath(node, propertyPath, String.class));
- }
-}
\ No newline at end of file
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/spi/IBasicOutputConfigSupplier.java b/fcli-common/src/main/java/com/fortify/cli/common/output/spi/IBasicOutputConfigSupplier.java
deleted file mode 100644
index 3d73aaef16..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/spi/IBasicOutputConfigSupplier.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.fortify.cli.common.output.spi;
-
-import com.fortify.cli.common.output.cli.mixin.spi.basic.AbstractBasicOutputHelper;
-import com.fortify.cli.common.output.cli.mixin.spi.unirest.AbstractUnirestOutputHelper;
-import com.fortify.cli.common.output.writer.output.standard.IOutputConfigSupplier;
-import com.fortify.cli.common.output.writer.output.standard.StandardOutputConfig;
-
-/**
- * Interface for supplying a basic output configuration which may not have
- * been fully configured yet. For example, {@link AbstractBasicOutputHelper}
- * and {@link AbstractUnirestOutputHelper} will update the basic output
- * configuration, like adding transformers from various sources.
- *
- * Note that this interface is very similar to {@link IOutputConfigSupplier},
- * but has a different purpose.
- *
- * @author rsenden
- *
- */
-public interface IBasicOutputConfigSupplier {
- StandardOutputConfig getBasicOutputConfig();
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/spi/IOutputWriterFactorySupplier.java b/fcli-common/src/main/java/com/fortify/cli/common/output/spi/IOutputWriterFactorySupplier.java
deleted file mode 100644
index ff8207c1d6..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/spi/IOutputWriterFactorySupplier.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.fortify.cli.common.output.spi;
-
-import com.fortify.cli.common.output.writer.output.IOutputWriterFactory;
-
-public interface IOutputWriterFactorySupplier {
- IOutputWriterFactory getOutputWriterFactory();
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/spi/ISingularSupplier.java b/fcli-common/src/main/java/com/fortify/cli/common/output/spi/ISingularSupplier.java
deleted file mode 100644
index c9084b0500..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/spi/ISingularSupplier.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package com.fortify.cli.common.output.spi;
-
-public interface ISingularSupplier {
- boolean isSingular();
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/spi/product/IProductHelper.java b/fcli-common/src/main/java/com/fortify/cli/common/output/spi/product/IProductHelper.java
deleted file mode 100644
index 0616247cf0..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/spi/product/IProductHelper.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.fortify.cli.common.output.spi.product;
-
-import com.fortify.cli.common.output.cli.mixin.spi.unirest.IUnirestOutputHelper;
-
-public interface IProductHelper {
- void setOutputHelper(IUnirestOutputHelper unirestOutputHelper);
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/spi/product/ProductHelperClass.java b/fcli-common/src/main/java/com/fortify/cli/common/output/spi/product/ProductHelperClass.java
deleted file mode 100644
index a1f5fb3eed..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/spi/product/ProductHelperClass.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.fortify.cli.common.output.spi.product;
-
-import static java.lang.annotation.ElementType.*;
-import static java.lang.annotation.RetentionPolicy.*;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-@Retention(RUNTIME)
-@Target(TYPE)
-public @interface ProductHelperClass {
- Class extends IProductHelper> value();
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/spi/request/IHttpRequestUpdater.java b/fcli-common/src/main/java/com/fortify/cli/common/output/spi/request/IHttpRequestUpdater.java
deleted file mode 100644
index b504b9492a..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/spi/request/IHttpRequestUpdater.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package com.fortify.cli.common.output.spi.request;
-
-import kong.unirest.HttpRequest;
-import kong.unirest.UnirestInstance;
-
-public interface IHttpRequestUpdater {
- HttpRequest> updateRequest(UnirestInstance unirest, HttpRequest> request);
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/spi/request/INextPageUrlProducerSupplier.java b/fcli-common/src/main/java/com/fortify/cli/common/output/spi/request/INextPageUrlProducerSupplier.java
deleted file mode 100644
index c075f735b5..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/spi/request/INextPageUrlProducerSupplier.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.fortify.cli.common.output.spi.request;
-
-import com.fortify.cli.common.rest.paging.INextPageUrlProducer;
-
-import kong.unirest.HttpRequest;
-import kong.unirest.UnirestInstance;
-
-public interface INextPageUrlProducerSupplier {
- INextPageUrlProducer getNextPageUrlProducer(UnirestInstance unirest, HttpRequest> originalRequest);
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/spi/transform/IActionCommandResultSupplier.java b/fcli-common/src/main/java/com/fortify/cli/common/output/spi/transform/IActionCommandResultSupplier.java
deleted file mode 100644
index 226b8853b0..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/spi/transform/IActionCommandResultSupplier.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package com.fortify.cli.common.output.spi.transform;
-
-import com.fortify.cli.common.output.writer.record.AbstractFormattedRecordWriter;
-import com.fortify.cli.common.output.writer.record.RecordWriterConfig;
-
-/**
- * This interface can be implemented by commands to return the action
- * that was performed. If provided, this will result in an {@code __action__}
- * property being added to every output record being processed.
- * The value returned by the {@link #getActionCommandResult()} method
- * should usually be in one of the following formats:
- *
- * - Past tense of the command name in upper case, i.e. "DELETED", if
- * the remote system performs the requested actions immediately
- * - Command name in upper case followed by "_REQUESTED", i.e.
- * "DELETE_REQUESTED", if the remote system performs the requested
- * actions in the background, in which case the actions may not have
- * been completed yet by the time we output the results.
- *
- * {@link AbstractFormattedRecordWriter} automatically adds __action__ as
- * a field to the output format options if {@link RecordWriterConfig#isAddActionColumn()}
- * is set to true, so no need to manually add this column to (default)
- * output options.
- * @author rsenden
- *
- */
-public interface IActionCommandResultSupplier {
- public static final String actionFieldName = "__action__";
- public String getActionCommandResult();
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/spi/transform/IInputTransformer.java b/fcli-common/src/main/java/com/fortify/cli/common/output/spi/transform/IInputTransformer.java
deleted file mode 100644
index 4de0ca7e59..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/spi/transform/IInputTransformer.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.fortify.cli.common.output.spi.transform;
-
-import com.fasterxml.jackson.databind.JsonNode;
-
-public interface IInputTransformer {
- JsonNode transformInput(JsonNode input);
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/spi/transform/IInputTransformerSupplier.java b/fcli-common/src/main/java/com/fortify/cli/common/output/spi/transform/IInputTransformerSupplier.java
deleted file mode 100644
index e663974292..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/spi/transform/IInputTransformerSupplier.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.fortify.cli.common.output.spi.transform;
-
-import java.util.function.UnaryOperator;
-
-import com.fasterxml.jackson.databind.JsonNode;
-
-public interface IInputTransformerSupplier {
- UnaryOperator getInputTransformer();
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/spi/transform/IRecordTransformer.java b/fcli-common/src/main/java/com/fortify/cli/common/output/spi/transform/IRecordTransformer.java
deleted file mode 100644
index d2a03fcd10..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/spi/transform/IRecordTransformer.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.fortify.cli.common.output.spi.transform;
-
-import com.fasterxml.jackson.databind.JsonNode;
-
-public interface IRecordTransformer {
- JsonNode transformRecord(JsonNode record);
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/spi/transform/IRecordTransformerSupplier.java b/fcli-common/src/main/java/com/fortify/cli/common/output/spi/transform/IRecordTransformerSupplier.java
deleted file mode 100644
index e8390860c3..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/spi/transform/IRecordTransformerSupplier.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.fortify.cli.common.output.spi.transform;
-
-import java.util.function.UnaryOperator;
-
-import com.fasterxml.jackson.databind.JsonNode;
-
-public interface IRecordTransformerSupplier {
- UnaryOperator getRecordTransformer();
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/transform/AbstractJsonNodeTransformer.java b/fcli-common/src/main/java/com/fortify/cli/common/output/transform/AbstractJsonNodeTransformer.java
deleted file mode 100644
index d505965b33..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/transform/AbstractJsonNodeTransformer.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2020 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.output.transform;
-
-import java.util.function.Function;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.fasterxml.jackson.databind.node.JsonNodeFactory;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-
-import lombok.RequiredArgsConstructor;
-
-@RequiredArgsConstructor
-public abstract class AbstractJsonNodeTransformer implements IJsonNodeTransformer {
- private final boolean supportNestedArrays;
-
- @Override
- public final JsonNode transform(JsonNode input) {
- return transform(input, this::transformObjectNode, this::transformArrayNode);
- }
-
- protected final JsonNode transform(JsonNode input, Function objectTransformer, Function arrayTransformer) {
- if ( input==null ) { return null; }
- if ( input instanceof ObjectNode ) {
- return objectTransformer.apply((ObjectNode)input);
- } else if ( input instanceof ArrayNode ) {
- return arrayTransformer.apply((ArrayNode)input);
- } else {
- return transformNonObjectOrArrayNode(input);
- }
- }
-
- protected final ArrayNode transformArrayElements(ArrayNode input, Function objectTransformer, Function arrayTransformer) {
- ArrayNode output = new ArrayNode(JsonNodeFactory.instance);
- input.forEach(jsonNode->output.add(transform(jsonNode, objectTransformer, arrayTransformer)));
- return output;
- }
-
- protected JsonNode transformArrayNode(ArrayNode input) {
- return transformArrayElements(input, this::transformObjectNode, this::transformNestedArrayNode);
- }
-
- protected JsonNode transformNestedArrayNode(ArrayNode input) {
- if ( !supportNestedArrays ) {
- throw new IllegalArgumentException("Nested arrays are not supported");
- }
- return transformArrayNode(input);
- }
-
- protected JsonNode transformNonObjectOrArrayNode(JsonNode input) {
- throw new IllegalArgumentException("Unsupported input type: "+input.getClass().getName());
- }
-
- protected abstract JsonNode transformObjectNode(ObjectNode input);
-}
\ No newline at end of file
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/transform/IJsonNodeTransformer.java b/fcli-common/src/main/java/com/fortify/cli/common/output/transform/IJsonNodeTransformer.java
deleted file mode 100644
index 051220f248..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/transform/IJsonNodeTransformer.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.output.transform;
-
-import com.fasterxml.jackson.databind.JsonNode;
-
-@FunctionalInterface
-public interface IJsonNodeTransformer {
- public JsonNode transform(JsonNode input);
-}
\ No newline at end of file
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/transform/PropertyPathFormatter.java b/fcli-common/src/main/java/com/fortify/cli/common/output/transform/PropertyPathFormatter.java
deleted file mode 100644
index 58a8370f33..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/transform/PropertyPathFormatter.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2020 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.output.transform;
-
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-public final class PropertyPathFormatter {
- public static final String humanReadable(String propertyPath) {
- String normalizedWithSpaces = normalize(propertyPath).replace('.', ' ');
- return capitalize(normalizedWithSpaces);
- }
-
- public static final String snakeCase(String propertyPath) {
- return normalize(propertyPath).replace('.', '_');
- }
-
- public static final String pascalCase(String propertyPath) {
- String[] elts = normalize(propertyPath).split("\\.");
- return Stream.of(elts).map(PropertyPathFormatter::capitalize).collect(Collectors.joining());
- }
-
- public static final String camelCase(String propertyPath) {
- String pascalCase = pascalCase(propertyPath);
- return pascalCase.substring(0, 1).toLowerCase() + pascalCase.substring(1);
- }
-
- private static final String normalize(String s) {
- return s
- .replaceAll("_", ".") // Underscore to dot
- .replaceAll("[^a-zA-Z0-9. ]", "") // Remove all special characters
- .replaceAll("([A-Z]+)", ".$1") // Insert dot before uppercase words
- .replaceAll("\\.\\.", ".") // Remove any duplicate dots
- .replaceAll("^\\.+", "") // Remove leading dots
- .replaceAll("\\.+$", "") // Remove trailing dots
- .toLowerCase();
- }
-
- private static final String capitalize(String s) {
- return s.substring(0, 1).toUpperCase() + s.substring(1).toLowerCase();
- }
-}
\ No newline at end of file
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/transform/fields/AddFieldsTransformer.java b/fcli-common/src/main/java/com/fortify/cli/common/output/transform/fields/AddFieldsTransformer.java
deleted file mode 100644
index 35a57721f8..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/transform/fields/AddFieldsTransformer.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.output.transform.fields;
-
-import java.util.Collections;
-import java.util.Map;
-import java.util.function.Supplier;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.fortify.cli.common.output.transform.AbstractJsonNodeTransformer;
-import com.fortify.cli.common.output.transform.IJsonNodeTransformer;
-
-/**
- * This {@link IJsonNodeTransformer} allows for renaming fields in JSON objects or arrays.
- * For now, this only supports renaming top-level fields.
- *
- * @author rsenden
- *
- */
-public class AddFieldsTransformer extends AbstractJsonNodeTransformer implements IJsonNodeTransformer {
- private final Map> nameToValueSupplierMap;
- private boolean overwriteExisting = false;
-
- public AddFieldsTransformer(Map> nameToValueSupplierMap) {
- super(false);
- this.nameToValueSupplierMap = nameToValueSupplierMap;
- }
-
- public AddFieldsTransformer(String name, Supplier valueSupplier) {
- this(Collections.singletonMap(name, valueSupplier));
- }
-
- public AddFieldsTransformer(String name, String value) {
- this(Collections.singletonMap(name, ()->value));
- }
-
- public AddFieldsTransformer(String[] nameToValueSpecs) {
- this(Stream.of(nameToValueSpecs).map(s->s.split(":")).collect(Collectors.toMap(a->a[0], a->()->a[1])));
- }
-
- public AddFieldsTransformer overwiteExisting(boolean overwriteExisting) {
- this.overwriteExisting = overwriteExisting;
- return this;
- }
-
- @Override
- protected final ObjectNode transformObjectNode(ObjectNode input) {
- nameToValueSupplierMap.entrySet().forEach(
- e->put(input, e)
- );
-
- return input;
- }
-
- private final void put(ObjectNode input, Map.Entry> e) {
- if ( overwriteExisting || !input.has(e.getKey()) ) {
- input.put(e.getKey(), e.getValue().get());
- }
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/transform/fields/RenameFieldsTransformer.java b/fcli-common/src/main/java/com/fortify/cli/common/output/transform/fields/RenameFieldsTransformer.java
deleted file mode 100644
index 78f78f39db..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/transform/fields/RenameFieldsTransformer.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.output.transform.fields;
-
-import java.util.Collections;
-import java.util.Map;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import com.fasterxml.jackson.databind.node.JsonNodeFactory;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.fortify.cli.common.output.transform.AbstractJsonNodeTransformer;
-import com.fortify.cli.common.output.transform.IJsonNodeTransformer;
-
-/**
- * This {@link IJsonNodeTransformer} allows for renaming fields in JSON objects or arrays.
- * For now, this only supports renaming top-level fields.
- *
- * @author rsenden
- *
- */
-public class RenameFieldsTransformer extends AbstractJsonNodeTransformer implements IJsonNodeTransformer {
- private final Map oldToNewNameMap;
-
- public RenameFieldsTransformer(Map oldToNewNameMap) {
- super(true);
- this.oldToNewNameMap = oldToNewNameMap;
- }
-
- public RenameFieldsTransformer(String oldName, String newName) {
- this(Collections.singletonMap(oldName, newName));
- }
-
- public RenameFieldsTransformer(String[] oldToNewNameSpecs) {
- this(Stream.of(oldToNewNameSpecs).map(s->s.split(":")).collect(Collectors.toMap(a->a[0], a->a[1])));
- }
-
- @Override
- protected final ObjectNode transformObjectNode(ObjectNode input) {
- ObjectNode output = new ObjectNode(JsonNodeFactory.instance);
- input.fields().forEachRemaining(e->output.set(rename(e.getKey()), e.getValue()));
- return output;
- }
-
- private String rename(String fieldName) {
- return oldToNewNameMap.getOrDefault(fieldName, fieldName);
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/transform/identity/IdentityTransformer.java b/fcli-common/src/main/java/com/fortify/cli/common/output/transform/identity/IdentityTransformer.java
deleted file mode 100644
index f59b531c2a..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/transform/identity/IdentityTransformer.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.output.transform.identity;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fortify.cli.common.output.transform.IJsonNodeTransformer;
-
-public class IdentityTransformer implements IJsonNodeTransformer {
- @Override
- public JsonNode transform(JsonNode input) {
- return input;
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/transform/jsonpath/JsonPathTransformer.java b/fcli-common/src/main/java/com/fortify/cli/common/output/transform/jsonpath/JsonPathTransformer.java
deleted file mode 100644
index 393876375f..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/transform/jsonpath/JsonPathTransformer.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2020 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.output.transform.jsonpath;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fortify.cli.common.json.JsonHelper;
-import com.fortify.cli.common.output.transform.IJsonNodeTransformer;
-
-public class JsonPathTransformer implements IJsonNodeTransformer {
- private final String jsonPathExpression;
-
- public JsonPathTransformer(String jsonPathExpression) {
- this.jsonPathExpression = jsonPathExpression;
- }
-
- @Override
- public JsonNode transform(JsonNode input) {
- return JsonHelper.evaluateJsonPath(input, jsonPathExpression, JsonNode.class);
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/transform/package-info.java b/fcli-common/src/main/java/com/fortify/cli/common/output/transform/package-info.java
deleted file mode 100644
index 8c5e2e7a10..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/transform/package-info.java
+++ /dev/null
@@ -1,6 +0,0 @@
-/**
- * This package contains generic functionality for transforming Jackson {@link com.fasterxml.jackson.databind.JsonNode}
- * trees.
- */
-package com.fortify.cli.common.output.transform;
-
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/transform/single/ToSingleObjectNodeTransformer.java b/fcli-common/src/main/java/com/fortify/cli/common/output/transform/single/ToSingleObjectNodeTransformer.java
deleted file mode 100644
index afd37fb64f..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/transform/single/ToSingleObjectNodeTransformer.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2020 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.output.transform.single;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.fortify.cli.common.output.transform.AbstractJsonNodeTransformer;
-
-public class ToSingleObjectNodeTransformer extends AbstractJsonNodeTransformer {
- public final boolean failOnMultiple;
-
- public ToSingleObjectNodeTransformer(boolean failOnMultiple) {
- super(false);
- this.failOnMultiple = failOnMultiple;
- }
-
- @Override
- protected JsonNode transformObjectNode(ObjectNode input) {
- return input;
- }
-
- @Override
- protected JsonNode transformArrayNode(ArrayNode input) {
- if ( input==null || input.size()==0 ) {
- return null;
- } else if ( input.size()>1 && failOnMultiple ) {
- throw new IllegalArgumentException("Expected single JSON object, received multiple");
- } else {
- return input.get(0);
- }
- }
-
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/CommandSpecMessageResolver.java b/fcli-common/src/main/java/com/fortify/cli/common/output/writer/CommandSpecMessageResolver.java
deleted file mode 100644
index ffbdfb6720..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/CommandSpecMessageResolver.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package com.fortify.cli.common.output.writer;
-
-import com.fortify.cli.common.util.CommandSpecHelper;
-
-import lombok.RequiredArgsConstructor;
-import picocli.CommandLine.Model.CommandSpec;
-
-@RequiredArgsConstructor
-public final class CommandSpecMessageResolver implements IMessageResolver {
- private final CommandSpec commandSpec;
-
- @Override
- public String getMessageString(String keySuffix) {
- return CommandSpecHelper.getMessageString(commandSpec, keySuffix);
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/IMessageResolver.java b/fcli-common/src/main/java/com/fortify/cli/common/output/writer/IMessageResolver.java
deleted file mode 100644
index 494dbd128c..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/IMessageResolver.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package com.fortify.cli.common.output.writer;
-
-public interface IMessageResolver {
- String getMessageString(String keySuffix);
-}
\ No newline at end of file
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/output/IOutputWriter.java b/fcli-common/src/main/java/com/fortify/cli/common/output/writer/output/IOutputWriter.java
deleted file mode 100644
index 3d5c8f695c..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/output/IOutputWriter.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.fortify.cli.common.output.writer.output;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fortify.cli.common.rest.paging.INextPageUrlProducer;
-
-import kong.unirest.HttpRequest;
-import kong.unirest.HttpResponse;
-
-public interface IOutputWriter {
-
- void write(JsonNode jsonNode);
-
- void write(HttpRequest> httpRequest);
-
- void write(HttpRequest> httpRequest, INextPageUrlProducer nextPageUrlProducer);
-
- void write(HttpResponse httpResponse);
-
-}
\ No newline at end of file
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/output/IOutputWriterFactory.java b/fcli-common/src/main/java/com/fortify/cli/common/output/writer/output/IOutputWriterFactory.java
deleted file mode 100644
index 356b3acd01..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/output/IOutputWriterFactory.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.fortify.cli.common.output.writer.output;
-
-import com.fortify.cli.common.output.writer.output.standard.StandardOutputConfig;
-
-public interface IOutputWriterFactory {
- IOutputWriter createOutputWriter(StandardOutputConfig standardOutputConfig);
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/output/query/OutputWriterWithQuery.java b/fcli-common/src/main/java/com/fortify/cli/common/output/writer/output/query/OutputWriterWithQuery.java
deleted file mode 100644
index aa9ae462e4..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/output/query/OutputWriterWithQuery.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package com.fortify.cli.common.output.writer.output.query;
-
-import java.util.Collections;
-import java.util.List;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fortify.cli.common.output.OutputFormat;
-import com.fortify.cli.common.output.cli.mixin.UnirestOutputHelperMixins;
-import com.fortify.cli.common.output.cli.mixin.writer.OutputWriterWithQueryFactoryMixin;
-import com.fortify.cli.common.output.query.IOutputQueriesSupplier;
-import com.fortify.cli.common.output.query.OutputQuery;
-import com.fortify.cli.common.output.writer.output.standard.IOutputOptions;
-import com.fortify.cli.common.output.writer.output.standard.StandardOutputConfig;
-import com.fortify.cli.common.output.writer.output.standard.StandardOutputWriter;
-
-import io.micronaut.core.annotation.ReflectiveAccess;
-import picocli.CommandLine.Model.CommandSpec;
-
-/**
- * TODO Refactor this class once all commands have been refactored to use {@link UnirestOutputHelperMixins};
- * all picocli annotatations should be removed, as they will be passed by {@link OutputWriterWithQueryFactoryMixin}
- * through our constructor. As this class by then will no longer be a mixin, it should be renamed
- * to OutputWriterWithQuery, and moved to the writer.output.query package.
- * @author rsenden
- *
- */
-@ReflectiveAccess
-public class OutputWriterWithQuery extends StandardOutputWriter {
- private final IOutputQueriesSupplier outputQueriesSupplier;
-
- public OutputWriterWithQuery(CommandSpec mixee, IOutputOptions outputOptions, IOutputQueriesSupplier outputQueriesSupplier, StandardOutputConfig defaultOutputConfig) {
- super(mixee, outputOptions, defaultOutputConfig);
- this.outputQueriesSupplier = outputQueriesSupplier;
- }
-
- private List getOutputQueries() {
- return outputQueriesSupplier==null ? Collections.emptyList() : outputQueriesSupplier.getOutputQueries();
- }
-
- @Override
- protected JsonNode applyRecordOutputFilters(OutputFormat outputFormat, JsonNode record) {
- List outputQueries = getOutputQueries();
- return outputQueries==null
- || outputQueries.isEmpty()
- || outputQueries.stream().allMatch(q->q.matches(record))
- ? record
- : null;
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/output/standard/IOutputConfigSupplier.java b/fcli-common/src/main/java/com/fortify/cli/common/output/writer/output/standard/IOutputConfigSupplier.java
deleted file mode 100644
index b1947639f5..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/output/standard/IOutputConfigSupplier.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2020 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.output.writer.output.standard;
-
-/**
- * TODO Should we remove this interface, or keep it to allow commands to override the
- * default output configuration?
- */
-public interface IOutputConfigSupplier {
- public StandardOutputConfig getOutputConfig();
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/output/standard/IOutputOptions.java b/fcli-common/src/main/java/com/fortify/cli/common/output/writer/output/standard/IOutputOptions.java
deleted file mode 100644
index 6529db8a7c..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/output/standard/IOutputOptions.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.fortify.cli.common.output.writer.output.standard;
-
-public interface IOutputOptions {
- OutputFormatConfig getOutputFormatConfig();
- VariableStoreConfig getVariableStoreConfig();
- String getOutputFile();
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/output/standard/OutputFormatConfig.java b/fcli-common/src/main/java/com/fortify/cli/common/output/writer/output/standard/OutputFormatConfig.java
deleted file mode 100644
index 97c8cbcba0..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/output/standard/OutputFormatConfig.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.fortify.cli.common.output.writer.output.standard;
-
-import com.fortify.cli.common.output.OutputFormat;
-
-import lombok.Data;
-
-@Data
-public final class OutputFormatConfig {
- private final OutputFormat outputFormat;
- private final String options;
-}
\ No newline at end of file
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/output/standard/OutputFormatConfigConverter.java b/fcli-common/src/main/java/com/fortify/cli/common/output/writer/output/standard/OutputFormatConfigConverter.java
deleted file mode 100644
index 50ee18baee..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/output/standard/OutputFormatConfigConverter.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package com.fortify.cli.common.output.writer.output.standard;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.stream.Stream;
-
-import com.fortify.cli.common.output.OutputFormat;
-
-import io.micronaut.core.annotation.ReflectiveAccess;
-import picocli.CommandLine.ITypeConverter;
-
-public final class OutputFormatConfigConverter implements ITypeConverter {
- @Override
- public OutputFormatConfig convert(String value) throws Exception {
- int pos = value.indexOf('=');
- String outputFormatString = pos==-1 ? value : value.substring(0, pos);
- String options = pos==-1 ? null : value.substring(pos+1);
- return new OutputFormatConfig(valueOfFormattedString(outputFormatString), options);
- }
-
- public static final String[] formattedValueStrings() {
- return Stream.of(OutputFormat.values())
- .map(OutputFormat::name)
- .map(s->s.replace('_', '-'))
- .toArray(String[]::new);
- }
-
- public static final OutputFormat valueOfFormattedString(String s) {
- return OutputFormat.valueOf(s.replace('-', '_'));
- }
-
- @ReflectiveAccess
- public static final class OutputFormatIterable extends ArrayList {
- private static final long serialVersionUID = 1L;
- public OutputFormatIterable() {
- super(Arrays.asList(formattedValueStrings()));
- }
- }
-}
\ No newline at end of file
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/output/standard/StandardOutputConfig.java b/fcli-common/src/main/java/com/fortify/cli/common/output/writer/output/standard/StandardOutputConfig.java
deleted file mode 100644
index 752b2f7f3d..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/output/standard/StandardOutputConfig.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2020 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.output.writer.output.standard;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.function.BiFunction;
-import java.util.function.Function;
-import java.util.function.UnaryOperator;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fortify.cli.common.output.OutputFormat;
-import com.fortify.cli.common.output.cli.mixin.UnirestOutputHelperMixins;
-
-import lombok.Getter;
-import lombok.Setter;
-import lombok.experimental.Accessors;
-
-/**
- * TODO Move this class to the writer.output package once all commands have been refactored to use {@link UnirestOutputHelperMixins}.
- * @author rsenden
- *
- */
-@Accessors(fluent = true)
-// TODO Add null checks in case any input or record transformation returns null?
-public class StandardOutputConfig {
- @Getter @Setter private OutputFormat defaultFormat;
- private final List> inputTransformers = new ArrayList<>();
- private final List> recordTransformers = new ArrayList<>();
-
- public final StandardOutputConfig inputTransformer(final Function applyIf, final UnaryOperator transformer) {
- if ( transformer!=null ) {
- inputTransformers.add((fmt,o)->!applyIf.apply(fmt) ? o : transformer.apply(o));
- }
- return this;
- }
-
- public final StandardOutputConfig inputTransformer(UnaryOperator transformer) {
- return inputTransformer(fmt->true, transformer);
- }
-
- public final StandardOutputConfig recordTransformer(Function applyIf, UnaryOperator transformer) {
- if ( transformer!=null ) {
- recordTransformers.add((fmt,o)->!applyIf.apply(fmt) ? o : transformer.apply(o));
- }
- return this;
- }
-
- public final StandardOutputConfig recordTransformer(UnaryOperator transformer) {
- return recordTransformer(fmt->true, transformer);
- }
-
- final JsonNode applyInputTransformations(OutputFormat outputFormat, JsonNode input) {
- return applyTransformations(inputTransformers, outputFormat, input);
- }
-
- final JsonNode applyRecordTransformations(OutputFormat outputFormat, JsonNode record) {
- return applyTransformations(recordTransformers, outputFormat, record);
- }
-
- private final JsonNode applyTransformations(List> transformations, OutputFormat outputFormat, JsonNode input) {
- return transformations.stream()
- .reduce(input, (o, t) -> t.apply(outputFormat, o), (m1, m2) -> m2);
- }
-
- public static final StandardOutputConfig csv() {
- return new StandardOutputConfig().defaultFormat(OutputFormat.csv);
- }
-
- public static final StandardOutputConfig json() {
- return new StandardOutputConfig().defaultFormat(OutputFormat.json);
- }
-
- public static final StandardOutputConfig table() {
- return new StandardOutputConfig().defaultFormat(OutputFormat.table);
- }
-
- public static final StandardOutputConfig tree() {
- return new StandardOutputConfig().defaultFormat(OutputFormat.tree);
- }
-
- public static final StandardOutputConfig xml() {
- return new StandardOutputConfig().defaultFormat(OutputFormat.xml);
- }
-
- public static final StandardOutputConfig yaml() {
- return new StandardOutputConfig().defaultFormat(OutputFormat.yaml);
- }
-
- public static final StandardOutputConfig details() {
- // TODO For now we use yaml output, until #104 has been fixed so we can properly use tree() instead
- return yaml();
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/output/standard/VariableStoreConfig.java b/fcli-common/src/main/java/com/fortify/cli/common/output/writer/output/standard/VariableStoreConfig.java
deleted file mode 100644
index faf94a1374..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/output/standard/VariableStoreConfig.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.fortify.cli.common.output.writer.output.standard;
-
-import lombok.Data;
-
-@Data
-public final class VariableStoreConfig {
- private final String variableName;
- private final String options;
-}
\ No newline at end of file
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/output/standard/VariableStoreConfigConverter.java b/fcli-common/src/main/java/com/fortify/cli/common/output/writer/output/standard/VariableStoreConfigConverter.java
deleted file mode 100644
index e95dda3c2e..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/output/standard/VariableStoreConfigConverter.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.fortify.cli.common.output.writer.output.standard;
-
-import picocli.CommandLine.ITypeConverter;
-
-public final class VariableStoreConfigConverter implements ITypeConverter {
- @Override
- public VariableStoreConfig convert(String value) throws Exception {
- int pos = value.indexOf(':');
- String variableName = pos==-1 ? value : value.substring(0, pos);
- String options = pos==-1 ? null : value.substring(pos+1);
- return new VariableStoreConfig(variableName, options);
- }
-}
\ No newline at end of file
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/AbstractRecordWriter.java b/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/AbstractRecordWriter.java
deleted file mode 100644
index e4bdfee67e..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/AbstractRecordWriter.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.fortify.cli.common.output.writer.record;
-
-import com.fortify.cli.common.util.StringUtils;
-
-import lombok.Getter;
-
-public abstract class AbstractRecordWriter implements IRecordWriter {
- @Getter private final RecordWriterConfig config;
-
- public AbstractRecordWriter(RecordWriterConfig config) {
- this.config = updateConfig(config);;
- }
-
- protected RecordWriterConfig updateConfig(RecordWriterConfig config) {
- String options = config.getOptions();
- if ( StringUtils.isBlank(options) ) {
- String keySuffix = "output."+config.getOutputFormat().getMessageKey()+".options";
- options = config.getMessageResolver().getMessageString(keySuffix);
- }
- config.setOptions(options);
- return config;
- }
-
-
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/IRecordWriter.java b/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/IRecordWriter.java
deleted file mode 100644
index 14e370d44e..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/IRecordWriter.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.output.writer.record;
-
-import java.io.Closeable;
-
-import com.fasterxml.jackson.databind.node.ObjectNode;
-
-public interface IRecordWriter extends Closeable, AutoCloseable {
- public void writeRecord(ObjectNode record);
- default void close() {}
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/IRecordWriterFactory.java b/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/IRecordWriterFactory.java
deleted file mode 100644
index e80aee818b..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/IRecordWriterFactory.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.output.writer.record;
-
-public interface IRecordWriterFactory {
- public IRecordWriter createRecordWriter(RecordWriterConfig config);
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/RecordWriterConfig.java b/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/RecordWriterConfig.java
deleted file mode 100644
index 39c40e2451..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/RecordWriterConfig.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.output.writer.record;
-
-import java.io.Writer;
-
-import com.fortify.cli.common.output.OutputFormat;
-import com.fortify.cli.common.output.spi.transform.IActionCommandResultSupplier;
-import com.fortify.cli.common.output.writer.IMessageResolver;
-
-import lombok.Builder;
-import lombok.Data;
-
-@Data @Builder
-public class RecordWriterConfig {
- /** Writer to which to write the output */
- private Writer writer;
- /** Write singular output rather than an array/list;
- * assumes that only a single record is passed to the {@link IRecordWriter} */
- private boolean singular;
- /** Free-format {@link IRecordWriter} options */
- private String options;
- /** The actual output format that was requested */
- private OutputFormat outputFormat;
- /** Whether to pretty-print the output */
- @Builder.Default private boolean pretty = true;
- /** I18n message resolver */
- private IMessageResolver messageResolver;
- /** Whether to add an {@value IActionCommandResultSupplier#actionFieldName} column */
- private boolean addActionColumn;
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/csv/CsvRecordWriter.java b/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/csv/CsvRecordWriter.java
deleted file mode 100644
index 7d8aeb29ef..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/csv/CsvRecordWriter.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.output.writer.record.csv;
-
-import com.fasterxml.jackson.core.JsonGenerator.Feature;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.fasterxml.jackson.dataformat.csv.CsvFactory;
-import com.fasterxml.jackson.dataformat.csv.CsvGenerator;
-import com.fasterxml.jackson.dataformat.csv.CsvSchema;
-import com.fortify.cli.common.output.writer.record.AbstractFormattedRecordWriter;
-import com.fortify.cli.common.output.writer.record.RecordWriterConfig;
-
-import lombok.SneakyThrows;
-
-public class CsvRecordWriter extends AbstractFormattedRecordWriter {
- public static enum CsvType { HEADERS, NO_HEADERS }
- private final CsvType csvType;
- private CsvGenerator generator;
-
- public CsvRecordWriter(CsvType csvType, RecordWriterConfig config) {
- super(config);
- this.csvType = csvType;
- }
-
- @SneakyThrows
- private CsvGenerator getGenerator(ObjectNode record) {
- if ( generator==null ) {
- if ( record!=null ) {
- CsvSchema.Builder schemaBuilder = CsvSchema.builder();
- record.fieldNames().forEachRemaining(schemaBuilder::addColumn);
- CsvSchema schema = schemaBuilder.build()
- .withUseHeader(CsvType.HEADERS==csvType);
- this.generator = (CsvGenerator)CsvFactory.builder().
- build().createGenerator(getWriter())
- .setCodec(new ObjectMapper())
- .enable(Feature.IGNORE_UNKNOWN)
- .disable(Feature.AUTO_CLOSE_TARGET);
- this.generator.setSchema(schema);
- if ( !getConfig().isSingular() ) {
- generator.writeStartArray();
- }
- }
- }
- return generator;
- }
-
- @Override @SneakyThrows
- public void writeFormattedRecord(ObjectNode record) {
- getGenerator(record).writeTree(record);
- }
-
- @Override @SneakyThrows
- public void close() {
- if ( !getConfig().isSingular() && generator!=null ) {
- generator.writeEndArray();
- generator.close();
- }
- }
-
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/csv/CsvRecordWriterFactory.java b/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/csv/CsvRecordWriterFactory.java
deleted file mode 100644
index d8588465fe..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/csv/CsvRecordWriterFactory.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.output.writer.record.csv;
-
-import com.fortify.cli.common.output.writer.record.IRecordWriter;
-import com.fortify.cli.common.output.writer.record.IRecordWriterFactory;
-import com.fortify.cli.common.output.writer.record.RecordWriterConfig;
-import com.fortify.cli.common.output.writer.record.csv.CsvRecordWriter.CsvType;
-
-import lombok.RequiredArgsConstructor;
-
-@RequiredArgsConstructor
-public class CsvRecordWriterFactory implements IRecordWriterFactory {
- private final CsvType csvType;
- @Override
- public IRecordWriter createRecordWriter(RecordWriterConfig config) {
- return new CsvRecordWriter(csvType, config);
- }
-
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/csv/package-info.java b/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/csv/package-info.java
deleted file mode 100644
index 3e738d4c6f..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/csv/package-info.java
+++ /dev/null
@@ -1,5 +0,0 @@
-/**
- * This package provides functionality for outputting data to CSV format.
- */
-package com.fortify.cli.common.output.writer.record.csv;
-
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/expr/ExprRecordWriter.java b/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/expr/ExprRecordWriter.java
deleted file mode 100644
index d17e456683..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/expr/ExprRecordWriter.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.output.writer.record.expr;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.fortify.cli.common.json.JsonHelper;
-import com.fortify.cli.common.output.writer.record.AbstractRecordWriter;
-import com.fortify.cli.common.output.writer.record.RecordWriterConfig;
-
-import lombok.SneakyThrows;
-
-public class ExprRecordWriter extends AbstractRecordWriter {
- private static final Pattern exprPattern = Pattern.compile("\\{(.+?)\\}");
-
- public ExprRecordWriter(RecordWriterConfig config) {
- super(config);
- }
-
- @Override @SneakyThrows
- public void writeRecord(ObjectNode record) {
- getConfig().getWriter().write(evaluateExpression(getConfig().getOptions(), record));
- }
-
- private static final String evaluateExpression(String expr, ObjectNode input) {
- expr = insertControlCharacters(expr);
- StringBuilder sb = new StringBuilder();
- Matcher matcher = exprPattern.matcher(expr);
- while (matcher.find()) {
- String propertyPath = matcher.group(1);
- String value = JsonHelper.evaluateJsonPath(input, propertyPath, String.class);
- if ( value==null ) { value = matcher.group(2); }
- if ( value==null ) { value = ""; }
- matcher.appendReplacement(sb, value);
- }
- matcher.appendTail(sb);
- return sb.toString();
- }
-
- private static final String insertControlCharacters(String s) {
- return s.replaceAll("\\\\t", "\t")
- .replaceAll("\\\\b", "\b")
- .replaceAll("\\\\n", "\n")
- .replaceAll("\\\\r", "\r")
- .replaceAll("\\\\f", "\f");
- }
-
-
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/expr/ExprRecordWriterFactory.java b/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/expr/ExprRecordWriterFactory.java
deleted file mode 100644
index c01b4d3a88..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/expr/ExprRecordWriterFactory.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.output.writer.record.expr;
-
-import com.fortify.cli.common.output.writer.record.IRecordWriter;
-import com.fortify.cli.common.output.writer.record.IRecordWriterFactory;
-import com.fortify.cli.common.output.writer.record.RecordWriterConfig;
-
-public class ExprRecordWriterFactory implements IRecordWriterFactory {
- @Override
- public IRecordWriter createRecordWriter(RecordWriterConfig config) {
- return new ExprRecordWriter(config);
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/json/JsonRecordWriter.java b/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/json/JsonRecordWriter.java
deleted file mode 100644
index 2228c89f4a..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/json/JsonRecordWriter.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.output.writer.record.json;
-
-import com.fasterxml.jackson.core.JsonFactory;
-import com.fasterxml.jackson.core.JsonGenerator;
-import com.fasterxml.jackson.core.JsonGenerator.Feature;
-import com.fasterxml.jackson.core.PrettyPrinter;
-import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.fortify.cli.common.output.writer.record.AbstractFormattedRecordWriter;
-import com.fortify.cli.common.output.writer.record.RecordWriterConfig;
-
-import lombok.SneakyThrows;
-
-public class JsonRecordWriter extends AbstractFormattedRecordWriter {
- private JsonGenerator generator;
-
- public JsonRecordWriter(RecordWriterConfig config) {
- super(config);
- }
-
- @SneakyThrows
- private JsonGenerator getGenerator() {
- if ( generator==null ) {
- PrettyPrinter pp = !getConfig().isPretty() ? null : new DefaultPrettyPrinter();
- this.generator = JsonFactory.builder().
- build().createGenerator(getWriter())
- .setPrettyPrinter(pp)
- .setCodec(new ObjectMapper())
- .disable(Feature.AUTO_CLOSE_TARGET);
- if ( !getConfig().isSingular() ) {
- generator.writeStartArray();
- }
- }
- return generator;
- }
-
- @Override @SneakyThrows
- public void writeFormattedRecord(ObjectNode record) {
- getGenerator().writeTree(record);
- }
-
- @Override @SneakyThrows
- public void close() {
- if ( !getConfig().isSingular() ) {
- getGenerator().writeEndArray();
- getGenerator().close();
- }
- getWriter().write("\n"); // End with a newline
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/json/JsonRecordWriterFactory.java b/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/json/JsonRecordWriterFactory.java
deleted file mode 100644
index cb2dbf5405..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/json/JsonRecordWriterFactory.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.output.writer.record.json;
-
-import com.fortify.cli.common.output.writer.record.IRecordWriter;
-import com.fortify.cli.common.output.writer.record.IRecordWriterFactory;
-import com.fortify.cli.common.output.writer.record.RecordWriterConfig;
-
-public class JsonRecordWriterFactory implements IRecordWriterFactory {
-
- @Override
- public IRecordWriter createRecordWriter(RecordWriterConfig config) {
- return new JsonRecordWriter(config);
- }
-
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/json/package-info.java b/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/json/package-info.java
deleted file mode 100644
index 4d0fe82604..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/json/package-info.java
+++ /dev/null
@@ -1,5 +0,0 @@
-/**
- * This package provides functionality for outputting data to JSON format.
- */
-package com.fortify.cli.common.output.writer.record.json;
-
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/json_properties/JsonPropertiesRecordWriter.java b/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/json_properties/JsonPropertiesRecordWriter.java
deleted file mode 100644
index 13b06e18aa..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/json_properties/JsonPropertiesRecordWriter.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.output.writer.record.json_properties;
-
-import java.util.TreeSet;
-import java.util.stream.Collectors;
-
-import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.fortify.cli.common.json.JsonHelper;
-import com.fortify.cli.common.output.writer.record.AbstractRecordWriter;
-import com.fortify.cli.common.output.writer.record.RecordWriterConfig;
-import com.jayway.jsonpath.Configuration;
-import com.jayway.jsonpath.JsonPath;
-import com.jayway.jsonpath.Option;
-import com.jayway.jsonpath.spi.json.JacksonJsonNodeJsonProvider;
-import com.jayway.jsonpath.spi.mapper.JacksonMappingProvider;
-
-import lombok.SneakyThrows;
-
-public class JsonPropertiesRecordWriter extends AbstractRecordWriter {
- private final TreeSet paths = new TreeSet<>();
-
- public JsonPropertiesRecordWriter(RecordWriterConfig config) {
- super(config);
- }
-
- @Override @SneakyThrows
- public void writeRecord(ObjectNode record) {
- Configuration configuration = Configuration.builder()
- .options(Option.AS_PATH_LIST)
- .jsonProvider(new JacksonJsonNodeJsonProvider(JsonHelper.getObjectMapper()))
- .mappingProvider(new JacksonMappingProvider(JsonHelper.getObjectMapper()))
- .build();
- JsonPath.using(configuration).parse(record).read("$..*", ArrayNode.class).forEach(j->paths.add(normalize(j.asText())));;
- }
-
- private String normalize(String s) {
- return s.replaceAll("\\['(.+?)'\\]", ".$1").replaceFirst("\\$\\.", "");
- }
-
- @Override @SneakyThrows
- public void close() {
- getConfig().getWriter().write(paths.stream().collect(Collectors.joining("\n")));
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/json_properties/JsonPropertiesRecordWriterFactory.java b/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/json_properties/JsonPropertiesRecordWriterFactory.java
deleted file mode 100644
index cbaf6e7a2c..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/json_properties/JsonPropertiesRecordWriterFactory.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.output.writer.record.json_properties;
-
-import com.fortify.cli.common.output.writer.record.IRecordWriter;
-import com.fortify.cli.common.output.writer.record.IRecordWriterFactory;
-import com.fortify.cli.common.output.writer.record.RecordWriterConfig;
-
-public class JsonPropertiesRecordWriterFactory implements IRecordWriterFactory {
- @Override
- public IRecordWriter createRecordWriter(RecordWriterConfig config) {
- return new JsonPropertiesRecordWriter(config);
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/package-info.java b/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/package-info.java
deleted file mode 100644
index 174b025ad8..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/package-info.java
+++ /dev/null
@@ -1,9 +0,0 @@
-/**
- * This package provides generic functionality for outputting data to various output formats. At the moment, this
- * output framework accepts {@link com.fasterxml.jackson.databind.JsonNode} instances as its input, which is
- * appropriate for almost all commands working with REST API's. Potentially in the future we may need to add
- * support for other input formats, for example raw data produced by 3rd-party tools that are being run by fcli.
- * The actual output format implementations are defined in the appropriate sub-packages.
- */
-package com.fortify.cli.common.output.writer.record;
-
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/table/TableRecordWriter.java b/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/table/TableRecordWriter.java
deleted file mode 100644
index ca406550ca..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/table/TableRecordWriter.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.output.writer.record.table;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.stream.Stream;
-import java.util.stream.StreamSupport;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.fortify.cli.common.output.transform.PropertyPathFormatter;
-import com.fortify.cli.common.output.writer.record.AbstractFormattedRecordWriter;
-import com.fortify.cli.common.output.writer.record.RecordWriterConfig;
-import com.github.freva.asciitable.AsciiTable;
-import com.github.freva.asciitable.Column;
-import com.github.freva.asciitable.HorizontalAlign;
-
-import lombok.SneakyThrows;
-
-public class TableRecordWriter extends AbstractFormattedRecordWriter {
- public static enum TableType { HEADERS, NO_HEADERS }
- private final TableType tableType;
- private String[] fields;
- private final List rows = new ArrayList<>();
-
- public TableRecordWriter(TableType tableType, RecordWriterConfig config) {
- super(config);
- this.tableType = tableType;
- }
-
- @Override @SneakyThrows
- public void writeFormattedRecord(ObjectNode record) {
- String[] columns = getFields(record);
- String[] row = getRow(record, columns);
- rows.add(row);
- }
-
- @Override @SneakyThrows
- public void close() {
- getWriter().write(getTable(fields, rows.toArray(new String[rows.size()][])));
- }
-
- private String getTable(String[] fields, String[][] data) {
- if ( fields == null ) {
- return "No data"; // TODO properly handle this
- } else {
- Column[] columnObjects = Stream.of(fields).map(field->
- new Column()
- .dataAlign(HorizontalAlign.LEFT)
- .headerAlign(HorizontalAlign.LEFT)
- .header(TableType.HEADERS==tableType ? getHeader(field) : null))
- .toArray(Column[]::new);
- return AsciiTable.getTable(AsciiTable.NO_BORDERS, columnObjects, data);
- }
- }
-
- private String getHeader(String fieldName) {
- String header = getConfig().getMessageResolver().getMessageString("output.header."+fieldName);
- return header!=null ? header : PropertyPathFormatter.humanReadable(fieldName);
- }
-
- private String[] getFields(ObjectNode firstObjectNode) {
- if ( fields==null ) {
- fields = asStream(firstObjectNode.fieldNames()).toArray(String[]::new);
- }
- return fields;
- }
-
- // TODO: Some REST APIs will return a varying set of properties for individual records. We should review null processing here.
- private String[] getRow(ObjectNode record, String[] columns) {
- for(String propertyName : columns){
- if (record.get(propertyName) == null) {
- record.put(propertyName, "null");
- }
- }
- return Stream.of(columns).map(record::get).map(JsonNode::asText).map(v->"null".equals(v)?"N/A":v).toArray(String[]::new);
- }
-
- private static final Stream asStream(Iterator sourceIterator) {
- Iterable iterable = () -> sourceIterator;
- return StreamSupport.stream(iterable.spliterator(), false);
- }
-
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/table/TableRecordWriterFactory.java b/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/table/TableRecordWriterFactory.java
deleted file mode 100644
index 9ce0f7c277..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/table/TableRecordWriterFactory.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.output.writer.record.table;
-
-import com.fortify.cli.common.output.writer.record.IRecordWriter;
-import com.fortify.cli.common.output.writer.record.IRecordWriterFactory;
-import com.fortify.cli.common.output.writer.record.RecordWriterConfig;
-import com.fortify.cli.common.output.writer.record.table.TableRecordWriter.TableType;
-
-import lombok.RequiredArgsConstructor;
-
-@RequiredArgsConstructor
-public class TableRecordWriterFactory implements IRecordWriterFactory {
- private final TableType tableType;
-
- @Override
- public IRecordWriter createRecordWriter(RecordWriterConfig config) {
- return new TableRecordWriter(tableType, config);
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/table/package-info.java b/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/table/package-info.java
deleted file mode 100644
index ceec583ffa..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/table/package-info.java
+++ /dev/null
@@ -1,5 +0,0 @@
-/**
- * This package provides functionality for outputting data to human-readable table format.
- */
-package com.fortify.cli.common.output.writer.record.table;
-
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/tree/TreeRecordWriter.java b/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/tree/TreeRecordWriter.java
deleted file mode 100644
index a86cc5405c..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/tree/TreeRecordWriter.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.output.writer.record.tree;
-
-import java.util.Iterator;
-import java.util.Map;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.node.JsonNodeType;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.fortify.cli.common.output.writer.record.AbstractFormattedRecordWriter;
-import com.fortify.cli.common.output.writer.record.RecordWriterConfig;
-
-import hu.webarticum.treeprinter.SimpleTreeNode;
-//import hu.webarticum.treeprinter.ListingTreePrinter;
-import hu.webarticum.treeprinter.printer.listing.ListingTreePrinter;
-
-// TODO Use PrintWriter from RecordWriterConfig, wo allow output to file
-public class TreeRecordWriter extends AbstractFormattedRecordWriter {
- public TreeRecordWriter(RecordWriterConfig config) {
- super(config);
- }
-
- @Override
- public void writeFormattedRecord(ObjectNode record) {
- SimpleTreeNode rootNode = new SimpleTreeNode("-+-");
- treeBuilder(rootNode, record, null);
- ListingTreePrinter.builder().ascii().build().print(rootNode); // TODO print to actual output, but for some reason line below doesn't work
- //ListingTreePrinter.createBuilder().ascii().build().print(rootNode, config.getPrintWriterSupplier().get()); // print with ascii
- //new ListingTreePrinter().print(rootNode); // print with unicode
- }
-
- private static void treeBuilder(SimpleTreeNode treeNode, JsonNode inputNode, String firstLevelLabelSuffix){
- firstLevelLabelSuffix = (firstLevelLabelSuffix == null) ? "" : firstLevelLabelSuffix;
- if( inputNode.getNodeType() == JsonNodeType.ARRAY){
- int cnt = 0;
- for (JsonNode n: inputNode) {
- SimpleTreeNode childNode = new SimpleTreeNode(String.format("#%d:%s", cnt, firstLevelLabelSuffix) );
- treeBuilder(childNode, n, null);
- treeNode.addChild(childNode);
- cnt++;
- }
- }else if(inputNode.getNodeType() == JsonNodeType.OBJECT){
- for (Iterator> it = inputNode.fields(); it.hasNext(); ) {
- Map.Entry n = it.next();
- if(n.getValue().getNodeType() != JsonNodeType.OBJECT){
- SimpleTreeNode childNode = new SimpleTreeNode( n.getKey() + ": " + n.getValue().asText());
- treeNode.addChild(childNode);
- }else if(n.getValue().getNodeType() == JsonNodeType.OBJECT){
- SimpleTreeNode childNode = new SimpleTreeNode(n.getKey());
- treeBuilder(childNode, n.getValue(), null);
- treeNode.addChild(childNode);
- }
- }
- } else if(inputNode.getNodeType() == JsonNodeType.NUMBER || inputNode.getNodeType() == JsonNodeType.STRING ) {
- SimpleTreeNode childNode = new SimpleTreeNode( inputNode.asText());
- treeNode.addChild(childNode);
- }
-
- }
-
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/tree/TreeRecordWriterFactory.java b/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/tree/TreeRecordWriterFactory.java
deleted file mode 100644
index 62b1f6f2ba..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/tree/TreeRecordWriterFactory.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.output.writer.record.tree;
-
-import com.fortify.cli.common.output.writer.record.IRecordWriter;
-import com.fortify.cli.common.output.writer.record.IRecordWriterFactory;
-import com.fortify.cli.common.output.writer.record.RecordWriterConfig;
-
-public class TreeRecordWriterFactory implements IRecordWriterFactory {
-
- @Override
- public IRecordWriter createRecordWriter(RecordWriterConfig config) {
- return new TreeRecordWriter(config);
- }
-
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/tree/package-info.java b/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/tree/package-info.java
deleted file mode 100644
index 5fbfc533ef..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/tree/package-info.java
+++ /dev/null
@@ -1,5 +0,0 @@
-/**
- * This package provides functionality for outputting data to human-readable tree format.
- */
-package com.fortify.cli.common.output.writer.record.tree;
-
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/xml/XmlRecordWriter.java b/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/xml/XmlRecordWriter.java
deleted file mode 100644
index c94e665294..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/xml/XmlRecordWriter.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.output.writer.record.xml;
-
-import javax.xml.namespace.QName;
-
-import com.fasterxml.jackson.core.JsonGenerator.Feature;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.fasterxml.jackson.dataformat.xml.XmlFactory;
-import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator;
-import com.fortify.cli.common.output.writer.record.AbstractFormattedRecordWriter;
-import com.fortify.cli.common.output.writer.record.RecordWriterConfig;
-
-import lombok.SneakyThrows;
-
-// TODO Add support for writing a single item if config.singular()==true
-public class XmlRecordWriter extends AbstractFormattedRecordWriter {
- private ToXmlGenerator generator;
-
- public XmlRecordWriter(RecordWriterConfig config) {
- super(config);
- }
-
- @SneakyThrows
- private ToXmlGenerator getGenerator() {
- if ( generator==null ) {
- XmlFactory factory = new XmlFactory();
- this.generator = (ToXmlGenerator)factory.createGenerator(getWriter())
- .setCodec(new ObjectMapper())
- .disable(Feature.AUTO_CLOSE_TARGET);
- if ( getConfig().isPretty() ) generator = (ToXmlGenerator)generator.useDefaultPrettyPrinter();
- generator.setNextName(new QName(null, "items"));
- generator.writeStartObject();
- }
- return generator;
- }
-
- @Override @SneakyThrows
- public void writeFormattedRecord(ObjectNode record) {
- getGenerator().writeFieldName("item");
- getGenerator().writeTree(record);
- }
-
- @Override @SneakyThrows
- public void close() {
- getGenerator().writeEndObject();
- getGenerator().close();
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/xml/XmlRecordWriterFactory.java b/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/xml/XmlRecordWriterFactory.java
deleted file mode 100644
index e4f851d6aa..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/xml/XmlRecordWriterFactory.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.output.writer.record.xml;
-
-import com.fortify.cli.common.output.writer.record.IRecordWriter;
-import com.fortify.cli.common.output.writer.record.IRecordWriterFactory;
-import com.fortify.cli.common.output.writer.record.RecordWriterConfig;
-
-public class XmlRecordWriterFactory implements IRecordWriterFactory {
-
- @Override
- public IRecordWriter createRecordWriter(RecordWriterConfig config) {
- return new XmlRecordWriter(config);
- }
-
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/xml/package-info.java b/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/xml/package-info.java
deleted file mode 100644
index 3e342867c6..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/xml/package-info.java
+++ /dev/null
@@ -1,5 +0,0 @@
-/**
- * This package provides functionality for outputting data to XML format.
- */
-package com.fortify.cli.common.output.writer.record.xml;
-
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/yaml/YamlRecordWriter.java b/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/yaml/YamlRecordWriter.java
deleted file mode 100644
index 589eee2606..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/yaml/YamlRecordWriter.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.output.writer.record.yaml;
-
-import com.fasterxml.jackson.core.JsonGenerator.Feature;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
-import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator;
-import com.fortify.cli.common.output.writer.record.AbstractFormattedRecordWriter;
-import com.fortify.cli.common.output.writer.record.RecordWriterConfig;
-
-import lombok.SneakyThrows;
-
-public class YamlRecordWriter extends AbstractFormattedRecordWriter {
- private YAMLGenerator generator;
-
- public YamlRecordWriter(RecordWriterConfig config) {
- super(config);
- }
-
- @SneakyThrows
- private YAMLGenerator getGenerator() {
- if ( generator==null ) {
- YAMLFactory factory = new YAMLFactory();
- this.generator = (YAMLGenerator)factory.createGenerator(getWriter())
- .setCodec(new ObjectMapper())
- .disable(Feature.AUTO_CLOSE_TARGET);
- if ( getConfig().isPretty() ) generator = (YAMLGenerator)generator.useDefaultPrettyPrinter();
- if ( !getConfig().isSingular() ) {
- generator.writeStartArray();
- }
- }
- return generator;
- }
-
- @Override @SneakyThrows
- public void writeFormattedRecord(ObjectNode record) {
- getGenerator().writeTree(record);
- }
-
- @Override @SneakyThrows
- public void close() {
- if ( !getConfig().isSingular() ) {
- getGenerator().writeEndArray();
- }
- getGenerator().close();
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/yaml/YamlRecordWriterFactory.java b/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/yaml/YamlRecordWriterFactory.java
deleted file mode 100644
index a54bf4fc74..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/yaml/YamlRecordWriterFactory.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.output.writer.record.yaml;
-
-import com.fortify.cli.common.output.writer.record.IRecordWriter;
-import com.fortify.cli.common.output.writer.record.IRecordWriterFactory;
-import com.fortify.cli.common.output.writer.record.RecordWriterConfig;
-
-public class YamlRecordWriterFactory implements IRecordWriterFactory {
-
- @Override
- public IRecordWriter createRecordWriter(RecordWriterConfig config) {
- return new YamlRecordWriter(config);
- }
-
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/yaml/package-info.java b/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/yaml/package-info.java
deleted file mode 100644
index 39a17a1f9c..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/yaml/package-info.java
+++ /dev/null
@@ -1,5 +0,0 @@
-/**
- * This package provides functionality for outputting data to Yaml format.
- */
-package com.fortify.cli.common.output.writer.record.yaml;
-
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/rest/cli/cmd/AbstractRestCallCommand.java b/fcli-common/src/main/java/com/fortify/cli/common/rest/cli/cmd/AbstractRestCallCommand.java
deleted file mode 100644
index 8715da1235..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/rest/cli/cmd/AbstractRestCallCommand.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.rest.cli.cmd;
-
-import com.fortify.cli.common.output.cli.mixin.writer.StandardOutputWriterFactoryMixin;
-import com.fortify.cli.common.output.writer.output.standard.StandardOutputConfig;
-import com.fortify.cli.common.session.manager.api.ISessionData;
-
-import io.micronaut.core.annotation.ReflectiveAccess;
-import io.micronaut.core.util.StringUtils;
-import kong.unirest.HttpRequest;
-import kong.unirest.UnirestInstance;
-import lombok.Getter;
-import picocli.CommandLine.Mixin;
-import picocli.CommandLine.Option;
-import picocli.CommandLine.Parameters;
-
-@ReflectiveAccess
-public abstract class AbstractRestCallCommand extends AbstractUnirestRunnerCommand {
- public static final String CMD_NAME = "call";
- @Mixin private StandardOutputWriterFactoryMixin outputWriterFactory;
- @Parameters(index = "0", arity = "1..1", descriptionKey = "api.uri") String uri;
-
- @Option(names = {"--request", "-X"}, required = false, defaultValue = "GET")
- @Getter private String httpMethod;
-
- @Option(names = {"--data", "-d"}, required = false)
- @Getter private String data; // TODO Add ability to read data from file
-
- // TODO Add options for content-type, arbitrary headers, ...?
-
- @Override
- protected final Void run(UnirestInstance unirest) {
- outputWriterFactory.createOutputWriter(StandardOutputConfig.json())
- .write(prepareRequest(unirest));
- return null;
- }
-
- protected final HttpRequest> prepareRequest(UnirestInstance unirest) {
- if ( StringUtils.isEmpty(uri) ) {
- throw new IllegalArgumentException("Uri must be specified");
- }
- var request = unirest.request(httpMethod, uri);
- // TODO Add Content-Type & accept headers
- return data==null ? request : request.body(data);
- }
-
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/rest/cli/cmd/AbstractUnirestRunnerCommand.java b/fcli-common/src/main/java/com/fortify/cli/common/rest/cli/cmd/AbstractUnirestRunnerCommand.java
deleted file mode 100644
index fd63d7b83c..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/rest/cli/cmd/AbstractUnirestRunnerCommand.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.rest.cli.cmd;
-
-import com.fortify.cli.common.cli.cmd.AbstractFortifyCLICommand;
-import com.fortify.cli.common.rest.runner.IUnirestWithSessionDataRunner;
-import com.fortify.cli.common.session.manager.api.ISessionData;
-
-import io.micronaut.core.annotation.ReflectiveAccess;
-import kong.unirest.UnirestInstance;
-import lombok.SneakyThrows;
-
-@ReflectiveAccess
-public abstract class AbstractUnirestRunnerCommand extends AbstractFortifyCLICommand implements Runnable {
- @Override @SneakyThrows
- public final void run() {
- // TODO Do we want to do anything with the results, like formatting it based on output options?
- // Or do we let the actual implementation handle this?
- getUnirestRunner().run(this::run);
- }
-
- protected Void run(UnirestInstance unirest, D sessionData) {
- return run(unirest);
- }
-
- // TODO Eventually, we'll likely want to change all command implementations to implement
- // the run(UnirestInstance, SessionData) method; we can then remove this method and
- // make the run(UnirestInstance, Session) method abstract.
- protected Void run(UnirestInstance unirest) {
- throw new RuntimeException("Command must implement either run(UnirestInstance,SessionData) or run(UnirestInstance)");
- }
-
- protected abstract IUnirestWithSessionDataRunner getUnirestRunner();
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/rest/cli/cmd/AbstractWaitForCommand.java b/fcli-common/src/main/java/com/fortify/cli/common/rest/cli/cmd/AbstractWaitForCommand.java
deleted file mode 100644
index 81a3b5bb5e..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/rest/cli/cmd/AbstractWaitForCommand.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.rest.cli.cmd;
-
-import com.fortify.cli.common.output.cli.mixin.BasicOutputHelperMixins;
-import com.fortify.cli.common.output.spi.ISingularSupplier;
-import com.fortify.cli.common.output.spi.transform.IActionCommandResultSupplier;
-import com.fortify.cli.common.rest.cli.mixin.StandardWaitHelperProgressMonitorMixin;
-import com.fortify.cli.common.rest.cli.mixin.WaitHelperControlOptions;
-import com.fortify.cli.common.rest.cli.mixin.WaitHelperWaitOptions;
-import com.fortify.cli.common.rest.wait.WaitHelper;
-import com.fortify.cli.common.rest.wait.WaitHelper.WaitHelperBuilder;
-import com.fortify.cli.common.session.manager.api.ISessionData;
-
-import io.micronaut.core.annotation.ReflectiveAccess;
-import kong.unirest.UnirestInstance;
-import lombok.Getter;
-import picocli.CommandLine.Mixin;
-
-@ReflectiveAccess
-public abstract class AbstractWaitForCommand extends AbstractUnirestRunnerCommand implements IActionCommandResultSupplier, ISingularSupplier {
- @Getter @Mixin private BasicOutputHelperMixins.WaitFor outputHelper;
- @Mixin private WaitHelperControlOptions controlOptions;
- @Mixin private WaitHelperWaitOptions waitOptions;
- @Mixin StandardWaitHelperProgressMonitorMixin progressMonitorMixin;
-
- @Override
- protected Void run(UnirestInstance unirest) {
- configure(
- WaitHelper.builder()
- .controlProperties(controlOptions)
- .progressMonitor(progressMonitorMixin.createProgressMonitor(false))
- .onFinish(WaitHelper::recordsWithActionAsArrayNode, outputHelper::write)
- ).build().wait(unirest, waitOptions);
- return null;
- }
-
- protected abstract WaitHelperBuilder configure(WaitHelperBuilder builder);
-
- @Override
- public String getActionCommandResult() {
- return "N/A"; // Action result will be provided by WaitHelper
- }
-
- @Override
- public boolean isSingular() {
- return false;
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/rest/cli/mixin/AbstractSimpleUnirestRunnerMixin.java b/fcli-common/src/main/java/com/fortify/cli/common/rest/cli/mixin/AbstractSimpleUnirestRunnerMixin.java
deleted file mode 100644
index 280abbe25f..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/rest/cli/mixin/AbstractSimpleUnirestRunnerMixin.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.fortify.cli.common.rest.cli.mixin;
-
-import java.util.function.BiFunction;
-
-import com.fortify.cli.common.session.manager.api.ISessionData;
-
-import io.micronaut.core.annotation.ReflectiveAccess;
-import kong.unirest.UnirestInstance;
-
-@ReflectiveAccess
-public abstract class AbstractSimpleUnirestRunnerMixin extends AbstractUnirestRunnerMixin {
- @Override
- public final R run(BiFunction f) {
- return run(this::configure, f);
- }
-
- protected abstract void configure(UnirestInstance unirest, D sessionData);
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/rest/cli/mixin/AbstractUnirestRunnerMixin.java b/fcli-common/src/main/java/com/fortify/cli/common/rest/cli/mixin/AbstractUnirestRunnerMixin.java
deleted file mode 100644
index bab99a7e3e..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/rest/cli/mixin/AbstractUnirestRunnerMixin.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package com.fortify.cli.common.rest.cli.mixin;
-
-import java.util.function.BiConsumer;
-import java.util.function.BiFunction;
-
-import com.fortify.cli.common.rest.runner.GenericUnirestFactory;
-import com.fortify.cli.common.rest.runner.IUnirestWithSessionDataRunner;
-import com.fortify.cli.common.session.cli.mixin.SessionNameMixin;
-import com.fortify.cli.common.session.manager.api.ISessionData;
-import com.fortify.cli.common.util.FixInjection;
-
-import io.micronaut.core.annotation.ReflectiveAccess;
-import jakarta.inject.Inject;
-import kong.unirest.UnirestInstance;
-import picocli.CommandLine.Mixin;
-
-@ReflectiveAccess @FixInjection
-public abstract class AbstractUnirestRunnerMixin implements IUnirestWithSessionDataRunner {
- @Inject private GenericUnirestFactory genericUnirestFactory;
- @Mixin private SessionNameMixin.OptionalOption sessionNameMixin;
-
- protected final R run(BiConsumer configurer, BiFunction f) {
- if ( f == null ) { throw new IllegalStateException("Function may not be null"); }
- D sessionData = getSessionData();
- try ( var unirest = genericUnirestFactory.createUnirestInstance() ) {
- configurer.accept(unirest, sessionData);
- return f.apply(unirest, sessionData);
- }
- }
-
- public D getSessionData() {
- return getSessionData(sessionNameMixin.getSessionName());
- }
-
- protected abstract D getSessionData(String sessionName);
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/rest/cli/mixin/StandardWaitHelperProgressMonitorMixin.java b/fcli-common/src/main/java/com/fortify/cli/common/rest/cli/mixin/StandardWaitHelperProgressMonitorMixin.java
deleted file mode 100644
index 52680405b4..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/rest/cli/mixin/StandardWaitHelperProgressMonitorMixin.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package com.fortify.cli.common.rest.cli.mixin;
-
-import com.fortify.cli.common.output.writer.CommandSpecMessageResolver;
-import com.fortify.cli.common.output.writer.IMessageResolver;
-import com.fortify.cli.common.rest.wait.StandardWaitHelperProgressMonitor;
-
-import io.micronaut.core.annotation.ReflectiveAccess;
-import picocli.CommandLine.Command;
-import picocli.CommandLine.Model.CommandSpec;
-import picocli.CommandLine.Option;
-import picocli.CommandLine.Spec;
-import picocli.CommandLine.Spec.Target;
-
-@Command @ReflectiveAccess
-public class StandardWaitHelperProgressMonitorMixin {
- private IMessageResolver messageResolver;
- @Option(names="--no-progress") private boolean noProgress;
-
- @Spec(Target.MIXEE)
- public void setCommandSpec(CommandSpec commandSpec) {
- commandSpec = commandSpec.commandLine()==null ? commandSpec : commandSpec.commandLine().getCommandSpec();
- this.messageResolver = new CommandSpecMessageResolver(commandSpec);
- }
-
- public StandardWaitHelperProgressMonitor createProgressMonitor(boolean writeFinalStatus) {
- return noProgress ? null : new StandardWaitHelperProgressMonitor(messageResolver, writeFinalStatus);
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/rest/cli/mixin/UrlConfigOptions.java b/fcli-common/src/main/java/com/fortify/cli/common/rest/cli/mixin/UrlConfigOptions.java
deleted file mode 100644
index 866dd7a025..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/rest/cli/mixin/UrlConfigOptions.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.rest.cli.mixin;
-
-import com.fortify.cli.common.rest.runner.config.IUrlConfig;
-
-import io.micronaut.core.annotation.ReflectiveAccess;
-import lombok.Getter;
-import picocli.CommandLine.Option;
-
-/**
- * Configure connection options to a remote system
- *
- * @author Ruud Senden
- */
-@ReflectiveAccess
-public class UrlConfigOptions extends ConnectionConfigOptions implements IUrlConfig {
- @Option(names = {"--url"}, required = true, order=1)
- @Getter private String url;
-
- public boolean hasUrlConfig() {
- return url!=null;
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/rest/cli/mixin/WaitHelperControlOptions.java b/fcli-common/src/main/java/com/fortify/cli/common/rest/cli/mixin/WaitHelperControlOptions.java
deleted file mode 100644
index f43b7b92a8..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/rest/cli/mixin/WaitHelperControlOptions.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.fortify.cli.common.rest.cli.mixin;
-
-import com.fortify.cli.common.rest.wait.IWaitHelperControlProperties;
-import com.fortify.cli.common.rest.wait.WaitTimeoutAction;
-import com.fortify.cli.common.rest.wait.WaitUnknownOrFailureStateAction;
-import com.fortify.cli.common.rest.wait.WaitUnknownStateRequestedAction;
-
-import io.micronaut.core.annotation.ReflectiveAccess;
-import lombok.Getter;
-import picocli.CommandLine.Option;
-
-@ReflectiveAccess
-public class WaitHelperControlOptions implements IWaitHelperControlProperties {
- @Option(names= {"--on-unknown-state-requested"}, defaultValue = "fail")
- @Getter private WaitUnknownStateRequestedAction onUnknownStateRequested;
- @Option(names= {"--on-failure-state"}, defaultValue = "fail")
- @Getter private WaitUnknownOrFailureStateAction onFailureState;
- @Option(names= {"--on-unknown-state"}, defaultValue = "fail")
- @Getter private WaitUnknownOrFailureStateAction onUnknownState;
- @Option(names= {"--on-timeout"}, defaultValue = "fail")
- @Getter private WaitTimeoutAction onTimeout;
- @Option(names= {"--interval", "-i"}, defaultValue = "30s")
- @Getter private String intervalPeriod;
- @Option(names= {"--timeout", "-t"}, defaultValue = "1h")
- @Getter private String timeoutPeriod;
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/rest/cli/mixin/WaitHelperWaitOptions.java b/fcli-common/src/main/java/com/fortify/cli/common/rest/cli/mixin/WaitHelperWaitOptions.java
deleted file mode 100644
index f5de2e3770..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/rest/cli/mixin/WaitHelperWaitOptions.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package com.fortify.cli.common.rest.cli.mixin;
-
-import com.fortify.cli.common.rest.wait.IWaitHelperWaitDefinition;
-import com.fortify.cli.common.rest.wait.IWaitHelperWaitDefinitionSupplier;
-
-import io.micronaut.core.annotation.ReflectiveAccess;
-import lombok.Getter;
-import picocli.CommandLine.ArgGroup;
-import picocli.CommandLine.Option;
-
-@ReflectiveAccess
-public final class WaitHelperWaitOptions implements IWaitHelperWaitDefinitionSupplier {
- @Getter @ArgGroup(exclusive = true, multiplicity = "0..1")
- private WaitHelperWaitOptionsArgGroup waitDefinition = new WaitHelperWaitOptionsArgGroup();
-
- @ReflectiveAccess
- private static final class WaitHelperWaitOptionsArgGroup implements IWaitHelperWaitDefinition {
- @Option(names = {"--while-all"}, required = true, paramLabel = "[|]...")
- @Getter private String whileAll;
- @Option(names = {"--while-any", "--while", "-w"}, required = true, paramLabel = "[|]...")
- @Getter private String whileAny;
- @Option(names = {"--until-all", "--until", "-u"}, required = true, paramLabel = "[|]...")
- @Getter private String untilAll;
- @Getter @Option(names = {"--until-any"}, required = true, paramLabel = "[|]...")
- private String untilAny;
- }
-}
\ No newline at end of file
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/rest/cli/mixin/package-info.java b/fcli-common/src/main/java/com/fortify/cli/common/rest/cli/mixin/package-info.java
deleted file mode 100644
index 203e491a76..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/rest/cli/mixin/package-info.java
+++ /dev/null
@@ -1,5 +0,0 @@
-/**
- * This package defines a mixin for invoking arbitrary REST API endpoints.
- */
-package com.fortify.cli.common.rest.cli.mixin;
-
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/rest/paging/INextPageUrlProducer.java b/fcli-common/src/main/java/com/fortify/cli/common/rest/paging/INextPageUrlProducer.java
deleted file mode 100644
index 1c52a686e8..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/rest/paging/INextPageUrlProducer.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.fortify.cli.common.rest.paging;
-
-import com.fasterxml.jackson.databind.JsonNode;
-
-import kong.unirest.HttpResponse;
-
-public interface INextPageUrlProducer {
- String getNextPageUrl(HttpResponse jsonNodeResponse);
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/rest/paging/PagingHelper.java b/fcli-common/src/main/java/com/fortify/cli/common/rest/paging/PagingHelper.java
deleted file mode 100644
index 50c3e7974c..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/rest/paging/PagingHelper.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.fortify.cli.common.rest.paging;
-
-import com.fasterxml.jackson.databind.JsonNode;
-
-import kong.unirest.HttpRequest;
-import kong.unirest.PagedList;
-
-public class PagingHelper {
- @SuppressWarnings("unchecked") // TODO Can we get rid of this warning in a better way?
- public static final PagedList pagedRequest(HttpRequest> request, INextPageUrlProducer nextPageUrlProducer) {
- return request.asPaged(r->r.asObject(JsonNode.class), nextPageUrlProducer::getNextPageUrl);
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/GenericUnirestFactory.java b/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/GenericUnirestFactory.java
deleted file mode 100644
index de6127f1ad..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/GenericUnirestFactory.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.rest.runner;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-import io.micronaut.core.annotation.ReflectiveAccess;
-import jakarta.inject.Inject;
-import kong.unirest.Unirest;
-import kong.unirest.UnirestInstance;
-import kong.unirest.jackson.JacksonObjectMapper;
-import lombok.Getter;
-
-@ReflectiveAccess
-public final class GenericUnirestFactory {
- @Getter @Inject private ObjectMapper objectMapper;
-
- public final UnirestInstance createUnirestInstance() {
- UnirestInstance instance = Unirest.spawnInstance();
- instance.config().setObjectMapper(new JacksonObjectMapper(objectMapper));
- return instance;
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/GenericUnirestRunner.java b/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/GenericUnirestRunner.java
deleted file mode 100644
index 50ea481a25..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/GenericUnirestRunner.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.rest.runner;
-
-import java.util.function.Function;
-
-import io.micronaut.core.annotation.ReflectiveAccess;
-import jakarta.inject.Inject;
-import kong.unirest.UnirestInstance;
-
-@ReflectiveAccess
-public final class GenericUnirestRunner implements IUnirestRunner {
- @Inject private GenericUnirestFactory genericUnirestFactory;
-
- public final R run(Function f) {
- if ( f == null ) { throw new IllegalStateException("Function may not be null"); }
- try ( var unirestInstance = genericUnirestFactory.createUnirestInstance() ) {
- return f.apply(unirestInstance);
- }
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/IUnirestRunner.java b/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/IUnirestRunner.java
deleted file mode 100644
index 76a4925d81..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/IUnirestRunner.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.fortify.cli.common.rest.runner;
-
-import java.util.function.Function;
-
-import kong.unirest.UnirestInstance;
-
-public interface IUnirestRunner {
- R run(Function f);
-}
\ No newline at end of file
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/IUnirestWithSessionDataRunner.java b/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/IUnirestWithSessionDataRunner.java
deleted file mode 100644
index 96e3989721..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/IUnirestWithSessionDataRunner.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.fortify.cli.common.rest.runner;
-
-import java.util.function.BiFunction;
-
-import com.fortify.cli.common.session.manager.api.ISessionData;
-
-import kong.unirest.UnirestInstance;
-
-public interface IUnirestWithSessionDataRunner {
- R run(BiFunction f);
-}
\ No newline at end of file
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/IfFailureHandler.java b/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/IfFailureHandler.java
deleted file mode 100644
index a75f2eaa19..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/IfFailureHandler.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2020 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.rest.runner;
-
-import kong.unirest.HttpResponse;
-
-public class IfFailureHandler {
- public static final void handle(HttpResponse> failureResponse) {
- throw new UnexpectedHttpResponseException(failureResponse);
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/UnexpectedHttpResponseException.java b/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/UnexpectedHttpResponseException.java
deleted file mode 100644
index fd7b576bf5..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/UnexpectedHttpResponseException.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2020 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.rest.runner;
-
-import kong.unirest.HttpRequestSummary;
-import kong.unirest.HttpResponse;
-import kong.unirest.UnirestException;
-import lombok.Getter;
-
-public final class UnexpectedHttpResponseException extends UnirestException {
- private static final long serialVersionUID = 1L;
- @Getter private int status = 200;
-
- public UnexpectedHttpResponseException(HttpResponse> failureResponse) {
- super(getMessage(failureResponse), getCause(failureResponse));
- this.status = failureResponse.getStatus();
- }
-
- public UnexpectedHttpResponseException(HttpResponse> failureResponse, HttpRequestSummary requestSummary) {
- super(getMessage(failureResponse, requestSummary), getCause(failureResponse));
- this.status = failureResponse.getStatus();
- }
-
- private static final String getMessage(HttpResponse> failureResponse, HttpRequestSummary requestSummary) {
- var httpMethod = requestSummary.getHttpMethod().name();
- var url = requestSummary.getUrl();
- return String.format("\nRequest: %s %s: %s", httpMethod, url, getMessage(failureResponse));
- }
-
- private static final String getMessage(HttpResponse> failureResponse) {
- if ( isHttpFailure(failureResponse) ) {
- // TODO Better format response body if it's a standard XML or JSON response containing an msg property
- return String.format("\nResponse: %d %s\nResponse Body:\n%s", failureResponse.getStatus(), failureResponse.getStatusText(), failureResponse.getBody());
- } else if ( failureResponse.getParsingError().isPresent() ) {
- return "Error parsing response";
- } else {
- return "Unknown error";
- }
- }
-
- private static final Throwable getCause(HttpResponse> failureResponse) {
- return isHttpFailure(failureResponse) ? null : failureResponse.getParsingError().orElse(null);
- }
-
- private static final boolean isHttpFailure(HttpResponse> failureResponse) {
- int httpStatus = failureResponse.getStatus();
- return httpStatus < 200 || httpStatus >= 300;
- }
-}
\ No newline at end of file
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/config/IUrlConfig.java b/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/config/IUrlConfig.java
deleted file mode 100644
index ec7d3bf0e5..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/config/IUrlConfig.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2020 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.rest.runner.config;
-
-public interface IUrlConfig extends IConnectionConfig {
- String getUrl();
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/config/IUrlConfigSupplier.java b/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/config/IUrlConfigSupplier.java
deleted file mode 100644
index 58580e6824..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/config/IUrlConfigSupplier.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.rest.runner.config;
-
-public interface IUrlConfigSupplier {
- public IUrlConfig getUrlConfig();
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/config/IUserCredentialsConfig.java b/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/config/IUserCredentialsConfig.java
deleted file mode 100644
index 3c6a93b4a1..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/config/IUserCredentialsConfig.java
+++ /dev/null
@@ -1,6 +0,0 @@
-package com.fortify.cli.common.rest.runner.config;
-
-public interface IUserCredentialsConfig {
- public String getUser();
- public char[] getPassword();
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/config/UnirestBasicAuthConfigurer.java b/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/config/UnirestBasicAuthConfigurer.java
deleted file mode 100644
index 78a92fd217..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/config/UnirestBasicAuthConfigurer.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.rest.runner.config;
-
-import kong.unirest.UnirestInstance;
-
-public final class UnirestBasicAuthConfigurer {
- /**
- * Configure the given {@link UnirestInstance} to use basic authentication based on the
- * given {@link IUserCredentialsConfig} instance
- * @param unirestInstance {@link UnirestInstance} to be configured
- * @param userCredentialsConfig used to provide the basic authentication credentials {@link UnirestInstance}
- */
- public static final void configure(UnirestInstance unirestInstance, IUserCredentialsConfig userCredentialsConfig) {
- if ( unirestInstance==null ) { throw new IllegalArgumentException("Unirest instance may not be null"); }
- if ( userCredentialsConfig==null ) { throw new IllegalArgumentException("User credentials may not be null"); }
- unirestInstance.config()
- .setDefaultBasicAuth(userCredentialsConfig.getUser(), new String(userCredentialsConfig.getPassword()));
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/config/UnirestJsonHeaderConfigurer.java b/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/config/UnirestJsonHeaderConfigurer.java
deleted file mode 100644
index e80336cf64..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/config/UnirestJsonHeaderConfigurer.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.fortify.cli.common.rest.runner.config;
-
-import kong.unirest.UnirestInstance;
-
-public class UnirestJsonHeaderConfigurer {
- public static final void configure(UnirestInstance unirest) {
- unirest.config()
- .setDefaultHeader("Accept", "application/json")
- .setDefaultHeader("Content-Type", "application/json");
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/config/UnirestUnexpectedHttpResponseConfigurer.java b/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/config/UnirestUnexpectedHttpResponseConfigurer.java
deleted file mode 100644
index 1e8bbd1517..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/config/UnirestUnexpectedHttpResponseConfigurer.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2020 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.rest.runner.config;
-
-import com.fortify.cli.common.rest.runner.UnexpectedHttpResponseException;
-
-import kong.unirest.Config;
-import kong.unirest.HttpRequestSummary;
-import kong.unirest.HttpResponse;
-import kong.unirest.Interceptor;
-import kong.unirest.UnirestException;
-import kong.unirest.UnirestInstance;
-
-public class UnirestUnexpectedHttpResponseConfigurer implements Interceptor {
-
- public static final void configure(UnirestInstance unirestInstance) {
- unirestInstance.config().interceptor(UnexpectedHttpResponseInterceptor.INSTANCE);
- }
-
- private static final class UnexpectedHttpResponseInterceptor implements Interceptor {
- private static final UnexpectedHttpResponseInterceptor INSTANCE = new UnexpectedHttpResponseInterceptor();
-
- @Override
- public void onResponse(HttpResponse> response, HttpRequestSummary requestSummary, Config config) {
- if ( !response.isSuccess() ) {
- throw new UnexpectedHttpResponseException(response, requestSummary);
- }
- }
-
- @Override
- public HttpResponse> onFail(Exception e, HttpRequestSummary request, Config config) throws UnirestException {
- throw (e instanceof UnirestException) ? (UnirestException)e : new UnirestException(e);
- }
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/config/UnirestUrlConfigConfigurer.java b/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/config/UnirestUrlConfigConfigurer.java
deleted file mode 100644
index 8c6c91a78c..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/config/UnirestUrlConfigConfigurer.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.rest.runner.config;
-
-import kong.unirest.UnirestInstance;
-
-public final class UnirestUrlConfigConfigurer {
- /**
- * Configure the given {@link UnirestInstance} based on the given {@link IUrlConfig} instance
- * @param unirestInstance {@link UnirestInstance} to be configured
- * @param urlConfig used to configure the {@link UnirestInstance}
- */
- public static final void configure(UnirestInstance unirestInstance, IUrlConfig urlConfig) {
- if ( unirestInstance==null ) { throw new IllegalArgumentException("Unirest instance may not be null"); }
- if ( urlConfig==null ) { throw new IllegalArgumentException("URL configuration may not be null"); }
- unirestInstance.config()
- .defaultBaseUrl(normalizeUrl(urlConfig.getUrl()))
- .verifySsl(!urlConfig.isInsecureModeEnabled())
- .socketTimeout(urlConfig.getSocketTimeoutInMillis())
- .connectTimeout(urlConfig.getConnectTimeoutInMillis());
- }
-
- /**
- * Configure the given {@link UnirestInstance} based on the {@link IUrlConfig} returned
- * by the given {@link IUrlConfigSupplier} instance.
- * @param unirestInstance {@link UnirestInstance} to be configured
- * @param urlConfigSupplier used to configure the {@link UnirestInstance}
- */
- public static final void configure(UnirestInstance unirestInstance, IUrlConfigSupplier urlConfigSupplier) {
- if ( urlConfigSupplier==null ) { throw new IllegalArgumentException("URL configuration provider may not be null"); }
- configure(unirestInstance, urlConfigSupplier.getUrlConfig());
- }
-
- private static final String normalizeUrl(String url) {
- // We remove any trailing slashes, assuming that most users will specify relative URL's starting with /
- return url.replaceAll("/+$", "");
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/config/UrlConfig.java b/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/config/UrlConfig.java
deleted file mode 100644
index 4bd8c7885c..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/config/UrlConfig.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.rest.runner.config;
-
-import java.util.function.Consumer;
-
-import com.fortify.cli.common.util.StringUtils;
-
-import io.micronaut.core.annotation.ReflectiveAccess;
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-@Data @ReflectiveAccess @NoArgsConstructor @AllArgsConstructor @Builder
-public class UrlConfig implements IUrlConfig {
- private String url;
- private int socketTimeoutInMillis;
- private int connectTimeoutInMillis;
- private Boolean insecureModeEnabled;
-
- public static final UrlConfig from(IUrlConfig other) {
- return builderFrom(other).build();
- }
-
- public static final UrlConfigBuilder builderFrom(IUrlConfig other) {
- UrlConfigBuilder builder = UrlConfig.builder();
- if ( other!=null ) {
- builder = builder
- .url(other.getUrl())
- .insecureModeEnabled(other.isInsecureModeEnabled())
- .connectTimeoutInMillis(other.getConnectTimeoutInMillis())
- .socketTimeoutInMillis(other.getSocketTimeoutInMillis());
- }
- return builder;
- }
-
- public static final UrlConfigBuilder builderFrom(IUrlConfig other, IUrlConfig overrides) {
- UrlConfigBuilder builder = other==null ? builderFrom(overrides) : builderFrom(other);
- if ( other!=null && overrides!=null ) {
- override(overrides.getUrl(), builder::url);
- override(overrides.getInsecureModeEnabled(), builder::insecureModeEnabled);
- builder.connectTimeoutInMillis(overrides.getConnectTimeoutInMillis())
- .socketTimeoutInMillis(overrides.getSocketTimeoutInMillis());
- }
- return builder;
- }
-
- private static final void override(String value, Consumer setter) {
- if ( StringUtils.isNotBlank(value) ) { setter.accept(value); }
- }
-
- private static final void override(T value, Consumer setter) {
- if ( value!=null ) { setter.accept(value); }
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/config/package-info.java b/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/config/package-info.java
deleted file mode 100644
index a2b28e3844..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/config/package-info.java
+++ /dev/null
@@ -1,4 +0,0 @@
-/**
- * This package contains classes used for configuring a {@link kong.unirest.UnirestInstance}.
- */
-package com.fortify.cli.common.rest.runner.config;
\ No newline at end of file
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/package-info.java b/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/package-info.java
deleted file mode 100644
index 27e755c38f..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/rest/runner/package-info.java
+++ /dev/null
@@ -1,5 +0,0 @@
-/**
- * This package provides generic functionality for working with REST API's.
- */
-package com.fortify.cli.common.rest.runner;
-
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/rest/wait/IWaitHelperControlProperties.java b/fcli-common/src/main/java/com/fortify/cli/common/rest/wait/IWaitHelperControlProperties.java
deleted file mode 100644
index 4816478068..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/rest/wait/IWaitHelperControlProperties.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.fortify.cli.common.rest.wait;
-
-public interface IWaitHelperControlProperties {
- WaitUnknownStateRequestedAction getOnUnknownStateRequested();
- WaitUnknownOrFailureStateAction getOnFailureState();
- WaitUnknownOrFailureStateAction getOnUnknownState();
- WaitTimeoutAction getOnTimeout();
- String getIntervalPeriod();
- String getTimeoutPeriod();
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/rest/wait/IWaitHelperProgressMonitor.java b/fcli-common/src/main/java/com/fortify/cli/common/rest/wait/IWaitHelperProgressMonitor.java
deleted file mode 100644
index 7887007676..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/rest/wait/IWaitHelperProgressMonitor.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.fortify.cli.common.rest.wait;
-
-import java.util.Map;
-
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.fortify.cli.common.rest.wait.WaitHelper.WaitStatus;
-
-public interface IWaitHelperProgressMonitor {
- void updateProgress(Map recordsWithWaitStatus);
- void finish(Map recordsWithWaitStatus);
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/rest/wait/IWaitHelperWaitDefinition.java b/fcli-common/src/main/java/com/fortify/cli/common/rest/wait/IWaitHelperWaitDefinition.java
deleted file mode 100644
index 3f965519c6..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/rest/wait/IWaitHelperWaitDefinition.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package com.fortify.cli.common.rest.wait;
-
-public interface IWaitHelperWaitDefinition {
- String getWhileAll();
- String getWhileAny();
- String getUntilAll();
- String getUntilAny();
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/rest/wait/IWaitHelperWaitDefinitionSupplier.java b/fcli-common/src/main/java/com/fortify/cli/common/rest/wait/IWaitHelperWaitDefinitionSupplier.java
deleted file mode 100644
index ad88193050..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/rest/wait/IWaitHelperWaitDefinitionSupplier.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package com.fortify.cli.common.rest.wait;
-
-public interface IWaitHelperWaitDefinitionSupplier {
- public IWaitHelperWaitDefinition getWaitDefinition();
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/rest/wait/StandardWaitHelperProgressMonitor.java b/fcli-common/src/main/java/com/fortify/cli/common/rest/wait/StandardWaitHelperProgressMonitor.java
deleted file mode 100644
index 97f463266a..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/rest/wait/StandardWaitHelperProgressMonitor.java
+++ /dev/null
@@ -1,86 +0,0 @@
-package com.fortify.cli.common.rest.wait;
-
-import java.io.IOException;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.util.Map;
-
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.fortify.cli.common.output.OutputFormat;
-import com.fortify.cli.common.output.spi.transform.IActionCommandResultSupplier;
-import com.fortify.cli.common.output.writer.IMessageResolver;
-import com.fortify.cli.common.output.writer.record.IRecordWriter;
-import com.fortify.cli.common.output.writer.record.RecordWriterConfig;
-import com.fortify.cli.common.rest.wait.WaitHelper.WaitStatus;
-import com.fortify.cli.common.util.ProgressHelper;
-import com.fortify.cli.common.util.ProgressHelper.IProgressHelper;
-
-public class StandardWaitHelperProgressMonitor implements IWaitHelperProgressMonitor {
- private static final OutputFormat outputFormat = OutputFormat.table;
- private final IProgressHelper progressHelper = ProgressHelper.createProgressHelper();
- private final IMessageResolver messageResolver;
- private final boolean writeFinalStatus;
-
- public StandardWaitHelperProgressMonitor(IMessageResolver messageResolver, boolean writeFinalStatus) {
- this.messageResolver = messageResolver;
- this.writeFinalStatus = writeFinalStatus;
- }
-
- @Override
- public void updateProgress(Map recordsWithWaitStatus) {
- if ( progressHelper!=null ) {
- try ( StringWriter sw = new StringWriter() ) {
- if ( progressHelper.isMultiLineSupported() ) {
- writeRecordsMultiLine(recordsWithWaitStatus, sw);
- } else {
- writeRecordsSingleLine(recordsWithWaitStatus, sw);
- }
- String output = sw.toString();
- progressHelper.writeProgress(output);
- } catch ( IOException e ) {
- throw new RuntimeException(e);
- }
- }
- }
-
- @Override
- public void finish(Map recordsWithWaitStatus) {
- if ( writeFinalStatus ) {
- updateProgress(recordsWithWaitStatus);
- } else if ( progressHelper!=null ) {
- progressHelper.clearProgress();
- }
- }
-
- private void writeRecordsMultiLine(Map recordsWithWaitStatus, StringWriter sw) {
- try ( IRecordWriter recordWriter = createRecordWriter(sw, recordsWithWaitStatus.size()==1) ) {
- for ( Map.Entry entry : recordsWithWaitStatus.entrySet() ) {
- recordWriter.writeRecord(entry.getKey().put(IActionCommandResultSupplier.actionFieldName, entry.getValue().name()));
- }
- }
- }
-
- private void writeRecordsSingleLine(Map recordsWithWaitStatus, StringWriter sw) {
- long completeCount = recordsWithWaitStatus.values().stream().filter(s->s==WaitStatus.WAIT_COMPLETE).count();
- // TODO Should we differentiate on failure/unknown states?
- long waitingCount = recordsWithWaitStatus.size()-completeCount;
- sw.write(String.format("Wait completed: %s, waiting: %s", completeCount, waitingCount));
- }
-
- private IRecordWriter createRecordWriter(StringWriter sw, boolean singular) {
- RecordWriterConfig recordWriterConfig = createRecordWriterConfig(sw, singular);
- return outputFormat.getRecordWriterFactory().createRecordWriter(recordWriterConfig);
- }
-
- private RecordWriterConfig createRecordWriterConfig(Writer writer, boolean singular) {
- return RecordWriterConfig.builder()
- .singular(singular)
- .messageResolver(messageResolver)
- .addActionColumn(true)
- .writer(writer)
- .options(null)
- .outputFormat(outputFormat)
- .build();
- }
-
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/rest/wait/WaitTimeoutAction.java b/fcli-common/src/main/java/com/fortify/cli/common/rest/wait/WaitTimeoutAction.java
deleted file mode 100644
index c309db076d..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/rest/wait/WaitTimeoutAction.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package com.fortify.cli.common.rest.wait;
-
-public enum WaitTimeoutAction {
- terminate, fail
-}
\ No newline at end of file
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/rest/wait/WaitUnknownOrFailureStateAction.java b/fcli-common/src/main/java/com/fortify/cli/common/rest/wait/WaitUnknownOrFailureStateAction.java
deleted file mode 100644
index 4be372607b..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/rest/wait/WaitUnknownOrFailureStateAction.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package com.fortify.cli.common.rest.wait;
-
-public enum WaitUnknownOrFailureStateAction {
- wait, terminate, fail
-}
\ No newline at end of file
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/rest/wait/WaitUnknownStateRequestedAction.java b/fcli-common/src/main/java/com/fortify/cli/common/rest/wait/WaitUnknownStateRequestedAction.java
deleted file mode 100644
index c603f19bef..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/rest/wait/WaitUnknownStateRequestedAction.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package com.fortify.cli.common.rest.wait;
-
-public enum WaitUnknownStateRequestedAction {
- ignore, fail
-}
\ No newline at end of file
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/session/cli/cmd/AbstractSessionCommand.java b/fcli-common/src/main/java/com/fortify/cli/common/session/cli/cmd/AbstractSessionCommand.java
deleted file mode 100644
index 1c279accba..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/session/cli/cmd/AbstractSessionCommand.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.session.cli.cmd;
-
-import com.fortify.cli.common.output.cli.cmd.basic.AbstractBasicOutputCommand;
-import com.fortify.cli.common.session.manager.spi.ISessionDataManager;
-
-import io.micronaut.core.annotation.ReflectiveAccess;
-
-@ReflectiveAccess
-public abstract class AbstractSessionCommand extends AbstractBasicOutputCommand {
- protected abstract ISessionDataManager> getSessionDataManager();
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/session/cli/cmd/AbstractSessionListCommand.java b/fcli-common/src/main/java/com/fortify/cli/common/session/cli/cmd/AbstractSessionListCommand.java
deleted file mode 100644
index 1a21287fe6..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/session/cli/cmd/AbstractSessionListCommand.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.session.cli.cmd;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fortify.cli.common.output.cli.mixin.BasicOutputHelperMixins;
-
-import io.micronaut.core.annotation.ReflectiveAccess;
-import lombok.Getter;
-import picocli.CommandLine.Mixin;
-
-@ReflectiveAccess
-public abstract class AbstractSessionListCommand extends AbstractSessionCommand {
- @Getter @Mixin private BasicOutputHelperMixins.List outputHelper;
-
- @Override
- protected JsonNode getJsonNode() {
- return getSessionDataManager().sessionSummariesAsArrayNode();
- }
-
- @Override
- public boolean isSingular() {
- return false;
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/session/cli/cmd/AbstractSessionLoginCommand.java b/fcli-common/src/main/java/com/fortify/cli/common/session/cli/cmd/AbstractSessionLoginCommand.java
deleted file mode 100644
index 066d92f242..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/session/cli/cmd/AbstractSessionLoginCommand.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.session.cli.cmd;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fortify.cli.common.output.cli.mixin.BasicOutputHelperMixins;
-import com.fortify.cli.common.output.spi.transform.IActionCommandResultSupplier;
-import com.fortify.cli.common.session.cli.mixin.SessionNameMixin;
-import com.fortify.cli.common.session.manager.api.ISessionData;
-import com.fortify.cli.common.session.manager.spi.ISessionDataManager;
-import com.fortify.cli.common.util.FixInjection;
-
-import io.micronaut.core.annotation.ReflectiveAccess;
-import lombok.Getter;
-import picocli.CommandLine.Mixin;
-
-@ReflectiveAccess @FixInjection
-public abstract class AbstractSessionLoginCommand extends AbstractSessionCommand implements IActionCommandResultSupplier {
- private static final Logger LOG = LoggerFactory.getLogger(AbstractSessionLoginCommand.class);
- @Getter @Mixin private SessionNameMixin.OptionalParameter sessionNameMixin;
- @Getter @Mixin private BasicOutputHelperMixins.Login outputHelper;
-
- @Override
- protected JsonNode getJsonNode() {
- String sessionName = sessionNameMixin.getSessionName();
- ISessionDataManager sessionDataManager = getSessionDataManager();
- logoutIfSessionExists(sessionName);
- D authSessionData = login(sessionName);
- sessionDataManager.save(sessionName, authSessionData);
- testAuthenticatedConnection(sessionName);
- return sessionDataManager.sessionSummaryAsObjectNode(sessionName);
- }
-
- @Override
- public String getActionCommandResult() {
- return "CREATED";
- }
-
- @Override
- public boolean isSingular() {
- return true;
- }
-
- private void logoutIfSessionExists(String sessionName) {
- ISessionDataManager sessionDataManager = getSessionDataManager();
- if ( sessionDataManager.exists(sessionName) ) {
- try {
- logoutBeforeNewLogin(sessionName, sessionDataManager.get(sessionName, false));
- } catch ( Exception e ) {
- LOG.warn("Error logging out previous session");
- LOG.debug("Exception details:", e);
- } finally {
- sessionDataManager.destroy(sessionName);
- }
- }
- }
-
- protected abstract void logoutBeforeNewLogin(String sessionName, D sessionData);
- protected abstract D login(String sessionName);
- protected void testAuthenticatedConnection(String sessionName) {}
- protected abstract ISessionDataManager getSessionDataManager();
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/session/cli/cmd/AbstractSessionLogoutCommand.java b/fcli-common/src/main/java/com/fortify/cli/common/session/cli/cmd/AbstractSessionLogoutCommand.java
deleted file mode 100644
index 5eeba3ae2a..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/session/cli/cmd/AbstractSessionLogoutCommand.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.session.cli.cmd;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fortify.cli.common.output.cli.mixin.BasicOutputHelperMixins;
-import com.fortify.cli.common.output.spi.transform.IActionCommandResultSupplier;
-import com.fortify.cli.common.session.cli.mixin.SessionNameMixin;
-import com.fortify.cli.common.session.manager.api.ISessionData;
-import com.fortify.cli.common.session.manager.spi.ISessionDataManager;
-
-import io.micronaut.core.annotation.ReflectiveAccess;
-import lombok.Getter;
-import picocli.CommandLine.Mixin;
-
-@ReflectiveAccess
-public abstract class AbstractSessionLogoutCommand extends AbstractSessionCommand implements IActionCommandResultSupplier {
- @Getter @Mixin private SessionNameMixin.OptionalParameter sessionNameMixin;
- @Getter @Mixin private BasicOutputHelperMixins.Logout outputHelper;
-
- @Override
- protected JsonNode getJsonNode() {
- String sessionName = sessionNameMixin.getSessionName();
- JsonNode result = null;
- ISessionDataManager sessionDataManager = getSessionDataManager();
- if ( sessionDataManager.exists(sessionName) ) {
- result = sessionDataManager.sessionSummaryAsObjectNode(sessionName);
- logout(sessionName, sessionDataManager.get(sessionName, true));
- // TODO Optionally delete all variables
- getSessionDataManager().destroy(sessionName);
- }
- return result;
- }
-
- @Override
- public String getActionCommandResult() {
- return "TERMINATED";
- }
-
- @Override
- public boolean isSingular() {
- return false;
- }
-
- protected abstract void logout(String sessionName, D sessionData);
- protected abstract ISessionDataManager getSessionDataManager();
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/session/cli/mixin/SessionNameMixin.java b/fcli-common/src/main/java/com/fortify/cli/common/session/cli/mixin/SessionNameMixin.java
deleted file mode 100644
index 2e652d7d78..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/session/cli/mixin/SessionNameMixin.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.session.cli.mixin;
-
-import com.fortify.cli.common.cli.util.EnvSuffix;
-import com.fortify.cli.common.util.StringUtils;
-
-import io.micronaut.core.annotation.ReflectiveAccess;
-import picocli.CommandLine.ArgGroup;
-import picocli.CommandLine.Option;
-import picocli.CommandLine.Parameters;
-
-public class SessionNameMixin {
- @ReflectiveAccess
- private static abstract class AbstractSessionNameMixin {
- protected abstract String getSessionNameOrNull();
- public final String getSessionName() {
- return hasSessionName() ? getSessionNameOrNull() : "default";
- }
-
- public final boolean hasSessionName() {
- return StringUtils.isNotBlank(getSessionNameOrNull());
- }
- }
-
- @ReflectiveAccess
- public static class OptionalOption extends AbstractSessionNameMixin {
- @ArgGroup(headingKey = "arggroup.optional.session-name.heading", order = 20)
- private SessionNameArgGroup nameOptions = new SessionNameArgGroup();
-
- static class SessionNameArgGroup {
- @Option(names = {"--session"}, required = false)
- private String sessionName;
- }
- @Override
- protected String getSessionNameOrNull() {
- return nameOptions.sessionName;
- }
- }
-
- @ReflectiveAccess
- public static class OptionalParameter extends AbstractSessionNameMixin {
- @ArgGroup(headingKey = "arggroup.optional.session-name.heading", order = 1000)
- private SessionNameArgGroup nameOptions = new SessionNameArgGroup();
-
- static class SessionNameArgGroup {
- @Parameters(arity="0..1", index="0", paramLabel="session-name") @EnvSuffix("SESSION")
- private String sessionName;
- }
- @Override
- protected String getSessionNameOrNull() {
- return nameOptions.sessionName;
- }
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/session/cli/mixin/UserCredentialOptions.java b/fcli-common/src/main/java/com/fortify/cli/common/session/cli/mixin/UserCredentialOptions.java
deleted file mode 100644
index b3b30396b3..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/session/cli/mixin/UserCredentialOptions.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.session.cli.mixin;
-
-import com.fortify.cli.common.rest.runner.config.IUserCredentialsConfig;
-
-import io.micronaut.core.annotation.ReflectiveAccess;
-import lombok.Getter;
-import picocli.CommandLine.Option;
-
-@ReflectiveAccess
-public class UserCredentialOptions implements IUserCredentialsConfig {
- @Option(names = {"--user", "-u"}, required = true)
- @Getter private String user;
-
- @Option(names = {"--password", "-p"}, interactive = true, echo = false, arity = "0..1", required = true)
- @Getter private char[] password;
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/session/manager/api/ISessionData.java b/fcli-common/src/main/java/com/fortify/cli/common/session/manager/api/ISessionData.java
deleted file mode 100644
index 91f13cbbe7..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/session/manager/api/ISessionData.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2020 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.session.manager.api;
-
-import java.util.Date;
-
-import com.fasterxml.jackson.annotation.JsonIgnore;
-
-/**
- * Interface describing session data
- *
- * @author Ruud Senden
- */
-public interface ISessionData {
- @JsonIgnore String getUrlDescriptor();
- Date getCreatedDate();
- Date getExpiryDate();
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/session/manager/api/SessionSummary.java b/fcli-common/src/main/java/com/fortify/cli/common/session/manager/api/SessionSummary.java
deleted file mode 100644
index 057081decd..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/session/manager/api/SessionSummary.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.session.manager.api;
-
-import java.util.Date;
-
-import com.fasterxml.jackson.annotation.JsonFormat;
-
-import io.micronaut.core.annotation.ReflectiveAccess;
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-@Data @ReflectiveAccess @Builder @NoArgsConstructor @AllArgsConstructor
-public class SessionSummary {
- public static final Date EXPIRES_UNKNOWN = null;
- public static final Date EXPIRES_NEVER = new Date(Long.MAX_VALUE);
- private String name;
- private String type;
- private String url;
- @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss z")
- private Date created;
- @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss z")
- private Date expires;
-
- public String getExpired() {
- if ( expires==null ) {
- return "Unknown";
- } else if ( expires.after(new Date()) ) {
- return "No";
- } else {
- return "Yes";
- }
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/session/manager/api/package-info.java b/fcli-common/src/main/java/com/fortify/cli/common/session/manager/api/package-info.java
deleted file mode 100644
index a3983a9bd4..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/session/manager/api/package-info.java
+++ /dev/null
@@ -1,4 +0,0 @@
-/**
- * This package provides an API for managing authentication sessions.
- */
-package com.fortify.cli.common.session.manager.api;
\ No newline at end of file
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/session/manager/spi/AbstractSessionData.java b/fcli-common/src/main/java/com/fortify/cli/common/session/manager/spi/AbstractSessionData.java
deleted file mode 100644
index 961677794d..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/session/manager/spi/AbstractSessionData.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.session.manager.spi;
-
-import java.util.Date;
-
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fortify.cli.common.session.manager.api.ISessionData;
-
-import io.micronaut.core.annotation.ReflectiveAccess;
-import lombok.Data;
-
-@Data @ReflectiveAccess @JsonIgnoreProperties(ignoreUnknown = true)
-public abstract class AbstractSessionData implements ISessionData {
- private Date createdDate = new Date();
-
- /**
- * Subclasses may override this method to provide an actual session expiration date/time if available
- * @return Date/time when this session will expire
- */
- @JsonIgnore public Date getExpiryDate() {
- return null;
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/session/manager/spi/AbstractSessionDataManager.java b/fcli-common/src/main/java/com/fortify/cli/common/session/manager/spi/AbstractSessionDataManager.java
deleted file mode 100644
index bd444c6197..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/session/manager/spi/AbstractSessionDataManager.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.session.manager.spi;
-
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-import java.util.Objects;
-import java.util.function.Supplier;
-import java.util.stream.Collectors;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.fortify.cli.common.json.JsonHelper;
-import com.fortify.cli.common.session.manager.api.ISessionData;
-import com.fortify.cli.common.session.manager.api.SessionSummary;
-import com.fortify.cli.common.util.FcliHomeHelper;
-import com.fortify.cli.common.util.FixInjection;
-
-import io.micronaut.core.annotation.ReflectiveAccess;
-import jakarta.inject.Inject;
-import lombok.Getter;
-import lombok.SneakyThrows;
-
-@ReflectiveAccess @FixInjection
-public abstract class AbstractSessionDataManager implements ISessionDataManager {
- private static final Logger LOG = LoggerFactory.getLogger(AbstractSessionDataManager.class);
- @Getter @Inject private ObjectMapper objectMapper;
-
- @Override
- @SneakyThrows // TODO Do we want to use SneakyThrows?
- public final T get(String sessionName, boolean failIfUnavailable) {
- Path authSessionDataPath = Paths.get("sessions", getSessionTypeName(), sessionName);
- checkSessionExists(sessionName, failIfUnavailable);
- try {
- String authSessionDataJson = FcliHomeHelper.readSecuredFile(authSessionDataPath, failIfUnavailable);
- T authSessionData = authSessionDataJson==null ? null : objectMapper.readValue(authSessionDataJson, getSessionDataType());
- checkNonExpiredSessionAvailable(sessionName, failIfUnavailable, authSessionData);
- return authSessionData;
- } catch ( Exception e ) {
- FcliHomeHelper.deleteFile(authSessionDataPath, false);
- conditionalThrow(failIfUnavailable, ()->new IllegalStateException("Error reading auth session data, please try logging in again", e));
- LOG.warn("Error reading session data from {}; session data has been deleted", authSessionDataPath);
- LOG.warn("Exception details: ", e);
- return null;
- }
- }
-
- @Override
- @SneakyThrows // TODO Do we want to use SneakyThrows?
- public final void save(String sessionName, T sessionData) {
- String authSessionDataJson = objectMapper.writeValueAsString(sessionData);
- FcliHomeHelper.saveSecuredFile(Paths.get("sessions", getSessionTypeName(), sessionName), authSessionDataJson, true);
- }
-
- @Override
- @SneakyThrows // TODO Do we want to use SneakyThrows?
- public final void destroy(String sessionName) {
- FcliHomeHelper.deleteFile(Paths.get("sessions", getSessionTypeName(), sessionName), true);
- }
-
- @Override
- public final boolean exists(String sessionName) {
- return FcliHomeHelper.isReadable(Paths.get("sessions", getSessionTypeName(), sessionName));
- }
-
- @Override
- @SneakyThrows // TODO Do we want to use SneakyThrows?
- public final List sessionNames() {
- Path path = Paths.get("sessions", getSessionTypeName());
- if ( !FcliHomeHelper.exists(path) ) {
- return Collections.emptyList();
- }
- return FcliHomeHelper.listFilesInDir(path, true)
- .map(Path::getFileName)
- .map(Path::toString)
- .collect(Collectors.toList());
- }
-
- @Override
- public final Collection sessionSummaries() {
- return sessionNames().stream()
- .map(this::getSessionSummary)
- .filter(Objects::nonNull)
- .collect(Collectors.toList());
- }
-
- @Override
- public final ArrayNode sessionSummariesAsArrayNode() {
- return sessionSummaries().stream()
- .map(objectMapper::valueToTree)
- .map(JsonNode.class::cast) // TODO Not sure why this is necessary
- .collect(JsonHelper.arrayNodeCollector());
- }
-
- @Override
- public ObjectNode sessionSummaryAsObjectNode(String sessionName) {
- return objectMapper.valueToTree(getSessionSummary(sessionName));
- }
-
- private SessionSummary getSessionSummary(String sessionName) {
- T sessionData = get(sessionName, false);
- return sessionData==null ? null :
- SessionSummary.builder()
- .name(sessionName)
- .type(getSessionTypeName())
- .url(sessionData.getUrlDescriptor())
- .created(sessionData.getCreatedDate())
- .expires(sessionData.getExpiryDate())
- .build();
- }
-
- private void conditionalThrow(boolean throwException, Supplier exceptionSupplier) {
- if ( throwException ) { throw exceptionSupplier.get(); }
- }
-
- private void checkNonExpiredSessionAvailable(String sessionName, boolean failIfUnavailable, T authSessionData) {
- if ( failIfUnavailable && isExpiredOrUnavailable(authSessionData) )
- {
- throw new IllegalStateException(getSessionTypeName()+" session '"+sessionName+"' cannot be retrieved or has expired, please login again");
- }
- }
-
- private void checkSessionExists(String sessionName, boolean failIfUnavailable) {
- if ( failIfUnavailable && !exists(sessionName) ) {
- throw new IllegalStateException(getSessionTypeName()+" session '"+sessionName+"' not found, please login first");
- }
- }
-
- private boolean isExpiredOrUnavailable(T authSessionData) {
- return authSessionData==null ||
- (authSessionData.getExpiryDate()!=null // We don't know whether session is expired if expiryDate is null
- && authSessionData.getExpiryDate().before(new Date()));
- }
-
- @Override
- public abstract String getSessionTypeName();
-
- protected abstract Class getSessionDataType();
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/session/manager/spi/AbstractSessionDataWithSingleUrlConfig.java b/fcli-common/src/main/java/com/fortify/cli/common/session/manager/spi/AbstractSessionDataWithSingleUrlConfig.java
deleted file mode 100644
index ad00e3aed8..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/session/manager/spi/AbstractSessionDataWithSingleUrlConfig.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.session.manager.spi;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
-import com.fortify.cli.common.rest.runner.config.IUrlConfig;
-import com.fortify.cli.common.rest.runner.config.IUrlConfigSupplier;
-import com.fortify.cli.common.rest.runner.config.UrlConfig;
-import com.fortify.cli.common.session.manager.api.ISessionData;
-
-import io.micronaut.core.annotation.ReflectiveAccess;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.ToString;
-
-@Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) @ReflectiveAccess @JsonIgnoreProperties(ignoreUnknown = true)
-public abstract class AbstractSessionDataWithSingleUrlConfig extends AbstractSessionData implements ISessionData, IUrlConfigSupplier {
- @JsonDeserialize(as = UrlConfig.class) private IUrlConfig urlConfig;
-
- // No-arg constructor required for Jackson deserialization
- protected AbstractSessionDataWithSingleUrlConfig() {}
-
- public AbstractSessionDataWithSingleUrlConfig(IUrlConfig urlConfig) {
- this.urlConfig = urlConfig;
- }
-
- @Override
- public String getUrlDescriptor() {
- return urlConfig==null ? "Unknown" : urlConfig.getUrl();
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/session/manager/spi/ISessionDataManager.java b/fcli-common/src/main/java/com/fortify/cli/common/session/manager/spi/ISessionDataManager.java
deleted file mode 100644
index 7aca2519b7..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/session/manager/spi/ISessionDataManager.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.fortify.cli.common.session.manager.spi;
-
-import java.util.Collection;
-import java.util.List;
-
-import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.fortify.cli.common.session.manager.api.ISessionData;
-import com.fortify.cli.common.session.manager.api.SessionSummary;
-
-public interface ISessionDataManager {
- T get(String sessionName, boolean failIfUnavailable);
- void save(String sessionName, T sessionData);
- void destroy(String sessionName);
- boolean exists(String sessionName);
- List sessionNames();
- Collection sessionSummaries();
- String getSessionTypeName();
- ArrayNode sessionSummariesAsArrayNode();
- ObjectNode sessionSummaryAsObjectNode(String sessionName);
-}
\ No newline at end of file
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/session/manager/spi/package-info.java b/fcli-common/src/main/java/com/fortify/cli/common/session/manager/spi/package-info.java
deleted file mode 100644
index aba1e015e3..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/session/manager/spi/package-info.java
+++ /dev/null
@@ -1,6 +0,0 @@
-/**
- * This package contains the Service Provider Interface for system-specific
- * session managers, containing interfaces and abstract classes to be
- * implemented by such providers.
- */
-package com.fortify.cli.common.session.manager.spi;
\ No newline at end of file
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/util/CommandSpecHelper.java b/fcli-common/src/main/java/com/fortify/cli/common/util/CommandSpecHelper.java
deleted file mode 100644
index 57bb515b3d..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/util/CommandSpecHelper.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package com.fortify.cli.common.util;
-
-import java.lang.annotation.Annotation;
-import java.util.ResourceBundle;
-
-import picocli.CommandLine.Model.CommandSpec;
-import picocli.CommandLine.Model.Messages;
-
-public class CommandSpecHelper {
- public static final T findAnnotation(CommandSpec commandSpec, Class annotationType) {
- T annotation = null;
- while ( commandSpec!=null && annotation==null ) {
- Object cmd = commandSpec.userObject();
- annotation = cmd==null ? null : cmd.getClass().getAnnotation(annotationType);
- commandSpec = commandSpec.parent();
- }
- return annotation;
- }
-
- public static final String getMessageString(CommandSpec commandSpec, String keySuffix) {
- Messages messages = getMessages(commandSpec);
- String value = null;
- while ( commandSpec!=null && value==null ) {
- String key = commandSpec.qualifiedName(".")+"."+keySuffix;
- value = messages.getString(key, null);
- commandSpec = commandSpec.parent();
- }
- // If value is still null, try without any prefix
- return value!=null ? value : messages.getString(keySuffix, null);
- }
-
- /**
- * @param commandSpec {@link CommandSpec} instance for looking up a {@link ResourceBundle}
- * @return {@link Messages} instance for the given {@link CommandSpec},
- * or null if {@link CommandSpec} doesn't have a {@link ResourceBundle}
- */
- public static final Messages getMessages(CommandSpec commandSpec) {
- ResourceBundle resourceBundle = commandSpec.resourceBundle();
- return resourceBundle==null ? null : new Messages(commandSpec, resourceBundle);
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/util/DateTimePeriodHelper.java b/fcli-common/src/main/java/com/fortify/cli/common/util/DateTimePeriodHelper.java
deleted file mode 100644
index 75fd6ba54e..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/util/DateTimePeriodHelper.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2020 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.util;
-
-import java.time.Duration;
-import java.time.Instant;
-import java.time.OffsetDateTime;
-import java.time.ZoneOffset;
-import java.time.temporal.ChronoUnit;
-import java.time.temporal.TemporalUnit;
-import java.util.Date;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import lombok.Getter;
-import lombok.RequiredArgsConstructor;
-
-public class DateTimePeriodHelper {
- private final Pattern periodPattern;
-
- @RequiredArgsConstructor @Getter
- public static enum Period {
- SECONDS("s", ChronoUnit.SECONDS),
- MINUTES("m", ChronoUnit.MINUTES),
- HOURS("h", ChronoUnit.HOURS),
- DAYS("d", ChronoUnit.DAYS),
- WEEKS("w", ChronoUnit.WEEKS),
- MONTHS("M", ChronoUnit.MONTHS),
- YEARS("y", ChronoUnit.YEARS)
- ;
-
- private final String type;
- private final TemporalUnit unit;
-
- public static final Period[] getRange(Period min, Period max) {
- return Stream.of(Period.values())
- .filter(p->p.ordinal()>=min.ordinal())
- .filter(p->p.ordinal()<=max.ordinal())
- .toArray(Period[]::new);
- }
-
- public static final Period getByType(String type) {
- return Stream.of(Period.values()).filter(p->p.getType().equals(type)).findFirst().get();
- }
- }
-
- public DateTimePeriodHelper(Period... periods) {
- this.periodPattern = buildPeriodPattern(periods);
- }
-
- public static final DateTimePeriodHelper byRange(Period min, Period max) {
- return new DateTimePeriodHelper(Period.getRange(min, max));
- }
-
- private Pattern buildPeriodPattern(Period... periods) {
- String patternString = String.format("([0-9]+)([%s])", Stream.of(periods).map(Period::getType).collect(Collectors.joining("")));
- return Pattern.compile(patternString);
- }
-
- public long parsePeriodToEpochMillis(String periodString){
- if(periodString == null) return 0;
- Matcher matcher = periodPattern.matcher(periodString);
- Instant instant=Instant.EPOCH;
- while(matcher.find()){
- int num = Integer.parseInt(matcher.group(1));
- String type = matcher.group(2);
- Period period = Period.getByType(type);
- instant=instant.plus(Duration.of(num, period.getUnit()));
- }
- return instant.toEpochMilli();
- }
-
- public long parsePeriodToMillis(String periodString) {
- return parsePeriodToEpochMillis(periodString)-Instant.EPOCH.toEpochMilli();
- }
-
- public final Date getCurrentDatePlusPeriod(String period) {
- return new Date(System.currentTimeMillis() + parsePeriodToEpochMillis(period));
- }
-
- public final OffsetDateTime getCurrentOffsetDateTimePlusPeriod(String period) {
- return OffsetDateTime.now(ZoneOffset.UTC).plusNanos(parsePeriodToEpochMillis(period)*1000000);
- }
-
- public final OffsetDateTime getCurrentOffsetDateTimeMinusPeriod(String period) {
- return OffsetDateTime.now(ZoneOffset.UTC).minusNanos(parsePeriodToEpochMillis(period)*1000000);
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/util/EncryptionHelper.java b/fcli-common/src/main/java/com/fortify/cli/common/util/EncryptionHelper.java
deleted file mode 100644
index 5331cb44ee..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/util/EncryptionHelper.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.util;
-
-import java.io.IOException;
-import java.io.StringWriter;
-import java.io.Writer;
-
-import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
-import org.jasypt.iv.RandomIvGenerator;
-
-import lombok.RequiredArgsConstructor;
-
-public class EncryptionHelper {
- private static final StandardPBEStringEncryptor encryptor = createAES256TextEncryptor();
- public static final String encrypt(String source) {
- if ( source==null ) { return null; }
- return encryptor.encrypt(source);
- }
-
- public static final String decrypt(String source) {
- if ( source==null ) { return null; }
- return encryptor.decrypt(source);
- }
-
- private static final StandardPBEStringEncryptor createAES256TextEncryptor() {
- var encryptor = new StandardPBEStringEncryptor();
- encryptor.setAlgorithm("PBEWithHMACSHA512AndAES_256");
- encryptor.setIvGenerator(new RandomIvGenerator());
- encryptor.setPassword(getEncryptPassword());
- return encryptor;
- }
-
- private static final String getEncryptPassword() {
- String userPassword = System.getenv("FCLI_ENCRYPT_KEY");
- userPassword = StringUtils.isBlank(userPassword) ? "" : userPassword;
- return userPassword+"ds$%YTjdwaf#$47672dfdsGVFDa";
- }
-
- @RequiredArgsConstructor
- // TODO Can we optimize this to not buffer the full contents before encrypting and writing the output?
- public static final class EncryptWriter extends StringWriter {
- private final Writer originalWriter;
-
- @Override
- public void close() throws IOException {
- originalWriter.write(encrypt(getBuffer().toString()));
- originalWriter.flush();
- originalWriter.close();
- }
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/util/EnvHelper.java b/fcli-common/src/main/java/com/fortify/cli/common/util/EnvHelper.java
deleted file mode 100644
index af68f97c9b..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/util/EnvHelper.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.util;
-
-public final class EnvHelper {
- private static final String PFX = "FCLI";
- private EnvHelper() {}
-
- public static final void checkSecondaryWithoutPrimary(String secondaryEnvName, String primaryEnvName) {
- if ( env(primaryEnvName)==null && env(secondaryEnvName)!=null ) {
- throw new IllegalStateException("Environment variable "+secondaryEnvName+" requires "+primaryEnvName+" to be set as well");
- }
- }
-
- public static final void checkBothOrNone(String envName1, String envName2) {
- checkSecondaryWithoutPrimary(envName1, envName2);
- checkSecondaryWithoutPrimary(envName2, envName1);
- }
-
- public static final void checkExclusive(String envName1, String envName2) {
- if ( env(envName1)!=null && env(envName2)!=null ) {
- throw new IllegalStateException("Only one of "+envName1+" and "+envName2+" environment variables may be configured");
- }
- }
-
- public static final String envNameWithOrWithoutProductEnvId(String productEnvId, String suffix) {
- String envNameWithProductName = envName(productEnvId, suffix);
- String envValueWithProductName = env(envNameWithProductName);
- String envNameWithoutProductName = envName(null, suffix);
- String envValueWithoutProductName = env(envNameWithoutProductName);
- boolean hasEnvValueWithProductName = StringUtils.isNotBlank(envValueWithProductName);
- boolean hasEnvValueWithoutProductName = StringUtils.isNotBlank(envValueWithoutProductName);
- return hasEnvValueWithProductName || !hasEnvValueWithoutProductName
- ? envNameWithProductName
- : envNameWithoutProductName;
- }
-
- public static final String envName(String productEnvId, String suffix) {
- return StringUtils.isBlank(productEnvId)
- ? String.format("%s_%s", PFX, suffix)
- : String.format("%s_%s_%s", PFX, productEnvId, suffix);
- }
-
- public static final String env(String name) {
- return System.getenv(name);
- }
-
- public static final Boolean asBoolean(String s) {
- return "true".equalsIgnoreCase(s) || "1".equals(s);
- }
-
- public static final char[] asCharArray(String s) {
- return s==null ? null : s.toCharArray();
- }
-
- public static final Integer asInteger(String s) {
- return s==null ? null : Integer.parseInt(s);
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/util/FcliBuildPropertiesHelper.java b/fcli-common/src/main/java/com/fortify/cli/common/util/FcliBuildPropertiesHelper.java
deleted file mode 100644
index 9f1a338015..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/util/FcliBuildPropertiesHelper.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.fortify.cli.common.util;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Properties;
-
-public class FcliBuildPropertiesHelper {
- private static final Properties buildProperties = loadProperties();
-
- public static final Properties getBuildProperties() {
- return buildProperties;
- }
-
- private static final Properties loadProperties() {
- final Properties p = new Properties();
- try (final InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream("com/fortify/cli/app/fcli-build.properties")) {
- if ( stream!=null ) { p.load(stream); }
- } catch ( IOException ioe ) {
- throw new RuntimeException("Error reading fcli-build.properties from classpath", ioe);
- }
- return p;
- }
-
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/util/FcliHomeHelper.java b/fcli-common/src/main/java/com/fortify/cli/common/util/FcliHomeHelper.java
deleted file mode 100644
index 6a4f1888df..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/util/FcliHomeHelper.java
+++ /dev/null
@@ -1,197 +0,0 @@
-package com.fortify.cli.common.util;
-
-import static java.nio.file.StandardOpenOption.*;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.FileSystems;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.attribute.PosixFilePermissions;
-import java.util.Comparator;
-import java.util.stream.Stream;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fortify.cli.common.json.JsonHelper;
-
-public class FcliHomeHelper {
- private static final String ENVNAME_FORTIFY_HOME = "FORTIFY_HOME";
- private static final String ENVNAME_FCLI_HOME = "FCLI_HOME";
- private static final String DEFAULT_FORTIFY_DIR_NAME = ".fortify";
- private static final String DEFAULT_FCLI_DIR_NAME = "fcli";
- private static final Logger LOG = LoggerFactory.getLogger(FcliHomeHelper.class);
- private static final ObjectMapper objectMapper = JsonHelper.getObjectMapper();
-
- public static final Path getFortifyHomePath() {
- String fortifyHome = System.getenv(ENVNAME_FORTIFY_HOME);
- return StringUtils.isNotBlank(fortifyHome)
- ? Path.of(fortifyHome).toAbsolutePath()
- : Path.of(System.getProperty("user.home"), DEFAULT_FORTIFY_DIR_NAME).toAbsolutePath();
- }
-
- public static final Path getFcliHomePath() {
- String fcliHome = System.getenv(ENVNAME_FCLI_HOME);
- return StringUtils.isNotBlank(fcliHome)
- ? Path.of(fcliHome).toAbsolutePath()
- : getFortifyHomePath().resolve(DEFAULT_FCLI_DIR_NAME).toAbsolutePath();
- }
-
- public static final Path getFcliConfigPath() {
- return getFcliHomePath().resolve("config");
- }
-
- public static final void saveSecuredFile(Path relativePath, Object contents, boolean failOnError) {
- if ( contents == null ) {
- throwOrLog("Contents may not be null", null, failOnError);
- }
- try {
- String stringContents = contents instanceof String
- ? (String)contents
- : objectMapper.writeValueAsString(contents);
- saveFile(relativePath, EncryptionHelper.encrypt(stringContents), failOnError);
- } catch (JsonProcessingException e) {
- throwOrLog("Error serializing contents as String for class "+contents.getClass().getName(), e, failOnError);
- }
- }
-
- public static final String readSecuredFile(Path relativePath, boolean failOnError) {
- return readSecuredFile(relativePath, String.class, failOnError);
- }
-
-
- @SuppressWarnings("unchecked")
- public static final T readSecuredFile(Path relativePath, Class returnType, boolean failOnError) {
- String contents = EncryptionHelper.decrypt(readFile(relativePath, failOnError));
- return String.class.isAssignableFrom(returnType)
- ? (T)contents
- : JsonHelper.jsonStringToValue(readSecuredFile(relativePath, failOnError), returnType);
- }
-
- public static final void saveFile(Path relativePath, Object contents, boolean failOnError) {
- if ( contents == null ) {
- throwOrLog("Contents may not be null", null, failOnError);
- }
- try {
- String stringContents = contents instanceof String
- ? (String)contents
- : objectMapper.writeValueAsString(contents);
- final Path filePath = resolveFcliHomePath(relativePath);
- final Path parentDir = filePath.getParent();
- if (!Files.exists(parentDir)) {
- try {
- Files.createDirectories(parentDir);
- } catch ( IOException e ) {
- throwOrLog("Error creating parent directories for "+filePath, e, failOnError);
- }
- }
- writeFileWithOwnerOnlyPermissions(filePath, stringContents, failOnError);
- } catch (JsonProcessingException e ) {
- throwOrLog("Error serializing contents as String for class "+contents.getClass().getName(), e, failOnError);
- }
- }
-
- private static void writeFileWithOwnerOnlyPermissions(final Path filePath, final String contents, boolean failOnError) {
- try {
- Files.writeString(filePath, "", CREATE, WRITE, TRUNCATE_EXISTING);
- if ( FileSystems.getDefault().supportedFileAttributeViews().contains("posix") ) {
- Files.setPosixFilePermissions(filePath, PosixFilePermissions.fromString("rw-------"));
- } else {
- File file = filePath.toFile();
- file.setExecutable(false, false);
- file.setReadable(true, true);
- file.setWritable(true, true);
- }
- Files.writeString(filePath, contents, CREATE, WRITE, TRUNCATE_EXISTING);
- } catch ( IOException e ) {
- throwOrLog("Error writing file "+filePath, e, failOnError);
- }
- }
-
- public static final String readFile(Path relativePath, boolean failOnError) {
- return readFile(relativePath, String.class, failOnError);
- }
-
- @SuppressWarnings("unchecked")
- public static final R readFile(Path relativePath, Class returnType, boolean failOnError) {
- final Path filePath = resolveFcliHomePath(relativePath);
- try {
- String contents = Files.readString(filePath);
- return String.class.isAssignableFrom(returnType)
- ? (R)contents
- : JsonHelper.jsonStringToValue(contents, returnType);
- } catch ( IOException e ) {
- throwOrLog("Error reading file "+filePath, e, failOnError);
- return null;
- }
- }
-
- public static final boolean isReadable(Path relativePath) {
- final Path filePath = resolveFcliHomePath(relativePath);
- return Files.isReadable(filePath);
- }
-
- public static final Stream listFilesInDir(Path relativePath, boolean failOnError) {
- Stream stream = listDir(relativePath, failOnError);
- return stream ==null ? null : stream.filter(Files::isRegularFile);
- }
-
- public static final Stream listDirsInDir(Path relativePath, boolean failOnError) {
- Stream stream = listDir(relativePath, failOnError);
- return stream==null ? null : stream.filter(Files::isDirectory);
- }
-
- public static final Stream listDir(Path relativePath, boolean failOnError) {
- final Path dirPath = resolveFcliHomePath(relativePath);
- try {
- return Files.list(dirPath);
- } catch ( IOException e ) {
- throwOrLog("Error getting directory listing for "+dirPath, e, failOnError);
- return null;
- }
- }
-
- public static final void deleteFile(Path relativePath, boolean failOnError) {
- final Path filePath = resolveFcliHomePath(relativePath);
- try {
- Files.deleteIfExists(filePath);
- } catch ( IOException e ) {
- throwOrLog("Error deleting file "+filePath, e, failOnError);
- }
- }
-
- public static final void deleteDir(Path relativePath, boolean failOnError) {
- final Path filePath = resolveFcliHomePath(relativePath);
- try {
- Files.walk(filePath)
- .sorted(Comparator.reverseOrder())
- .map(Path::toFile)
- .forEach(File::delete);
- } catch ( IOException e ) {
- throwOrLog("Error recursively deleting directory "+filePath, e, failOnError);
- }
- }
-
- public static final boolean exists(Path relativePath) {
- final Path filePath = resolveFcliHomePath(relativePath);
- return Files.exists(filePath);
- }
-
- public static Path resolveFcliHomePath(Path relativePath) {
- if ( relativePath.isAbsolute() && !relativePath.toAbsolutePath().startsWith(getFcliHomePath()) ) {
- throw new IllegalArgumentException(String.format("Path %s is not within fcli home directory", relativePath));
- }
- return getFcliHomePath().resolve(relativePath);
- }
-
- private static final void throwOrLog(String msg, Exception e, boolean failOnError) {
- if ( failOnError ) {
- throw new RuntimeException(msg, e);
- } else {
- LOG.info(msg, e);
- }
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/util/FixInjection.java b/fcli-common/src/main/java/com/fortify/cli/common/util/FixInjection.java
deleted file mode 100644
index f38803fa63..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/util/FixInjection.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package com.fortify.cli.common.util;
-
-import static java.lang.annotation.ElementType.TYPE;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Inherited;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import jakarta.inject.Inject;
-import jakarta.inject.Qualifier;
-
-/**
- * For some reason, Micronaut/picocli fail to inject fields annotated
- * with {@link Inject} in (abstract) superclasses used by command
- * implementation. Although unclear why, having this annotation present
- * fixes this issue. See https://github.com/remkop/picocli/issues/1794
- * for details.
- *
- * @author rsenden
- *
- */
-@Qualifier
-@Retention(RUNTIME)
-@Target(TYPE)
-@Inherited
-public @interface FixInjection {}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/util/ProgressHelper.java b/fcli-common/src/main/java/com/fortify/cli/common/util/ProgressHelper.java
deleted file mode 100644
index 541dae1022..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/util/ProgressHelper.java
+++ /dev/null
@@ -1,86 +0,0 @@
-package com.fortify.cli.common.util;
-
-import picocli.CommandLine.Help.Ansi;
-
-public final class ProgressHelper {
- private static final boolean hasConsole = System.console()!=null;
- private static final boolean hasAnsiConsole = Ansi.AUTO.enabled() && hasConsole;
- private static final String LINE_UP = "\033[1A";
- private static final String LINE_CLEAR = "\033[2K";
- private static final String LINE_START = "\r";
-
- private ProgressHelper() {}
-
- public static final IProgressHelper createProgressHelper() {
- if ( hasAnsiConsole ) { return new AnsiConsoleProgressHelper(); }
- else if ( hasConsole ) { return new BasicConsoleProgressHelper(); }
- else { return new BasicProgressHelper(); }
- }
-
- public static interface IProgressHelper {
- boolean isMultiLineSupported();
- void writeProgress(String message);
- void clearProgress();
- }
-
- private static final class BasicProgressHelper implements IProgressHelper {
- @Override
- public boolean isMultiLineSupported() {
- return true;
- }
-
- @Override
- public void writeProgress(String message) {
- System.out.println(message+"\n");
- }
-
- @Override
- public void clearProgress() {}
- }
-
- private static final class BasicConsoleProgressHelper implements IProgressHelper {
- private int lastNumberOfChars;
-
- @Override
- public boolean isMultiLineSupported() {
- return false;
- }
-
- @Override
- public void writeProgress(String message) {
- if ( message.contains("\n") ) { throw new RuntimeException("Multiline status updates are not supported; please file a bug"); }
- clearProgress();
- System.out.print(message);
- this.lastNumberOfChars = message.length();
- }
-
- @Override
- public void clearProgress() {
- System.out.print(LINE_START+" ".repeat(lastNumberOfChars)+LINE_START);
- }
- }
-
- private static final class AnsiConsoleProgressHelper implements IProgressHelper {
- private int lastNumberOfLines = 0;
-
- @Override
- public boolean isMultiLineSupported() {
- return true;
- }
-
- @Override
- public void writeProgress(String message) {
- clearProgress();
- System.out.print(message);
- this.lastNumberOfLines = (int)message.chars().filter(ch -> ch == '\n').count();
- }
-
- @Override
- public void clearProgress() {
- // TODO Any way we can use ESC[3J to clear all saved lines, instead of removing lines one-by-one?
- // Not sure what escape code to use for 'start lines to be saved'...
- System.out.print((LINE_CLEAR+LINE_UP).repeat(lastNumberOfLines)+LINE_CLEAR+LINE_START);
- lastNumberOfLines = 0;
- }
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/util/StringUtils.java b/fcli-common/src/main/java/com/fortify/cli/common/util/StringUtils.java
deleted file mode 100644
index e73cf5b4da..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/util/StringUtils.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package com.fortify.cli.common.util;
-
-public class StringUtils {
- private StringUtils() {}
-
- public static final boolean isBlank(String s) {
- return s==null || s.isBlank();
- }
-
- public static final boolean isNotBlank(String s) {
- return !isBlank(s);
- }
-
- public static final String substringBefore(String str, String separator) {
- final int pos = str.indexOf(separator);
- return pos==-1 ? str : str.substring(0, pos);
- }
-
- public static final String substringAfter(String str, String separator) {
- final int pos = str.indexOf(separator);
- return pos==-1 ? "" : str.substring(pos + separator.length());
- }
-
- public static final String substringAfterLast(String str, String separator) {
- final int pos = str.lastIndexOf(separator);
- return pos==-1 ? "" : str.substring(pos + separator.length());
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/util/package-info.java b/fcli-common/src/main/java/com/fortify/cli/common/util/package-info.java
deleted file mode 100644
index 9e24960610..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/util/package-info.java
+++ /dev/null
@@ -1,6 +0,0 @@
-/**
- * This package contains simple, low-level utility and helper classes. Classes in this package
- * usually shouldn't depend on any other fcli functionality or packages.
- */
-package com.fortify.cli.common.util;
-
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/variable/AbstractPredefinedVariableResolverMixin.java b/fcli-common/src/main/java/com/fortify/cli/common/variable/AbstractPredefinedVariableResolverMixin.java
deleted file mode 100644
index a79b426a48..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/variable/AbstractPredefinedVariableResolverMixin.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package com.fortify.cli.common.variable;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fortify.cli.common.json.JsonHelper;
-
-public abstract class AbstractPredefinedVariableResolverMixin {
- protected String resolvePredefinedVariable(String value) {
- if ( !FcliVariableHelper.PREDEFINED_VARIABLE_PLACEHOLDER.equals(value) ) { return value; }
- PredefinedVariable predefinedVariable = getPredefinedVariable();
- String variableName = predefinedVariable.name();
- String variableField = predefinedVariable.field();
- JsonNode contents = FcliVariableHelper.getVariableContents(variableName, false);
- if ( contents==null ) {
- throw new IllegalStateException(String.format("No previously stored value found for '%s' (variable name: %s)", FcliVariableHelper.PREDEFINED_VARIABLE_PLACEHOLDER, variableName));
- }
- return JsonHelper.evaluateJsonPath(contents, variableField, String.class);
- }
-
- private final PredefinedVariable getPredefinedVariable() {
- PredefinedVariable definition = getPredefinedVariableClass().getAnnotation(PredefinedVariable.class);
- if ( definition==null ) {
- throw new RuntimeException(String.format("%s doesn't provide @%s", getPredefinedVariableClass().getName(), PredefinedVariable.class.getSimpleName()));
- }
- return definition;
- }
-
- protected abstract Class> getPredefinedVariableClass();
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/variable/EncryptVariable.java b/fcli-common/src/main/java/com/fortify/cli/common/variable/EncryptVariable.java
deleted file mode 100644
index c4fc8188bd..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/variable/EncryptVariable.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.fortify.cli.common.variable;
-
-import static java.lang.annotation.ElementType.*;
-import static java.lang.annotation.RetentionPolicy.*;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-@Retention(RUNTIME)
-@Target(TYPE)
-public @interface EncryptVariable {}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/variable/FcliVariableHelper.java b/fcli-common/src/main/java/com/fortify/cli/common/variable/FcliVariableHelper.java
deleted file mode 100644
index 443acd4e14..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/variable/FcliVariableHelper.java
+++ /dev/null
@@ -1,262 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.common.variable;
-
-import java.io.PrintWriter;
-import java.io.Writer;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.StandardOpenOption;
-import java.util.Date;
-import java.util.List;
-import java.util.function.Supplier;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import com.fasterxml.jackson.annotation.JsonFormat;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.fortify.cli.common.json.JsonHelper;
-import com.fortify.cli.common.json.JsonNodeHolder;
-import com.fortify.cli.common.util.EncryptionHelper;
-import com.fortify.cli.common.util.FcliHomeHelper;
-
-import io.micronaut.core.annotation.ReflectiveAccess;
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.NoArgsConstructor;
-import lombok.SneakyThrows;
-
-// TODO This class could probably use some cleanup
-public final class FcliVariableHelper {
- public static final String PREDEFINED_VARIABLE_PLACEHOLDER = "?";
- private static final ObjectMapper objectMapper = new ObjectMapper();
- private static final Pattern variableNamePattern = Pattern.compile("^[a-zA-Z0-9_]+$");
- private static final Pattern variableReferencePattern = Pattern.compile("\\{\\?([a-zA-Z0-9_]+):(.+?)\\}");
- private FcliVariableHelper() {}
-
- public static enum VariableType { PREDEFINED, USER_PROVIDED }
- @Data @EqualsAndHashCode(callSuper = true) @ReflectiveAccess @Builder @NoArgsConstructor @AllArgsConstructor
- public static class VariableDescriptor extends JsonNodeHolder {
- @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd@HH:mm:ss.SSSZ")
- private Date created;
- @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd@HH:mm:ss.SSSZ")
- private transient Date accessed;
- private VariableType type;
- private String name;
- private boolean encrypted;
- }
-
- public static final Path getVariablesPath() {
- return Path.of("vars");
- }
-
- @SneakyThrows // TODO Do we want to use SneakyThrows?
- public static final VariableDescriptor getVariableDescriptor(String variableName, boolean failIfUnavailable) {
- Path variablePath = getVariableDescriptorPathIfExists(variableName, failIfUnavailable);
- try {
- String variableDescriptor = FcliHomeHelper.readFile(variablePath, failIfUnavailable);
- JsonNode variableDescriptorJson = variableDescriptor==null ? null : objectMapper.readValue(variableDescriptor, JsonNode.class);
- return JsonHelper.treeToValue(variableDescriptorJson, VariableDescriptor.class);
- } catch ( Exception e ) {
- FcliHomeHelper.deleteDir(variablePath.getParent(), true);
- conditionalThrow(failIfUnavailable, ()->new IllegalStateException("Error reading variable descriptor, data has been deleted", e));
- // TODO Log warning message
- return null;
- }
- }
-
- @SneakyThrows // TODO Do we want to use SneakyThrows?
- public static final JsonNode getVariableContents(String variableName, boolean failIfUnavailable) {
- VariableDescriptor descriptor = getVariableDescriptor(variableName, failIfUnavailable);
- if ( descriptor==null ) { return null; }
- descriptor.setAccessed(new Date());
- Path variablePath = getVariableContentsPathIfExists(variableName, failIfUnavailable);
- try {
- String variableContents = FcliHomeHelper.readFile(variablePath, failIfUnavailable);
- if ( descriptor.encrypted ) {
- variableContents = EncryptionHelper.decrypt(variableContents);
- }
- saveVariableDescriptor(descriptor);
- return variableContents==null ? null : objectMapper.readValue(variableContents, JsonNode.class);
- } catch ( Exception e ) {
- FcliHomeHelper.deleteDir(variablePath.getParent(), true);
- conditionalThrow(failIfUnavailable, ()->new IllegalStateException("Error reading variable descriptor or contents, data has been deleted", e));
- // TODO Log warning message
- return null;
- }
- }
-
- public static final VariableDescriptor save(VariableType variableType, String variableName, JsonNode variableContents, boolean encrypt) {
- checkVariableName(variableName);
- VariableDescriptor descriptor = createVariableDescriptor(variableType, variableName, encrypt);
- saveVariableContents(descriptor, variableContents);
- return saveVariableDescriptor(descriptor);
- }
-
- @SneakyThrows // TODO Do we want to use SneakyThrows?
- public static final Writer getVariableContentsWriter(VariableType variableType, String variableName, boolean encrypt) {
- checkVariableName(variableName);
- VariableDescriptor descriptor = createVariableDescriptor(variableType, variableName, encrypt);
- saveVariableDescriptor(descriptor);
- PrintWriter pw = new PrintWriter(Files.newOutputStream(getVariableContentsAbsolutePath(variableName), StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING));
- return encrypt ? new EncryptionHelper.EncryptWriter(pw) : pw;
- }
-
- public static final String[] resolveVariables(String[] args) {
- return Stream.of(args).map(FcliVariableHelper::resolveVariables).toArray(String[]::new);
- }
-
- public static final String resolveVariables(String arg) {
- StringBuilder sb = new StringBuilder();
- Matcher matcher = variableReferencePattern.matcher(arg);
- while (matcher.find()) {
- String variableName = matcher.group(1);
- String propertyPath = matcher.group(2);
- JsonNode contents = getVariableContents(variableName, true);
- String value = JsonHelper.evaluateJsonPath(contents, propertyPath, String.class);
- if ( value==null ) {
- throw new IllegalArgumentException(String.format("Property path '%s' for variable '%s' resolves to null", propertyPath, variableName));
- }
- matcher.appendReplacement(sb, value);
- }
- matcher.appendTail(sb);
- return sb.toString();
- }
-
- private static final void checkVariableName(String variableName) {
- if ( !variableNamePattern.matcher(variableName).matches() ) {
- throw new IllegalArgumentException(String.format("Variable name '%s' doesn't match pattern '%s'", variableName, variableNamePattern.pattern()));
- }
- }
-
- private static final VariableDescriptor createVariableDescriptor(VariableType variableType, String variableName, boolean encrypt) {
- Date currentDateTime = new Date();
- return VariableDescriptor.builder()
- .created(currentDateTime)
- .accessed(currentDateTime)
- .type(variableType)
- .name(variableName)
- .encrypted(encrypt)
- .build();
- }
-
- @SneakyThrows // TODO Do we want to use SneakyThrows?
- private static final VariableDescriptor saveVariableDescriptor(VariableDescriptor descriptor) {
- String variableDescriptorString = objectMapper.writeValueAsString(descriptor);
- FcliHomeHelper.saveFile(getVariableDescriptorRelativePath(descriptor.getName()), variableDescriptorString, true);
- return descriptor;
- }
-
- @SneakyThrows // TODO Do we want to use SneakyThrows?
- private static void saveVariableContents(VariableDescriptor descriptor, JsonNode variableContents) {
- String variableContentsString = objectMapper.writeValueAsString(variableContents);
- if ( descriptor.encrypted ) {
- variableContentsString = EncryptionHelper.encrypt(variableContentsString);
- }
- FcliHomeHelper.saveFile(getVariableContentsRelativePath(descriptor.getName()), variableContentsString, true);
- }
-
- @SneakyThrows // TODO Do we want to use SneakyThrows?
- public static final void delete(String variableName) {
- Path variableDirPath = getVariablePathIfExists(variableName, getVariablePath(variableName), false);
- if ( variableDirPath!=null ) {
- FcliHomeHelper.deleteDir(variableDirPath, true);
- }
- }
-
- public static final void delete(JsonNode variableDescriptor) {
- delete(variableDescriptor.get("name").asText());
- }
-
- public static final boolean exists(String variableName) {
- return FcliHomeHelper.isReadable(getVariablePath(variableName));
- }
-
- public static final List variableNames() {
- return variableNamesStream().collect(Collectors.toList());
- }
-
- @SneakyThrows // TODO Do we want to use SneakyThrows?
- public static final Stream variableNamesStream() {
- Path path = getVariablesPath();
- if ( !FcliHomeHelper.exists(path) ) {
- return Stream.empty();
- }
- return FcliHomeHelper.listDirsInDir(path, true)
- .map(Path::getFileName)
- .map(Path::toString);
- }
-
- public static final ArrayNode listDescriptors() {
- return variableNames().stream()
- .map(FcliVariableHelper::getVariableDescriptorAsJson)
- .collect(JsonHelper.arrayNodeCollector());
- }
-
- private static final JsonNode getVariableDescriptorAsJson(String variableName) {
- return getVariableDescriptor(variableName, true).asJsonNode();
- }
-
- private static final void conditionalThrow(boolean throwException, Supplier exceptionSupplier) {
- if ( throwException ) { throw exceptionSupplier.get(); }
- }
-
- private static final Path getVariableDescriptorPathIfExists(String variableName, boolean failIfUnavailable) {
- return getVariablePathIfExists(variableName, getVariableDescriptorRelativePath(variableName), failIfUnavailable);
- }
-
- private static final Path getVariableContentsPathIfExists(String variableName, boolean failIfUnavailable) {
- return getVariablePathIfExists(variableName, getVariableContentsRelativePath(variableName), failIfUnavailable);
- }
-
- private static final Path getVariablePathIfExists(String variableName, Path path, boolean failIfUnavailable) {
- if ( failIfUnavailable && !FcliHomeHelper.isReadable(path) ) {
- throw new IllegalStateException("Variable "+variableName+" not found");
- }
- return path;
- }
-
- private static final Path getVariablePath(String variableName) {
- return getVariablesPath().resolve(variableName);
- }
-
- private static final Path getVariableDescriptorRelativePath(String variableName) {
- return getVariablePath(variableName).resolve("descriptor.json");
- }
-
- private static final Path getVariableContentsRelativePath(String variableName) {
- return getVariablePath(variableName).resolve("contents.json");
- }
-
- private static final Path getVariableContentsAbsolutePath(String variableName) {
- return FcliHomeHelper.getFcliHomePath().resolve(getVariableContentsRelativePath(variableName));
- }
-}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/variable/IPredefinedVariableUnsupported.java b/fcli-common/src/main/java/com/fortify/cli/common/variable/IPredefinedVariableUnsupported.java
deleted file mode 100644
index 93b1631d77..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/variable/IPredefinedVariableUnsupported.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.fortify.cli.common.variable;
-
-/**
- * Marker interface for commands that don't support storing their
- * data in the '-' variable alias.
- * @author rsenden
- *
- */
-public interface IPredefinedVariableUnsupported {}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/variable/PredefinedVariable.java b/fcli-common/src/main/java/com/fortify/cli/common/variable/PredefinedVariable.java
deleted file mode 100644
index 596eb5c245..0000000000
--- a/fcli-common/src/main/java/com/fortify/cli/common/variable/PredefinedVariable.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.fortify.cli.common.variable;
-
-import static java.lang.annotation.ElementType.*;
-import static java.lang.annotation.RetentionPolicy.*;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-@Retention(RUNTIME)
-@Target(TYPE)
-public @interface PredefinedVariable {
- String name();
- String field();
-}
diff --git a/fcli-common/src/main/resources/com/fortify/cli/common/i18n/FortifyCLIMessages.properties b/fcli-common/src/main/resources/com/fortify/cli/common/i18n/FortifyCLIMessages.properties
deleted file mode 100644
index 1ab3602208..0000000000
--- a/fcli-common/src/main/resources/com/fortify/cli/common/i18n/FortifyCLIMessages.properties
+++ /dev/null
@@ -1,74 +0,0 @@
-# Error messages:
-error.missing.subcommand = Missing required subcommand
-error.missing.parameter = Missing required parameter:
-error.missing.option = Missing required option
-error.unmatched.argument = Unmatched argument at index
-error.unmatched.command = Did you mean
-
-# Generic help text elements
-usage.synopsisHeading = %nUsage:\u0020
-usage.descriptionHeading = %n
-usage.footer = %n(c) Copyright 2022 Micro Focus
-usage.parameterListHeading = %nCommand parameters:%n
-usage.optionListHeading = %nCommand options:%n
-
-fcli.genericOptions.heading = Generic fcli options:%n
-
-# Generic option descriptions
-help = Show this help message and exit. Use 'fcli -h' to display help for subcommands.
-version = Print version information and exit
-env-prefix = Environment variable prefix for resolving default option and parameter values. Default value is ${DEFAULT-VALUE}.
-log-level = Set logging level. Note that DEBUG and TRACE levels may result in sensitive data being written to the log file. Allowed values: ${COMPLETION-CANDIDATES}
-log-file = File where logging data will be written. If not specified, no logging data will be written.
-fcli.destination-file = Destination file
-
-# Output mixin class
-arggroup.output.heading = Output options:%n
-output = Output format: ${COMPLETION-CANDIDATES}. The 'json-properties' format ignores any options. The 'expr' output format takes a string containing '{}' placeholders, other output formats take an optional, comma-separated list of property paths. Use '-o json-properties' on the current command to see available '' values.
-output-to-file = Write results to the specified files in the given output format. By default, results will be written to stdout
-store = Store the JSON results of this command in a variable. Variables can be managed through the 'fcli config variable' command, and can be referenced using {?variableName:property} on any subsequent command. Most commands that return a single record (get, start, create, ...) also support '?' to store the record identifier in a predefined variable, which can later be referenced using '?' on options/parameters that take the id of such records as input.
-
-arggroup.query.heading = Query options:%n
-query = Return records that match the given query. specifies the property path against which the given value should be matched; use the '-o json-properties' option on the current command to see available properties. specifies the operator; currently only '=' is supported.
-
-# Help text elements for FCLIRootCommands
-fcli.usage.header = Command-line interface for working with various Fortify products
-
-# REST command options mixin
-api.uri = The uri to the REST API function that you want to invoke
-request = HTTP request type. (eg: GET, POST, PUT, DELETE)
-data = This option will read data from a file for your request.
-
-# WaitHelperControlOptions
-on-unknown-state-requested=Action to take when an unknown state is passed in any of the --while or --until options: ${COMPLETION-CANDIDATES}
-on-failure-state=Action to take when a failure state is returned for any of the records: ${COMPLETION-CANDIDATES}
-on-unknown-state=Action to take when an unknown state is returned for any of the records: ${COMPLETION-CANDIDATES}
-on-timeout=Action to take when timeout occurs: ${COMPLETION-CANDIDATES}
-interval=Polling interval, for example 5s (5 seconds) or 1m (1 minute)
-timeout=Time-out, for example 30s (30 seconds), 5m (5 minutes), 1h (1 hour)
-
-# WaitHelperWaitOptions
-while-all=Wait while all records match any of the given states
-while-any=Wait while any records match any of the given states
-until-all=Wait until all records match any of the given states
-until-any=Wait until any of the records match any of the given states
-
-# StandardWaitHelperProgressMonitorMixin
-no-progress=Don't show progress information
-
-# Login and connection options
-arggroup.optional.session-name.heading = Session options:%n
-session-name[0] = Name for this session
-session = Session name to use
-url = Full url to the remote system
-k = Disable SSL checks.
-
-#################################################################################################################
-# The following are technical properties that shouldn't be internationalized ####################################
-#################################################################################################################
-
-# Property default values that are usually set when running fcli, but which may not be available when
-# generating AsciiDoc man-pages.
-fcli.env.default.prefix=FCLI_DEFAULT
-
-
diff --git a/fcli-config/src/main/java/com/fortify/cli/config/_main/cli/cmd/ConfigClearCommand.java b/fcli-config/src/main/java/com/fortify/cli/config/_main/cli/cmd/ConfigClearCommand.java
deleted file mode 100644
index 0fa838dbee..0000000000
--- a/fcli-config/src/main/java/com/fortify/cli/config/_main/cli/cmd/ConfigClearCommand.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package com.fortify.cli.config._main.cli.cmd;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.Comparator;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.fortify.cli.common.json.JsonHelper;
-import com.fortify.cli.common.output.cli.cmd.basic.AbstractBasicOutputCommand;
-import com.fortify.cli.common.output.cli.mixin.BasicOutputHelperMixins;
-import com.fortify.cli.common.output.spi.transform.IActionCommandResultSupplier;
-import com.fortify.cli.common.util.FcliHomeHelper;
-
-import lombok.Getter;
-import picocli.CommandLine.Command;
-import picocli.CommandLine.Mixin;
-import picocli.CommandLine.Option;
-
-@Command(name = BasicOutputHelperMixins.Clear.CMD_NAME)
-public class ConfigClearCommand extends AbstractBasicOutputCommand implements IActionCommandResultSupplier {
- private static final ObjectMapper objectMapper = JsonHelper.getObjectMapper();
- @Getter @Mixin private BasicOutputHelperMixins.Clear outputHelper;
- @Option(names={"-y", "--confirm"}, required = true) private boolean confirm;
-
- @Override
- protected JsonNode getJsonNode() {
- ArrayNode result = objectMapper.createArrayNode();
- try {
- if ( FcliHomeHelper.getFcliHomePath().toFile().exists() ) {
- Files.walk(FcliHomeHelper.getFcliHomePath())
- .sorted(Comparator.reverseOrder())
- .map(Path::toFile)
- .peek(f->addResult(result,f))
- .forEach(File::delete);
- }
- } catch ( IOException e ) {
- throw new RuntimeException("Error clearing fcli home directory", e);
- }
- return result;
- }
-
- @Override
- public String getActionCommandResult() {
- return "DELETED";
- }
-
- @Override
- public boolean isSingular() {
- return true;
- }
-
- private void addResult(ArrayNode result, File f) {
- try {
- result.add(objectMapper.createObjectNode()
- .put("name", f.getCanonicalPath())
- .put("type", f.isFile() ? "FILE" : "DIR"));
- } catch ( IOException e ) {
- throw new RuntimeException("Error processing file "+f, e);
- }
- }
-}
diff --git a/fcli-config/src/main/java/com/fortify/cli/config/_main/cli/cmd/ConfigCommands.java b/fcli-config/src/main/java/com/fortify/cli/config/_main/cli/cmd/ConfigCommands.java
deleted file mode 100644
index 985df28549..0000000000
--- a/fcli-config/src/main/java/com/fortify/cli/config/_main/cli/cmd/ConfigCommands.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.fortify.cli.config._main.cli.cmd;
-
-import com.fortify.cli.common.cli.cmd.AbstractFortifyCLICommand;
-import com.fortify.cli.config.language.cli.cmd.LanguageCommands;
-import com.fortify.cli.config.proxy.cli.cmd.ProxyCommands;
-import com.fortify.cli.config.ssl.cli.cmd.SSLCommands;
-import com.fortify.cli.config.variable.cli.cmd.VariableCommands;
-
-import picocli.CommandLine.Command;
-
-@Command(
- name = "config",
- aliases = "cfg",
- resourceBundle = "com.fortify.cli.config.i18n.ConfigMessages",
- subcommands = {
- ConfigClearCommand.class,
- LanguageCommands.class,
- ProxyCommands.class,
- SSLCommands.class,
- VariableCommands.class
- }
-)
-public class ConfigCommands extends AbstractFortifyCLICommand {
-}
diff --git a/fcli-config/src/main/java/com/fortify/cli/config/_main/cli/cmd/package-info.java b/fcli-config/src/main/java/com/fortify/cli/config/_main/cli/cmd/package-info.java
deleted file mode 100644
index 57c663347f..0000000000
--- a/fcli-config/src/main/java/com/fortify/cli/config/_main/cli/cmd/package-info.java
+++ /dev/null
@@ -1,8 +0,0 @@
-/**
- * This package defines the 'config' top-level command, some generic sub-commands, and any accompanying
- * classes like mixins and (abstract) base classes (at the time of writing there are no accompanying classes).
- * At the moment there's only a small number of configuration commands, we could consider using some command
- * hierarchy if we think the list of direct sub-commands grows too large.
- */
-package com.fortify.cli.config._main.cli.cmd;
-
diff --git a/fcli-config/src/main/java/com/fortify/cli/config/language/cli/cmd/AbstractLanguageCommand.java b/fcli-config/src/main/java/com/fortify/cli/config/language/cli/cmd/AbstractLanguageCommand.java
deleted file mode 100644
index 0b6ea96b55..0000000000
--- a/fcli-config/src/main/java/com/fortify/cli/config/language/cli/cmd/AbstractLanguageCommand.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.fortify.cli.config.language.cli.cmd;
-
-import com.fortify.cli.common.output.cli.cmd.basic.AbstractBasicOutputCommand;
-import com.fortify.cli.common.util.FixInjection;
-import com.fortify.cli.config.language.util.LanguagePropertiesManager;
-
-import io.micronaut.core.annotation.ReflectiveAccess;
-import jakarta.inject.Inject;
-import lombok.Getter;
-
-@ReflectiveAccess @FixInjection
-public abstract class AbstractLanguageCommand extends AbstractBasicOutputCommand {
- @Inject @Getter private LanguagePropertiesManager languageConfigManager;
-}
diff --git a/fcli-config/src/main/java/com/fortify/cli/config/language/cli/cmd/LanguageCommands.java b/fcli-config/src/main/java/com/fortify/cli/config/language/cli/cmd/LanguageCommands.java
deleted file mode 100644
index 30339a695b..0000000000
--- a/fcli-config/src/main/java/com/fortify/cli/config/language/cli/cmd/LanguageCommands.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.fortify.cli.config.language.cli.cmd;
-
-import com.fortify.cli.common.cli.cmd.AbstractFortifyCLICommand;
-
-import picocli.CommandLine;
-
-@CommandLine.Command(
- name = "language",
- aliases = "lang",
- subcommands = {
- LanguageListCommand.class,
- LanguageSetCommand.class,
- LanguageGetCommand.class
- }
-)
-public class LanguageCommands extends AbstractFortifyCLICommand {
-}
diff --git a/fcli-config/src/main/java/com/fortify/cli/config/language/cli/cmd/LanguageGetCommand.java b/fcli-config/src/main/java/com/fortify/cli/config/language/cli/cmd/LanguageGetCommand.java
deleted file mode 100644
index e12c22a92e..0000000000
--- a/fcli-config/src/main/java/com/fortify/cli/config/language/cli/cmd/LanguageGetCommand.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.fortify.cli.config.language.cli.cmd;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fortify.cli.common.output.cli.mixin.BasicOutputHelperMixins;
-
-import lombok.Getter;
-import picocli.CommandLine.Command;
-import picocli.CommandLine.Mixin;
-
-@Command(name = BasicOutputHelperMixins.Get.CMD_NAME)
-public class LanguageGetCommand extends AbstractLanguageCommand {
- @Mixin @Getter private BasicOutputHelperMixins.Get outputHelper;
-
- @Override
- protected JsonNode getJsonNode() {
- return getLanguageConfigManager().getCurrentLanguageDescriptor().asObjectNode();
- }
-
- @Override
- public boolean isSingular() {
- return true;
- }
-}
diff --git a/fcli-config/src/main/java/com/fortify/cli/config/language/cli/cmd/LanguageListCommand.java b/fcli-config/src/main/java/com/fortify/cli/config/language/cli/cmd/LanguageListCommand.java
deleted file mode 100644
index 2796f52554..0000000000
--- a/fcli-config/src/main/java/com/fortify/cli/config/language/cli/cmd/LanguageListCommand.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package com.fortify.cli.config.language.cli.cmd;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fortify.cli.common.json.JsonHelper;
-import com.fortify.cli.common.output.cli.mixin.BasicOutputHelperMixins;
-import com.fortify.cli.config.language.util.LanguagePropertiesManager.LanguageDescriptor;
-
-import lombok.Getter;
-import picocli.CommandLine.Command;
-import picocli.CommandLine.Mixin;
-
-@Command(name=BasicOutputHelperMixins.List.CMD_NAME)
-public class LanguageListCommand extends AbstractLanguageCommand {
- @Mixin @Getter private BasicOutputHelperMixins.List outputHelper;
-
- @Override
- protected JsonNode getJsonNode() {
- return getLanguageConfigManager().getSupportLanguageDescriptorsStream()
- .map(LanguageDescriptor::asObjectNode)
- .collect(JsonHelper.arrayNodeCollector());
- }
-
- @Override
- public boolean isSingular() {
- return false;
- }
-}
diff --git a/fcli-config/src/main/java/com/fortify/cli/config/language/cli/cmd/LanguageSetCommand.java b/fcli-config/src/main/java/com/fortify/cli/config/language/cli/cmd/LanguageSetCommand.java
deleted file mode 100644
index 08b2971c09..0000000000
--- a/fcli-config/src/main/java/com/fortify/cli/config/language/cli/cmd/LanguageSetCommand.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.fortify.cli.config.language.cli.cmd;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fortify.cli.common.output.cli.mixin.BasicOutputHelperMixins;
-import com.fortify.cli.config.language.util.LanguagePropertiesManager;
-
-import lombok.Getter;
-import picocli.CommandLine.Command;
-import picocli.CommandLine.Mixin;
-import picocli.CommandLine.Parameters;
-
-@Command(name = BasicOutputHelperMixins.Set.CMD_NAME)
-public class LanguageSetCommand extends AbstractLanguageCommand {
- @Mixin @Getter private BasicOutputHelperMixins.Set outputHelper;
- @Parameters(index = "0", descriptionKey = "fcli.config.language.set.language")
- private String language;
-
- @Override
- protected JsonNode getJsonNode() {
- LanguagePropertiesManager languageConfigManager = getLanguageConfigManager();
- languageConfigManager.setLanguage(language);
- return languageConfigManager.getCurrentLanguageDescriptor().asObjectNode();
- }
-
- @Override
- public boolean isSingular() {
- return true;
- }
-}
diff --git a/fcli-config/src/main/java/com/fortify/cli/config/language/util/LanguagePropertiesManager.java b/fcli-config/src/main/java/com/fortify/cli/config/language/util/LanguagePropertiesManager.java
deleted file mode 100644
index 15ec2d90ba..0000000000
--- a/fcli-config/src/main/java/com/fortify/cli/config/language/util/LanguagePropertiesManager.java
+++ /dev/null
@@ -1,80 +0,0 @@
-package com.fortify.cli.config.language.util;
-
-import java.util.Locale;
-import java.util.stream.Stream;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.fortify.cli.config.util.ConfigPropertiesManager;
-
-import io.micronaut.core.annotation.ReflectiveAccess;
-import jakarta.inject.Inject;
-import jakarta.inject.Singleton;
-import lombok.Data;
-
-@Singleton
-public final class LanguagePropertiesManager {
- // TODO Any way we can dynamically determine available languages?
- // TODO Re-add NL and other languages once resource bundles are up to date
- private static final String[] supportedLanguages = {"en"};
- private static final String CONFIG_KEY = "defaultUserLanguage";
- private final ConfigPropertiesManager config;
-
- @Inject
- public LanguagePropertiesManager(ConfigPropertiesManager config) {
- this.config = config;
- }
-
- private static final boolean isNullEmptyOrEn(String lang){
- return lang == null || lang.isEmpty() || lang.toLowerCase() == "en";
- }
-
- public final boolean isNullEmptyOrEn(){
- return isNullEmptyOrEn(config.get(CONFIG_KEY));
- }
-
- public final String getLanguage(){
- return !isNullEmptyOrEn() ? config.get(CONFIG_KEY) : "en";
- }
-
- public void setLanguage(String lang){
- if(isNullEmptyOrEn(lang)){
- lang = ""; // done this way to force the locale/language to the "default locale" which is English.
- }
- config.set(CONFIG_KEY, lang);
- config.save();
- }
-
- public Stream getSupportLanguageDescriptorsStream() {
- return Stream.of(supportedLanguages)
- .map(this::getLanguageDescriptor);
- }
-
- public LanguageDescriptor getCurrentLanguageDescriptor() {
- return getLanguageDescriptor(getLanguage());
- }
-
- public LanguageDescriptor getLanguageDescriptor(String langCode){
- Locale l = new Locale(langCode);
- return new LanguageDescriptor(l.getLanguage(), l.getDisplayLanguage(l), l.getDisplayLanguage(new Locale("en")));
- }
-
- public Locale getLocale() {
- return isNullEmptyOrEn() ? new Locale("") : new Locale(getLanguage());
- }
-
- @Data @ReflectiveAccess
- public final class LanguageDescriptor {
- private final String languageCode;
- private final String languageLocalName;
- private final String languageName;
-
- public final boolean isActive() {
- return getLanguage().equals(languageCode);
- }
-
- public final ObjectNode asObjectNode() {
- return new ObjectMapper().valueToTree(this);
- }
- }
-}
\ No newline at end of file
diff --git a/fcli-config/src/main/java/com/fortify/cli/config/proxy/cli/cmd/ProxyAddCommand.java b/fcli-config/src/main/java/com/fortify/cli/config/proxy/cli/cmd/ProxyAddCommand.java
deleted file mode 100644
index 1ae28e795d..0000000000
--- a/fcli-config/src/main/java/com/fortify/cli/config/proxy/cli/cmd/ProxyAddCommand.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package com.fortify.cli.config.proxy.cli.cmd;
-
-import java.util.function.UnaryOperator;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fortify.cli.common.http.proxy.helper.ProxyHelper;
-import com.fortify.cli.common.output.cli.cmd.basic.AbstractBasicOutputCommand;
-import com.fortify.cli.common.output.cli.mixin.BasicOutputHelperMixins;
-import com.fortify.cli.common.output.spi.transform.IRecordTransformerSupplier;
-import com.fortify.cli.config.proxy.cli.mixin.ProxyAddOptions;
-import com.fortify.cli.config.proxy.helper.ProxyOutputHelper;
-
-import lombok.Getter;
-import picocli.CommandLine.Command;
-import picocli.CommandLine.Mixin;
-
-@Command(name=BasicOutputHelperMixins.Add.CMD_NAME)
-public class ProxyAddCommand extends AbstractBasicOutputCommand implements IRecordTransformerSupplier {
- @Mixin @Getter private BasicOutputHelperMixins.Add outputHelper;
- @Mixin private ProxyAddOptions proxyCreateOptions;
-
- @Override
- protected JsonNode getJsonNode() {
- return ProxyHelper.addProxy(proxyCreateOptions.asProxyDescriptor()).asJsonNode();
- }
-
- @Override
- public boolean isSingular() {
- return true;
- }
-
- @Override
- public UnaryOperator getRecordTransformer() {
- return ProxyOutputHelper::transformRecord;
- }
-}
diff --git a/fcli-config/src/main/java/com/fortify/cli/config/proxy/cli/cmd/ProxyClearCommand.java b/fcli-config/src/main/java/com/fortify/cli/config/proxy/cli/cmd/ProxyClearCommand.java
deleted file mode 100644
index 5bf2372b91..0000000000
--- a/fcli-config/src/main/java/com/fortify/cli/config/proxy/cli/cmd/ProxyClearCommand.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package com.fortify.cli.config.proxy.cli.cmd;
-
-import java.util.function.UnaryOperator;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fortify.cli.common.http.proxy.helper.ProxyDescriptor;
-import com.fortify.cli.common.http.proxy.helper.ProxyHelper;
-import com.fortify.cli.common.json.JsonHelper;
-import com.fortify.cli.common.output.cli.cmd.basic.AbstractBasicOutputCommand;
-import com.fortify.cli.common.output.cli.mixin.BasicOutputHelperMixins;
-import com.fortify.cli.common.output.spi.transform.IActionCommandResultSupplier;
-import com.fortify.cli.common.output.spi.transform.IRecordTransformerSupplier;
-import com.fortify.cli.config.proxy.helper.ProxyOutputHelper;
-
-import lombok.Getter;
-import picocli.CommandLine.Command;
-import picocli.CommandLine.Mixin;
-
-@Command(name=BasicOutputHelperMixins.Clear.CMD_NAME)
-public class ProxyClearCommand extends AbstractBasicOutputCommand implements IActionCommandResultSupplier, IRecordTransformerSupplier {
- @Mixin @Getter private BasicOutputHelperMixins.Clear outputHelper;
-
- @Override
- protected JsonNode getJsonNode() {
- return ProxyHelper.deleteAllProxies().map(ProxyDescriptor::asJsonNode).collect(JsonHelper.arrayNodeCollector());
- }
-
- @Override
- public boolean isSingular() {
- return false;
- }
-
- @Override
- public String getActionCommandResult() {
- return "DELETED";
- }
-
- @Override
- public UnaryOperator getRecordTransformer() {
- return ProxyOutputHelper::transformRecord;
- }
-}
diff --git a/fcli-config/src/main/java/com/fortify/cli/config/proxy/cli/cmd/ProxyCommands.java b/fcli-config/src/main/java/com/fortify/cli/config/proxy/cli/cmd/ProxyCommands.java
deleted file mode 100644
index 212b5ed637..0000000000
--- a/fcli-config/src/main/java/com/fortify/cli/config/proxy/cli/cmd/ProxyCommands.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.fortify.cli.config.proxy.cli.cmd;
-
-import com.fortify.cli.common.cli.cmd.AbstractFortifyCLICommand;
-
-import picocli.CommandLine.Command;
-
-@Command(
- name = "proxy",
- description = "Commands for managing connectivity through proxies",
- subcommands = {
- ProxyAddCommand.class,
- ProxyClearCommand.class,
- ProxyDeleteCommand.class,
- ProxyListCommand.class,
- ProxyUpdateCommand.class
- }
-)
-public class ProxyCommands extends AbstractFortifyCLICommand {
-}
diff --git a/fcli-config/src/main/java/com/fortify/cli/config/proxy/cli/cmd/ProxyDeleteCommand.java b/fcli-config/src/main/java/com/fortify/cli/config/proxy/cli/cmd/ProxyDeleteCommand.java
deleted file mode 100644
index c3883ad139..0000000000
--- a/fcli-config/src/main/java/com/fortify/cli/config/proxy/cli/cmd/ProxyDeleteCommand.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package com.fortify.cli.config.proxy.cli.cmd;
-
-import java.util.function.UnaryOperator;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fortify.cli.common.http.proxy.helper.ProxyHelper;
-import com.fortify.cli.common.output.cli.cmd.basic.AbstractBasicOutputCommand;
-import com.fortify.cli.common.output.cli.mixin.BasicOutputHelperMixins;
-import com.fortify.cli.common.output.spi.transform.IActionCommandResultSupplier;
-import com.fortify.cli.common.output.spi.transform.IRecordTransformerSupplier;
-import com.fortify.cli.config.proxy.helper.ProxyOutputHelper;
-
-import lombok.Getter;
-import picocli.CommandLine.Command;
-import picocli.CommandLine.Mixin;
-import picocli.CommandLine.Parameters;
-
-@Command(name=BasicOutputHelperMixins.Delete.CMD_NAME)
-public class ProxyDeleteCommand extends AbstractBasicOutputCommand implements IActionCommandResultSupplier, IRecordTransformerSupplier {
- @Mixin @Getter private BasicOutputHelperMixins.Delete outputHelper;
- @Parameters(arity="1", descriptionKey = "fcli.config.proxy.delete.name", paramLabel = "NAME")
- private String name;
-
- @Override
- protected JsonNode getJsonNode() {
- return ProxyHelper.deleteProxy(ProxyHelper.getProxy(name)).asJsonNode();
- }
-
- @Override
- public boolean isSingular() {
- return true;
- }
-
- @Override
- public String getActionCommandResult() {
- return "DELETED";
- }
-
- @Override
- public UnaryOperator getRecordTransformer() {
- return ProxyOutputHelper::transformRecord;
- }
-}
diff --git a/fcli-config/src/main/java/com/fortify/cli/config/proxy/cli/cmd/ProxyListCommand.java b/fcli-config/src/main/java/com/fortify/cli/config/proxy/cli/cmd/ProxyListCommand.java
deleted file mode 100644
index 3a73dff281..0000000000
--- a/fcli-config/src/main/java/com/fortify/cli/config/proxy/cli/cmd/ProxyListCommand.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package com.fortify.cli.config.proxy.cli.cmd;
-
-import java.util.function.UnaryOperator;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fortify.cli.common.http.proxy.helper.ProxyDescriptor;
-import com.fortify.cli.common.http.proxy.helper.ProxyHelper;
-import com.fortify.cli.common.json.JsonHelper;
-import com.fortify.cli.common.output.cli.cmd.basic.AbstractBasicOutputCommand;
-import com.fortify.cli.common.output.cli.mixin.BasicOutputHelperMixins;
-import com.fortify.cli.common.output.spi.transform.IRecordTransformerSupplier;
-import com.fortify.cli.config.proxy.helper.ProxyOutputHelper;
-
-import lombok.Getter;
-import picocli.CommandLine.Command;
-import picocli.CommandLine.Mixin;
-
-@Command(name=BasicOutputHelperMixins.List.CMD_NAME)
-public class ProxyListCommand extends AbstractBasicOutputCommand implements IRecordTransformerSupplier {
- @Mixin @Getter private BasicOutputHelperMixins.List outputHelper;
-
- @Override
- protected JsonNode getJsonNode() {
- return ProxyHelper.getProxiesStream().map(ProxyDescriptor::asJsonNode).collect(JsonHelper.arrayNodeCollector());
- }
-
- @Override
- public boolean isSingular() {
- return false;
- }
-
- @Override
- public UnaryOperator getRecordTransformer() {
- return ProxyOutputHelper::transformRecord;
- }
-}
diff --git a/fcli-config/src/main/java/com/fortify/cli/config/proxy/cli/cmd/ProxyUpdateCommand.java b/fcli-config/src/main/java/com/fortify/cli/config/proxy/cli/cmd/ProxyUpdateCommand.java
deleted file mode 100644
index 7767630dd2..0000000000
--- a/fcli-config/src/main/java/com/fortify/cli/config/proxy/cli/cmd/ProxyUpdateCommand.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package com.fortify.cli.config.proxy.cli.cmd;
-
-import java.util.function.UnaryOperator;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fortify.cli.common.http.proxy.helper.ProxyHelper;
-import com.fortify.cli.common.output.cli.cmd.basic.AbstractBasicOutputCommand;
-import com.fortify.cli.common.output.cli.mixin.BasicOutputHelperMixins;
-import com.fortify.cli.common.output.spi.transform.IActionCommandResultSupplier;
-import com.fortify.cli.common.output.spi.transform.IRecordTransformerSupplier;
-import com.fortify.cli.config.proxy.cli.mixin.ProxyUpdateOptions;
-import com.fortify.cli.config.proxy.helper.ProxyOutputHelper;
-
-import lombok.Getter;
-import picocli.CommandLine.Command;
-import picocli.CommandLine.Mixin;
-
-@Command(name=BasicOutputHelperMixins.Update.CMD_NAME)
-public class ProxyUpdateCommand extends AbstractBasicOutputCommand implements IActionCommandResultSupplier, IRecordTransformerSupplier {
- @Mixin @Getter private BasicOutputHelperMixins.Update outputHelper;
- @Mixin private ProxyUpdateOptions proxyUpdateOptions;
-
- @Override
- protected JsonNode getJsonNode() {
- return ProxyHelper.updateProxy(proxyUpdateOptions.asProxyDescriptor()).asJsonNode();
- }
-
- @Override
- public boolean isSingular() {
- return true;
- }
-
- @Override
- public String getActionCommandResult() {
- return "UPDATED";
- }
-
- @Override
- public UnaryOperator getRecordTransformer() {
- return ProxyOutputHelper::transformRecord;
- }
-}
diff --git a/fcli-config/src/main/java/com/fortify/cli/config/proxy/cli/mixin/ProxyAddOptions.java b/fcli-config/src/main/java/com/fortify/cli/config/proxy/cli/mixin/ProxyAddOptions.java
deleted file mode 100644
index 680481b621..0000000000
--- a/fcli-config/src/main/java/com/fortify/cli/config/proxy/cli/mixin/ProxyAddOptions.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.fortify.cli.config.proxy.cli.mixin;
-
-import com.fortify.cli.common.http.proxy.helper.ProxyDescriptor;
-
-import lombok.Getter;
-import picocli.CommandLine.Option;
-import picocli.CommandLine.Parameters;
-
-public class ProxyAddOptions extends AbstractProxyOptions {
- @Parameters(arity="1", descriptionKey = "fcli.config.proxy.hostAndPort", paramLabel = "HOST:PORT")
- @Getter private String proxyHostAndPort;
-
- @Getter @Option(names = {"--name"}, descriptionKey = "fcli.config.proxy.add.name") private String name;
-
- public ProxyDescriptor asProxyDescriptor() {
- return getProxyDescriptorBuilder(null)
- .name(name)
- .proxyHostAndPort(proxyHostAndPort)
- .build();
- }
-}
diff --git a/fcli-config/src/main/java/com/fortify/cli/config/proxy/cli/mixin/ProxyUpdateOptions.java b/fcli-config/src/main/java/com/fortify/cli/config/proxy/cli/mixin/ProxyUpdateOptions.java
deleted file mode 100644
index ef7531c420..0000000000
--- a/fcli-config/src/main/java/com/fortify/cli/config/proxy/cli/mixin/ProxyUpdateOptions.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.fortify.cli.config.proxy.cli.mixin;
-
-import com.fortify.cli.common.http.proxy.helper.ProxyDescriptor;
-import com.fortify.cli.common.http.proxy.helper.ProxyDescriptor.ProxyDescriptorBuilder;
-import com.fortify.cli.common.http.proxy.helper.ProxyHelper;
-
-import lombok.Getter;
-import picocli.CommandLine.Option;
-import picocli.CommandLine.Parameters;
-
-public class ProxyUpdateOptions extends AbstractProxyOptions {
- @Parameters(arity="1", descriptionKey = "fcli.config.proxy.update.name", paramLabel = "NAME")
- @Getter private String name;
-
- @Getter @Option(names = {"--proxy"}, required=false, descriptionKey = "fcli.config.proxy.hostAndPort") private String proxyHostAndPort;
-
- public ProxyDescriptor asProxyDescriptor() {
- ProxyDescriptorBuilder builder = getProxyDescriptorBuilder(ProxyHelper.getProxy(name));
- if ( proxyHostAndPort!=null ) { builder.proxyHostAndPort(proxyHostAndPort); }
- return builder.build();
- }
-}
diff --git a/fcli-config/src/main/java/com/fortify/cli/config/proxy/helper/ProxyOutputHelper.java b/fcli-config/src/main/java/com/fortify/cli/config/proxy/helper/ProxyOutputHelper.java
deleted file mode 100644
index 1eb5d4c830..0000000000
--- a/fcli-config/src/main/java/com/fortify/cli/config/proxy/helper/ProxyOutputHelper.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.fortify.cli.config.proxy.helper;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-
-public class ProxyOutputHelper {
- private ProxyOutputHelper() {}
-
- public static final JsonNode transformRecord(JsonNode record) {
- ObjectNode node = ((ObjectNode)record);
- node.put("proxyPassword", "****"); // Hide proxy password in any output
- return node;
- }
-}
diff --git a/fcli-config/src/main/java/com/fortify/cli/config/ssl/cli/cmd/SSLCommands.java b/fcli-config/src/main/java/com/fortify/cli/config/ssl/cli/cmd/SSLCommands.java
deleted file mode 100644
index e0cbbf3252..0000000000
--- a/fcli-config/src/main/java/com/fortify/cli/config/ssl/cli/cmd/SSLCommands.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package com.fortify.cli.config.ssl.cli.cmd;
-
-import com.fortify.cli.common.cli.cmd.AbstractFortifyCLICommand;
-import com.fortify.cli.config.ssl.truststore.cli.cmd.SSLTrustStoreCommands;
-
-import picocli.CommandLine.Command;
-
-@Command(
- name = "ssl",
- description = "Commands for managing SSL connections",
- subcommands = {
- SSLTrustStoreCommands.class
- }
-)
-public class SSLCommands extends AbstractFortifyCLICommand {
-}
diff --git a/fcli-config/src/main/java/com/fortify/cli/config/ssl/truststore/cli/cmd/SSLTrustStoreClearCommand.java b/fcli-config/src/main/java/com/fortify/cli/config/ssl/truststore/cli/cmd/SSLTrustStoreClearCommand.java
deleted file mode 100644
index 39ae05879c..0000000000
--- a/fcli-config/src/main/java/com/fortify/cli/config/ssl/truststore/cli/cmd/SSLTrustStoreClearCommand.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package com.fortify.cli.config.ssl.truststore.cli.cmd;
-
-import java.util.function.UnaryOperator;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fortify.cli.common.http.ssl.truststore.helper.TrustStoreConfigDescriptor;
-import com.fortify.cli.common.http.ssl.truststore.helper.TrustStoreConfigHelper;
-import com.fortify.cli.common.output.cli.cmd.basic.AbstractBasicOutputCommand;
-import com.fortify.cli.common.output.cli.mixin.BasicOutputHelperMixins;
-import com.fortify.cli.common.output.spi.transform.IActionCommandResultSupplier;
-import com.fortify.cli.common.output.spi.transform.IRecordTransformerSupplier;
-import com.fortify.cli.config.ssl.truststore.helper.TrustStoreOutputHelper;
-
-import lombok.Getter;
-import picocli.CommandLine.Command;
-import picocli.CommandLine.Mixin;
-
-@Command(name=BasicOutputHelperMixins.Clear.CMD_NAME)
-public class SSLTrustStoreClearCommand extends AbstractBasicOutputCommand implements IActionCommandResultSupplier, IRecordTransformerSupplier {
- @Mixin @Getter private BasicOutputHelperMixins.Clear outputHelper;
-
- @Override
- protected JsonNode getJsonNode() {
- TrustStoreConfigDescriptor descriptor = TrustStoreConfigHelper.getTrustStoreConfig();
- TrustStoreConfigHelper.clearTrustStoreConfig();
- return descriptor.asJsonNode();
- }
-
- @Override
- public boolean isSingular() {
- return true;
- }
-
- @Override
- public String getActionCommandResult() {
- return "CLEARED";
- }
-
- @Override
- public UnaryOperator getRecordTransformer() {
- return TrustStoreOutputHelper::transformRecord;
- }
-}
diff --git a/fcli-config/src/main/java/com/fortify/cli/config/ssl/truststore/cli/cmd/SSLTrustStoreCommands.java b/fcli-config/src/main/java/com/fortify/cli/config/ssl/truststore/cli/cmd/SSLTrustStoreCommands.java
deleted file mode 100644
index 41cc1f8cbe..0000000000
--- a/fcli-config/src/main/java/com/fortify/cli/config/ssl/truststore/cli/cmd/SSLTrustStoreCommands.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.fortify.cli.config.ssl.truststore.cli.cmd;
-
-import com.fortify.cli.common.cli.cmd.AbstractFortifyCLICommand;
-
-import picocli.CommandLine.Command;
-
-@Command(
- name = "truststore",
- description = "Commands for managing the trust store for SSL connections",
- subcommands = {
- SSLTrustStoreClearCommand.class,
- SSLTrustStoreGetCommand.class,
- SSLTrustStoreSetCommand.class,
- }
-)
-public class SSLTrustStoreCommands extends AbstractFortifyCLICommand {
-}
diff --git a/fcli-config/src/main/java/com/fortify/cli/config/ssl/truststore/cli/cmd/SSLTrustStoreGetCommand.java b/fcli-config/src/main/java/com/fortify/cli/config/ssl/truststore/cli/cmd/SSLTrustStoreGetCommand.java
deleted file mode 100644
index 9e3f7a52e4..0000000000
--- a/fcli-config/src/main/java/com/fortify/cli/config/ssl/truststore/cli/cmd/SSLTrustStoreGetCommand.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package com.fortify.cli.config.ssl.truststore.cli.cmd;
-
-import java.util.function.UnaryOperator;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fortify.cli.common.http.ssl.truststore.helper.TrustStoreConfigHelper;
-import com.fortify.cli.common.output.cli.cmd.basic.AbstractBasicOutputCommand;
-import com.fortify.cli.common.output.cli.mixin.BasicOutputHelperMixins;
-import com.fortify.cli.common.output.spi.transform.IRecordTransformerSupplier;
-import com.fortify.cli.config.ssl.truststore.helper.TrustStoreOutputHelper;
-
-import lombok.Getter;
-import picocli.CommandLine.Command;
-import picocli.CommandLine.Mixin;
-
-@Command(name=BasicOutputHelperMixins.Get.CMD_NAME)
-public class SSLTrustStoreGetCommand extends AbstractBasicOutputCommand implements IRecordTransformerSupplier {
- @Mixin @Getter private BasicOutputHelperMixins.Get outputHelper;
-
- @Override
- protected JsonNode getJsonNode() {
- return TrustStoreConfigHelper.getTrustStoreConfig().asJsonNode();
- }
-
- @Override
- public boolean isSingular() {
- return true;
- }
-
- @Override
- public UnaryOperator getRecordTransformer() {
- return TrustStoreOutputHelper::transformRecord;
- }
-}
diff --git a/fcli-config/src/main/java/com/fortify/cli/config/ssl/truststore/cli/cmd/SSLTrustStoreSetCommand.java b/fcli-config/src/main/java/com/fortify/cli/config/ssl/truststore/cli/cmd/SSLTrustStoreSetCommand.java
deleted file mode 100644
index 02bcac5e5d..0000000000
--- a/fcli-config/src/main/java/com/fortify/cli/config/ssl/truststore/cli/cmd/SSLTrustStoreSetCommand.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package com.fortify.cli.config.ssl.truststore.cli.cmd;
-
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.function.UnaryOperator;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fortify.cli.common.http.ssl.truststore.helper.TrustStoreConfigDescriptor;
-import com.fortify.cli.common.http.ssl.truststore.helper.TrustStoreConfigHelper;
-import com.fortify.cli.common.output.cli.cmd.basic.AbstractBasicOutputCommand;
-import com.fortify.cli.common.output.cli.mixin.BasicOutputHelperMixins;
-import com.fortify.cli.common.output.spi.transform.IActionCommandResultSupplier;
-import com.fortify.cli.common.output.spi.transform.IRecordTransformerSupplier;
-import com.fortify.cli.config.ssl.truststore.helper.TrustStoreOutputHelper;
-
-import lombok.Getter;
-import picocli.CommandLine.Command;
-import picocli.CommandLine.Mixin;
-import picocli.CommandLine.Option;
-import picocli.CommandLine.Parameters;
-
-@Command(name=BasicOutputHelperMixins.Set.CMD_NAME)
-public class SSLTrustStoreSetCommand extends AbstractBasicOutputCommand implements IActionCommandResultSupplier, IRecordTransformerSupplier {
- @Mixin @Getter private BasicOutputHelperMixins.Set outputHelper;
-
- @Parameters(arity = "1", descriptionKey = "fcli.config.ssl.truststore.set.trustStorePath")
- private String trustStorePath;
-
- @Option(names = {"-p", "--truststore-password"})
- private String trustStorePassword;
-
- @Option(names = {"-t", "--truststore-type"}, defaultValue = "jks")
- private String trustStoreType;
-
- @Override
- protected JsonNode getJsonNode() {
- Path absolutePath = Path.of(trustStorePath).toAbsolutePath();
- if ( !Files.exists(absolutePath) ) {
- throw new IllegalArgumentException("Trust store cannot be found: "+absolutePath);
- }
- String absolutePathString = absolutePath.toString();
- TrustStoreConfigDescriptor descriptor = TrustStoreConfigDescriptor.builder()
- .path(absolutePathString)
- .type(trustStoreType)
- .password(trustStorePassword)
- .build();
- TrustStoreConfigHelper.setTrustStoreConfig(descriptor);
- return descriptor.asJsonNode();
- }
-
- @Override
- public boolean isSingular() {
- return true;
- }
-
- @Override
- public String getActionCommandResult() {
- return "CONFIGURED";
- }
-
- @Override
- public UnaryOperator getRecordTransformer() {
- return TrustStoreOutputHelper::transformRecord;
- }
-}
diff --git a/fcli-config/src/main/java/com/fortify/cli/config/ssl/truststore/helper/TrustStoreOutputHelper.java b/fcli-config/src/main/java/com/fortify/cli/config/ssl/truststore/helper/TrustStoreOutputHelper.java
deleted file mode 100644
index 4d7ab8a94b..0000000000
--- a/fcli-config/src/main/java/com/fortify/cli/config/ssl/truststore/helper/TrustStoreOutputHelper.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.fortify.cli.config.ssl.truststore.helper;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-
-public class TrustStoreOutputHelper {
- private TrustStoreOutputHelper() {}
-
- public static final JsonNode transformRecord(JsonNode record) {
- ObjectNode node = ((ObjectNode)record);
- node.put("password", "****"); // Hide trust store password in any output
- return node;
- }
-}
diff --git a/fcli-config/src/main/java/com/fortify/cli/config/util/ConfigPropertiesManager.java b/fcli-config/src/main/java/com/fortify/cli/config/util/ConfigPropertiesManager.java
deleted file mode 100644
index cf8bcb781c..0000000000
--- a/fcli-config/src/main/java/com/fortify/cli/config/util/ConfigPropertiesManager.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.config.util;
-
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fortify.cli.common.util.FcliHomeHelper;
-
-import io.micronaut.core.annotation.ReflectiveAccess;
-import io.micronaut.core.util.StringUtils;
-import jakarta.annotation.PreDestroy;
-import jakarta.inject.Inject;
-import jakarta.inject.Singleton;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import lombok.SneakyThrows;
-
-// TODO Use SneakThrows or use proper exception handling?
-@Singleton
-public class ConfigPropertiesManager {
- private static final Path CONFIG_PATH = Paths.get("config.json");
- private final ObjectMapper objectMapper;
- private final Map config = new HashMap<>();
- private boolean dirty = false;
-
- @Inject
- public ConfigPropertiesManager(ObjectMapper objectMapper) {
- this.objectMapper = objectMapper;
- load();
- }
-
- public void set(String name, String value) {
- config.put(name, value);
- dirty = true;
- }
-
- public String get(String name) {
- return config.get(name);
- }
-
- public boolean contains(String name) {
- return config.containsKey(name);
- }
-
- public Map all() {
- return Collections.unmodifiableMap(config);
- }
-
- @SneakyThrows
- private void load() {
- String configString = FcliHomeHelper.readFile(CONFIG_PATH, false);
- if ( StringUtils.isNotEmpty(configString) ) {
- loadFromJson(configString);
- }
- }
-
- @PreDestroy @SneakyThrows
- public void save() {
- if ( dirty ) {
- FcliHomeHelper.saveFile(CONFIG_PATH, getAsJsonString(), true);
- }
- dirty = false;
- }
-
- @SneakyThrows
- private final String getAsJsonString() {
- List configPropertyList = config.entrySet().stream().map(this::mapEntryToConfigProperty).collect(Collectors.toList());
- return objectMapper.writeValueAsString(configPropertyList);
- }
-
- @SneakyThrows
- private void loadFromJson(String configString) {
- config.clear();
- ConfigProperty[] configPropertyArray = objectMapper.readValue(configString, ConfigProperty[].class);
- Stream.of(configPropertyArray).forEach(this::addMapEntry);
- }
-
- private final ConfigProperty mapEntryToConfigProperty(Map.Entry entry) {
- return new ConfigProperty(entry.getKey(), entry.getValue());
- }
-
- private final void addMapEntry(ConfigProperty configProperty) {
- config.put(configProperty.getKey(), configProperty.getValue());
- }
-
- @Data @AllArgsConstructor @NoArgsConstructor
- @ReflectiveAccess
- protected static final class ConfigProperty {
- private String key, value;
- }
-}
diff --git a/fcli-config/src/main/java/com/fortify/cli/config/variable/cli/cmd/VariableCommands.java b/fcli-config/src/main/java/com/fortify/cli/config/variable/cli/cmd/VariableCommands.java
deleted file mode 100644
index 4adebb4b1a..0000000000
--- a/fcli-config/src/main/java/com/fortify/cli/config/variable/cli/cmd/VariableCommands.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.fortify.cli.config.variable.cli.cmd;
-
-import com.fortify.cli.common.cli.cmd.AbstractFortifyCLICommand;
-
-import picocli.CommandLine.Command;
-
-@Command(
- name = "variable",
- aliases = "var",
- description = "Commands for managing fcli variables",
- subcommands = {
- VariableDefinitionCommands.class,
- VariableContentsCommands.class
- }
-)
-public class VariableCommands extends AbstractFortifyCLICommand {
-}
diff --git a/fcli-config/src/main/java/com/fortify/cli/config/variable/cli/cmd/VariableContentsCommands.java b/fcli-config/src/main/java/com/fortify/cli/config/variable/cli/cmd/VariableContentsCommands.java
deleted file mode 100644
index a5817d6eb8..0000000000
--- a/fcli-config/src/main/java/com/fortify/cli/config/variable/cli/cmd/VariableContentsCommands.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package com.fortify.cli.config.variable.cli.cmd;
-
-import com.fortify.cli.common.cli.cmd.AbstractFortifyCLICommand;
-
-import picocli.CommandLine.Command;
-
-@Command(
- name = "contents",
- description = "Commands for managing fcli variable contents",
- subcommands = {
- VariableContentsGetCommand.class,
- VariableContentsListCommand.class
- }
-)
-public class VariableContentsCommands extends AbstractFortifyCLICommand {
-}
diff --git a/fcli-config/src/main/java/com/fortify/cli/config/variable/cli/cmd/VariableContentsGetCommand.java b/fcli-config/src/main/java/com/fortify/cli/config/variable/cli/cmd/VariableContentsGetCommand.java
deleted file mode 100644
index 265f58dfbb..0000000000
--- a/fcli-config/src/main/java/com/fortify/cli/config/variable/cli/cmd/VariableContentsGetCommand.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.config.variable.cli.cmd;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fortify.cli.common.output.cli.cmd.basic.AbstractBasicOutputCommand;
-import com.fortify.cli.common.output.cli.mixin.BasicOutputHelperMixins;
-import com.fortify.cli.config.variable.cli.mixin.VariableResolverMixin;
-
-import io.micronaut.core.annotation.ReflectiveAccess;
-import lombok.Getter;
-import picocli.CommandLine.Command;
-import picocli.CommandLine.Mixin;
-
-@ReflectiveAccess
-@Command(name = BasicOutputHelperMixins.Get.CMD_NAME)
-public class VariableContentsGetCommand extends AbstractBasicOutputCommand {
- @Getter @Mixin private BasicOutputHelperMixins.Get outputHelper;
- @Mixin private VariableResolverMixin.PositionalParameter variableResolver;
-
- @Override
- public JsonNode getJsonNode() {
- return variableResolver.getVariableContents(); // TODO Check that variable represents an ObjectNode?
- }
-
- @Override
- public boolean isSingular() {
- return !variableResolver.getVariableContents().isArray();
- }
-}
diff --git a/fcli-config/src/main/java/com/fortify/cli/config/variable/cli/cmd/VariableContentsListCommand.java b/fcli-config/src/main/java/com/fortify/cli/config/variable/cli/cmd/VariableContentsListCommand.java
deleted file mode 100644
index 19fd1524b7..0000000000
--- a/fcli-config/src/main/java/com/fortify/cli/config/variable/cli/cmd/VariableContentsListCommand.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.config.variable.cli.cmd;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fortify.cli.common.output.cli.cmd.basic.AbstractBasicOutputCommand;
-import com.fortify.cli.common.output.cli.mixin.BasicOutputHelperMixins;
-import com.fortify.cli.config.variable.cli.mixin.VariableResolverMixin;
-
-import io.micronaut.core.annotation.ReflectiveAccess;
-import lombok.Getter;
-import picocli.CommandLine.Command;
-import picocli.CommandLine.Mixin;
-
-@ReflectiveAccess
-@Command(name = BasicOutputHelperMixins.List.CMD_NAME)
-public class VariableContentsListCommand extends AbstractBasicOutputCommand {
- @Getter @Mixin private BasicOutputHelperMixins.List outputHelper;
- @Mixin private VariableResolverMixin.PositionalParameter variableResolver;
-
- @Override
- public JsonNode getJsonNode() {
- return variableResolver.getVariableContents(); // TODO Check that variable represents an ArrayNode?
- }
-
- @Override
- public boolean isSingular() {
- return false;
- }
-}
diff --git a/fcli-config/src/main/java/com/fortify/cli/config/variable/cli/cmd/VariableDefinitionClearCommand.java b/fcli-config/src/main/java/com/fortify/cli/config/variable/cli/cmd/VariableDefinitionClearCommand.java
deleted file mode 100644
index ea85c61bb9..0000000000
--- a/fcli-config/src/main/java/com/fortify/cli/config/variable/cli/cmd/VariableDefinitionClearCommand.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.config.variable.cli.cmd;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fortify.cli.common.output.cli.cmd.basic.AbstractBasicOutputCommand;
-import com.fortify.cli.common.output.cli.mixin.BasicOutputHelperMixins;
-import com.fortify.cli.common.output.spi.transform.IActionCommandResultSupplier;
-import com.fortify.cli.common.variable.FcliVariableHelper;
-
-import io.micronaut.core.annotation.ReflectiveAccess;
-import lombok.Getter;
-import picocli.CommandLine.Command;
-import picocli.CommandLine.Mixin;
-
-@ReflectiveAccess
-@Command(name = BasicOutputHelperMixins.Clear.CMD_NAME)
-public class VariableDefinitionClearCommand extends AbstractBasicOutputCommand implements IActionCommandResultSupplier {
- @Getter @Mixin private BasicOutputHelperMixins.Clear outputHelper;
-
- @Override
- public JsonNode getJsonNode() {
- JsonNode descriptors = FcliVariableHelper.listDescriptors();
- descriptors.forEach(FcliVariableHelper::delete);
- return descriptors;
- }
-
- @Override
- public String getActionCommandResult() {
- return "DELETED";
- }
-
- @Override
- public boolean isSingular() {
- return false;
- }
-}
diff --git a/fcli-config/src/main/java/com/fortify/cli/config/variable/cli/cmd/VariableDefinitionCommands.java b/fcli-config/src/main/java/com/fortify/cli/config/variable/cli/cmd/VariableDefinitionCommands.java
deleted file mode 100644
index 05e7276fa9..0000000000
--- a/fcli-config/src/main/java/com/fortify/cli/config/variable/cli/cmd/VariableDefinitionCommands.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.fortify.cli.config.variable.cli.cmd;
-
-import com.fortify.cli.common.cli.cmd.AbstractFortifyCLICommand;
-
-import picocli.CommandLine.Command;
-
-@Command(
- name = "definition",
- aliases = "def",
- description = "Commands for managing fcli variable definitions",
- subcommands = {
- VariableDefinitionClearCommand.class,
- VariableDefinitionDeleteCommand.class,
- VariableDefinitionGetCommand.class,
- VariableDefinitionListCommand.class
-
- }
-)
-public class VariableDefinitionCommands extends AbstractFortifyCLICommand {
-}
diff --git a/fcli-config/src/main/java/com/fortify/cli/config/variable/cli/cmd/VariableDefinitionDeleteCommand.java b/fcli-config/src/main/java/com/fortify/cli/config/variable/cli/cmd/VariableDefinitionDeleteCommand.java
deleted file mode 100644
index a2c5a2f37e..0000000000
--- a/fcli-config/src/main/java/com/fortify/cli/config/variable/cli/cmd/VariableDefinitionDeleteCommand.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.config.variable.cli.cmd;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fortify.cli.common.output.cli.cmd.basic.AbstractBasicOutputCommand;
-import com.fortify.cli.common.output.cli.mixin.BasicOutputHelperMixins;
-import com.fortify.cli.common.output.spi.transform.IActionCommandResultSupplier;
-import com.fortify.cli.common.variable.FcliVariableHelper;
-import com.fortify.cli.config.variable.cli.mixin.VariableResolverMixin;
-
-import io.micronaut.core.annotation.ReflectiveAccess;
-import lombok.Getter;
-import picocli.CommandLine.Command;
-import picocli.CommandLine.Mixin;
-
-@ReflectiveAccess
-@Command(name = BasicOutputHelperMixins.Delete.CMD_NAME)
-public class VariableDefinitionDeleteCommand extends AbstractBasicOutputCommand implements IActionCommandResultSupplier {
- @Getter @Mixin private BasicOutputHelperMixins.Delete outputHelper;
- @Mixin private VariableResolverMixin.PositionalParameter variableResolver;
-
- @Override
- public JsonNode getJsonNode() {
- JsonNode descriptorNode = variableResolver.getVariableDescriptor().asJsonNode();
- FcliVariableHelper.delete(descriptorNode);
- return descriptorNode;
- }
-
- @Override
- public String getActionCommandResult() {
- return "DELETED";
- }
-
- @Override
- public boolean isSingular() {
- return true;
- }
-}
diff --git a/fcli-config/src/main/java/com/fortify/cli/config/variable/cli/cmd/VariableDefinitionGetCommand.java b/fcli-config/src/main/java/com/fortify/cli/config/variable/cli/cmd/VariableDefinitionGetCommand.java
deleted file mode 100644
index aeadb2f5c1..0000000000
--- a/fcli-config/src/main/java/com/fortify/cli/config/variable/cli/cmd/VariableDefinitionGetCommand.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.config.variable.cli.cmd;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fortify.cli.common.output.cli.cmd.basic.AbstractBasicOutputCommand;
-import com.fortify.cli.common.output.cli.mixin.BasicOutputHelperMixins;
-import com.fortify.cli.config.variable.cli.mixin.VariableResolverMixin;
-
-import io.micronaut.core.annotation.ReflectiveAccess;
-import lombok.Getter;
-import picocli.CommandLine.Command;
-import picocli.CommandLine.Mixin;
-
-@ReflectiveAccess
-@Command(name = BasicOutputHelperMixins.Get.CMD_NAME)
-public class VariableDefinitionGetCommand extends AbstractBasicOutputCommand {
- @Getter @Mixin private BasicOutputHelperMixins.Get outputHelper;
- @Mixin private VariableResolverMixin.PositionalParameter variableResolver;
-
- @Override
- public JsonNode getJsonNode() {
- return variableResolver.getVariableDescriptor().asJsonNode();
- }
-
- @Override
- public boolean isSingular() {
- return true;
- }
-}
diff --git a/fcli-config/src/main/java/com/fortify/cli/config/variable/cli/cmd/VariableDefinitionListCommand.java b/fcli-config/src/main/java/com/fortify/cli/config/variable/cli/cmd/VariableDefinitionListCommand.java
deleted file mode 100644
index 57b68d271c..0000000000
--- a/fcli-config/src/main/java/com/fortify/cli/config/variable/cli/cmd/VariableDefinitionListCommand.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2021 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.config.variable.cli.cmd;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fortify.cli.common.output.cli.cmd.basic.AbstractBasicOutputCommand;
-import com.fortify.cli.common.output.cli.mixin.BasicOutputHelperMixins;
-import com.fortify.cli.common.variable.FcliVariableHelper;
-
-import io.micronaut.core.annotation.ReflectiveAccess;
-import lombok.Getter;
-import picocli.CommandLine.Command;
-import picocli.CommandLine.Mixin;
-
-@ReflectiveAccess
-@Command(name = BasicOutputHelperMixins.List.CMD_NAME)
-public class VariableDefinitionListCommand extends AbstractBasicOutputCommand {
- @Getter @Mixin private BasicOutputHelperMixins.List outputHelper;
-
- @Override
- public JsonNode getJsonNode() {
- return FcliVariableHelper.listDescriptors();
- }
-
- @Override
- public boolean isSingular() {
- return false;
- }
-}
diff --git a/fcli-config/src/main/java/com/fortify/cli/config/variable/cli/mixin/VariableResolverMixin.java b/fcli-config/src/main/java/com/fortify/cli/config/variable/cli/mixin/VariableResolverMixin.java
deleted file mode 100644
index 95fbaf4b25..0000000000
--- a/fcli-config/src/main/java/com/fortify/cli/config/variable/cli/mixin/VariableResolverMixin.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*******************************************************************************
- * (c) Copyright 2020 Micro Focus or one of its affiliates
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to
- * whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- ******************************************************************************/
-package com.fortify.cli.config.variable.cli.mixin;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fortify.cli.common.variable.FcliVariableHelper;
-import com.fortify.cli.common.variable.FcliVariableHelper.VariableDescriptor;
-
-import io.micronaut.core.annotation.ReflectiveAccess;
-import lombok.Getter;
-import picocli.CommandLine.Option;
-import picocli.CommandLine.Parameters;
-
-public class VariableResolverMixin {
-
- @ReflectiveAccess
- public static abstract class AbstractVariableResolverMixin {
- public abstract String getVariableName();
- public abstract boolean isRequired();
-
- public VariableDescriptor getVariableDescriptor(){
- return FcliVariableHelper.getVariableDescriptor(getVariableName(), isRequired());
- }
-
- public JsonNode getVariableContents(){
- return FcliVariableHelper.getVariableContents(getVariableName(), isRequired());
- }
- }
-
- @ReflectiveAccess
- public static abstract class AbstractRequiredVariableResolverMixin extends AbstractVariableResolverMixin {
- @Getter private boolean required = true;
- }
-
- @ReflectiveAccess
- public static class RequiredOption extends AbstractRequiredVariableResolverMixin {
- @Option(names = {"--variable"}, required = true)
- @Getter private String variableName;
- }
-
- @ReflectiveAccess
- public static class PositionalParameter extends AbstractRequiredVariableResolverMixin {
- @Parameters(index = "0", arity = "1")
- @Getter private String variableName;
- }
-}
diff --git a/fcli-config/src/main/resources/com/fortify/cli/config/i18n/ConfigMessages.properties b/fcli-config/src/main/resources/com/fortify/cli/config/i18n/ConfigMessages.properties
deleted file mode 100644
index 0a6f873881..0000000000
--- a/fcli-config/src/main/resources/com/fortify/cli/config/i18n/ConfigMessages.properties
+++ /dev/null
@@ -1,53 +0,0 @@
-# fcli config
-fcli.config.usage.header = Commands for configuring fcli
-
-# fcli config clear
-fcli.config.clear.usage.header = Clear full fcli configuration and data
-fcli.config.clear.usage.description = This command deletes the fcli home directory, clearing all fcli configuration settings and other data like sessions and variables. As a best practice, you should log out of any existing sessions before running this command.
-fcli.config.clear.confirm = Confirm clearing all fcli configuration settings and other data
-
-# fcli config language
-fcli.config.language.usage.header = Commands for listing and setting languages that FCLI's help information can be outputted in.
-fcli.config.language.list.usage.header = List all supported languages.
-fcli.config.language.set.usage.header = Set a default language.
-fcli.config.language.set.language = The 2 letter code for the language you want FCLI to output information in. For a list of supported languages, please use the `${ROOT-COMMAND-NAME:-$PARENTCOMMAND} config language list` command.
-fcli.config.language.get.usage.header = Get the currently set language/locale.
-
-# fcli config proxy
-fcli.config.proxy.usage.header = Commands for configuring proxy servers used to connect to target systems
-fcli.config.proxy.add.usage.header = Add a proxy configuration
-fcli.config.proxy.add.name = Name for the proxy configuration to be added; defaults to :
-fcli.config.proxy.clear.usage.header = Clear all proxy configurations
-fcli.config.proxy.delete.usage.header = Delete a proxy configuration
-fcli.config.proxy.delete.name = Name of the proxy configuration to be deleted
-fcli.config.proxy.list.usage.header = List proxy configurations
-fcli.config.proxy.update.usage.header = Update a proxy configuration
-fcli.config.proxy.update.name = Name of the proxy configuration to be updated
-fcli.config.proxy.hostAndPort = Proxy host and port in the format :
-fcli.config.proxy.user = Username used to authenticate with the proxy server
-fcli.config.proxy.password = Password used to authenticate with the proxy server
-fcli.config.proxy.priority = Priority of this proxy configuration. If multiple configuration match the target module & URL, the proxy configuration with highest priority is used.
-fcli.config.proxy.modules = Comma-separated list of fcli modules / target systems (fod, sc-dast, sc-sast, ssc, debricked, tool) on which to apply this proxy configuration
-fcli.config.proxy.include-hosts = Comma-separated list of target host names on which to apply this proxy configuration. Host names may include wildcard characters, like *.fortifyhosted.net.
-fcli.config.proxy.exclude-hosts = Comma-separated list of target host names on which not to apply this proxy configuration. Host names may include wildcard characters, like *.myintra.net.
-
-fcli.config.ssl.usage.header = Commands for configuring SSL connectivity
-fcli.config.ssl.truststore.usage.header = Commands for managing the SSL trust store
-fcli.config.ssl.truststore.clear.usage.header = Reset SSL trust store configuration to use default trust store
-fcli.config.ssl.truststore.get.usage.header = Get current SSL trust store configuration
-fcli.config.ssl.truststore.set.usage.header = Configure SSL trust store
-fcli.config.ssl.truststore.set.trustStorePath = Path to custom SSL trust store
-fcli.config.ssl.truststore.set.truststore-password = SSL trust store password
-fcli.config.ssl.truststore.set.truststore-type = SSL trust store type (jks, pkcs12)
-
-# fcli config variable
-fcli.config.variable.usage.header = Manage fcli variables
-fcli.config.variable.definition.usage.header = Manage fcli variable definitions
-fcli.config.variable.definition.clear.usage.header = Clear all variable definitions
-fcli.config.variable.definition.delete.usage.header = Delete a variable definition
-fcli.config.variable.definition.get.usage.header = Get a single variable definition
-fcli.config.variable.definition.list.usage.header = List variable definitions
-fcli.config.variable.contents.usage.header = Manage fcli variable contents
-fcli.config.variable.contents.get.usage.header = Get the contents of a variable as a single record
-fcli.config.variable.contents.list.usage.header = Get the contents of a variable as a list of records
-
diff --git a/fcli-core/fcli-app/build.gradle b/fcli-core/fcli-app/build.gradle
new file mode 100644
index 0000000000..fa1372fe36
--- /dev/null
+++ b/fcli-core/fcli-app/build.gradle
@@ -0,0 +1,92 @@
+apply from: "${sharedGradleScriptsDir}/fcli-java.gradle"
+apply plugin: 'com.github.johnrengelman.shadow'
+
+// Define dependencies on all fcli Gradle projects
+dependencies {
+ implementation project("${fcliCommonRef}")
+ implementation project("${fcliConfigRef}")
+ implementation project("${fcliFoDRef}")
+ implementation project("${fcliSSCRef}")
+ implementation project("${fcliSCSastRef}")
+ implementation project("${fcliSCDastRef}")
+ implementation project("${fcliToolRef}")
+ implementation project("${fcliLicenseRef}")
+ implementation project("${fcliUtilRef}")
+
+ // Logging dependencies
+ runtimeOnly('org.slf4j:jcl-over-slf4j')
+
+ // Enable ANSI support
+ runtimeOnly("org.fusesource.jansi:jansi")
+}
+
+// Generate build properties and associated resource-config.json file
+ext.buildPropertiesDir = "${buildDir}/generated-build-properties"
+task generateFcliBuildProperties {
+ doLast {
+ def outputDir = "${buildPropertiesDir}/com/fortify/cli/app"
+ mkdir "${outputDir}"
+ ant.propertyfile(file: "${outputDir}/fcli-build.properties") {
+ entry(key: "projectName", value: "fcli")
+ entry(key: "projectVersion", value: project.version)
+ entry(key: "buildDate", value: buildTime.format('yyyy-MM-dd HH:mm:ss'))
+ }
+ def resourceConfigOutputDir = "${buildPropertiesDir}/META-INF/native-image/fcli-build-properties"
+ mkdir "${resourceConfigOutputDir}"
+ def contents =
+ '{"resources":[\n' +
+ ' {"pattern":"com/fortify/cli/app/fcli-build.properties"}\n' +
+ ']}\n'
+ file("${resourceConfigOutputDir}/resource-config.json").text = contents;
+ println contents
+ }
+}
+sourceSets.main.output.dir buildPropertiesDir, builtBy: generateFcliBuildProperties
+
+// Generate reflect-config.json for picocli-related classes
+ext.generatedPicocliReflectConfigDir = "${buildDir}/generated-reflect-config"
+task generatePicocliReflectConfig(type: JavaExec) {
+ group = "GeneratePicocliReflectConfig"
+ description = "Generate picocli reflect-config.json"
+ classpath(configurations.runtimeClasspath, configurations.annotationProcessor, sourceSets.main.runtimeClasspath)
+ main 'picocli.codegen.aot.graalvm.ReflectionConfigGenerator'
+ args fcliRootCommandsClassName, "-o", "${generatedPicocliReflectConfigDir}/META-INF/native-image/picocli-reflect-config/reflect-config.json"
+}
+
+// Generate shadow jar
+apply plugin: 'application'
+application {
+ // fcliMainClassName is defined in top-level gradle.properties
+ mainClass.set(fcliMainClassName)
+}
+shadowJar {
+ mergeServiceFiles()
+ archiveBaseName.set('fcli')
+ archiveClassifier.set('')
+ archiveVersion.set('')
+ from(["$generatedPicocliReflectConfigDir"])
+}
+shadowJar.dependsOn generatePicocliReflectConfig
+
+ext {
+ thirdPartyBaseName = "${project.name}"
+}
+apply plugin: 'com.github.jk1.dependency-license-report'
+apply from: "${gradleHelpersLocation}/thirdparty-helper.gradle"
+
+task distThirdPartyReleaseAsset {
+ dependsOn 'distThirdParty'
+ dependsOn(createDistDir)
+ doLast {
+ file("$buildDir/dist/fcli-app-thirdparty.zip").renameTo(file("${releaseAssetsDir}/fcli-thirdparty.zip"))
+ }
+}
+
+task dist(type: Copy) {
+ dependsOn 'shadowJar'
+ dependsOn(createDistDir)
+ into "${releaseAssetsDir}"
+ from("${buildDir}/libs") {
+ include "fcli.jar"
+ }
+}
\ No newline at end of file
diff --git a/fcli-core/fcli-app/src/main/java/com/fortify/cli/app/FortifyCLI.java b/fcli-core/fcli-app/src/main/java/com/fortify/cli/app/FortifyCLI.java
new file mode 100644
index 0000000000..7d25fa25d8
--- /dev/null
+++ b/fcli-core/fcli-app/src/main/java/com/fortify/cli/app/FortifyCLI.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright 2021, 2023 Open Text.
+ *
+ * The only warranties for products and services of Open Text
+ * and its affiliates and licensors ("Open Text") are as may
+ * be set forth in the express warranty statements accompanying
+ * such products and services. Nothing herein should be construed
+ * as constituting an additional warranty. Open Text shall not be
+ * liable for technical or editorial errors or omissions contained
+ * herein. The information contained herein is subject to change
+ * without notice.
+ *******************************************************************************/
+package com.fortify.cli.app;
+
+import com.fortify.cli.app.runner.DefaultFortifyCLIRunner;
+
+/**
+ * This class provides the {@link #main(String[])} entrypoint into the application,
+ * and also registers some GraalVM features, allowing the application to run properly
+ * as GraalVM native images.
+ *
+ * @author Ruud Senden
+ */
+public class FortifyCLI {
+ private static final Boolean JANSI_DISABLE = Boolean.getBoolean("jansi.disable");
+
+ /**
+ * This is the main entry point for executing the Fortify CLI.
+ * @param args Command line options passed to Fortify CLI
+ */
+ public static final void main(String[] args) {
+ System.exit(execute(args));
+ }
+
+ private static final int execute(String[] args) {
+ try ( var runner = new DefaultFortifyCLIRunner() ) {
+ installAnsiConsole();
+ return runner.run(args);
+ } finally {
+ uninstallAnsiConsole();
+ }
+ }
+
+ private static final void installAnsiConsole() {
+ tryInvokeAnsiConsoleMethod("systemInstall");
+ }
+
+ private static final void uninstallAnsiConsole() {
+ tryInvokeAnsiConsoleMethod("systemUninstall");
+ }
+
+ private static final void tryInvokeAnsiConsoleMethod(String methodName) {
+ if ( !JANSI_DISABLE ) {
+ try {
+ // AnsiConsole performs eager initialization in a static block, so
+ // referencing the class directly would initialize Jansi even if
+ // isJansiEnabled() returns false. As such, we use reflection to
+ // only load the AnsiConsole class if Jansi is enabled, and then
+ // invoke the specified method. Note that in order for this to work,
+ // we have a reflect-config.json file to allow reflective access to
+ // AnsiConsole.
+ Class.forName("org.fusesource.jansi.AnsiConsole")
+ .getMethod(methodName).invoke(null);
+ } catch ( Throwable t ) {
+ t.printStackTrace();
+ }
+ }
+ }
+}
diff --git a/fcli-core/fcli-app/src/main/java/com/fortify/cli/app/FortifyCLIVersionProvider.java b/fcli-core/fcli-app/src/main/java/com/fortify/cli/app/FortifyCLIVersionProvider.java
new file mode 100644
index 0000000000..c084d4d6ec
--- /dev/null
+++ b/fcli-core/fcli-app/src/main/java/com/fortify/cli/app/FortifyCLIVersionProvider.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright 2021, 2023 Open Text.
+ *
+ * The only warranties for products and services of Open Text
+ * and its affiliates and licensors ("Open Text") are as may
+ * be set forth in the express warranty statements accompanying
+ * such products and services. Nothing herein should be construed
+ * as constituting an additional warranty. Open Text shall not be
+ * liable for technical or editorial errors or omissions contained
+ * herein. The information contained herein is subject to change
+ * without notice.
+ *******************************************************************************/
+package com.fortify.cli.app;
+
+import com.fortify.cli.common.util.FcliBuildPropertiesHelper;
+
+import picocli.CommandLine.IVersionProvider;
+
+public class FortifyCLIVersionProvider implements IVersionProvider {
+ @Override
+ public final String[] getVersion() throws Exception {
+ return new String[] {FcliBuildPropertiesHelper.getFcliBuildInfo()};
+ }
+}
diff --git a/fcli-core/fcli-app/src/main/java/com/fortify/cli/app/_main/cli/cmd/FCLIRootCommands.java b/fcli-core/fcli-app/src/main/java/com/fortify/cli/app/_main/cli/cmd/FCLIRootCommands.java
new file mode 100644
index 0000000000..06d1638bf0
--- /dev/null
+++ b/fcli-core/fcli-app/src/main/java/com/fortify/cli/app/_main/cli/cmd/FCLIRootCommands.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright 2021, 2023 Open Text.
+ *
+ * The only warranties for products and services of Open Text
+ * and its affiliates and licensors ("Open Text") are as may
+ * be set forth in the express warranty statements accompanying
+ * such products and services. Nothing herein should be construed
+ * as constituting an additional warranty. Open Text shall not be
+ * liable for technical or editorial errors or omissions contained
+ * herein. The information contained herein is subject to change
+ * without notice.
+ *******************************************************************************/
+package com.fortify.cli.app._main.cli.cmd;
+
+import com.fortify.cli.app.FortifyCLIVersionProvider;
+import com.fortify.cli.common.cli.cmd.AbstractContainerCommand;
+import com.fortify.cli.common.util.DisableTest;
+import com.fortify.cli.common.util.DisableTest.TestType;
+import com.fortify.cli.config._main.cli.cmd.ConfigCommands;
+import com.fortify.cli.fod._main.cli.cmd.FoDCommands;
+import com.fortify.cli.license._main.cli.cmd.LicenseCommands;
+import com.fortify.cli.sc_dast._main.cli.cmd.SCDastCommands;
+import com.fortify.cli.sc_sast._main.cli.cmd.SCSastCommands;
+import com.fortify.cli.ssc._main.cli.cmd.SSCCommands;
+import com.fortify.cli.tool._main.cli.cmd.ToolCommands;
+import com.fortify.cli.util._main.cli.cmd.UtilCommands;
+
+import picocli.CommandLine.Command;
+import picocli.CommandLine.Option;
+import picocli.CommandLine.ScopeType;
+
+/**
+ * This is the root command for the fcli application, defining common properties
+ * like help options mixin and help footer that will be inherited by all
+ * sub-commands. Other than that, it also includes the {@link LoggingMixin}
+ * to avoid picocli from complaining about not recognizing those options.
+ * Actual logging setup will already have been completed before this command
+ * is even loaded, so the logging options themselves are not being processed here.
+ *
+ * @author Ruud Senden
+ */
+@Command(name = "fcli",
+ resourceBundle = "com.fortify.cli.common.i18n.FortifyCLIMessages",
+ versionProvider = FortifyCLIVersionProvider.class,
+ subcommands = {
+ ConfigCommands.class,
+ FoDCommands.class,
+ SCDastCommands.class,
+ SCSastCommands.class,
+ SSCCommands.class,
+ ToolCommands.class,
+ LicenseCommands.class,
+ UtilCommands.class
+ }
+)
+public class FCLIRootCommands extends AbstractContainerCommand {
+ // We only want to have the --version option on the top-level fcli command,
+ @Option(names = {"-V", "--version"}, versionHelp = true, scope = ScopeType.LOCAL, order = -1002)
+ @DisableTest(TestType.OPT_SHORT_NAME)
+ boolean versionInfoRequested;
+}
diff --git a/fcli-core/fcli-app/src/main/java/com/fortify/cli/app/package-info.java b/fcli-core/fcli-app/src/main/java/com/fortify/cli/app/package-info.java
new file mode 100644
index 0000000000..81cf21ecd1
--- /dev/null
+++ b/fcli-core/fcli-app/src/main/java/com/fortify/cli/app/package-info.java
@@ -0,0 +1,17 @@
+/*******************************************************************************
+ * Copyright 2021, 2022 Open Text.
+ *
+ * The only warranties for products and services of Open Text
+ * and its affiliates and licensors ("Open Text") are as may
+ * be set forth in the express warranty statements accompanying
+ * such products and services. Nothing herein should be construed
+ * as constituting an additional warranty. Open Text shall not be
+ * liable for technical or editorial errors or omissions contained
+ * herein. The information contained herein is subject to change
+ * without notice.
+ *******************************************************************************/
+/**
+ * This package contains the main entrypoint for fcli.
+ */
+package com.fortify.cli.app;
+
diff --git a/fcli-core/fcli-app/src/main/java/com/fortify/cli/app/runner/DefaultFortifyCLIRunner.java b/fcli-core/fcli-app/src/main/java/com/fortify/cli/app/runner/DefaultFortifyCLIRunner.java
new file mode 100644
index 0000000000..75baf3aa7a
--- /dev/null
+++ b/fcli-core/fcli-app/src/main/java/com/fortify/cli/app/runner/DefaultFortifyCLIRunner.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright 2021, 2023 Open Text.
+ *
+ * The only warranties for products and services of Open Text
+ * and its affiliates and licensors ("Open Text") are as may
+ * be set forth in the express warranty statements accompanying
+ * such products and services. Nothing herein should be construed
+ * as constituting an additional warranty. Open Text shall not be
+ * liable for technical or editorial errors or omissions contained
+ * herein. The information contained herein is subject to change
+ * without notice.
+ *******************************************************************************/
+package com.fortify.cli.app.runner;
+
+import java.util.List;
+
+import com.fortify.cli.app._main.cli.cmd.FCLIRootCommands;
+import com.fortify.cli.app.runner.util.FortifyCLIDefaultValueProvider;
+import com.fortify.cli.app.runner.util.FortifyCLIDynamicInitializer;
+import com.fortify.cli.app.runner.util.FortifyCLIStaticInitializer;
+import com.fortify.cli.common.rest.unirest.GenericUnirestFactory;
+import com.fortify.cli.common.variable.FcliVariableHelper;
+
+import picocli.CommandLine;
+
+public final class DefaultFortifyCLIRunner implements IFortifyCLIRunner {
+ // TODO See https://github.com/remkop/picocli/issues/2066
+ //@Getter(value = AccessLevel.PRIVATE, lazy = true)
+ //private final CommandLine commandLine = createCommandLine();
+
+ private CommandLine createCommandLine() {
+ FortifyCLIStaticInitializer.getInstance().initialize();
+ CommandLine cl = new CommandLine(FCLIRootCommands.class);
+ // Custom parameter exception handler is disabled for now as it causes https://github.com/fortify/fcli/issues/434.
+ // See comments in I18nParameterExceptionHandler for more detail.
+ //cl.setParameterExceptionHandler(new I18nParameterExceptionHandler(cl.getParameterExceptionHandler()));
+ cl.setDefaultValueProvider(FortifyCLIDefaultValueProvider.getInstance());
+ return cl;
+ }
+
+ @Override
+ public int run(String... args) {
+ try {
+ String[] resolvedArgs = FcliVariableHelper.resolveVariables(args);
+ FortifyCLIDynamicInitializer.getInstance().initialize(resolvedArgs);
+ //CommandLine cl = getCommandLine(); // TODO See https://github.com/remkop/picocli/issues/2066
+ CommandLine cl = createCommandLine();
+ cl.clearExecutionResults();
+ return cl.execute(resolvedArgs);
+ } finally {
+ // TODO For now, this is required to ensure new connections are used for
+ // every fcli invocation, as otherwise we may be using older proxy settings
+ // after proxy has been reconfigured.
+ GenericUnirestFactory.shutdown();
+ }
+ }
+
+ @Override
+ public int run(List args) {
+ return run(args.toArray(new String[] {}));
+ }
+
+ @Override
+ public void close() {
+ GenericUnirestFactory.shutdown();
+ }
+}
diff --git a/fcli-core/fcli-app/src/main/java/com/fortify/cli/app/runner/IFortifyCLIRunner.java b/fcli-core/fcli-app/src/main/java/com/fortify/cli/app/runner/IFortifyCLIRunner.java
new file mode 100644
index 0000000000..9d32ae105d
--- /dev/null
+++ b/fcli-core/fcli-app/src/main/java/com/fortify/cli/app/runner/IFortifyCLIRunner.java
@@ -0,0 +1,20 @@
+/**
+ * Copyright 2023 Open Text.
+ *
+ * The only warranties for products and services of Open Text
+ * and its affiliates and licensors ("Open Text") are as may
+ * be set forth in the express warranty statements accompanying
+ * such products and services. Nothing herein should be construed
+ * as constituting an additional warranty. Open Text shall not be
+ * liable for technical or editorial errors or omissions contained
+ * herein. The information contained herein is subject to change
+ * without notice.
+ */
+package com.fortify.cli.app.runner;
+
+import java.util.List;
+
+public interface IFortifyCLIRunner extends AutoCloseable {
+ int run(String... args);
+ int run(List args);
+}
diff --git a/fcli-core/fcli-app/src/main/java/com/fortify/cli/app/runner/util/FortifyCLIDefaultValueProvider.java b/fcli-core/fcli-app/src/main/java/com/fortify/cli/app/runner/util/FortifyCLIDefaultValueProvider.java
new file mode 100644
index 0000000000..f5b916a278
--- /dev/null
+++ b/fcli-core/fcli-app/src/main/java/com/fortify/cli/app/runner/util/FortifyCLIDefaultValueProvider.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright 2021, 2023 Open Text.
+ *
+ * The only warranties for products and services of Open Text
+ * and its affiliates and licensors ("Open Text") are as may
+ * be set forth in the express warranty statements accompanying
+ * such products and services. Nothing herein should be construed
+ * as constituting an additional warranty. Open Text shall not be
+ * liable for technical or editorial errors or omissions contained
+ * herein. The information contained herein is subject to change
+ * without notice.
+ *******************************************************************************/
+package com.fortify.cli.app.runner.util;
+
+import java.lang.reflect.AnnotatedElement;
+
+import com.fortify.cli.common.cli.util.EnvSuffix;
+import com.fortify.cli.common.util.EnvHelper;
+import com.fortify.cli.common.util.StringUtils;
+
+import lombok.AccessLevel;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import picocli.CommandLine.IDefaultValueProvider;
+import picocli.CommandLine.Model.ArgSpec;
+import picocli.CommandLine.Model.CommandSpec;
+import picocli.CommandLine.Model.OptionSpec;
+
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class FortifyCLIDefaultValueProvider implements IDefaultValueProvider {
+ @Getter private static final FortifyCLIDefaultValueProvider instance = new FortifyCLIDefaultValueProvider();
+
+ @Setter private String envPrefix = "FCLI_DEFAULT";
+
+ @Override
+ public String defaultValue(ArgSpec argSpec) {
+ String envVarSuffix;
+ if (argSpec instanceof OptionSpec) {
+ final var optionSpec = (OptionSpec) argSpec;
+ envVarSuffix = getEnvVarSuffix(optionSpec.userObject(), optionSpec.longestName().replaceAll("^-+", ""));
+ } else {
+ envVarSuffix = getEnvVarSuffix(argSpec.userObject(), normalizeParamLabel(argSpec.paramLabel()));
+ }
+ return resolve(argSpec.command(), envVarSuffix);
+ }
+
+ private String resolve(CommandSpec command, String suffix) {
+ if ( command!=null && suffix!=null ) {
+ var envVarName = getEnvVarName(command, suffix);
+ String value = EnvHelper.env(envVarName);
+ if ( StringUtils.isNotBlank(value) ) { return value; }
+ return resolve(command.parent(), suffix);
+ }
+ return null;
+ }
+
+ private final String getEnvVarSuffix(Object userObject, String defaultValue) {
+ if ( userObject!=null && userObject instanceof AnnotatedElement ) {
+ EnvSuffix envSuffixAnnotation = ((AnnotatedElement)userObject).getAnnotation(EnvSuffix.class);
+ if ( envSuffixAnnotation!=null ) { return envSuffixAnnotation.value(); }
+ }
+ return defaultValue;
+ }
+
+ private final String getEnvVarName(CommandSpec command, String suffix) {
+ String qualifiedCommandName = command.qualifiedName("_");
+ String combinedName = String.format("%s_%s", qualifiedCommandName, suffix);
+ return combinedName.replace('-', '_')
+ .replaceAll("__", "_") // Replace duplicate underscores
+ .replaceAll("^_+|_+$", "") // Strip leading and trailing underscores
+ .toUpperCase().replaceFirst("FCLI", envPrefix);
+ }
+
+ private final String normalizeParamLabel(String paramLabel) {
+ return paramLabel
+ .replaceAll("\\s", "_") // Replace whitespace by underscores
+ .replaceAll("[^a-zA-Z\\d-_]", "_") // Replace all special characters by underscore
+ .replaceAll("(?!a.matches("-h|--help")).toArray(String[]::new);
+ getGenericOptionsCommandLine().execute(argsWithoutHelp);
+ }
+
+ private void initialize(GenericOptionsArgGroup genericOptions) {
+ initializeEnvPrefix(genericOptions);
+ initializeLogging(genericOptions);
+ }
+
+ private void initializeEnvPrefix(GenericOptionsArgGroup genericOptions) {
+ String envPrefix = genericOptions.getEnvPrefix();
+ System.setProperty("fcli.env.default.prefix", envPrefix);
+ FortifyCLIDefaultValueProvider.getInstance().setEnvPrefix(envPrefix);
+ }
+
+ public void initializeLogging(GenericOptionsArgGroup genericOptions) {
+ String logFile = genericOptions.getLogFile().getAbsolutePath();
+ LogLevel logLevel = genericOptions.getLogLevel();
+ if ( logFile!=null || logLevel!=null ) {
+ LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
+ Logger rootLogger = loggerContext.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);
+ configureLogFile(rootLogger, logFile==null ? "fcli.log" : logFile);
+ configureLogLevel(rootLogger, logLevel==null ? LogLevel.INFO : logLevel);
+ }
+ }
+
+ private void configureLogFile(Logger rootLogger, String logFile) {
+ LoggerContext loggerContext = rootLogger.getLoggerContext();
+ FileAppender fileAppender = new FileAppender();
+ fileAppender.setFile(logFile);
+ fileAppender.setAppend(false);
+ LayoutWrappingEncoder encoder = new LayoutWrappingEncoder();
+ encoder.setContext(loggerContext);
+ TTLLLayout layout = new TTLLLayout();
+ layout.setContext(loggerContext);
+ layout.start();
+ encoder.setLayout(layout);
+ fileAppender.setEncoder(encoder);
+ fileAppender.setContext(loggerContext);
+ fileAppender.start();
+ rootLogger.addAppender(fileAppender);
+ }
+
+ private void configureLogLevel(Logger rootLogger, LogLevel level) {
+ rootLogger.setLevel(level.getLogbackLevel());
+ }
+
+ private CommandLine createGenericOptionsCommandLine() {
+ return new CommandLine(new FortifyCLIInitializerCommand(this::initialize))
+ .setOut(DUMMY_WRITER)
+ .setErr(DUMMY_WRITER)
+ .setUnmatchedArgumentsAllowed(true)
+ .setUnmatchedOptionsArePositionalParams(true)
+ .setExpandAtFiles(true)
+ .setDefaultValueProvider(FortifyCLIDefaultValueProvider.getInstance());
+ }
+
+ @Command(name = "fcli")
+ @RequiredArgsConstructor
+ public static final class FortifyCLIInitializerCommand extends AbstractRunnableCommand implements Runnable {
+ private final Consumer consumer;
+
+ @Override
+ public void run() {
+ consumer.accept(getGenericOptions());
+ }
+ }
+}
diff --git a/fcli-core/fcli-app/src/main/java/com/fortify/cli/app/runner/util/FortifyCLIStaticInitializer.java b/fcli-core/fcli-app/src/main/java/com/fortify/cli/app/runner/util/FortifyCLIStaticInitializer.java
new file mode 100644
index 0000000000..1158f83fdc
--- /dev/null
+++ b/fcli-core/fcli-app/src/main/java/com/fortify/cli/app/runner/util/FortifyCLIStaticInitializer.java
@@ -0,0 +1,108 @@
+/**
+ * Copyright 2023 Open Text.
+ *
+ * The only warranties for products and services of Open Text
+ * and its affiliates and licensors ("Open Text") are as may
+ * be set forth in the express warranty statements accompanying
+ * such products and services. Nothing herein should be construed
+ * as constituting an additional warranty. Open Text shall not be
+ * liable for technical or editorial errors or omissions contained
+ * herein. The information contained herein is subject to change
+ * without notice.
+ */
+package com.fortify.cli.app.runner.util;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Locale;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.fortify.cli.common.http.ssl.truststore.helper.TrustStoreConfigDescriptor;
+import com.fortify.cli.common.http.ssl.truststore.helper.TrustStoreConfigHelper;
+import com.fortify.cli.common.i18n.helper.LanguageHelper;
+import com.fortify.cli.common.util.StringUtils;
+import com.fortify.cli.fod._common.scan.helper.FoDScanStatus;
+import com.fortify.cli.sc_dast.scan.helper.SCDastScanStatus;
+import com.fortify.cli.sc_sast.scan.helper.SCSastControllerScanJobArtifactState;
+import com.fortify.cli.sc_sast.scan.helper.SCSastControllerScanJobState;
+import com.fortify.cli.ssc.artifact.helper.SSCArtifactStatus;
+
+import lombok.AccessLevel;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+/**
+ * This class is responsible for performing static initialization of fcli, i.e.,
+ * initialization that is not dependent on command-line options.
+ *
+ * @author Ruud Senden
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class FortifyCLIStaticInitializer {
+ private final Log log = LogFactory.getLog(getClass());
+ @Getter(lazy = true)
+ private static final FortifyCLIStaticInitializer instance = new FortifyCLIStaticInitializer();
+
+ public void initialize() {
+ initializeTrustStore();
+ initializeLocale();
+ initializeFoDProperties();
+ initializeSCDastProperties();
+ initializeSCSastProperties();
+ initializeSSCProperties();
+ }
+
+ private void initializeFoDProperties() {
+ System.setProperty("fcli.fod.scan.states", getValuesString(FoDScanStatus.values()));
+ System.setProperty("fcli.fod.scan.states.complete", getValuesString(FoDScanStatus.getDefaultCompleteStates()));
+ }
+
+ private void initializeSCDastProperties() {
+ System.setProperty("fcli.sc-dast.scan.states", getValuesString(SCDastScanStatus.values()));
+ System.setProperty("fcli.sc-dast.scan.states.complete", getValuesString(SCDastScanStatus.getDefaultCompleteStates()));
+ }
+
+ private void initializeSCSastProperties() {
+ System.setProperty("fcli.sc-sast.scan.jobStates", getValuesString(SCSastControllerScanJobState.values()));
+ System.setProperty("fcli.sc-sast.scan.jobStates.complete", getValuesString(SCSastControllerScanJobState.getDefaultCompleteStates()));
+ System.setProperty("fcli.sc-sast.scan.jobArtifactStates", getValuesString(SCSastControllerScanJobArtifactState.values()));
+ System.setProperty("fcli.sc-sast.scan.jobArtifactStates.complete", getValuesString(SCSastControllerScanJobArtifactState.getDefaultCompleteStates()));
+ }
+
+ private void initializeSSCProperties() {
+ System.setProperty("fcli.ssc.artifact.states", getValuesString(SSCArtifactStatus.values()));
+ System.setProperty("fcli.ssc.artifact.states.complete", getValuesString(SSCArtifactStatus.getDefaultCompleteStates()));
+ }
+
+ private void initializeTrustStore() {
+ // First clear existing configuration
+ System.clearProperty("javax.net.ssl.trustStore");
+ System.clearProperty("avax.net.ssl.trustStorePassword");
+ TrustStoreConfigDescriptor descriptor = TrustStoreConfigHelper.getTrustStoreConfig();
+ if ( descriptor!=null && StringUtils.isNotBlank(descriptor.getPath()) ) {
+ Path absolutePath = Path.of(descriptor.getPath()).toAbsolutePath();
+ if ( !Files.exists(absolutePath) ) {
+ log.warn("WARN: Trust store cannot be found: "+absolutePath);
+ }
+ System.setProperty("javax.net.ssl.trustStore", descriptor.getPath());
+ if ( StringUtils.isNotBlank(descriptor.getType()) ) {
+ System.setProperty("javax.net.ssl.trustStoreType", descriptor.getType());
+ }
+ if ( StringUtils.isNotBlank(descriptor.getPassword()) ) {
+ System.setProperty("javax.net.ssl.trustStorePassword", descriptor.getPassword());
+ }
+ }
+ }
+
+ private void initializeLocale() {
+ Locale.setDefault(LanguageHelper.getConfiguredLanguageDescriptor().getLocale());
+ }
+
+ private String getValuesString(Enum>[] values) {
+ return Stream.of(values).map(Enum::name).collect(Collectors.joining(", "));
+ }
+}
diff --git a/fcli-core/fcli-app/src/main/java/com/fortify/cli/app/runner/util/I18nParameterExceptionHandler.java b/fcli-core/fcli-app/src/main/java/com/fortify/cli/app/runner/util/I18nParameterExceptionHandler.java
new file mode 100644
index 0000000000..0028cef8a3
--- /dev/null
+++ b/fcli-core/fcli-app/src/main/java/com/fortify/cli/app/runner/util/I18nParameterExceptionHandler.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright 2021, 2023 Open Text.
+ *
+ * The only warranties for products and services of Open Text
+ * and its affiliates and licensors ("Open Text") are as may
+ * be set forth in the express warranty statements accompanying
+ * such products and services. Nothing herein should be construed
+ * as constituting an additional warranty. Open Text shall not be
+ * liable for technical or editorial errors or omissions contained
+ * herein. The information contained herein is subject to change
+ * without notice.
+ *******************************************************************************/
+package com.fortify.cli.app.runner.util;
+
+import java.util.ResourceBundle;
+
+import com.fortify.cli.common.i18n.helper.LanguageHelper;
+
+import picocli.CommandLine;
+import picocli.CommandLine.IParameterExceptionHandler;
+import picocli.CommandLine.ParameterException;
+
+public class I18nParameterExceptionHandler implements CommandLine.IParameterExceptionHandler {
+ private final IParameterExceptionHandler origDefaultHandler;
+ private final ResourceBundle i18nResource;
+
+
+ /**
+ * This constructor will setup the custom Picocli Parameter Exception Handler so that error messages can be
+ * localized. The constructor needs the original default exception handler from Picocli so that if there's an error
+ * that does not have a localized version of the error message, then the original error message in English can still
+ * be displayed. Finally, access to {@link LanguagePropertiesManager} will provide access to the appropriate resource file.
+ * @param origDefaultHandler
+ * @param languageConfigManager
+ */
+ public I18nParameterExceptionHandler(IParameterExceptionHandler origDefaultHandler){
+ this.origDefaultHandler = origDefaultHandler;
+ String resourceBundleName = "com.fortify.cli.common.i18n.FortifyCLIMessages";
+ i18nResource = ResourceBundle.getBundle(resourceBundleName, LanguageHelper.getConfiguredLanguageDescriptor().getLocale());
+ }
+
+ /**
+ * A custom handler to allow for internationalization of important error messages.
+ * Handles a {@code ParameterException} that occurred and returns an exit code.
+ *
+ * @param ex the ParameterException describing the problem that occurred while parsing the command line arguments,
+ * and the CommandLine representing the command or subcommand whose input was invalid
+ * @param args the command line arguments that could not be parsed
+ * @return an exit code
+ */
+ @Override
+ public int handleParseException(ParameterException ex, String[] args) throws Exception {
+ // TODO: Add additional cases so that all standard error messages can be handled.
+ if (ex != null && ex.getMessage().contains("Missing required subcommand")){
+ String msg = i18nResource.getString("error.missing.subcommand");
+ CommandLine cmd = ex.getCommandLine();
+ cmd.getErr().println(msg);
+ cmd.usage(cmd.getErr());
+ return cmd.getCommandSpec().exitCodeOnInvalidInput();
+ } else if(ex != null && ex.getMessage().contains("Missing required parameter:")){
+ String msg = i18nResource.getString("error.missing.parameter");
+ CommandLine cmd = ex.getCommandLine();
+ // Not sure what the intention was for split(":")[1] but this is causing
+ // truncated parameter labels like the following on 'fcli fod release update'
+ // command (see https://github.com/fortify/fcli/issues/434):
+ // Missing required parameter: 'id|app[
+ // As currently we don't support alternative languages anyway, we'll
+ // just disable this handler for now to fix #434. If we ever wish to
+ // re-enable, we'll need to fix this issue first.
+ cmd.getErr().println(msg + ex.getMessage().split(":")[1]);
+ cmd.usage(cmd.getErr());
+ return cmd.getCommandSpec().exitCodeOnInvalidInput();
+ }
+ // returns the original default handler and print things normally
+ return origDefaultHandler.handleParseException(ex, args);
+ }
+}
diff --git a/src/main/resources/META-INF/native-image/fcli/fcli-app/static/reflect-config.json b/fcli-core/fcli-app/src/main/resources/META-INF/native-image/fcli/fcli-app/jansi/reflect-config.json
similarity index 100%
rename from src/main/resources/META-INF/native-image/fcli/fcli-app/static/reflect-config.json
rename to fcli-core/fcli-app/src/main/resources/META-INF/native-image/fcli/fcli-app/jansi/reflect-config.json
diff --git a/fcli-core/fcli-app/src/main/resources/META-INF/native-image/fcli/fcli-app/jasypt/reflect-config.json b/fcli-core/fcli-app/src/main/resources/META-INF/native-image/fcli/fcli-app/jasypt/reflect-config.json
new file mode 100644
index 0000000000..4aba214d10
--- /dev/null
+++ b/fcli-core/fcli-app/src/main/resources/META-INF/native-image/fcli/fcli-app/jasypt/reflect-config.json
@@ -0,0 +1,12 @@
+[
+ {
+ "name": "java.text.Normalizer",
+ "allDeclaredConstructors": true,
+ "allPublicMethods":true
+ },
+ {
+ "name": "java.text.Normalizer$Form",
+ "allPublicFields":true
+ }
+
+]
diff --git a/fcli-core/fcli-app/src/main/resources/META-INF/native-image/fcli/fcli-app/logback/reflect-config.json b/fcli-core/fcli-app/src/main/resources/META-INF/native-image/fcli/fcli-app/logback/reflect-config.json
new file mode 100644
index 0000000000..90ff119ef9
--- /dev/null
+++ b/fcli-core/fcli-app/src/main/resources/META-INF/native-image/fcli/fcli-app/logback/reflect-config.json
@@ -0,0 +1,186 @@
+[
+ {
+ "name": "org.slf4j.impl.StaticLoggerBinder",
+ "allDeclaredConstructors": true
+ },
+ {
+ "name": "ch.qos.logback.classic.pattern.DateConverter",
+ "allDeclaredConstructors": true
+ },
+ {
+ "name": "ch.qos.logback.classic.pattern.MessageConverter",
+ "allDeclaredConstructors": true
+ },
+ {
+ "name": "ch.qos.logback.classic.pattern.ThrowableProxyConverter",
+ "allDeclaredConstructors": true
+ },
+ {
+ "name": "ch.qos.logback.classic.pattern.NopThrowableInformationConverter",
+ "allDeclaredConstructors": true
+ },
+ {
+ "name": "ch.qos.logback.classic.pattern.ContextNameConverter",
+ "allDeclaredConstructors": true
+ },
+ {
+ "name": "ch.qos.logback.core.pattern.color.BoldYellowCompositeConverter",
+ "allDeclaredConstructors": true
+ },
+ {
+ "name": "ch.qos.logback.classic.pattern.LoggerConverter",
+ "allDeclaredConstructors": true
+ },
+ {
+ "name": "ch.qos.logback.core.pattern.ReplacingCompositeConverter",
+ "allDeclaredConstructors": true
+ },
+ {
+ "name": "ch.qos.logback.core.pattern.color.BoldBlueCompositeConverter",
+ "allDeclaredConstructors": true
+ },
+ {
+ "name": "ch.qos.logback.core.pattern.color.CyanCompositeConverter",
+ "allDeclaredConstructors": true
+ },
+ {
+ "name": "ch.qos.logback.core.pattern.color.RedCompositeConverter",
+ "allDeclaredConstructors": true
+ },
+ {
+ "name": "ch.qos.logback.core.pattern.color.WhiteCompositeConverter",
+ "allDeclaredConstructors": true
+ },
+ {
+ "name": "ch.qos.logback.classic.pattern.PropertyConverter",
+ "allDeclaredConstructors": true
+ },
+ {
+ "name": "ch.qos.logback.classic.pattern.ExtendedThrowableProxyConverter",
+ "allDeclaredConstructors": true
+ },
+ {
+ "name": "ch.qos.logback.classic.pattern.RootCauseFirstThrowableProxyConverter",
+ "allDeclaredConstructors": true
+ },
+ {
+ "name": "ch.qos.logback.classic.pattern.MethodOfCallerConverter",
+ "allDeclaredConstructors": true
+ },
+ {
+ "name": "ch.qos.logback.classic.pattern.LevelConverter",
+ "allDeclaredConstructors": true
+ },
+ {
+ "name": "ch.qos.logback.core.pattern.IdentityCompositeConverter",
+ "allDeclaredConstructors": true
+ },
+ {
+ "name": "ch.qos.logback.core.pattern.color.BoldWhiteCompositeConverter",
+ "allDeclaredConstructors": true
+ },
+ {
+ "name": "ch.qos.logback.classic.pattern.MarkerConverter",
+ "allDeclaredConstructors": true
+ },
+ {
+ "name": "ch.qos.logback.core.pattern.color.BoldCyanCompositeConverter",
+ "allDeclaredConstructors": true
+ },
+ {
+ "name": "ch.qos.logback.core.pattern.color.BoldMagentaCompositeConverter",
+ "allDeclaredConstructors": true
+ },
+ {
+ "name": "ch.qos.logback.classic.pattern.RelativeTimeConverter",
+ "allDeclaredConstructors": true
+ },
+ {
+ "name": "ch.qos.logback.core.pattern.color.MagentaCompositeConverter",
+ "allDeclaredConstructors": true
+ },
+ {
+ "name": "ch.qos.logback.classic.pattern.ClassOfCallerConverter",
+ "allDeclaredConstructors": true
+ },
+ {
+ "name": "ch.qos.logback.classic.pattern.LineOfCallerConverter",
+ "allDeclaredConstructors": true
+ },
+ {
+ "name": "ch.qos.logback.classic.pattern.FileOfCallerConverter",
+ "allDeclaredConstructors": true
+ },
+ {
+ "name": "ch.qos.logback.core.pattern.color.BoldGreenCompositeConverter",
+ "allDeclaredConstructors": true
+ },
+ {
+ "name": "ch.qos.logback.classic.pattern.LocalSequenceNumberConverter",
+ "allDeclaredConstructors": true
+ },
+ {
+ "name": "ch.qos.logback.core.pattern.color.YellowCompositeConverter",
+ "allDeclaredConstructors": true
+ },
+ {
+ "name": "ch.qos.logback.classic.pattern.ExtendedThrowableProxyConverter",
+ "allDeclaredConstructors": true
+ },
+ {
+ "name": "ch.qos.logback.classic.pattern.color.HighlightingCompositeConverter",
+ "allDeclaredConstructors": true
+ },
+ {
+ "name": "ch.qos.logback.core.pattern.color.GrayCompositeConverter",
+ "allDeclaredConstructors": true
+ },
+ {
+ "name": "ch.qos.logback.classic.pattern.MDCConverter",
+ "allDeclaredConstructors": true
+ },
+ {
+ "name": "ch.qos.logback.classic.pattern.ClassOfCallerConverter",
+ "allDeclaredConstructors": true
+ },
+ {
+ "name": "ch.qos.logback.core.pattern.color.BoldRedCompositeConverter",
+ "allDeclaredConstructors": true
+ },
+ {
+ "name": "ch.qos.logback.core.pattern.color.GreenCompositeConverter",
+ "allDeclaredConstructors": true
+ },
+ {
+ "name": "ch.qos.logback.core.pattern.color.BlackCompositeConverter",
+ "allDeclaredConstructors": true
+ },
+ {
+ "name": "ch.qos.logback.classic.pattern.ThreadConverter",
+ "allDeclaredConstructors": true
+ },
+ {
+ "name": "ch.qos.logback.classic.pattern.LineSeparatorConverter",
+ "allDeclaredConstructors": true
+ },
+ {
+ "name": "ch.qos.logback.classic.encoder.PatternLayoutEncoder",
+ "allPublicMethods":true,
+ "allDeclaredConstructors": true
+ },
+ {
+ "name": "ch.qos.logback.core.ConsoleAppender",
+ "allPublicMethods":true,
+ "allDeclaredConstructors": true
+ },
+ {
+ "name": "com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl",
+ "allDeclaredConstructors": true
+ },
+ {
+ "name": "ch.qos.logback.classic.filter.ThresholdFilter",
+ "allDeclaredConstructors": true,
+ "allPublicMethods":true
+ }
+
+]
diff --git a/fcli-core/fcli-app/src/main/resources/META-INF/native-image/fcli/fcli-app/spel/reflect-config.json b/fcli-core/fcli-app/src/main/resources/META-INF/native-image/fcli/fcli-app/spel/reflect-config.json
new file mode 100644
index 0000000000..55a1ddd7ce
--- /dev/null
+++ b/fcli-core/fcli-app/src/main/resources/META-INF/native-image/fcli/fcli-app/spel/reflect-config.json
@@ -0,0 +1,156 @@
+[{
+ "name" : "org.springframework.integration.json.JsonPropertyAccessor$ArrayNodeAsList",
+ "allPublicMethods" : true
+},{
+ "name" : "org.springframework.integration.json.JsonPropertyAccessor$ComparableJsonNode",
+ "allPublicMethods" : true
+},{
+ "name" : "com.fasterxml.jackson.databind.Base",
+ "allPublicMethods" : true
+},{
+ "name" : "com.fasterxml.jackson.databind.JsonNode",
+ "allPublicMethods" : true
+},{
+ "name" : "com.fasterxml.jackson.databind.node.BaseJsonNode",
+ "allPublicMethods" : true
+},{
+ "name" : "com.fasterxml.jackson.databind.node.ContainerNode",
+ "allPublicMethods" : true
+},{
+ "name" : "com.fasterxml.jackson.databind.node.ArrayNode",
+ "allPublicMethods" : true
+},{
+ "name" : "com.fasterxml.jackson.databind.node.ObjectNode",
+ "allPublicMethods" : true
+},{
+ "name" : "com.fasterxml.jackson.databind.node.ValueNode",
+ "allPublicMethods" : true
+},{
+ "name" : "com.fasterxml.jackson.databind.node.BinaryNode",
+ "allPublicMethods" : true
+},{
+ "name" : "com.fasterxml.jackson.databind.node.BooleanNode",
+ "allPublicMethods" : true
+},{
+ "name" : "com.fasterxml.jackson.databind.node.MissingNode",
+ "allPublicMethods" : true
+},{
+ "name" : "com.fasterxml.jackson.databind.node.NullNode",
+ "allPublicMethods" : true
+},{
+ "name" : "com.fasterxml.jackson.databind.node.NumericNode",
+ "allPublicMethods" : true
+},{
+ "name" : "com.fasterxml.jackson.databind.node.BigIntegerNode",
+ "allPublicMethods" : true
+},{
+ "name" : "com.fasterxml.jackson.databind.node.DecimalNode",
+ "allPublicMethods" : true
+},{
+ "name" : "com.fasterxml.jackson.databind.node.DoubleNode",
+ "allPublicMethods" : true
+},{
+ "name" : "com.fasterxml.jackson.databind.node.FloatNode",
+ "allPublicMethods" : true
+},{
+ "name" : "com.fasterxml.jackson.databind.node.IntNode",
+ "allPublicMethods" : true
+},{
+ "name" : "com.fasterxml.jackson.databind.node.LongNode",
+ "allPublicMethods" : true
+},{
+ "name" : "com.fasterxml.jackson.databind.node.ShortNode",
+ "allPublicMethods" : true
+},{
+ "name" : "com.fasterxml.jackson.databind.node.TextNode",
+ "allPublicMethods" : true
+},{
+ "name" : "java.lang.Boolean",
+ "allPublicMethods" : true
+},{
+ "name" : "java.lang.Double",
+ "allPublicMethods" : true
+},{
+ "name" : "java.lang.Float",
+ "allPublicMethods" : true
+},{
+ "name" : "java.lang.Integer",
+ "allPublicMethods" : true
+},{
+ "name" : "java.lang.Long",
+ "allPublicMethods" : true
+},{
+ "name" : "java.lang.Short",
+ "allPublicMethods" : true
+},{
+ "name" : "java.lang.String",
+ "allPublicMethods" : true
+},{
+ "name" : "java.util.ArrayList",
+ "allPublicMethods" : true
+},{
+ "name" : "java.util.LinkedHashMap",
+ "allPublicMethods" : true
+},{
+ "name" : "java.util.HashSet",
+ "allPublicMethods" : true,
+ "allPublicConstructors" : true
+},{
+ "name" : "java.util.Collections$UnmodifiableCollection",
+ "allPublicMethods" : true
+},{
+ "name" : "java.util.Collections$UnmodifiableSet",
+ "allPublicMethods" : true
+},{
+ "name" : "java.util.Collections$UnmodifiableSortedSet",
+ "allPublicMethods" : true
+},{
+ "name" : "java.util.Collections$UnmodifiableNavigableSet",
+ "allPublicMethods" : true
+},{
+ "name" : "java.util.Collections$UnmodifiableList",
+ "allPublicMethods" : true
+},{
+ "name" : "java.util.Collections$UnmodifiableRandomAccessList",
+ "allPublicMethods" : true
+},{
+ "name" : "java.util.Collections$UnmodifiableMap",
+ "allPublicMethods" : true
+},{
+ "name" : "java.util.Collections$UnmodifiableSortedMap",
+ "allPublicMethods" : true
+},{
+ "name" : "java.util.Collections$UnmodifiableNavigableMap",
+ "allPublicMethods" : true
+},{
+ "name" : "java.util.Collections$EmptyEnumeration",
+ "allPublicMethods" : true
+},{
+ "name" : "java.util.Collections$EmptyIterator",
+ "allPublicMethods" : true
+},{
+ "name" : "java.util.Collections$EmptyList",
+ "allPublicMethods" : true
+},{
+ "name" : "java.util.Collections$EmptyListIterator",
+ "allPublicMethods" : true
+},{
+ "name" : "java.util.Collections$EmptyMap",
+ "allPublicMethods" : true
+},{
+ "name" : "java.util.Collections$EmptySet",
+ "allPublicMethods" : true
+},{
+ "name" : "java.util.Collections$SetFromMap",
+ "allPublicMethods" : true
+},{
+ "name" : "java.util.Collections$SingletonList",
+ "allPublicMethods" : true
+},{
+ "name" : "java.util.Collections$SingletonMap",
+ "allPublicMethods" : true
+},{
+ "name" : "java.util.Collections$SingletonSet",
+ "allPublicMethods" : true
+}
+]
\ No newline at end of file
diff --git a/fcli-core/fcli-app/src/main/resources/META-INF/native-image/fcli/fcli-app/static/native-image.properties b/fcli-core/fcli-app/src/main/resources/META-INF/native-image/fcli/fcli-app/static/native-image.properties
new file mode 100644
index 0000000000..2a5e846002
--- /dev/null
+++ b/fcli-core/fcli-app/src/main/resources/META-INF/native-image/fcli/fcli-app/static/native-image.properties
@@ -0,0 +1,2 @@
+Args=--enable-http --enable-https --initialize-at-build-time=org.codehaus.stax2.typed.Base64Variants \
+ -H:+IncludeAllLocales --no-fallback --add-opens=java.base/java.util=ALL-UNNAMED
\ No newline at end of file
diff --git a/fcli-core/fcli-app/src/main/resources/logback.xml b/fcli-core/fcli-app/src/main/resources/logback.xml
new file mode 100644
index 0000000000..0a12bd9db2
--- /dev/null
+++ b/fcli-core/fcli-app/src/main/resources/logback.xml
@@ -0,0 +1,30 @@
+
+
+
+ System.err
+
+ WARN
+
+
+ %msg%n
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/fcli-core/fcli-app/src/test/java/com/fortify/cli/CompletionCandidatesTest.java b/fcli-core/fcli-app/src/test/java/com/fortify/cli/CompletionCandidatesTest.java
new file mode 100644
index 0000000000..644747dfaa
--- /dev/null
+++ b/fcli-core/fcli-app/src/test/java/com/fortify/cli/CompletionCandidatesTest.java
@@ -0,0 +1,211 @@
+/*******************************************************************************
+ * Copyright 2021, 2023 Open Text.
+ *
+ * The only warranties for products and services of Open Text
+ * and its affiliates and licensors ("Open Text") are as may
+ * be set forth in the express warranty statements accompanying
+ * such products and services. Nothing herein should be construed
+ * as constituting an additional warranty. Open Text shall not be
+ * liable for technical or editorial errors or omissions contained
+ * herein. The information contained herein is subject to change
+ * without notice.
+ *******************************************************************************/
+package com.fortify.cli;
+
+import java.io.File;
+import java.lang.reflect.Member;
+import java.lang.reflect.Parameter;
+import java.net.InetAddress;
+import java.nio.file.Path;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.junit.jupiter.api.Test;
+import org.junit.platform.commons.util.StringUtils;
+
+import com.fortify.cli.app._main.cli.cmd.FCLIRootCommands;
+
+import picocli.CommandLine;
+import picocli.CommandLine.Model.ArgSpec;
+import picocli.CommandLine.Model.CommandSpec;
+import picocli.CommandLine.Model.OptionSpec;
+import picocli.CommandLine.Model.PositionalParamSpec;
+
+public class CompletionCandidatesTest {
+ // Ignore any fields that end with any of these strings. Be careful not to ignore
+ // too much.
+ private static final String[] ignoreFieldEndsWith = {
+ "name", "id", "user", "users", "userGroups", "email", "phoneNumber", "password", "tenant",
+ "token", "tokens", "secret", "secrets", "description", "message", "owner", "date", "period",
+ "url", "uri", "applications",
+ };
+ // Map of :: or to alternative messages, allowing to suppress
+ // (empty string) or provide an alternative message after having reviewed the output
+ // of a previous run of this test.
+ private static Map fieldAltMessagesMap = createFieldAltMessageMap();
+ private static final Map createFieldAltMessageMap() {
+ var altMessages = new String[][]{
+ {"delimiter", ""},
+ {"envPrefix", ""},
+ {"variableStoreConfig", ""},
+ {"queryExpression", ""},
+ {"logFile", "Should change to File or Path"},
+ {"outputFile", "Should change to File or Path"},
+ {"trustStorePath", "Should change to File or Path"},
+ {"installDir", "Should change to File or Path"},
+ {"answerFile", "Should change to File or Path"},
+ {"templatePath", "Should change to File or Path"},
+ {"destination", "Should change to File or Path"},
+ {"seedBundle", "Should change to File or Path"},
+ {"attributes", ""},
+ {"filtersParam", ""},
+ {"microservices", ""},
+ {"releaseMicroservice", ""},
+ {"scanIds", ""},
+ {"chunkSize", ""},
+ {"authEntitySpec", ""},
+ {"authEntitySpecs", ""},
+ {"tokenIdsOrValues", ""},
+ {"expireIn", ""},
+ {"permissionIds", ""},
+ {"artifactIds", ""},
+ {"engineType", ""},
+ {"serverQueries", ""},
+ {"notes", ""},
+ {"data", ""},
+ {"sensorVersion", ""},
+ {"qParam", ""},
+ {"olderThan", ""},
+ {"repository", ""},
+ {"branch", ""},
+
+ {"LanguageSetCommand::language", "Can we generate list of supported languages?"},
+ {"AbstractProxyOptions.ProxyTargetHostsArgGroup::includedHosts", "Does it make sense to use InetAddress?"},
+ {"AbstractProxyOptions.ProxyTargetHostsArgGroup::excludedHosts", "Does it make sense to use InetAddress?"},
+ {"proxyHostAndPort", ""},
+ {"AbstractProxyOptions::priority",""},
+ {"AbstractProxyOptions::modules","Can we predefine/have modules enum?"},
+ {"TrustStoreSetCommand::trustStoreType","Can we predefine/have trustStoreType enum?"},
+ {"AbstractToolInstallCommand::version", "Can we generate completion candidates from tool config file?"},
+ {"AbstractToolUninstallCommand::version", "Can we generate completion candidates from tool config file?"},
+
+ {"WaitHelperWaitOptions.WaitHelperWaitOptionsArgGroup::whileAll", "Ideally, each wait-for command should provide appropriate completion candidates"},
+ {"WaitHelperWaitOptions.WaitHelperWaitOptionsArgGroup::whileAny", "Ideally, each wait-for command should provide appropriate completion candidates"},
+ {"WaitHelperWaitOptions.WaitHelperWaitOptionsArgGroup::untilAll", "Ideally, each wait-for command should provide appropriate completion candidates"},
+ {"WaitHelperWaitOptions.WaitHelperWaitOptionsArgGroup::untilAny", "Ideally, each wait-for command should provide appropriate completion candidates"},
+
+ {"AbstractRestCallCommand::httpMethod", "Can we generate completion candidates/change to enum?"},
+ {"SSCJobUpdateCommand::priority", "Can we provide completion candidates, like specific range of numbers?"},
+ {"SSCTokenCreateCommand::type", "We can potentially provide list of commonly used token types"},
+ {"SSCVulnerabilityCountCommand::groupingType", "Can we provide list of commonly used grouping types?"}
+ };
+ return Stream.of(altMessages).collect(Collectors.toMap(e->e[0], e->e[1]));
+ }
+
+ private Set processedFields = new HashSet<>();
+
+ /**
+ * This test never fails, but prints all options and positional
+ * parameters that don't have completion candidates, for manual
+ * verification whether completion candidates for such an option
+ * or parameter would make sense.
+ * @throws Exception
+ */
+ @Test
+ public void testCommands() throws Exception {
+ checkCommand(new CommandLine(FCLIRootCommands.class));
+ }
+
+ private void checkCommands(Map commands) {
+ if ( commands!=null && !commands.isEmpty() ) {
+ commands.values().stream().forEach(this::checkCommand);
+ }
+ }
+
+ private void checkCommand(CommandLine cl) {
+ CommandSpec spec = cl.getCommandSpec();
+ checkOptions(spec);
+ checkParameters(spec);
+ checkCommands(cl.getSubcommands());
+ }
+
+ private void checkOptions(CommandSpec cmdSpec) {
+ cmdSpec.options().forEach(optionSpec->checkOptionCompletionCandidates(cmdSpec, optionSpec));
+ }
+
+ private void checkOptionCompletionCandidates(CommandSpec cmdSpec, OptionSpec optionSpec) {
+ if ( !hasCompletionCandidates(optionSpec) ) {
+ printResult(cmdSpec, optionSpec, "Option has no completion candidates");
+ }
+ }
+
+ private void checkParameters(CommandSpec cmdSpec) {
+ cmdSpec.positionalParameters().forEach(paramSpec->checkParameterCompletionCandidates(cmdSpec, paramSpec));
+ }
+
+ private void checkParameterCompletionCandidates(CommandSpec cmdSpec, PositionalParamSpec paramSpec) {
+ if ( !hasCompletionCandidates(paramSpec) ) {
+ printResult(cmdSpec, paramSpec, "Parameter has no completion candidates");
+ }
+ }
+
+ private boolean hasCompletionCandidates(ArgSpec spec) {
+ if ( !spec.hidden() && spec.completionCandidates()==null ) {
+ Class> type = spec.type();
+ if ( spec instanceof PositionalParamSpec || (type!=Boolean.TYPE && type!=Boolean.class) ) {
+ if (spec.typeInfo().isMultiValue()){
+ type = spec.typeInfo().getAuxiliaryTypes()[0];
+ }
+ if ( !type.equals(File.class) && !type.equals(Path.class) && !type.equals(InetAddress.class)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ private void printResult(CommandSpec cmdSpec, ArgSpec argSpec, String msg) {
+ var argUserObject = argSpec.userObject();
+ String name = null;
+ Class> clazz;
+ if ( argUserObject instanceof Parameter ) {
+ var param = (Parameter)argUserObject;
+ clazz = param.getDeclaringExecutable().getDeclaringClass();
+ name = param.getDeclaringExecutable().getName() + "() - " + param.getName();
+ } else {
+ var member = (Member)argUserObject;
+ clazz = member.getDeclaringClass();
+ name = member.getName();
+ }
+ var qualifiedField = getClazzName(clazz) + "::" + name;
+ if ( !processedFields.contains(qualifiedField) && !isIgnored(name) ) {
+ processedFields.add(qualifiedField);
+ msg = fieldAltMessagesMap.getOrDefault(qualifiedField, fieldAltMessagesMap.getOrDefault(name, msg));
+ if ( StringUtils.isNotBlank(msg) ) {
+ System.out.println(String.format("INFO: %s: %s", qualifiedField, msg));
+ }
+ }
+ }
+
+ private boolean isIgnored(String name) {
+ return Stream.of(ignoreFieldEndsWith).anyMatch(ignore->
+ name.toLowerCase().endsWith(ignore.toLowerCase()));
+ }
+
+ private String getClazzName(Class> clazz) {
+ var clazzName = clazz.getSimpleName();
+ while ( clazz.getDeclaringClass()!=null ) {
+ clazz = clazz.getDeclaringClass();
+ clazzName = clazz.getSimpleName() + "." + clazzName;
+ }
+ return clazzName;
+ }
+
+ public static void main(String[] args) throws Exception {
+ new CompletionCandidatesTest().testCommands();
+ }
+
+}
diff --git a/fcli-core/fcli-app/src/test/java/com/fortify/cli/FortifyCLITest.java b/fcli-core/fcli-app/src/test/java/com/fortify/cli/FortifyCLITest.java
new file mode 100644
index 0000000000..089a1032cb
--- /dev/null
+++ b/fcli-core/fcli-app/src/test/java/com/fortify/cli/FortifyCLITest.java
@@ -0,0 +1,375 @@
+/*******************************************************************************
+ * Copyright 2021, 2023 Open Text.
+ *
+ * The only warranties for products and services of Open Text
+ * and its affiliates and licensors ("Open Text") are as may
+ * be set forth in the express warranty statements accompanying
+ * such products and services. Nothing herein should be construed
+ * as constituting an additional warranty. Open Text shall not be
+ * liable for technical or editorial errors or omissions contained
+ * herein. The information contained herein is subject to change
+ * without notice.
+ *******************************************************************************/
+package com.fortify.cli;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Member;
+import java.lang.reflect.Parameter;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import com.fortify.cli.app._main.cli.cmd.FCLIRootCommands;
+import com.fortify.cli.common.output.writer.CommandSpecMessageResolver;
+import com.fortify.cli.common.util.DisableTest;
+import com.fortify.cli.common.util.DisableTest.TestType;
+import com.fortify.cli.common.util.PicocliSpecHelper;
+import com.fortify.cli.common.util.StringUtils;
+
+import picocli.CommandLine;
+import picocli.CommandLine.Model.ArgSpec;
+import picocli.CommandLine.Model.CommandSpec;
+import picocli.CommandLine.Model.OptionSpec;
+import picocli.CommandLine.Model.PositionalParamSpec;
+import picocli.CommandLine.Spec;
+
+public class FortifyCLITest {
+ /**
+ * This test performs multiple checks on the fcli command tree.
+ * We iterate the command tree only once for performance reasons,
+ * collecting all results into a single failure if applicable.
+ * @throws Exception
+ */
+ @Test
+ public void testCommands() throws Exception {
+ Results results = new Results();
+ checkCommand(results, new CommandLine(FCLIRootCommands.class));
+ results.process();
+ }
+
+ private void checkCommands(Results results, Map commands) {
+ if ( commands!=null && !commands.isEmpty() ) {
+ commands.values().stream().forEach(c->checkCommand(results,c));
+ }
+ }
+
+ private void checkCommand(Results results, CommandLine cl) {
+ CommandSpec spec = cl.getCommandSpec();
+ checkOptions(results, spec);
+ checkParameters(results, spec);
+ checkCommandNamingConvention(results, spec);
+ checkUsageHeader(results, spec);
+ checkMaxCommandDepth(results, spec);
+ checkMixins(results, spec, spec.mixins());
+ Map subcommands = spec.subcommands();
+ if ( subcommands==null || subcommands.isEmpty() ) {
+ checkLeafCommand(results, spec);
+ } else {
+ checkContainerCommand(results, spec);
+ }
+ }
+
+ private void checkContainerCommand(Results results, CommandSpec spec) {
+ // TODO Any tests specific for container commands?
+ checkCommands(results, spec.subcommands());
+ }
+
+ private void checkLeafCommand(Results results, CommandSpec spec) {
+ checkDefaultTableOptionsPresent(results, spec);
+ }
+
+ private void checkDefaultTableOptionsPresent(Results results, CommandSpec spec) {
+ if ( spec.mixins().containsKey("outputHelper") ) {
+ var tableOptions = new CommandSpecMessageResolver(spec).getMessageString("output.table.options");
+ if ( StringUtils.isBlank(tableOptions) ) {
+ results.add(TestType.CMD_DEFAULT_TABLE_OPTIONS_PRESENT, Level.ERROR, spec, getBundleName(spec)+": No *.output.table.options defined to specify default table output columns");
+ }
+ }
+ }
+
+ private void checkOptions(Results results, CommandSpec cmdSpec) {
+ checkStandardOptions(results, cmdSpec);
+ cmdSpec.options().forEach(optionSpec->checkOptionSpec(results, cmdSpec, optionSpec));
+ }
+
+ private void checkStandardOptions(Results results, CommandSpec spec) {
+ var optionNames = spec.optionsMap().keySet();
+ var expectedOptionNames = spec.userObject() instanceof Runnable
+ ? Arrays.asList("-h", "--help", "--log-level", "--log-file", "--env-prefix")
+ : Arrays.asList("-h", "--help");
+ if ( !optionNames.containsAll(expectedOptionNames) ) {
+ results.add(TestType.CMD_STD_OPTS, Level.ERROR, spec, "Missing one or more standard option names: "+expectedOptionNames);
+ }
+ }
+
+ private void checkOptionSpec(Results results, CommandSpec cmdSpec, OptionSpec optionSpec) {
+ checkOptionNames(results, cmdSpec, optionSpec);
+ checkMultiValueOption(results, cmdSpec, optionSpec);
+ checkOptionArity(results, cmdSpec, optionSpec);
+ checkOptionDescription(results, cmdSpec, optionSpec);
+ }
+
+ private void checkOptionNames(Results results, CommandSpec cmdSpec, OptionSpec optionSpec) {
+ var names = optionSpec.names();
+ Stream.of(names).filter(this::isInvalidOptionFormat).forEach(
+ name->results.add(TestType.OPT_NAME_FORMAT, Level.ERROR, cmdSpec, optionSpec, "Invalid option format: "+name));
+ if ( Stream.of(names).filter(this::isShortOption).count() > 1 ) {
+ results.add(TestType.OPT_SHORT_NAME_COUNT, Level.ERROR, cmdSpec, optionSpec, "Option must have at most 1 short name");
+ }
+ if ( Stream.of(names).filter(this::isLongOption).count() < 1 ) {
+ results.add(TestType.OPT_LONG_NAME_COUNT, Level.ERROR, cmdSpec, optionSpec, "Option must have at least 1 long name");
+ }
+ Stream.of(names).filter(this::isShortOption).filter(this::isInvalidShortOptionName).forEach(
+ name->results.add(TestType.OPT_SHORT_NAME, Level.ERROR, cmdSpec, optionSpec, "Invalid short option name: "+name));
+ Stream.of(names).filter(this::isLongOption).filter(this::isInvalidLongOptionName).forEach(
+ name->results.add(TestType.OPT_LONG_NAME, Level.ERROR, cmdSpec, optionSpec, "Invalid long option name: "+name));
+ }
+
+ private void checkMultiValueOption(Results results, CommandSpec cmdSpec, OptionSpec optionSpec) {
+ if ( optionSpec.isMultiValue() ) {
+ Stream.of(optionSpec.names()).filter(n->n.startsWith("--") && !n.endsWith("s") && !n.contains("any")).forEach(
+ name->results.add(TestType.MULTI_OPT_PLURAL_NAME, Level.ERROR, cmdSpec, optionSpec, "Multi-value option should use plural option name: "+name));
+ if ( StringUtils.isBlank(optionSpec.splitRegex()) ) {
+ results.add(TestType.MULTI_OPT_SPLIT, Level.ERROR, cmdSpec, optionSpec, "Multi-value option should define a split expression");
+ }
+ }
+ }
+
+ private void checkOptionArity(Results results, CommandSpec cmdSpec, OptionSpec optionSpec) {
+ var arity = optionSpec.arity();
+ if ( arity.isVariable() ) {
+ results.add(TestType.OPT_ARITY_VARIABLE, Level.ERROR, cmdSpec, optionSpec, "Variable arity not allowed: "+arity.originalValue());
+ } else if ( !arity.isUnspecified() ) {
+ if ( optionSpec.type().isAssignableFrom(Boolean.class) || optionSpec.type().isAssignableFrom(boolean.class) ) {
+ if ( arity.min()!=arity.max() || (arity.min()!=0 && arity.min()!=1) ) {
+ results.add(TestType.OPT_ARITY_BOOL, Level.ERROR, cmdSpec, optionSpec, "Arity for boolean options must be either 0 (flags) or 1 (require true/false value)");
+ }
+ } else if ( optionSpec.interactive() ) {
+ if ( arity.min()!=0 || arity.max()!=1 ) {
+ results.add(TestType.OPT_ARITY_INTERACTIVE, Level.ERROR, cmdSpec, optionSpec, "Arity for interactive options must be 0..1");
+ }
+ } else {
+ results.add(TestType.OPT_ARITY_PRESENT, Level.ERROR, cmdSpec, optionSpec, "Arity may only be specified on boolean or interactive options");
+ }
+ }
+ }
+
+ private void checkOptionDescription(Results results, CommandSpec cmdSpec, OptionSpec optionSpec) {
+ var descriptionArray = optionSpec.description();
+ if ( descriptionArray.length==0 || Stream.of(descriptionArray).allMatch(StringUtils::isBlank) ) {
+ String descriptionKey = StringUtils.isBlank(optionSpec.descriptionKey()) ? "" : optionSpec.descriptionKey();
+ String cmd = cmdSpec.qualifiedName();
+ results.add(TestType.OPT_EMPTY_DESCRIPTION, Level.ERROR, cmdSpec, optionSpec, String.format("%s: Option has an empty description (%s, descriptionKey=%s)", getBundleName(cmdSpec), cmd, descriptionKey));
+ }
+ }
+
+ /**
+ * @param cmdSpec
+ * @return
+ */
+ private String getBundleName(CommandSpec cmdSpec) {
+ return StringUtils.substringAfterLast(cmdSpec.resourceBundleBaseName(), ".");
+ }
+
+ private boolean isInvalidOptionFormat(String s) {
+ return !isLongOption(s) && !isShortOption(s);
+ }
+
+ private boolean isLongOption(String s) {
+ // Long options must start with double dash, followed by any number of
+ // characters
+ return s.startsWith("--");
+ }
+
+ private boolean isShortOption(String s) {
+ // Short options must start with single dash, followed by single other character
+ return s.startsWith("-") && s.length()==2;
+ }
+
+ private boolean isInvalidShortOptionName(String s) {
+ // Short options must start with a single dash, followed by a single
+ // lower-case letter or number
+ return !s.matches("-[a-z0-9]");
+ }
+
+ private boolean isInvalidLongOptionName(String s) {
+ // Long options must be at least two characters after double dash,
+ // may contain only lower-case letters and numbers, optionally
+ // separated by dashes. but not ending with a dash
+ return !s.matches("--(?!-)[a-z0-9-]+[^-]");
+ }
+
+ private void checkParameters(Results results, CommandSpec cmdSpec) {
+ cmdSpec.positionalParameters().forEach(paramSpec->checkParameterSpec(results, cmdSpec, paramSpec));
+ }
+
+ private void checkParameterSpec(Results results, CommandSpec cmdSpec, PositionalParamSpec paramSpec) {
+ checkParameterDescription(results, cmdSpec, paramSpec);
+ }
+
+ private void checkParameterDescription(Results results, CommandSpec cmdSpec, PositionalParamSpec paramSpec) {
+ var descriptionArray = paramSpec.description();
+ if ( descriptionArray.length==0 || Stream.of(descriptionArray).allMatch(StringUtils::isBlank) ) {
+ String descriptionKey = StringUtils.isBlank(paramSpec.descriptionKey()) ? "" : paramSpec.descriptionKey();
+ results.add(TestType.PARAM_EMPTY_DESCRIPTION, Level.ERROR, cmdSpec, paramSpec, String.format("%s: Positional parameter has an empty description (descriptionKey=%s)", getBundleName(cmdSpec), descriptionKey));
+ }
+ }
+
+ private void checkUsageHeader(Results results, CommandSpec spec) {
+ if ( !spec.equals(spec.root()) ) {
+ var rootHeader = spec.root().usageMessage().header();
+ var cmdHeader = spec.usageMessage().header();
+ if ( cmdHeader==null
+ || Stream.of(cmdHeader).allMatch(StringUtils::isBlank)
+ || Arrays.equals(rootHeader, cmdHeader) ) {
+ results.add(TestType.CMD_USAGE_HEADER, Level.ERROR, spec, getBundleName(spec)+": Command doesn't define proper usage header: "+Arrays.asList(cmdHeader));
+ }
+ }
+ }
+
+ private void checkCommandNamingConvention(Results results, CommandSpec spec) {
+ if ( isInvalidCommandName(spec.name()) ) {
+ results.add(TestType.CMD_NAME, Level.ERROR, spec, "Invalid command name: "+spec.name());
+ }
+ Stream.of(spec.aliases()).filter(this::isInvalidCommandName).forEach(
+ name->results.add(TestType.CMD_NAME, Level.ERROR, spec, "Invalid alias name: "+name));
+ }
+
+ private void checkMixins(Results results, CommandSpec cmdSpec, Map mixins) {
+ if ( mixins!=null ) {
+ mixins.values().forEach(mixin->checkMixin(results, cmdSpec, mixin));
+ }
+ }
+
+ private void checkMixin(Results results, CommandSpec cmdSpec, CommandSpec mixinSpec) {
+ checkMixins(results, cmdSpec, mixinSpec.mixins());
+ checkMixeeAnnotationPresent(results, cmdSpec, mixinSpec);
+ }
+
+ private void checkMixeeAnnotationPresent(Results results, CommandSpec cmdSpec, CommandSpec mixinSpec) {
+ Object mixin = mixinSpec.userObject();
+ if ( mixin!=null ) {
+ checkMixeeAnnotation(results, cmdSpec, mixinSpec, mixin.getClass().getDeclaredFields());
+ checkMixeeAnnotation(results, cmdSpec, mixinSpec, mixin.getClass().getMethods());
+ }
+ }
+
+ private void checkMixeeAnnotation(Results results, CommandSpec cmdSpec, CommandSpec mixinSpec, AccessibleObject[] accessibleObjects) {
+ for ( var accessibleObject : accessibleObjects ) {
+ var annotation = accessibleObject.getAnnotation(Spec.class);
+ if ( annotation!=null ) {
+ results.add(TestType.INJECT_MIXEE, Level.ERROR, cmdSpec, "Mixin class must use CommandHelperMixin to access CommandSpec: "+mixinSpec.userObject().getClass().getName());
+ }
+ }
+ }
+
+ private boolean isInvalidCommandName(String s) {
+ // Check that command is kebab-case, not starting or ending with dash
+ // Command name must be at least two characters
+ return !s.matches("(?!-)[a-z0-9-]+[^-]$");
+ }
+
+ private void checkMaxCommandDepth(Results results, CommandSpec spec) {
+ // Check command depth doesn't exceed the maximum depth
+ final int maxDepth = 4;
+ if ( spec.qualifiedName().chars().filter(ch -> ch == ' ').count() > maxDepth-1 ) {
+ results.add(TestType.CMD_DEPTH, Level.ERROR, spec, "Command depth > "+maxDepth);
+ }
+ }
+
+ private static class Results {
+ private final Map> results = new HashMap<>();
+
+ private void add(TestType type, Level level, CommandSpec cmdSpec, ArgSpec argSpec, String msg) {
+ if ( isDisabled(type, cmdSpec, argSpec) ) {
+ level = Level.INFO;
+ msg = type.name()+ " test disabled";
+ }
+ var argUserObject = argSpec.userObject();
+ String name = null;
+ Class> clazz;
+ if ( argUserObject instanceof Parameter ) {
+ var param = (Parameter)argUserObject;
+ clazz = param.getDeclaringExecutable().getDeclaringClass();
+ name = param.getDeclaringExecutable().getName() + "() - " + param.getName();
+ } else {
+ var member = (Member)argUserObject;
+ clazz = member.getDeclaringClass();
+ name = member.getName();
+ }
+ add(level, getClazzName(clazz) + "::" + name+": "+msg);
+ }
+
+ private void add(TestType type, Level level, CommandSpec cmdSpec, String msg) {
+ if ( isDisabled(type, cmdSpec, null) ) {
+ level = Level.INFO;
+ msg = type.name()+ " test disabled";
+ }
+ add(level, getClazzName(cmdSpec.userObject().getClass())+ ": "+msg);
+ }
+
+ private void add(Level level, String msg) {
+ var set = results.computeIfAbsent(level, t->new TreeSet());
+ set.add(level.name().toUpperCase()+": "+msg);
+ results.put(level, set);
+ }
+
+ private String getClazzName(Class> clazz) {
+ var clazzName = clazz.getSimpleName();
+ while ( clazz.getDeclaringClass()!=null ) {
+ clazz = clazz.getDeclaringClass();
+ clazzName = clazz.getSimpleName() + "." + clazzName;
+ }
+ return clazzName;
+ }
+
+ private void process() {
+ String infoString = getResultsAsString(Level.INFO);
+ String warnString = getResultsAsString(Level.WARN);
+ String errString = getResultsAsString(Level.ERROR);
+ if ( infoString!=null ) {
+ System.err.println(infoString);
+ }
+ if ( warnString!=null ) {
+ System.err.println(warnString);
+ }
+ if ( errString!=null ) {
+ System.err.println(errString);
+ Assertions.fail("\n"+errString);
+ }
+ }
+
+ private boolean isDisabled(TestType type, CommandSpec cmdSpec, ArgSpec optionSpec) {
+ return isDisabled(type, PicocliSpecHelper.getAnnotation(cmdSpec, DisableTest.class))
+ || isDisabled(type, PicocliSpecHelper.getAnnotation(optionSpec, DisableTest.class));
+ }
+
+ private boolean isDisabled(TestType type, DisableTest annotation) {
+ return annotation!=null && Arrays.asList(annotation.value()).contains(type);
+ }
+
+ private String getResultsAsString(Level level) {
+ var resultsForType = results.get(level);
+ if ( resultsForType!=null && !resultsForType.isEmpty() ) {
+ return resultsForType.stream().collect(Collectors.joining("\n"));
+ }
+ return null;
+ }
+ }
+
+ private static enum Level {
+ INFO, WARN, ERROR
+ }
+
+ public static void main(String[] args) throws Exception {
+ new FortifyCLITest().testCommands();
+ }
+
+}
diff --git a/fcli-core/fcli-app/src/test/java/com/fortify/cli/GradlePropertiesTest.java b/fcli-core/fcli-app/src/test/java/com/fortify/cli/GradlePropertiesTest.java
new file mode 100644
index 0000000000..e1d119be37
--- /dev/null
+++ b/fcli-core/fcli-app/src/test/java/com/fortify/cli/GradlePropertiesTest.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright 2021, 2023 Open Text.
+ *
+ * The only warranties for products and services of Open Text
+ * and its affiliates and licensors ("Open Text") are as may
+ * be set forth in the express warranty statements accompanying
+ * such products and services. Nothing herein should be construed
+ * as constituting an additional warranty. Open Text shall not be
+ * liable for technical or editorial errors or omissions contained
+ * herein. The information contained herein is subject to change
+ * without notice.
+ *******************************************************************************/
+package com.fortify.cli;
+
+import java.util.stream.Stream;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.condition.EnabledIfSystemProperty;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.junit.platform.commons.util.StringUtils;
+
+public class GradlePropertiesTest {
+ private static final String PRP_EXPECTED_CLASS_NAMES = "gradle.expectedClassNames";
+
+ // This test checks whether class names passed by gradle in the gradle.expectedClassNames
+ // property (like main class and other classes referenced during the build) can be resolved
+ @ParameterizedTest @EnabledIfSystemProperty(named = PRP_EXPECTED_CLASS_NAMES, matches = ".+")
+ @MethodSource("getExpectedClassNames")
+ public void testExpectedClassName(String name) throws Exception {
+ try {
+ Class.forName(name);
+ } catch (ClassNotFoundException e) {
+ var msg = "Class name define in build.gradle doesn't exist: "+name;
+ System.err.println("ERROR: "+msg);
+ Assertions.fail(msg);
+ }
+ }
+
+ private static Stream getExpectedClassNames() {
+ var prp = System.getProperty(PRP_EXPECTED_CLASS_NAMES);
+ return StringUtils.isBlank(prp)
+ ? Stream.empty()
+ : Stream.of(prp.split(",")).map(Arguments::of);
+ }
+}
diff --git a/fcli-common/.gitignore b/fcli-core/fcli-common/.gitignore
similarity index 100%
rename from fcli-common/.gitignore
rename to fcli-core/fcli-common/.gitignore
diff --git a/fcli-core/fcli-common/build.gradle b/fcli-core/fcli-common/build.gradle
new file mode 100644
index 0000000000..4f8368616f
--- /dev/null
+++ b/fcli-core/fcli-common/build.gradle
@@ -0,0 +1 @@
+apply from: "${sharedGradleScriptsDir}/fcli-java.gradle"
\ No newline at end of file
diff --git a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/cli/cmd/AbstractContainerCommand.java b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/cli/cmd/AbstractContainerCommand.java
new file mode 100644
index 0000000000..93c82df210
--- /dev/null
+++ b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/cli/cmd/AbstractContainerCommand.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright 2021, 2023 Open Text.
+ *
+ * The only warranties for products and services of Open Text
+ * and its affiliates and licensors ("Open Text") are as may
+ * be set forth in the express warranty statements accompanying
+ * such products and services. Nothing herein should be construed
+ * as constituting an additional warranty. Open Text shall not be
+ * liable for technical or editorial errors or omissions contained
+ * herein. The information contained herein is subject to change
+ * without notice.
+ *******************************************************************************/
+package com.fortify.cli.common.cli.cmd;
+
+import picocli.CommandLine.Option;
+
+/**
+ * This abstract class should be used as the base class for all fcli container commands.
+ * It is responsible for providing the standard help option.
+ *
+ * @author Ruud Senden
+ */
+public abstract class AbstractContainerCommand {
+ @Option(names = {"-h", "--help"}, usageHelp = true)
+ private boolean usageHelpRequested;
+}
diff --git a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/cli/cmd/AbstractRunnableCommand.java b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/cli/cmd/AbstractRunnableCommand.java
new file mode 100644
index 0000000000..b581c0e6cd
--- /dev/null
+++ b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/cli/cmd/AbstractRunnableCommand.java
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Copyright 2021, 2023 Open Text.
+ *
+ * The only warranties for products and services of Open Text
+ * and its affiliates and licensors ("Open Text") are as may
+ * be set forth in the express warranty statements accompanying
+ * such products and services. Nothing herein should be construed
+ * as constituting an additional warranty. Open Text shall not be
+ * liable for technical or editorial errors or omissions contained
+ * herein. The information contained herein is subject to change
+ * without notice.
+ *******************************************************************************/
+package com.fortify.cli.common.cli.cmd;
+
+import java.io.File;
+import java.util.Map;
+
+import com.fortify.cli.common.cli.mixin.ICommandAware;
+
+import ch.qos.logback.classic.Level;
+import lombok.Getter;
+import picocli.CommandLine.ArgGroup;
+import picocli.CommandLine.Model.CommandSpec;
+import picocli.CommandLine.Option;
+import picocli.CommandLine.Spec;
+
+/**
+ * This abstract class should be used as the base class for all runnable fcli commands.
+ * It is responsible for providing the following fcli features:
+ *
+ * - Providing standard command configuration settings (default value provider, ...)
+ * - Providing standard command options (--help, --log-level, ...)
+ * - Injecting {@link CommandSpec} representing the current command into
+ * any mixins that implement the {@link ICommandAware} interface
+ *
+ *
+ * @author Ruud Senden
+ */
+public abstract class AbstractRunnableCommand implements Runnable {
+ // Have picocli inject the CommandSpec representing the current command
+ @Spec private CommandSpec commandSpec;
+
+ // Boolean indicating whether mixins have already been initialized by
+ // the initMixins() method
+ private boolean mixinsInitialized = false;
+
+ // ArgGroup for generic options like --help
+ @ArgGroup(exclusive = false, headingKey = "fcli.genericOptions.heading", order = 50)
+ @Getter private GenericOptionsArgGroup genericOptions = new GenericOptionsArgGroup();
+
+ /**
+ * Enum defining available log levels
+ */
+ public static enum LogLevel {
+ TRACE(Level.TRACE),
+ DEBUG(Level.DEBUG),
+ INFO(Level.INFO),
+ WARN(Level.WARN),
+ ERROR(Level.ERROR);
+
+ @Getter private final Level logbackLevel;
+ LogLevel(Level logbackLevel) {
+ this.logbackLevel = logbackLevel;
+ }
+ }
+
+ /**
+ * This method is supposed to be invoked by all command implementations
+ * in their {@link Runnable#run()} method (after picocli has had a chance
+ * to inject our {@link CommandSpec}). It will check whether mixins have
+ * already been initialized for this command; if not, the {@link #initMixins(CommandSpec, Map)}
+ * method will be invoked to initialize the mixins.
+ */
+ protected final void initMixins() {
+ if ( !mixinsInitialized ) {
+ initMixins(commandSpec, commandSpec.mixins());
+ mixinsInitialized = true;
+ }
+ }
+
+ /**
+ * This method recursively iterates over all given mixins to inject our {@link CommandSpec}
+ * into any mixins implementing the {@link ICommandAware} interface.
+ */
+ private void initMixins(CommandSpec commandSpec, Map mixins) {
+ if ( mixins != null ) {
+ for ( CommandSpec mixin : mixins.values() ) {
+ Object userObject = mixin.userObject();
+ if ( userObject!=null && userObject instanceof ICommandAware) {
+ ((ICommandAware)userObject).setCommandSpec(commandSpec);
+ }
+ initMixins(commandSpec, mixin.mixins());
+ }
+ }
+ }
+
+ /**
+ * This class (used as an {@link ArgGroup}) defines common fcli options that
+ * are available on every fcli command.
+ */
+ public static final class GenericOptionsArgGroup {
+ @Option(names = {"-h", "--help"}, usageHelp = true)
+ private boolean usageHelpRequested;
+
+ @Option(names = "--env-prefix", defaultValue = "FCLI_DEFAULT")
+ @Getter private String envPrefix;
+
+ @Option(names = "--log-file")
+ @Getter private File logFile;
+
+ @Option(names = "--log-level")
+ @Getter private LogLevel logLevel;
+ }
+}
diff --git a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/cli/mixin/CommandHelperMixin.java b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/cli/mixin/CommandHelperMixin.java
new file mode 100644
index 0000000000..0a6d3a96f3
--- /dev/null
+++ b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/cli/mixin/CommandHelperMixin.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright 2021, 2023 Open Text.
+ *
+ * The only warranties for products and services of Open Text
+ * and its affiliates and licensors ("Open Text") are as may
+ * be set forth in the express warranty statements accompanying
+ * such products and services. Nothing herein should be construed
+ * as constituting an additional warranty. Open Text shall not be
+ * liable for technical or editorial errors or omissions contained
+ * herein. The information contained herein is subject to change
+ * without notice.
+ *******************************************************************************/
+package com.fortify.cli.common.cli.mixin;
+
+import java.util.Optional;
+
+import com.fortify.cli.common.output.writer.CommandSpecMessageResolver;
+import com.fortify.cli.common.output.writer.IMessageResolver;
+import com.fortify.cli.common.util.JavaHelper;
+
+import lombok.Getter;
+import picocli.CommandLine.Command;
+import picocli.CommandLine.Model.CommandSpec;
+
+@Command
+public final class CommandHelperMixin implements ICommandAware {
+ @Getter private CommandSpec commandSpec;
+ @Getter private IMessageResolver messageResolver;
+
+ @Override
+ public final void setCommandSpec(CommandSpec commandSpec) {
+ this.commandSpec = commandSpec;
+ this.messageResolver = new CommandSpecMessageResolver(commandSpec);
+ }
+
+ /**
+ * Utility method for retrieving the command being invoked as the given
+ * type, returning null if the command is not an instance of the given
+ * type.
+ */
+ public final Optional getCommandAs(Class asType) {
+ return JavaHelper.as(getCommand(), asType);
+ }
+
+ /**
+ * Utility method for retrieving the command instance.
+ * @return
+ */
+ public final Object getCommand() {
+ return commandSpec.userObject();
+ }
+}
\ No newline at end of file
diff --git a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/cli/mixin/CommonOptionMixins.java b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/cli/mixin/CommonOptionMixins.java
new file mode 100644
index 0000000000..121a9d5a18
--- /dev/null
+++ b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/cli/mixin/CommonOptionMixins.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright 2021, 2023 Open Text.
+ *
+ * The only warranties for products and services of Open Text
+ * and its affiliates and licensors ("Open Text") are as may
+ * be set forth in the express warranty statements accompanying
+ * such products and services. Nothing herein should be construed
+ * as constituting an additional warranty. Open Text shall not be
+ * liable for technical or editorial errors or omissions contained
+ * herein. The information contained herein is subject to change
+ * without notice.
+ *******************************************************************************/
+package com.fortify.cli.common.cli.mixin;
+
+import java.io.File;
+
+import com.fortify.cli.common.util.PicocliSpecHelper;
+import com.fortify.cli.common.util.StringUtils;
+
+import lombok.Getter;
+import picocli.CommandLine.Mixin;
+import picocli.CommandLine.Model.CommandSpec;
+import picocli.CommandLine.Option;
+import picocli.CommandLine.ParameterException;
+
+public class CommonOptionMixins {
+ private CommonOptionMixins() {}
+
+ public static class OptionalFile {
+ @Option(names = {"-f", "--file"})
+ @Getter private File file;
+ }
+
+ public static class RequiredFile {
+ @Option(names = {"-f", "--file"}, required=true)
+ @Getter private File file;
+ }
+
+ public static class RequireConfirmation {
+ @Mixin private CommandHelperMixin commandHelper;
+ @Option(names = {"-y", "--confirm"}, defaultValue = "false")
+ private boolean confirmed;
+
+ public void checkConfirmed(Object... promptArgs) {
+ if (!confirmed) {
+ CommandSpec spec = commandHelper.getCommandSpec();
+ if ( System.console()==null ) {
+ throw new ParameterException(spec.commandLine(), "Missing option: Confirm operation with -y / --confirm (interactive prompt not available)");
+ } else {
+ String expectedResponse = PicocliSpecHelper.getRequiredMessageString(spec, "expectedConfirmPromptResponse");
+ String response = System.console().readLine(getPrompt(promptArgs));
+ if ( response.equalsIgnoreCase(expectedResponse) ) {
+ return;
+ } else {
+ throw new IllegalStateException("Aborting: operation aborted by user");
+ }
+ }
+ }
+ }
+
+ private String getPrompt(Object... promptArgs) {
+ CommandSpec spec = commandHelper.getCommandSpec();
+ String promptFormat = PicocliSpecHelper.getMessageString(spec, "confirmPrompt");
+ if ( StringUtils.isBlank(promptFormat) ) {
+ String[] descriptionLines = spec.optionsMap().get("-y").description();
+ if ( descriptionLines==null || descriptionLines.length<1 ) {
+ throw new RuntimeException("No proper description found for generating prompt for --confirm option");
+ }
+ promptFormat = spec.optionsMap().get("-y").description()[0].replaceAll("[. ]+$", "")+"?";
+ }
+ String prompt = String.format(promptFormat, promptArgs);
+ String promptOptions = PicocliSpecHelper.getRequiredMessageString(spec, "confirmPromptOptions");
+ return String.format("%s (%s) ", prompt, promptOptions);
+ }
+ }
+}
diff --git a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/cli/mixin/ICommandAware.java b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/cli/mixin/ICommandAware.java
new file mode 100644
index 0000000000..7b190d1fda
--- /dev/null
+++ b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/cli/mixin/ICommandAware.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright 2021, 2023 Open Text.
+ *
+ * The only warranties for products and services of Open Text
+ * and its affiliates and licensors ("Open Text") are as may
+ * be set forth in the express warranty statements accompanying
+ * such products and services. Nothing herein should be construed
+ * as constituting an additional warranty. Open Text shall not be
+ * liable for technical or editorial errors or omissions contained
+ * herein. The information contained herein is subject to change
+ * without notice.
+ *******************************************************************************/
+package com.fortify.cli.common.cli.mixin;
+
+import com.fortify.cli.common.cli.cmd.AbstractRunnableCommand;
+
+import picocli.CommandLine.Model.CommandSpec;
+import picocli.CommandLine.Spec;
+
+/**
+ * This interface is to be implemented by mixins that need access to
+ * the {@link CommandSpec} of the command that (directly or indirectly
+ * through intermediate mixins) references this mixin. Picocli provides
+ * the {@link Spec} annotation for injecting the mixee, but this may
+ * represent an intermediate mixin rather than the command that indirectly
+ * references the mixin.
+ *
+ * Mixins usually wouldn't implement this interface directly, but instead
+ * utilize {@link CommandHelperMixin} as it provides some useful utility methods
+ * related to the the injected {@link CommandSpec}. Injection is handled
+ * by {@link AbstractRunnableCommand}.
+ *
+ * @author rsenden
+ *
+ */
+public interface ICommandAware {
+ void setCommandSpec(CommandSpec commandSpec);
+}
diff --git a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/cli/util/CommandGroup.java b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/cli/util/CommandGroup.java
new file mode 100644
index 0000000000..321048442a
--- /dev/null
+++ b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/cli/util/CommandGroup.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright 2021, 2023 Open Text.
+ *
+ * The only warranties for products and services of Open Text
+ * and its affiliates and licensors ("Open Text") are as may
+ * be set forth in the express warranty statements accompanying
+ * such products and services. Nothing herein should be construed
+ * as constituting an additional warranty. Open Text shall not be
+ * liable for technical or editorial errors or omissions contained
+ * herein. The information contained herein is subject to change
+ * without notice.
+ *******************************************************************************/
+package com.fortify.cli.common.cli.util;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * This annotation allows for defining command groups. For now, this is only
+ * used for resource bundle lookups.
+ *
+ * @author rsenden
+ *
+ */
+@Retention(RUNTIME)
+@Target(ElementType.TYPE)
+@Inherited
+public @interface CommandGroup {
+ String value();
+}
diff --git a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/cli/util/EnvSuffix.java b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/cli/util/EnvSuffix.java
new file mode 100644
index 0000000000..7f30afec48
--- /dev/null
+++ b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/cli/util/EnvSuffix.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright 2021, 2023 Open Text.
+ *
+ * The only warranties for products and services of Open Text
+ * and its affiliates and licensors ("Open Text") are as may
+ * be set forth in the express warranty statements accompanying
+ * such products and services. Nothing herein should be construed
+ * as constituting an additional warranty. Open Text shall not be
+ * liable for technical or editorial errors or omissions contained
+ * herein. The information contained herein is subject to change
+ * without notice.
+ *******************************************************************************/
+package com.fortify.cli.common.cli.util;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * This annotation allows for defining an environment variable suffix
+ * on options and positional parameters for resolving default values
+ * from environment variables.
+ *
+ * @author rsenden
+ *
+ */
+@Retention(RUNTIME)
+@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
+public @interface EnvSuffix {
+ String value();
+}
diff --git a/fcli-common/src/main/java/com/fortify/cli/common/http/proxy/helper/ProxyDescriptor.java b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/http/proxy/helper/ProxyDescriptor.java
similarity index 76%
rename from fcli-common/src/main/java/com/fortify/cli/common/http/proxy/helper/ProxyDescriptor.java
rename to fcli-core/fcli-common/src/main/java/com/fortify/cli/common/http/proxy/helper/ProxyDescriptor.java
index 10ee531842..eb1306a7aa 100644
--- a/fcli-common/src/main/java/com/fortify/cli/common/http/proxy/helper/ProxyDescriptor.java
+++ b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/http/proxy/helper/ProxyDescriptor.java
@@ -1,13 +1,25 @@
+/*******************************************************************************
+ * Copyright 2021, 2023 Open Text.
+ *
+ * The only warranties for products and services of Open Text
+ * and its affiliates and licensors ("Open Text") are as may
+ * be set forth in the express warranty statements accompanying
+ * such products and services. Nothing herein should be construed
+ * as constituting an additional warranty. Open Text shall not be
+ * liable for technical or editorial errors or omissions contained
+ * herein. The information contained herein is subject to change
+ * without notice.
+ *******************************************************************************/
package com.fortify.cli.common.http.proxy.helper;
import java.net.URI;
import java.util.Set;
import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.formkiq.graalvm.annotations.Reflectable;
import com.fortify.cli.common.json.JsonNodeHolder;
import com.fortify.cli.common.util.StringUtils;
-import io.micronaut.core.annotation.ReflectiveAccess;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
@@ -15,7 +27,8 @@
import lombok.NoArgsConstructor;
@Data @EqualsAndHashCode(callSuper = false)
-@Builder @NoArgsConstructor @AllArgsConstructor @ReflectiveAccess
+@Builder
+@Reflectable @NoArgsConstructor @AllArgsConstructor
public class ProxyDescriptor extends JsonNodeHolder {
private String name;
private int priority;
diff --git a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/http/proxy/helper/ProxyHelper.java b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/http/proxy/helper/ProxyHelper.java
new file mode 100644
index 0000000000..b3ebb1cf6f
--- /dev/null
+++ b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/http/proxy/helper/ProxyHelper.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * Copyright 2021, 2023 Open Text.
+ *
+ * The only warranties for products and services of Open Text
+ * and its affiliates and licensors ("Open Text") are as may
+ * be set forth in the express warranty statements accompanying
+ * such products and services. Nothing herein should be construed
+ * as constituting an additional warranty. Open Text shall not be
+ * liable for technical or editorial errors or omissions contained
+ * herein. The information contained herein is subject to change
+ * without notice.
+ *******************************************************************************/
+package com.fortify.cli.common.http.proxy.helper;
+
+import java.nio.file.Path;
+import java.util.Comparator;
+import java.util.stream.Stream;
+
+import com.fortify.cli.common.util.FcliDataHelper;
+
+import kong.unirest.UnirestInstance;
+
+public final class ProxyHelper {
+ private ProxyHelper() {}
+
+ public static final void configureProxy(UnirestInstance unirest, String module, String url) {
+ getProxiesStream()
+ .sorted(Comparator.comparingInt(ProxyDescriptor::getPriority).reversed())
+ .filter(d->d.matches(module, url))
+ .findFirst()
+ .ifPresent(d->
+ unirest.config().proxy(d.getProxyHost(), d.getProxyPort(), d.getProxyUser(), d.getProxyPasswordAsString())
+ );
+ }
+
+ public static final ProxyDescriptor getProxy(String name) {
+ Path proxyConfigPath = getProxyConfigPath(name);
+ if ( !FcliDataHelper.exists(proxyConfigPath) ) {
+ throw new IllegalArgumentException("No proxy configuration found with name: "+name);
+ }
+ return getProxy(proxyConfigPath);
+ }
+
+ public static final ProxyDescriptor addProxy(ProxyDescriptor descriptor) {
+ Path proxyConfigPath = getProxyConfigPath(descriptor);
+ if ( FcliDataHelper.exists(proxyConfigPath) ) {
+ throw new IllegalArgumentException("proxy configuration with name "+descriptor.getName()+" already exists");
+ }
+ FcliDataHelper.saveSecuredFile(proxyConfigPath, descriptor, true);
+ return descriptor;
+ }
+
+ public static final ProxyDescriptor updateProxy(ProxyDescriptor descriptor) {
+ FcliDataHelper.saveSecuredFile(getProxyConfigPath(descriptor), descriptor, true);
+ return descriptor;
+ }
+
+ private static final ProxyDescriptor getProxy(Path proxyDescriptorPath) {
+ return FcliDataHelper.readSecuredFile(proxyDescriptorPath, ProxyDescriptor.class, true);
+ }
+
+ public static final ProxyDescriptor deleteProxy(ProxyDescriptor descriptor) {
+ FcliDataHelper.deleteFile(getProxyConfigPath(descriptor), true);
+ return descriptor;
+ }
+
+ public static final Stream deleteAllProxies() {
+ return getProxiesStream()
+ .peek(ProxyHelper::deleteProxy);
+ }
+
+ public static final Stream getProxiesStream() {
+ return FcliDataHelper.exists(getProxiesConfigPath())
+ ? FcliDataHelper.listFilesInDir(getProxiesConfigPath(), true).map(ProxyHelper::getProxy)
+ : Stream.empty();
+ }
+
+ private static final Path getProxiesConfigPath() {
+ return FcliDataHelper.getFcliConfigPath().resolve("proxies");
+ }
+
+ private static final Path getProxyConfigPath(ProxyDescriptor descriptor) {
+ return getProxyConfigPath(descriptor.getName());
+ }
+
+ private static final Path getProxyConfigPath(String name) {
+ return getProxiesConfigPath().resolve(getProxyFileName(name));
+ }
+
+ private static final String getProxyFileName(String name) {
+ return name.replaceAll("[^a-zA-Z0-9]", "_");
+ }
+}
diff --git a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/http/ssl/truststore/helper/TrustStoreConfigDescriptor.java b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/http/ssl/truststore/helper/TrustStoreConfigDescriptor.java
new file mode 100644
index 0000000000..dcd175f61c
--- /dev/null
+++ b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/http/ssl/truststore/helper/TrustStoreConfigDescriptor.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright 2021, 2023 Open Text.
+ *
+ * The only warranties for products and services of Open Text
+ * and its affiliates and licensors ("Open Text") are as may
+ * be set forth in the express warranty statements accompanying
+ * such products and services. Nothing herein should be construed
+ * as constituting an additional warranty. Open Text shall not be
+ * liable for technical or editorial errors or omissions contained
+ * herein. The information contained herein is subject to change
+ * without notice.
+ *******************************************************************************/
+package com.fortify.cli.common.http.ssl.truststore.helper;
+
+import com.formkiq.graalvm.annotations.Reflectable;
+import com.fortify.cli.common.json.JsonNodeHolder;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+@Data @EqualsAndHashCode(callSuper = false) @Builder
+@Reflectable @NoArgsConstructor @AllArgsConstructor
+public class TrustStoreConfigDescriptor extends JsonNodeHolder {
+ private String path;
+ private String type;
+ private String password;
+}
diff --git a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/http/ssl/truststore/helper/TrustStoreConfigHelper.java b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/http/ssl/truststore/helper/TrustStoreConfigHelper.java
new file mode 100644
index 0000000000..9c3499b7d4
--- /dev/null
+++ b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/http/ssl/truststore/helper/TrustStoreConfigHelper.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright 2021, 2023 Open Text.
+ *
+ * The only warranties for products and services of Open Text
+ * and its affiliates and licensors ("Open Text") are as may
+ * be set forth in the express warranty statements accompanying
+ * such products and services. Nothing herein should be construed
+ * as constituting an additional warranty. Open Text shall not be
+ * liable for technical or editorial errors or omissions contained
+ * herein. The information contained herein is subject to change
+ * without notice.
+ *******************************************************************************/
+package com.fortify.cli.common.http.ssl.truststore.helper;
+
+import java.nio.file.Path;
+
+import com.fortify.cli.common.util.FcliDataHelper;
+
+public final class TrustStoreConfigHelper {
+ private TrustStoreConfigHelper() {}
+
+ public static final TrustStoreConfigDescriptor getTrustStoreConfig() {
+ Path trustStoreConfigPath = getTrustStoreConfigPath();
+ return !FcliDataHelper.exists(trustStoreConfigPath)
+ ? new TrustStoreConfigDescriptor()
+ : FcliDataHelper.readSecuredFile(trustStoreConfigPath, TrustStoreConfigDescriptor.class, true);
+ }
+
+ public static final TrustStoreConfigDescriptor setTrustStoreConfig(TrustStoreConfigDescriptor descriptor) {
+ Path trustStoreConfigPath = getTrustStoreConfigPath();
+ FcliDataHelper.saveSecuredFile(trustStoreConfigPath, descriptor, true);
+ return descriptor;
+ }
+
+ public static final void clearTrustStoreConfig() {
+ FcliDataHelper.deleteFile(getTrustStoreConfigPath(), true);
+ }
+
+ private static final Path getTrustStoreConfigPath() {
+ return FcliDataHelper.getFcliConfigPath().resolve("ssl/truststore.json");
+ }
+}
diff --git a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/i18n/helper/LanguageDescriptor.java b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/i18n/helper/LanguageDescriptor.java
new file mode 100644
index 0000000000..7903ca4d04
--- /dev/null
+++ b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/i18n/helper/LanguageDescriptor.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright 2021, 2023 Open Text.
+ *
+ * The only warranties for products and services of Open Text
+ * and its affiliates and licensors ("Open Text") are as may
+ * be set forth in the express warranty statements accompanying
+ * such products and services. Nothing herein should be construed
+ * as constituting an additional warranty. Open Text shall not be
+ * liable for technical or editorial errors or omissions contained
+ * herein. The information contained herein is subject to change
+ * without notice.
+ *******************************************************************************/
+package com.fortify.cli.common.i18n.helper;
+
+import java.util.Locale;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data @AllArgsConstructor @NoArgsConstructor
+public final class LanguageDescriptor {
+ private Locale locale;
+
+ public LanguageDescriptor(String languageCode) {
+ this(new Locale(languageCode));
+ }
+
+ public final boolean isActive() {
+ return LanguageHelper.getConfiguredLanguageDescriptor().getLanguage().equals(getLanguage());
+ }
+
+ public final String getLanguage() {
+ return locale.getLanguage();
+ }
+
+ public final String getLocalName() {
+ return locale.getDisplayLanguage(locale);
+ }
+
+ public final String getName() {
+ return locale.getDisplayLanguage(new Locale("en"));
+ }
+
+ public final ObjectNode asObjectNode() {
+ return new ObjectMapper().valueToTree(this);
+ }
+}
diff --git a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/i18n/helper/LanguageHelper.java b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/i18n/helper/LanguageHelper.java
new file mode 100644
index 0000000000..0faf43facc
--- /dev/null
+++ b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/i18n/helper/LanguageHelper.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright 2021, 2023 Open Text.
+ *
+ * The only warranties for products and services of Open Text
+ * and its affiliates and licensors ("Open Text") are as may
+ * be set forth in the express warranty statements accompanying
+ * such products and services. Nothing herein should be construed
+ * as constituting an additional warranty. Open Text shall not be
+ * liable for technical or editorial errors or omissions contained
+ * herein. The information contained herein is subject to change
+ * without notice.
+ *******************************************************************************/
+package com.fortify.cli.common.i18n.helper;
+
+import java.nio.file.Path;
+import java.util.stream.Stream;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.formkiq.graalvm.annotations.Reflectable;
+import com.fortify.cli.common.json.JsonNodeHolder;
+import com.fortify.cli.common.util.FcliDataHelper;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+public final class LanguageHelper {
+ // TODO Any way we can dynamically determine available languages?
+ // TODO Re-add NL and other languages once resource bundles are up to date
+ private static final String[] supportedLanguages = {"en", "nl"};
+ private LanguageHelper() {}
+
+ public static final Stream getSupportedLanguageDescriptorsStream() {
+ return Stream.of(supportedLanguages)
+ .map(LanguageDescriptor::new);
+ }
+
+ public static final LanguageDescriptor getConfiguredLanguageDescriptor() {
+ Path languageConfigPath = getLanguageConfigPath();
+ LanguageConfigDescriptor configDescriptor = !FcliDataHelper.exists(languageConfigPath)
+ ? new LanguageConfigDescriptor()
+ : FcliDataHelper.readFile(languageConfigPath, LanguageConfigDescriptor.class, true);
+ return configDescriptor.getLanguageDescriptor();
+ }
+
+ public static final LanguageDescriptor setConfiguredLanguage(LanguageDescriptor descriptor) {
+ Path languageConfigPath = getLanguageConfigPath();
+ FcliDataHelper.saveFile(languageConfigPath, new LanguageConfigDescriptor(descriptor), true);
+ return descriptor;
+ }
+
+ public static final LanguageDescriptor setConfiguredLanguage(String language) {
+ return setConfiguredLanguage(new LanguageDescriptor(language));
+ }
+
+ public static final void clearLanguageConfig() {
+ FcliDataHelper.deleteFile(getLanguageConfigPath(), true);
+ }
+
+ private static final Path getLanguageConfigPath() {
+ return FcliDataHelper.getFcliConfigPath().resolve("i18n/language.json");
+ }
+
+ @Data @EqualsAndHashCode(callSuper = false)
+ @Reflectable @NoArgsConstructor @AllArgsConstructor
+ private static final class LanguageConfigDescriptor extends JsonNodeHolder {
+ private String language = "en";
+
+ public LanguageConfigDescriptor(LanguageDescriptor languageDescriptor) {
+ this.language = languageDescriptor.getLanguage();
+ }
+
+ @JsonIgnore
+ public LanguageDescriptor getLanguageDescriptor() {
+ return new LanguageDescriptor(language);
+ }
+ }
+}
diff --git a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/json/IJsonNodeHolder.java b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/json/IJsonNodeHolder.java
new file mode 100644
index 0000000000..3dc47b10c1
--- /dev/null
+++ b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/json/IJsonNodeHolder.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright 2021, 2022 Open Text.
+ *
+ * The only warranties for products and services of Open Text
+ * and its affiliates and licensors ("Open Text") are as may
+ * be set forth in the express warranty statements accompanying
+ * such products and services. Nothing herein should be construed
+ * as constituting an additional warranty. Open Text shall not be
+ * liable for technical or editorial errors or omissions contained
+ * herein. The information contained herein is subject to change
+ * without notice.
+ *******************************************************************************/
+package com.fortify.cli.common.json;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+public interface IJsonNodeHolder {
+ void setJsonNode(JsonNode jsonNode);
+ JsonNode asJsonNode();
+ ObjectNode asObjectNode();
+ ArrayNode asArrayNode();
+}
diff --git a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/json/JsonHelper.java b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/json/JsonHelper.java
new file mode 100644
index 0000000000..5495f20bc4
--- /dev/null
+++ b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/json/JsonHelper.java
@@ -0,0 +1,153 @@
+/*******************************************************************************
+ * Copyright 2021, 2023 Open Text.
+ *
+ * The only warranties for products and services of Open Text
+ * and its affiliates and licensors ("Open Text") are as may
+ * be set forth in the express warranty statements accompanying
+ * such products and services. Nothing herein should be construed
+ * as constituting an additional warranty. Open Text shall not be
+ * liable for technical or editorial errors or omissions contained
+ * herein. The information contained herein is subject to change
+ * without notice.
+ *******************************************************************************/
+package com.fortify.cli.common.json;
+
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.function.BiConsumer;
+import java.util.function.BinaryOperator;
+import java.util.function.Function;
+import java.util.function.Supplier;
+import java.util.stream.Collector;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+
+import org.springframework.expression.Expression;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.fasterxml.jackson.databind.node.TextNode;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+import com.fortify.cli.common.spring.expression.SpelEvaluator;
+import com.fortify.cli.common.util.StringUtils;
+
+import lombok.Getter;
+
+/**
+ * This bean provides utility methods for working with Jackson JsonNode trees.
+ *
+ * @author Ruud Senden
+ *
+ */
+public class JsonHelper {
+ @Getter private static final ObjectMapper objectMapper = _createObjectMapper();
+ //private static final Logger LOG = LoggerFactory.getLogger(JsonHelper.class);
+ private static final ObjectMapper _createObjectMapper() {
+ ObjectMapper objectMapper = new ObjectMapper();
+ objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
+ objectMapper.configure(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS, true);
+ objectMapper.registerModule(new JavaTimeModule());
+ return objectMapper;
+ }
+
+ public static final R evaluateSpelExpression(JsonNode input, Expression expression, Class returnClass) {
+ return SpelEvaluator.JSON_GENERIC.evaluate(expression, input, returnClass);
+ }
+
+ public static final R evaluateSpelExpression(JsonNode input, String expression, Class returnClass) {
+ return SpelEvaluator.JSON_GENERIC.evaluate(expression, input, returnClass);
+ }
+
+ public static final ObjectNode getFirstObjectNode(JsonNode input) {
+ if ( input instanceof ObjectNode ) {
+ return (ObjectNode)input;
+ } else if ( input instanceof ArrayNode ) {
+ ArrayNode array = (ArrayNode)input;
+ if ( array.size()==0 ) { return null; }
+ JsonNode node = array.get(0);
+ if ( node instanceof ObjectNode ) {
+ return (ObjectNode)node;
+ }
+ }
+ throw new IllegalArgumentException("Input must be an ObjectNode or array of ObjectNodes");
+ }
+
+ public static final Iterable iterable(ArrayNode arrayNode) {
+ Iterator iterator = arrayNode.iterator();
+ return () -> iterator;
+ }
+
+ public static final Stream stream(ArrayNode arrayNode) {
+ return StreamSupport.stream(iterable(arrayNode).spliterator(), false);
+ }
+
+ public static final ArrayNodeCollector arrayNodeCollector() {
+ return new ArrayNodeCollector();
+ }
+
+ public static final ArrayNode toArrayNode(String... objects) {
+ return Stream.of(objects).map(TextNode::new).collect(arrayNodeCollector());
+ }
+
+ public static final ArrayNode toArrayNode(JsonNode... objects) {
+ return Stream.of(objects).collect(arrayNodeCollector());
+ }
+
+ public static T treeToValue(JsonNode node, Class returnType) {
+ if ( node==null ) { return null; }
+ try {
+ T result = objectMapper.treeToValue(node, returnType);
+ if ( result instanceof IJsonNodeHolder ) {
+ ((IJsonNodeHolder)result).setJsonNode(node);
+ }
+ return result;
+ } catch (JsonProcessingException jpe ) {
+ throw new RuntimeException("Error processing JSON data", jpe);
+ }
+ }
+
+ public static T jsonStringToValue(String jsonString, Class