diff --git a/Jenkinsfile b/Jenkinsfile index efd463b..86298d4 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,186 +1,82 @@ -#!groovy - -// Required Jenkins plugins: -// https://wiki.jenkins-ci.org/display/JENKINS/Timestamper -// https://wiki.jenkins-ci.org/display/JENKINS/Static+Code+Analysis+Plug-ins -// https://wiki.jenkins-ci.org/display/JENKINS/Checkstyle+Plugin ? -// https://wiki.jenkins-ci.org/display/JENKINS/FindBugs+Plugin -// https://wiki.jenkins-ci.org/display/JENKINS/PMD+Plugin ? -// https://wiki.jenkins-ci.org/display/JENKINS/DRY+Plugin ? -// https://wiki.jenkins-ci.org/display/JENKINS/Task+Scanner+Plugin -// https://wiki.jenkins-ci.org/display/JENKINS/Javadoc+Plugin -// https://wiki.jenkins-ci.org/display/JENKINS/JaCoCo+Plugin ? - - -init() - -def branch_name -def branch_name_base -def build_number -def build_url -def git_commit -def job_name -def tag -def version -def build_type -def display_name - -def init() { - - // Keep the 5 most recent builds - properties([[$class: 'BuildDiscarderProperty', strategy: [$class: 'LogRotator', numToKeepStr: '5']]]) - - build_number = env.BUILD_NUMBER - build_url = env.BUILD_URL - job_name = "${env.JOB_NAME}" - branch_name = env.BRANCH_NAME - branch_name_docker = branch_name.replaceAll(/\//,'.') - persist = "/var/lib/jenkins/PERSIST/${branch_name_docker}" - - // execute the branch type specific pipeline code - try { - - if (branch_name.indexOf('release/')==0) build_type='release' - if (branch_name.indexOf('feature/')==0) build_type='feature' - if (branch_name.indexOf('develop')==0) build_type='develop' - if (branch_name.indexOf('hotfix')==0) build_type='hotfix' - if (branch_name.indexOf('bugfix')==0) build_type='bugfix' - if (branch_name.indexOf('master')==0) build_type='master' - - // common pipeline elements - node('master') { - Initialize() - SetVersion(build_type) - print_vars() // after SetVersion - all variables now defined - set_result('INPROGRESS') - Build() // builds database via flyway migration - } - - if (branch_name.indexOf('develop')==0) { - node('master') { - Deploy(); - } - } else if (branch_name.indexOf('release/')==0) { - node('master') { - Deploy(); - } - } - - node('master') { - set_result('SUCCESS') - } - - } catch (err) { - node() { - set_result('FAILURE') - } - throw err - } -} - -def Build() { - stage ('build') { - mvn "install -DskipTests=true -Dbuild.revision=${git_commit}" - step([$class: 'ArtifactArchiver', artifacts: '**/target/*.jar', fingerprint: true]) - } -} - -def Initialize() { - stage ('initialize') { - - // get new code - checkout scm - - git_commit = getSha1() - } -} - -def Deploy() { - stage ('deploy') { - mvn "deploy -DskipTests=true -Dbuild.number=${build_number} -Dbuild.revision=${git_commit}" - } -} - -def getSha1() { - sha1 = sh(script: 'git rev-parse HEAD', returnStdout: true).trim() - echo "sha1 is ${sha1}" - return sha1 -} - -def mvn(args) { - withMaven( - maven: 'maven-3.9.4', - globalMavenSettingsConfig: 'locusworks-settings' - ) { - - sh "mvn ${args}" - - } -} - -def mvn_initial(args) { - mvn(args) -} - -def set_result(status) { - if ( status == 'SUCCESS' ) { - currentBuild.result = status - notify_bitbucket('SUCCESSFUL') - } else if ( status == 'FAILURE' ) { - currentBuild.result = status - notify_bitbucket('FAILED') - } else if ( status == 'INPROGRESS' ) { - notify_bitbucket('INPROGRESS') - } else { - error ("unknown status") - } - - // save in persistence file for access the status page - // make sure the directory exists first - sh "mkdir -p $persist && echo $status > $persist/build.result" -} - -def notify_bitbucket(state) { -} - -def print_vars() { - echo "build_number = ${build_number}" - echo "build_url = ${build_url}" - echo "job_name = ${job_name}" - echo "branch_name = ${branch_name}" - echo "branch_name_base = ${branch_name_base}" - echo "build_type = ${build_type}" - echo "display_name = ${currentBuild.displayName}" - echo "version = ${version}" - echo "git_commit = ${git_commit}" - -} - -def SetVersion( v ) { - stage ('set version') { - echo "set version ${v}" - branch_name_base = (branch_name =~ /([^\/]+$)/)[0][0] - if ( v == 'release' ) { - // for release branches, where the branch is named "release/1.2.3", - // derive the version and display name derive from the numeric suffix and append the build number - // 3.2.1.100 - version = branch_name_base + "." + build_number + "-RELEASE"; - //version = branch_name.substring('release/'.length()) + "." + build_number - currentBuild.displayName = version - } else if (v == 'develop') { - version = branch_name_base + "." + build_number + "-SNAPSHOT"; - currentBuild.displayName = version - } else { - // for all other branches the version number is 0 with an appended build number - // and for the display name use the jenkins default #n and add the branch name - // #101 - feature/user/foo - //version = '0.' + build_number - version = branch_name_base + "." + build_number - currentBuild.displayName = "#" + build_number + " - " + branch_name_base - } - display_name = currentBuild.displayName - mvn_initial "versions:set -DnewVersion=${version}" - } -} - -return this +pipeline { + agent any + + options { + buildDiscarder(logRotator(numToKeepStr: '5')) + disableConcurrentBuilds() + skipDefaultCheckout(true) + timestamps() + } + + stages { + stage('Checkout') { + steps { checkout scm } + } + + stage('Set version') { + steps { + script { + String branch = env.BRANCH_NAME + if (!branch) { error('BRANCH_NAME is unavailable; this pipeline must run as a multibranch job') } + env.DEPLOY_BUILD = 'false' + def releaseMatch = branch =~ /^release\/(\d+\.\d+)$/ + if (releaseMatch.matches()) { + env.BUILD_VERSION = "${releaseMatch[0][1]}.${env.BUILD_NUMBER}-RELEASE" + env.DEPLOY_BUILD = 'true' + } else if (branch == 'develop') { + env.BUILD_VERSION = "develop.${env.BUILD_NUMBER}-SNAPSHOT" + env.DEPLOY_BUILD = 'true' + } else { + String safeBranch = branch.replaceAll(/[^A-Za-z0-9._-]/, '-') + env.BUILD_VERSION = "0.0.${env.BUILD_NUMBER}-${safeBranch}-SNAPSHOT" + } + currentBuild.displayName = env.BUILD_VERSION + } + withMaven(maven: 'maven-3.9.16', globalMavenSettingsConfig: 'locusworks-settings') { + sh 'mvn -B org.codehaus.mojo:versions-maven-plugin:2.21.0:set -DgenerateBackupPoms=false -DnewVersion="$BUILD_VERSION"' + } + } + } + + stage('Prepare OWASP cache') { + steps { + lock(resource: 'owasp-nvd-cache') { + withMaven(maven: 'maven-3.9.16', globalMavenSettingsConfig: 'locusworks-settings') { + sh 'mkdir -p "$HOME/.cache/dependency-check"' + sh 'mvn -B org.owasp:dependency-check-maven:13.0.0:update-only -DdataDirectory="$HOME/.cache/dependency-check"' + } + } + } + } + + stage('Build and test') { + steps { + withMaven(maven: 'maven-3.9.16', globalMavenSettingsConfig: 'locusworks-settings') { + sh 'mvn -B clean verify -DdataDirectory="$HOME/.cache/dependency-check" -DautoUpdate=false -Dbuild.revision="$GIT_COMMIT"' + } + } + post { + always { junit allowEmptyResults: true, testResults: '**/target/surefire-reports/*.xml' } + success { + archiveArtifacts artifacts: '**/target/*.jar', fingerprint: true + archiveArtifacts artifacts: '**/target/site/jacoco/**', fingerprint: true + } + } + } + + stage('Deploy') { + when { expression { env.DEPLOY_BUILD == 'true' } } + steps { + withMaven(maven: 'maven-3.9.16', globalMavenSettingsConfig: 'locusworks-settings') { + sh 'mvn -B deploy -DskipTests -Ddependency-check.skip=true -Dbuild.number="$BUILD_NUMBER" -Dbuild.revision="$GIT_COMMIT"' + } + } + } + } + + post { + success { echo "Published build ${env.BUILD_VERSION} successfully" } + failure { echo "Build ${env.BUILD_VERSION ?: env.BUILD_NUMBER} failed" } + cleanup { deleteDir() } + } +} diff --git a/README.md b/README.md index 1fe46b5..abc1916 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,27 @@ -Locusworks Commons -= - -- Library with common generic functions - -Install -== - -Maven -=== -```xml - - net.locusworks - locusworks-commons - ${latest_version} - -``` \ No newline at end of file +# Locusworks Commons (Deprecated) + +> **Deprecated:** Do not add `net.locusworks:locusworks-commons` to new projects. + +This artifact contains no implementation code. It exists temporarily as a compatibility dependency that brings in all of the replacement libraries below. + +| Replacement artifact | Purpose | +| --- | --- | +| `locusworks-commons-core` | General utilities, collections, tuples, validation, hashing, I/O, properties, interfaces, and annotations | +| `locusworks-commons-configuration` | Property-file loading, reconciliation, persistence, and optional value encryption | +| `locusworks-commons-json` | JSON serialization and object mapping | +| `locusworks-commons-http` | HTTP client and SSL helpers | +| `locusworks-commons-migration` | Flyway migration abstractions | + +## Migration + +Remove `locusworks-commons` and declare only the libraries the application actually uses: + +```xml + + net.locusworks + locusworks-commons-core + ${locusworks.commons.version} + +``` + +The Java package names remain unchanged, so source-code changes are generally unnecessary. diff --git a/bitbucket-pipelines.yml b/bitbucket-pipelines.yml deleted file mode 100644 index 8a373e0..0000000 --- a/bitbucket-pipelines.yml +++ /dev/null @@ -1,14 +0,0 @@ -# This is a sample build configuration for Java (Maven). -# Check our guides at https://confluence.atlassian.com/x/zd-5Mw for more examples. -# Only use spaces to indent your .yml configuration. -# ----- -# You can specify a custom docker image from Docker Hub as your build environment. -image: maven:3.3.9 - -pipelines: - default: - - step: - caches: - - maven - script: # Modify the commands below to build your repository. - - mvn -B verify # -B batch mode makes Maven less verbose \ No newline at end of file diff --git a/pom.xml b/pom.xml index 7c8e274..afdecab 100644 --- a/pom.xml +++ b/pom.xml @@ -1,40 +1,67 @@ - + + 4.0.0 net.locusworks locusworks-commons 0.0.1-SNAPSHOT - locusworks_commons - Common library for locusworks projects - - - Locusworks - http://www.locusworks.net - - - - locus2k@bitbucket.org:locus2k/commons.git - - + jar + Locusworks Commons + Convenience dependency that provides all standalone Locusworks commons libraries - 2.26.1 - 2.0.18 - 2.22.1 21 21 + UTF-8 + UTF-8 + 5.23.0 https://nexus.locusworks.net - + + + net.locusworks + locusworks-commons-core + 1.0.1-RELEASE + + + net.locusworks + locusworks-commons-configuration + 1.0.1-RELEASE + + + net.locusworks + locusworks-commons-json + 1.0.1-RELEASE + + + net.locusworks + locusworks-commons-http + 1.0.1-RELEASE + + + net.locusworks + locusworks-commons-migration + 1.0.1-RELEASE + + + net.locusworks + crypto + 2.0.1-RELEASE + + + org.mockito + mockito-core + ${mockito.version} + test + + org.apache.maven.plugins - maven-surefire-plugin - 3.5.6 - - @{argLine} --add-exports java.base/sun.security.jca=ALL-UNNAMED - + maven-surefire-plugin + 3.5.6 + + @{argLine} -javaagent:${settings.localRepository}/org/mockito/mockito-core/${mockito.version}/mockito-core-${mockito.version}.jar + org.apache.maven.plugins @@ -46,15 +73,13 @@ true -Xlint:all - --add-exports - java.base/sun.security.jca=ALL-UNNAMED org.owasp dependency-check-maven - 12.2.2 + 13.0.0 true true @@ -70,143 +95,8 @@ - - org.jacoco - jacoco-maven-plugin - 0.8.15 - - - - prepare-agent - - - - report - prepare-package - - report - - - - jacoco-check - - check - - - - - PACKAGE - - - LINE - COVEREDRATIO - 1.00 - - - BRANCH - COVEREDRATIO - 1.00 - - - - - - - - - - - - - commons-codec - commons-codec - 1.22.0 - compile - - - - org.junit.jupiter - junit-jupiter-api - 6.1.1 - test - - - org.junit.jupiter - junit-jupiter-params - 6.1.1 - test - - - org.mockito - mockito-core - 5.23.0 - test - - - - org.flywaydb - flyway-core - 12.10.0 - - - org.apache.logging.log4j - log4j-api - ${log4j.version} - - - org.apache.logging.log4j - log4j-core - ${log4j.version} - - - org.apache.logging.log4j - log4j-slf4j-impl - ${log4j.version} - - - org.slf4j - slf4j-api - ${slf4j.version} - - - org.slf4j - jcl-over-slf4j - ${slf4j.version} - - - - org.apache.httpcomponents.client5 - httpclient5 - 5.6.2 - - - - - com.fasterxml.jackson.core - jackson-core - ${jackson.version} - - - com.fasterxml.jackson.core - jackson-annotations - 2.22 - - - com.fasterxml.jackson.core - jackson-databind - ${jackson.version} - - - - com.google.code.gson - gson - 2.14.0 - - - - nexus-snapshot @@ -217,7 +107,6 @@ ${nexus.repo}/repository/locusworks-release/ - locusworks-public @@ -231,7 +120,6 @@ - locusworks-public @@ -244,5 +132,4 @@ - diff --git a/src/main/java/net/locusworks/common/.gitkeep b/src/main/java/net/locusworks/common/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/main/java/net/locusworks/common/Charsets.java b/src/main/java/net/locusworks/common/Charsets.java deleted file mode 100644 index 9503359..0000000 --- a/src/main/java/net/locusworks/common/Charsets.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package net.locusworks.common; - -import java.nio.charset.Charset; - -/** - * Contains constant definitions for the six standard {@link Charset} instances, which are - * guaranteed to be supported by all Java platform implementations. - * - *

Assuming you're free to choose, note that {@link #UTF_8} is widely preferred. - * - *

See the Guava User Guide article on {@code Charsets}. - *

- * Please do not add new Charset references to this class, unless those character encodings are - * part of the set required to be supported by all Java platform implementations! Any Charsets - * initialized here may cause unexpected delays when this class is loaded. See the Charset - * Javadocs for the list of built-in character encodings. - * - */ -public final class Charsets { - private Charsets() { - } - - /** - * US-ASCII: seven-bit ASCII, the Basic Latin block of the Unicode character set (ISO646-US). - */ - public static final Charset US_ASCII = java.nio.charset.StandardCharsets.US_ASCII; - - /** - * ISO-8859-1: ISO Latin Alphabet Number 1 (ISO-LATIN-1). - */ - public static final Charset ISO_8859_1 = java.nio.charset.StandardCharsets.ISO_8859_1; - - /** - * UTF-8: eight-bit UCS Transformation Format. - */ - public static final Charset UTF_8 = java.nio.charset.StandardCharsets.UTF_8; - - /** - * UTF-16BE: sixteen-bit UCS Transformation Format, big-endian byte order. - */ - public static final Charset UTF_16BE = java.nio.charset.StandardCharsets.UTF_16BE; - - /** - * UTF-16LE: sixteen-bit UCS Transformation Format, little-endian byte order. - */ - public static final Charset UTF_16LE = java.nio.charset.StandardCharsets.UTF_16LE; - - /** - * UTF-16: sixteen-bit UCS Transformation Format, byte order identified by an optional byte-order - * mark. - */ - public static final Charset UTF_16 = java.nio.charset.StandardCharsets.UTF_16; - -} \ No newline at end of file diff --git a/src/main/java/net/locusworks/common/annotations/MapValue.java b/src/main/java/net/locusworks/common/annotations/MapValue.java deleted file mode 100644 index 48b03ef..0000000 --- a/src/main/java/net/locusworks/common/annotations/MapValue.java +++ /dev/null @@ -1,25 +0,0 @@ -package net.locusworks.common.annotations; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Annotation that will map a POJO to a map object. - * This is at the field level and will map the - * filed name as the key and the field value as the value - * in the map - * - * @author Isaac Parenteau - * - */ -@Target({ElementType.FIELD}) -@Retention(RetentionPolicy.RUNTIME) -public @interface MapValue { - - String value() default ""; - - boolean ignore() default false; - -} diff --git a/src/main/java/net/locusworks/common/configuration/ConfigurationCallback.java b/src/main/java/net/locusworks/common/configuration/ConfigurationCallback.java deleted file mode 100644 index a21fce5..0000000 --- a/src/main/java/net/locusworks/common/configuration/ConfigurationCallback.java +++ /dev/null @@ -1,6 +0,0 @@ -package net.locusworks.common.configuration; - -@FunctionalInterface -public interface ConfigurationCallback { - void results(String msg); -} diff --git a/src/main/java/net/locusworks/common/configuration/ConfigurationManager.java b/src/main/java/net/locusworks/common/configuration/ConfigurationManager.java deleted file mode 100644 index 213a42e..0000000 --- a/src/main/java/net/locusworks/common/configuration/ConfigurationManager.java +++ /dev/null @@ -1,154 +0,0 @@ -package net.locusworks.common.configuration; - -import java.io.IOException; -import java.lang.reflect.Field; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.HashSet; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Properties; -import java.util.Set; - -import net.locusworks.common.Charsets; -import net.locusworks.common.crypto.AES; -import net.locusworks.common.exceptions.ApplicationException; -import net.locusworks.common.interfaces.PersistableRequest; - -import net.locusworks.common.utils.Utils; - -public class ConfigurationManager { - - private Properties configuration; - private Properties defaults = null; - private Path conf = null; - - protected AES aes; - - private ConfigurationCallback callback; - - protected void init(String baseDir, String propertiesFile, ConfigurationCallback callback) throws IOException { - init(baseDir, propertiesFile, this.getClass().getName().getBytes(Charsets.UTF_8), callback); - } - - protected void init(String baseDir, String propertiesFile, byte[] aesKey, ConfigurationCallback callback) throws IOException { - aes = aesKey.length > 0 ? AES.createInstance(aesKey) : AES.createInstance(); - this.callback = callback; - try { - defaults = PropertiesManager.loadConfiguration(this.getClass(), propertiesFile); - } catch (IOException ex) { - throw ex; - } - // create patchrepoConf File object - conf = Paths.get(baseDir).resolve(propertiesFile); - - loadConfiguration(); - } - - private void loadConfiguration() { - // load the active config file - // ignore read error, we can continue with an empty configuration map - // and all default items will be added below and the file created - - callbackMessage("Loading config file: " + conf); - try { - configuration = PropertiesManager.loadConfiguration(conf); - } catch (Exception e) { - callbackMessage("Config file: " + conf + " will be created from template"); - configuration = new Properties(); - } - - Map results = PropertiesManager.addConfiguration(configuration, defaults); - boolean changed = !results.isEmpty(); - if (!results.isEmpty()) { - StringBuilder sb = new StringBuilder("Added new configuration items:\n"); - for (Entry entry : results.entrySet()) { - sb.append(String.format("%s=%s\n", entry.getKey(), entry.getValue())); - } - callbackMessage(sb.toString()); - } - - results = PropertiesManager.removeConfiguration(configuration, defaults); - changed |= !results.isEmpty(); - if (!results.isEmpty()) { - StringBuilder sb = new StringBuilder("Added new configuration items:\n"); - for (Entry entry : results.entrySet()) { - sb.append(String.format("%s=%s\n", entry.getKey(), entry.getValue())); - } - callbackMessage(sb.toString()); - } - - if (changed) { - PropertiesManager.saveConfiguration(configuration, conf, "Patch Repository properties file"); - } - } - - /** - * Save the configuration values to file - * - * @param confs Configuration property values to save - * @throws Exception general exception - */ - public void saveToConf(Properties confs) throws Exception { - PropertiesManager.saveConfiguration(confs, conf, conf.getFileName().toString()); - callbackMessage("Saved config file: " + conf + ", " + confs.size() + " entries"); - loadConfiguration(); - } - - public String getPropertyValue(String key) { - return getPropertyValue(key, null); - } - - public String getPropertyValue(String key, String defaultValue) { - return configuration.containsKey(key) ? configuration.getProperty(key) : defaultValue; - } - - public Properties getConfiguration() { - return configuration; - } - - public void saveConfiguration(PersistableRequest request, Set fieldsToSave, Set excryptedFields) throws Exception { - if (fieldsToSave == null || fieldsToSave.isEmpty()) { - throw ApplicationException.generic("No fields to save were defined"); - } - if (excryptedFields == null) { - excryptedFields = new HashSet<>(); - } - try { - Properties props = new Properties(); - - //copy what is current in the configuration settings into the new properties file - configuration.entrySet().forEach(item -> props.setProperty(String.valueOf(item.getKey()), String.valueOf(item.getValue()))); - boolean changed = false; - for (Field f : request.getClass().getDeclaredFields()) { - f.setAccessible(true); - String fieldName = f.getName(); - String fieldValue = String.valueOf(f.get(request)); - - //Ensures we are only saving values that are already configured - if (!fieldsToSave.contains(fieldName)) continue; - - //Check to see if the old value changed - String oldValue = props.getProperty(fieldName); - if (Utils.isNotValid(oldValue, fieldValue) || oldValue.equals(fieldValue)) { - continue; - } - - changed = true; - - fieldValue = excryptedFields.contains(fieldName) ? aes.encrypt(fieldValue) : fieldValue; - - props.setProperty(fieldName, fieldValue); - } - if (changed) { - saveToConf(props); - } - } catch (Exception ex) { - throw ApplicationException.actionNotPermitted(ex.getMessage()); - } - } - - private void callbackMessage(String msg) { - if (callback != null) callback.results(msg); - } -} diff --git a/src/main/java/net/locusworks/common/configuration/PropertiesManager.java b/src/main/java/net/locusworks/common/configuration/PropertiesManager.java deleted file mode 100644 index de4143b..0000000 --- a/src/main/java/net/locusworks/common/configuration/PropertiesManager.java +++ /dev/null @@ -1,161 +0,0 @@ -package net.locusworks.common.configuration; - -import static net.locusworks.common.Charsets.UTF_8; - -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Map; -import java.util.Properties; -import java.util.stream.Collectors; - -import net.locusworks.common.immutables.Pair; -import net.locusworks.common.immutables.Unit; - -/** - * Properties manager class to help load and read properties - * - * @author Isaac Parenteau - * @version 2.0.0 - * @date 09/17/2023 - */ -public class PropertiesManager { - /** - * Load a configuration from a resource - * - * @param clazz class loader - * @param src source of the file - * @return properties - * @throws IOException Exception thrown the file can't be read - */ - public static Properties loadConfiguration(Class clazz, String src) throws IOException { - InputStream is = clazz.getResourceAsStream(src); - if (is == null) { - is = clazz.getClassLoader().getResourceAsStream(src); - } - if (is == null) { - return null; - } - BufferedReader br = new BufferedReader(new InputStreamReader(is, UTF_8)); - return loadConfiguration(br); - } - - /** - * Load configuration from a file. This method has been deprecated and may be removed in - * future released. Please use java.nio.Path - * - * @param file File to load - * @return properties - * @throws IOException Exception thrown the file can't be read - */ - @Deprecated - public static Properties loadConfiguration(File file) throws IOException { - return loadConfiguration(file.toPath()); - } - - /** - * Load configuration from a file. - * - * @param path the path to the file - * @return properties - * @throws IOException Exception thrown the file can't be read - */ - public static Properties loadConfiguration(Path path) throws IOException { - if (Files.notExists(path)) { - return new Properties(); - } - - try (BufferedReader br = Files.newBufferedReader(path)) { - return loadConfiguration(br); - } - } - - /** - * Load configuration from a buffered reader - * - * @param reader Buffered reader to read the properties values from - * @return properties - * @throws IOException Exception thrown the file can't be read - */ - public static Properties loadConfiguration(BufferedReader reader) throws IOException { - Properties config = new Properties(); - config.load(reader); - return config; - } - - /** - * Add configurations from one properties file to another - * - * @param to Properties file to copy values to - * @param from Properties file to copy values from - * @return a map containing the results of the values added - */ - public static Map addConfiguration(Properties to, Properties from) { - - return from.entrySet() - .stream() - .filter(entry -> !to.containsKey(entry.getKey())) - .map(entry -> { - String key = entry.getKey().toString(); - String value = entry.getValue().toString(); - to.put(key, value); - return new Pair(key, value); - }) - .collect(Collectors.toMap(Unit::getValue1, Pair::getValue2)); - } - - /** - * Removes configuration values that are not present in the comparedTo - * - * @param from Properties file to remove values from - * @param comparedTo Properties file to compare to - * @return a map containing the results of the values removed - */ - public static Map removeConfiguration(Properties from, Properties comparedTo) { - - return from.keySet() - .stream() - .filter(key -> !comparedTo.containsKey(key)) //only get the items that are not in the comparedTo properties - .map(key -> new Pair(String.valueOf(key), String.valueOf(from.get(key)))) - .toList() //Create a list of paired items (key value) of the items that were filtered - .stream() - .peek(pair -> { //remove those pairs from the from properties - from.remove(pair.getValue1()); - }) - .collect(Collectors.toMap(Unit::getValue1, Pair::getValue2)); - } - - /** - *

Save the properties file to disk.

- *

This method has been depecreated and could be removed in future release.
Please use java.nio.Path

- * - * @param props Properties file to save - * @param fileToSave File to save to - * @param comment Any comments to add - */ - @Deprecated - public static void saveConfiguration(Properties props, File fileToSave, String comment) { - saveConfiguration(props, fileToSave.toPath(), comment); - - } - - /** - *

Save the properties file to disk.

- * - * @param props Properties file to save - * @param fileToSave File to save to - * @param comment Any comments to add - */ - public static void saveConfiguration(Properties props, Path fileToSave, String comment) { - try (OutputStream fos = Files.newOutputStream(fileToSave)) { - props.store(fos, comment == null ? "" : comment); - } catch (IOException ex) { - throw new RuntimeException(ex.getMessage(), ex); - } - } -} diff --git a/src/main/java/net/locusworks/common/crypto/AES.java b/src/main/java/net/locusworks/common/crypto/AES.java deleted file mode 100644 index 91ef029..0000000 --- a/src/main/java/net/locusworks/common/crypto/AES.java +++ /dev/null @@ -1,162 +0,0 @@ -package net.locusworks.common.crypto; - -import javax.crypto.BadPaddingException; -import javax.crypto.Cipher; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.KeyGenerator; -import javax.crypto.spec.IvParameterSpec; -import javax.crypto.spec.SecretKeySpec; - -import java.security.*; -import java.util.Base64; - -import net.locusworks.common.utils.RandomString; -import net.locusworks.common.utils.Utils; - -import static net.locusworks.common.Charsets.UTF_8; - - -/** - * AES encryption/decryption class - * This class will encrypt/decrypt data. The encryption key is never known. - * Instead, it is generated by the provided seed. As long as the seed stays the same - * the key will remain the same and the encryption/decryption will work. This - * provides and added security. - * - * @author Isaac Parenteau - * @version 1.0.0 - * @date 02/15/2018 - * - */ -public class AES { - - private static final String ENCRYPTION_TYPE = "AES"; - private static final String ENCRYPTION_ALGORITHM = "AES/CBC/PKCS5Padding"; - private static final String PROVIDER = "SunJCE"; - private static final String ALGORITHM = "SHA1PRNG"; - - private Cipher cipher; - - private SecretKeySpec secretKeySpec; - - private IvParameterSpec ivParamSpec; - - private String seed; - - private RandomString randomizer; - - private void initSecureKey(String seed) { - try { - SecureRandom sr = getSecureRandom(seed); - KeyGenerator generator = KeyGenerator.getInstance(ENCRYPTION_TYPE); - generator.init(128, sr); - - randomizer = RandomString.newInstance(sr); - init(generator.generateKey().getEncoded()); - } catch (Exception ex) { - throw new IllegalArgumentException("Unable to initialize encryption:", ex); - } - } - - /** - * Initializes the secure random object to be the same across all platforms - * with regard to provider and algorithm used - * - * @param seed Seed to initialize SecureRandom with - * @return SecureRandom object - * @throws NoSuchAlgorithmException thrown when algorithm can't be used - */ - private static SecureRandom getSecureRandom(String seed) throws NoSuchAlgorithmException { - SecureRandom sr = SecureRandom.getInstance(ALGORITHM); - sr.setSeed(seed.getBytes(UTF_8)); - return sr; - } - - /** - * Initialize the aes engine - * - * @param key secret key to use - */ - private void init(final byte[] key) { - try { - this.cipher = Cipher.getInstance(ENCRYPTION_ALGORITHM, PROVIDER); - this.secretKeySpec = new SecretKeySpec(key, ENCRYPTION_TYPE); - this.ivParamSpec = new IvParameterSpec(randomizer.getBytes(16)); - } catch (Exception ex) { - throw new IllegalArgumentException("Unable to initialize encryption:", ex); - } - } - - /*** - * Encrypt a text string - * @param plainText String to encrypt - * @return encrypted string - */ - public String encrypt(String plainText) { - if (Utils.isEmptyString(plainText)) { - plainText = ""; - } - try { - cipher.init(Cipher.ENCRYPT_MODE, this.secretKeySpec, this.ivParamSpec); - byte[] cypherText = cipher.doFinal(plainText.getBytes(UTF_8)); - return new String(Base64.getEncoder().encode(cypherText), UTF_8); - } catch (Exception ex) { - throw new IllegalArgumentException(ex.getMessage(), ex); - } - } - - /*** - * Decrypt an encrypted string - * @param cipherString encrypted string to decrypt - * @return unecrypted string - */ - public String decrypt(String cipherString) { - if (Utils.isEmptyString(cipherString)) { - return ""; - } - byte[] cipherText = Base64.getDecoder().decode(cipherString.getBytes(UTF_8)); - try { - cipher.init(Cipher.DECRYPT_MODE, this.secretKeySpec, this.ivParamSpec); - return new String(cipher.doFinal(cipherText), UTF_8); - } catch (IllegalBlockSizeException | BadPaddingException | InvalidKeyException | - InvalidAlgorithmParameterException e) { - throw new IllegalArgumentException(e.getMessage(), e); - } - } - - public AES withSeed(String seed) { - if (this.seed == null || !this.seed.equals(seed)) { - initSecureKey(seed); - } - this.seed = seed; - return this; - } - - public final String getSeed() { - return this.seed; - } - - public static AES createInstance() { - return createInstance(RandomString.getInstance().getString(16)); - } - - public static AES createInstance(byte[] byteSeed) { - String seed = new String(byteSeed, UTF_8); - return createInstance(seed); - } - - public static AES createInstance(String seed) { - return new AES().withSeed(seed); - } - - public static void main(String[] args) throws NoSuchAlgorithmException { - if (args == null || !(args.length > 0)) { - throw new IllegalArgumentException("No args provided. Need password as argument"); - } - if (args.length % 2 == 0) { - System.out.println(AES.createInstance(String.valueOf(args[1])).decrypt(String.valueOf(args[0]))); - } else { - System.out.println(AES.createInstance().encrypt(String.valueOf(args[0]))); - } - } -} diff --git a/src/main/java/net/locusworks/common/crypto/AESKey.java b/src/main/java/net/locusworks/common/crypto/AESKey.java deleted file mode 100644 index c0a8ef0..0000000 --- a/src/main/java/net/locusworks/common/crypto/AESKey.java +++ /dev/null @@ -1,32 +0,0 @@ -package net.locusworks.common.crypto; - -import java.io.Serial; -import java.security.PrivateKey; - -import net.locusworks.common.Charsets; - -public class AESKey implements PrivateKey { - - @Serial - private static final long serialVersionUID = -8452357427706386362L; - private final String seed; - - public AESKey(String seed) { - this.seed = seed; - } - - @Override - public String getAlgorithm() { - return "aes"; - } - - @Override - public String getFormat() { - return "aes-seed"; - } - - @Override - public byte[] getEncoded() { - return this.seed.getBytes(Charsets.UTF_8); - } -} diff --git a/src/main/java/net/locusworks/common/crypto/AESKeySpec.java b/src/main/java/net/locusworks/common/crypto/AESKeySpec.java deleted file mode 100644 index 3df5ea9..0000000 --- a/src/main/java/net/locusworks/common/crypto/AESKeySpec.java +++ /dev/null @@ -1,45 +0,0 @@ -package net.locusworks.common.crypto; - -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.security.spec.EncodedKeySpec; -import java.security.spec.InvalidKeySpecException; -import java.util.Arrays; -import java.util.Base64; - -import net.locusworks.common.Charsets; -import net.locusworks.common.io.IOUtils; - -import static net.locusworks.common.utils.Checks.checkArguments; -import static net.locusworks.common.utils.Utils.get; -import static net.locusworks.common.utils.Utils.size; - -public class AESKeySpec extends EncodedKeySpec { - - private static final String AES_MARKER = "aes-seed"; - - public AESKeySpec(byte[] encodedKey) { - super(encodedKey); - } - - public AESKey generateKey() throws InvalidKeySpecException { - try { - byte[] data = this.getEncoded(); - InputStream stream = new ByteArrayInputStream(data); - Iterable parts = Arrays.asList(IOUtils.toString(stream, Charsets.UTF_8).split(" ")); - - checkArguments(size(parts) == 2 && AES_MARKER.equals(get(parts, 0)), "Bad format, should be: aes-seed AAB3..."); - stream = new ByteArrayInputStream(Base64.getDecoder().decode(String.valueOf(get(parts, 1)))); - String marker = IOUtils.toString(stream, Charsets.UTF_8); - return new AESKey(marker); - } catch (Exception ex) { - throw new InvalidKeySpecException(ex); - } - } - - @Override - public String getFormat() { - return "aes"; - } - -} diff --git a/src/main/java/net/locusworks/common/crypto/EncryptionKeyFactory.java b/src/main/java/net/locusworks/common/crypto/EncryptionKeyFactory.java deleted file mode 100644 index c2737f3..0000000 --- a/src/main/java/net/locusworks/common/crypto/EncryptionKeyFactory.java +++ /dev/null @@ -1,38 +0,0 @@ -package net.locusworks.common.crypto; - -import java.security.KeyFactory; -import java.security.KeyFactorySpi; -import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; -import java.security.Provider; -import java.security.PublicKey; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.KeySpec; - -import sun.security.jca.GetInstance; -import sun.security.jca.GetInstance.Instance; - -public class EncryptionKeyFactory extends KeyFactory { - - protected EncryptionKeyFactory(KeyFactorySpi keyFacSpi, Provider provider, String algorithm) { - super(keyFacSpi, provider, algorithm); - } - - public PrivateKey generatePrivateKey(KeySpec keySpec) throws InvalidKeySpecException { - if (keySpec instanceof AESKeySpec) { - return ((AESKeySpec) keySpec).generateKey(); - } - return super.generatePrivate(keySpec); - } - - public PublicKey generatePublicKey(KeySpec keySpec) throws InvalidKeySpecException { - keySpec = keySpec instanceof SSHEncodedKeySpec ? ((SSHEncodedKeySpec) keySpec).convertToRSAPubKeySpec() : keySpec; - return super.generatePublic(keySpec); - } - - public static EncryptionKeyFactory getInstance(String algorithm) throws NoSuchAlgorithmException { - Instance instance = GetInstance.getInstance("KeyFactory", KeyFactorySpi.class, algorithm); - return new EncryptionKeyFactory((KeyFactorySpi) instance.impl, instance.provider, algorithm); - } - -} diff --git a/src/main/java/net/locusworks/common/crypto/HashSalt.java b/src/main/java/net/locusworks/common/crypto/HashSalt.java deleted file mode 100644 index ca7ec9c..0000000 --- a/src/main/java/net/locusworks/common/crypto/HashSalt.java +++ /dev/null @@ -1,186 +0,0 @@ -package net.locusworks.common.crypto; - -import java.math.BigInteger; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; -import java.security.spec.InvalidKeySpecException; -import javax.crypto.SecretKeyFactory; -import javax.crypto.spec.PBEKeySpec; - -/** - * The type Hash salt. - * - * @author Isaac Parenteau - * @version 1.0.0 - * @date 02/15/2018 - */ -public class HashSalt { - /** - * The constant PBKDF2_ALGORITHM. - */ - private static final String PBKDF2_ALGORITHM = "PBKDF2WithHmacSHA256"; - - /** - * The constant SALT_BYTE_SIZE. - */ - private static final int SALT_BYTE_SIZE = 24; - - /** - * The constant HASH_BYTE_SIZE. - */ - private static final int HASH_BYTE_SIZE = 24; - - /** - * The constant PBKDF2_ITERATIONS. - */ - private static final int PBKDF2_ITERATIONS = 1000; - - /** - * The constant ITERATION_INDEX. - */ - private static final int ITERATION_INDEX = 0; - /** - * The constant SALT_INDEX. - */ - private static final int SALT_INDEX = 1; - /** - * The constant PBKDF2_INDEX. - */ - private static final int PBKDF2_INDEX = 2; - - /** - * Returns a salted PBKDF2 hash of the password. - * - * @param password the password to hash - * @return a salted PBKDF2 hash of the password - * @throws NoSuchAlgorithmException the no such algorithm exception - * @throws InvalidKeySpecException the invalid key spec exception - */ - public static String createHash(String password) throws NoSuchAlgorithmException, InvalidKeySpecException { - return createHash(password.toCharArray()); - } - - /** - * Returns a salted PBKDF2 hash of the password. - * - * @param password the password to hash - * @return a salted PBKDF2 hash of the password - * @throws NoSuchAlgorithmException the no such algorithm exception - * @throws InvalidKeySpecException the invalid key spec exception - */ - public static String createHash(char[] password) throws NoSuchAlgorithmException, InvalidKeySpecException { - // Generate a random salt - SecureRandom random = new SecureRandom(); - byte[] salt = new byte[SALT_BYTE_SIZE]; - random.nextBytes(salt); - - // Hash the password - byte[] hash = pbkdf2(password, salt, PBKDF2_ITERATIONS, HASH_BYTE_SIZE); - // format iterations:salt:hash - return PBKDF2_ITERATIONS + ":" + toHex(salt) + ":" + toHex(hash); - } - - /** - * Validates a password using a hash. - * - * @param password the password to check - * @param correctHash the hash of the valid password - * @return true if the password is correct, false if not - * @throws NoSuchAlgorithmException the no such algorithm exception - * @throws InvalidKeySpecException the invalid key spec exception - */ - public static boolean validatePassword(String password, String correctHash) throws NoSuchAlgorithmException, InvalidKeySpecException { - return validatePassword(password.toCharArray(), correctHash); - } - - /** - * Validates a password using a hash. - * - * @param password the password to check - * @param correctHash the hash of the valid password - * @return true if the password is correct, false if not - * @throws NoSuchAlgorithmException the no such algorithm exception - * @throws InvalidKeySpecException the invalid key spec exception - */ - public static boolean validatePassword(char[] password, String correctHash) throws NoSuchAlgorithmException, InvalidKeySpecException { - // Decode the hash into its parameters - String[] params = correctHash.split(":"); - int iterations = Integer.parseInt(params[ITERATION_INDEX]); - byte[] salt = fromHex(params[SALT_INDEX]); - byte[] hash = fromHex(params[PBKDF2_INDEX]); - // Compute the hash of the provided password, using the same salt, - // iteration count, and hash length - byte[] testHash = pbkdf2(password, salt, iterations, hash.length); - // Compare the hashes in constant time. The password is correct if - // both hashes match. - return slowEquals(hash, testHash); - } - - /** - * Compares two byte arrays in length-constant time. This comparison method - * is used so that password hashes cannot be extracted from an on-line - * system using a timing attack and then attacked off-line. - * - * @param a the first byte array - * @param b the second byte array - * @return true if both byte arrays are the same, false if not - */ - private static boolean slowEquals(byte[] a, byte[] b) { - int diff = a.length ^ b.length; - for (int i = 0; i < a.length && i < b.length; i++) - diff |= a[i] ^ b[i]; - return diff == 0; - } - - /** - * Computes the PBKDF2 hash of a password. - * - * @param password the password to hash. - * @param salt the salt - * @param iterations the iteration count (slowness factor) - * @param bytes the length of the hash to compute in bytes - * @return the PBDKF2 hash of the password - */ - private static byte[] pbkdf2(char[] password, byte[] salt, int iterations, int bytes) throws NoSuchAlgorithmException, InvalidKeySpecException { - PBEKeySpec spec = new PBEKeySpec(password, salt, iterations, bytes * 8); - SecretKeyFactory skf = SecretKeyFactory.getInstance(PBKDF2_ALGORITHM); - return skf.generateSecret(spec).getEncoded(); - } - - /** - * Converts a string of hexadecimal characters into a byte array. - * - * @param hex the hex string - * @return the hex string decoded into a byte array - */ - private static byte[] fromHex(String hex) { - byte[] binary = new byte[hex.length() / 2]; - for (int i = 0; i < binary.length; i++) { - binary[i] = (byte) Integer.parseInt(hex.substring(2 * i, 2 * i + 2), 16); - } - return binary; - } - - /** - * Converts a byte array into a hexadecimal string. - * - * @param array the byte array to convert - * @return a length*2 character string encoding the byte array - */ - private static String toHex(byte[] array) { - BigInteger bi = new BigInteger(1, array); - String hex = bi.toString(16); - int paddingLength = (array.length * 2) - hex.length(); - if (paddingLength > 0) - return String.format("%0" + paddingLength + "d", 0) + hex; - else - return hex; - } - - public static void main(String[] args) throws Exception { - if (args == null || !(args.length > 0)) { - throw new IllegalArgumentException("No args provided. Need password as argument"); - } - System.out.println(HashSalt.createHash(String.valueOf(args[0]))); - } -} \ No newline at end of file diff --git a/src/main/java/net/locusworks/common/crypto/KeyFile.java b/src/main/java/net/locusworks/common/crypto/KeyFile.java deleted file mode 100644 index bad712b..0000000 --- a/src/main/java/net/locusworks/common/crypto/KeyFile.java +++ /dev/null @@ -1,221 +0,0 @@ -package net.locusworks.common.crypto; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.io.Writer; -import java.security.Key; -import java.security.PrivateKey; -import java.security.interfaces.RSAPublicKey; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.KeySpec; -import java.security.spec.PKCS8EncodedKeySpec; -import java.security.spec.X509EncodedKeySpec; -import java.util.Arrays; -import java.util.Base64; -import java.util.List; - -import net.locusworks.common.Charsets; -import net.locusworks.common.io.IOUtils; -import net.locusworks.common.utils.DataOutputStreamHelper; -import net.locusworks.common.utils.Utils; - -import static net.locusworks.common.utils.Utils.handleExceptionWrapper; -import static net.locusworks.common.utils.Splitter.fixedLengthSplit; -import static java.lang.String.join; - -public class KeyFile implements AutoCloseable { - - public enum EncryptionType { - RSA, - AES, - SSH - } - - private Key key; - private String description; - private Writer writer; - private EncryptionType encryptionType; - - public KeyFile(Key key) { - this(key, null); - } - - public KeyFile(Key key, String description) { - this(key, description, EncryptionType.valueOf(key.getAlgorithm().toUpperCase())); - } - - public KeyFile(Key key, String description, EncryptionType encryptionType) { - this.key = key; - this.description = description; - this.encryptionType = encryptionType; - } - - private KeyFile() { - } - - private void loadFromFile(String fileName) { - if (Utils.isEmptyString(fileName)) return; - - this.key = null; - try { - File keyFile = new File(fileName); - if (!keyFile.exists()) { - throw new IllegalArgumentException(String.format("Unable to find file with name %s. Please check path", fileName)); - } - - String contentStr; - try (FileInputStream input = new FileInputStream(keyFile)) { - contentStr = IOUtils.toString(input, Charsets.UTF_8); - } - - boolean rsaFormat = !contentStr.startsWith("ssh-rsa") && !contentStr.startsWith("aes-seed"); - if (rsaFormat) { - contentStr = contentStr.replaceAll("-----[^-]+-----", ""); - contentStr = contentStr.replaceAll("\\s", ""); - } else { - contentStr = contentStr.trim(); - } - - byte[] content = rsaFormat ? Base64.getDecoder().decode(contentStr) : contentStr.getBytes(Charsets.UTF_8); - - EncryptionKeyFactory kf = EncryptionKeyFactory.getInstance("RSA"); - - List keySpecs = Utils.toList( - new KeySpecHelper(new AESKeySpec(content), true, EncryptionType.AES), - new KeySpecHelper(new SSHEncodedKeySpec(content), false, EncryptionType.SSH), - new KeySpecHelper(new PKCS8EncodedKeySpec(content), true, EncryptionType.RSA), - new KeySpecHelper(new X509EncodedKeySpec(content), false, EncryptionType.RSA) - ); - - for (KeySpecHelper ksh : keySpecs) { - try { - this.key = ksh.isPrivate() ? kf.generatePrivateKey(ksh.getKeySpec()) : kf.generatePublicKey(ksh.getKeySpec()); - this.encryptionType = ksh.getEncryptionType(); - break; - } catch (NullPointerException | InvalidKeySpecException ikse) { - continue; - } - } - if (this.key == null) { - throw new InvalidKeySpecException(String.format("Unable to determine if file %s is a private or public key. Not type of PKCS8, X509, SSH or AES spec", fileName)); - } - } catch (Exception ex) { - throw new RuntimeException(ex); - } - } - - public void write(String fileName) { - try { - String data; - switch (this.encryptionType) { - case AES: - data = String.format("%s %s", this.key.getFormat(), Base64.getEncoder().encodeToString(this.key.getEncoded())); - IOUtils.writeStringToFile(fileName, data); - break; - case SSH: - try (DataOutputStreamHelper dosh = new DataOutputStreamHelper()) { - getSSHPubKeyBytes(this.key) - .forEach(handleExceptionWrapper(item -> { - dosh.writeInt(item.length); - dosh.write(item); - })); - data = String.format("ssh-rsa %s %s", dosh.base64Encoded(), this.description); - IOUtils.writeStringToFile(fileName, data); - } - break; - default: - writePem(fileName); - } - } catch (Exception ex) { - throw new IllegalArgumentException(ex); - } - } - - public void setDescription(String description) { - this.description = description; - } - - public String getDescription() { - if (Utils.isEmptyString(this.description)) { - return this.key instanceof PrivateKey ? "PRIVATE KEY" : "PUBLIC KEY"; - } - return this.description; - } - - public Key getKey() { - return this.key; - } - - @Override - public void close() { - try { - if (this.writer != null) { - this.writer.flush(); - this.writer.close(); - this.writer = null; - } - } catch (Exception ex) { - throw new RuntimeException(ex); - } - } - - public static KeyFile read(String fileName) { - try (KeyFile kf = new KeyFile()) { - kf.loadFromFile(fileName); - return kf; - } - } - - private void writePem(String fileName) { - try { - String desc = getDescription(); - this.writer = new OutputStreamWriter(new FileOutputStream(fileName), Charsets.UTF_8); - this.writer.write(String.format("-----BEGIN RSA %s-----", desc)); - - String encoded = Base64.getEncoder().encodeToString(this.key.getEncoded()); - String out = join("\n", fixedLengthSplit(60).split(encoded)); - - this.writer.write(out); - this.writer.write(String.format("-----END RSA %s-----", desc)); - } catch (IOException ex) { - throw new RuntimeException(ex); - } - } - - private List getSSHPubKeyBytes(Key key) { - RSAPublicKey rpk = (RSAPublicKey) key; - return Arrays.asList("ssh-rsa".getBytes(Charsets.UTF_8), - rpk.getPublicExponent().toByteArray(), - rpk.getModulus().toByteArray() - ); - } - - private static class KeySpecHelper { - private final KeySpec keySpec; - private final boolean isPrivate; - private final EncryptionType encryptionType; - - public KeySpecHelper(KeySpec keySpec, boolean isPrivate, EncryptionType encryptionType) { - super(); - this.keySpec = keySpec; - this.isPrivate = isPrivate; - this.encryptionType = encryptionType; - } - - public synchronized final KeySpec getKeySpec() { - return keySpec; - } - - public synchronized final boolean isPrivate() { - return isPrivate; - } - - public synchronized final EncryptionType getEncryptionType() { - return encryptionType; - } - } - -} diff --git a/src/main/java/net/locusworks/common/crypto/RSA.java b/src/main/java/net/locusworks/common/crypto/RSA.java deleted file mode 100644 index 8ff6ee6..0000000 --- a/src/main/java/net/locusworks/common/crypto/RSA.java +++ /dev/null @@ -1,156 +0,0 @@ -package net.locusworks.common.crypto; - -import java.io.ByteArrayInputStream; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.security.Key; -import java.security.KeyPair; -import java.security.KeyPairGenerator; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.SecureRandom; -import java.security.interfaces.RSAKey; -import java.util.Base64; - -import javax.crypto.Cipher; -import javax.crypto.CipherInputStream; -import javax.crypto.IllegalBlockSizeException; - -import net.locusworks.common.Charsets; -import net.locusworks.common.crypto.KeyFile.EncryptionType; -import net.locusworks.common.io.IOUtils; - -public class RSA { - - private static final String ENCRYPTION_TYPE = "RSA"; - private static final String ENCRYPTION_ALGORITHM = "RSA/ECB/PKCS1PADDING"; - private static final String PROVIDER = "SunJCE"; - private static final String RANDOM_ALGORITHM = "SHA1PRNG"; - - private static final int PADDING_LENGTH = 11; - private static final int DEFAULT_KEY_LENGTH = 2048; - - public static KeyPair generateKeyPair() { - return generateKeyPair(DEFAULT_KEY_LENGTH); - } - - public static KeyPair generateKeyPair(int keyLength) { - try { - KeyPairGenerator kpg = KeyPairGenerator.getInstance(ENCRYPTION_TYPE); - SecureRandom sr = SecureRandom.getInstance(RANDOM_ALGORITHM); - kpg.initialize(keyLength, sr); - return kpg.genKeyPair(); - } catch (Exception ex) { - throw new RuntimeException(ex); - } - } - - public static KeyPair loadPrivateKey(String privateKeyFileName) { - return loadKeyPair(null, privateKeyFileName); - } - - public static KeyPair loadPublicKey(String publicKeyFileName) { - return loadKeyPair(publicKeyFileName, null); - } - - public static KeyPair loadKeyPair(String publicKey, String privateKey) { - KeyFile pubKey = KeyFile.read(publicKey); - KeyFile prvKey = KeyFile.read(privateKey); - return new KeyPair((PublicKey) pubKey.getKey(), (PrivateKey) prvKey.getKey()); - } - - public static boolean generateAndWriteSSHKeys() { - KeyPair kp = generateKeyPair(); - return writePrivateKey(kp) && writePublicKey(kp, true); - } - - public static boolean generateAndWriteKeyPair() { - return generateAndWriteKeyPair(DEFAULT_KEY_LENGTH); - } - - public static boolean generateAndWriteKeyPair(String keyPairName) { - return generateAndWriteKeyPair(keyPairName, DEFAULT_KEY_LENGTH); - } - - public static boolean generateAndWriteKeyPair(int keyLength) { - return generateAndWriteKeyPair("id_rsa", keyLength); - } - - public static boolean generateAndWriteKeyPair(String keyPairName, int keyLength) { - KeyPair kp = generateKeyPair(keyLength); - return writePrivateKey(kp, keyPairName, "PRIVATE KEY") && writePublicKey(kp, keyPairName + ".pub", "PUBLIC KEY"); - } - - public static boolean writePrivateKey(KeyPair kp) { - return writePrivateKey(kp, "id_rsa", "PRIVATE KEY"); - } - - public static boolean writePrivateKey(KeyPair kp, String fileName, String description) { - return writePemFile(kp.getPrivate(), fileName, description); - } - - public static boolean writePublicKey(KeyPair kp) { - return writePublicKey(kp, false); - } - - public static boolean writePublicKey(KeyPair kp, boolean sshFormat) { - return writePublicKey(kp, "id_rsa.pub", "PUBLIC KEY", sshFormat); - } - - public static boolean writePublicKey(KeyPair kp, String fileName, String description) { - return writePemFile(kp.getPublic(), fileName, description, false); - } - - public static boolean writePublicKey(KeyPair kp, String fileName, String description, boolean sshFormat) { - return writePemFile(kp.getPublic(), fileName, description, sshFormat); - } - - public static int calculateRequiredKeyLength(String message) { - return (message.getBytes(Charsets.UTF_8).length + PADDING_LENGTH) * 8; - } - - public static String encrypt(Key key, String message) { - try { - calculateKeyLength(key, message); - Cipher cipher = Cipher.getInstance(ENCRYPTION_ALGORITHM, PROVIDER); - cipher.init(Cipher.ENCRYPT_MODE, key); - CipherInputStream cis = new CipherInputStream(new ByteArrayInputStream(message.getBytes(Charsets.UTF_8)), cipher); - byte[] encrypted = IOUtils.toByteArray(cis); - return Base64.getEncoder().encodeToString(encrypted); - } catch (Exception ex) { - throw new RuntimeException(ex); - } - } - - public static String decrypt(Key key, String message) { - try { - Cipher cipher = Cipher.getInstance(ENCRYPTION_ALGORITHM, PROVIDER); - cipher.init(Cipher.DECRYPT_MODE, key); - byte[] decoded = Base64.getDecoder().decode(message); - byte[] plainTextArray = cipher.doFinal(decoded); - return new String(plainTextArray, Charsets.UTF_8); - } catch (Exception ex) { - throw new RuntimeException(ex); - } - } - - private static boolean writePemFile(Key key, String fileName, String description) { - return writePemFile(key, fileName, description, false); - } - - private static boolean writePemFile(Key key, String fileName, String description, boolean sshFormat) { - try (KeyFile kf = sshFormat ? new KeyFile(key, description, EncryptionType.SSH) : new KeyFile(key, description)) { - kf.write(fileName); - } - return Files.exists(Paths.get(fileName)); - } - - private static void calculateKeyLength(Key key, String message) throws IllegalBlockSizeException { - int keyLength = ((RSAKey) key).getModulus().bitLength(); - int requiredKeyLength = calculateRequiredKeyLength(message); - if (keyLength < requiredKeyLength) { - throw new IllegalBlockSizeException(String.format("RSA key size of %d is not large enough to encrypt message of length %d. " - + "Increase key size to a minimum of %d and re-encrypt with new key", keyLength, message.length(), requiredKeyLength)); - } - } -} diff --git a/src/main/java/net/locusworks/common/crypto/SSHEncodedKeySpec.java b/src/main/java/net/locusworks/common/crypto/SSHEncodedKeySpec.java deleted file mode 100644 index 8da2a4d..0000000 --- a/src/main/java/net/locusworks/common/crypto/SSHEncodedKeySpec.java +++ /dev/null @@ -1,64 +0,0 @@ -package net.locusworks.common.crypto; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.math.BigInteger; -import java.security.spec.EncodedKeySpec; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.RSAPublicKeySpec; -import java.util.Arrays; -import java.util.Base64; - -import net.locusworks.common.Charsets; -import net.locusworks.common.io.IOUtils; - -import static net.locusworks.common.utils.Checks.checkArguments; -import static net.locusworks.common.utils.Utils.get; -import static net.locusworks.common.utils.Utils.size; - -public class SSHEncodedKeySpec extends EncodedKeySpec { - - private static final String SSH_MARKER = "ssh-rsa"; - - public SSHEncodedKeySpec(byte[] encodedKey) { - super(encodedKey); - } - - public RSAPublicKeySpec convertToRSAPubKeySpec() throws InvalidKeySpecException { - try { - byte[] data = this.getEncoded(); - InputStream stream = new ByteArrayInputStream(data); - Iterable parts = Arrays.asList(IOUtils.toString(stream, Charsets.UTF_8).split(" ")); - - checkArguments(size(parts) >= 2 && SSH_MARKER.equals(get(parts, 0)), "Bad format, should be: ssh-rsa AAB3..."); - stream = new ByteArrayInputStream(Base64.getDecoder().decode(String.valueOf(get(parts, 1)))); - String marker = new String(readLengthFirst(stream)); - checkArguments(SSH_MARKER.equals(marker), "Looking for marker %s but received %s", SSH_MARKER, marker); - BigInteger publicExponent = new BigInteger(readLengthFirst(stream)); - BigInteger modulus = new BigInteger(readLengthFirst(stream)); - return new RSAPublicKeySpec(modulus, publicExponent); - } catch (Exception ex) { - throw new InvalidKeySpecException(ex); - } - } - - @Override - public String getFormat() { - return null; - } - - private static byte[] readLengthFirst(InputStream in) throws IOException { - int[] bytes = new int[]{in.read(), in.read(), in.read(), in.read()}; - int length = 0; - int shift = 24; - for (int aByte : bytes) { - length += aByte << shift; - shift -= 8; - } - byte[] val = new byte[length]; - in.read(val); - return val; - } - -} diff --git a/src/main/java/net/locusworks/common/crypto/package-info.java b/src/main/java/net/locusworks/common/crypto/package-info.java deleted file mode 100644 index 99ddca3..0000000 --- a/src/main/java/net/locusworks/common/crypto/package-info.java +++ /dev/null @@ -1,5 +0,0 @@ -/** - * Package contains classes that help encrypting, decrypting, salting and hashing objects - * @author Isaac Parenteau - */ -package net.locusworks.common.crypto; \ No newline at end of file diff --git a/src/main/java/net/locusworks/common/exceptions/ApplicationException.java b/src/main/java/net/locusworks/common/exceptions/ApplicationException.java deleted file mode 100644 index 9b0f813..0000000 --- a/src/main/java/net/locusworks/common/exceptions/ApplicationException.java +++ /dev/null @@ -1,111 +0,0 @@ -package net.locusworks.common.exceptions; - -import java.io.Serial; - -/*** - * Custom exception class for the patch repository - * @author Isaac Parenteau - * - */ -public class ApplicationException extends Exception { - private final Integer code; - boolean success = false; - @Serial - private static final long serialVersionUID = 1L; - - public static ApplicationException egregiousServer() { - return new ApplicationException(9001, "Something went wrong. Please see logs for details"); - } - - public static ApplicationException invalidCreds() { - return new ApplicationException(9001, "Invalid credentials provided"); - } - - public static ApplicationException notLoggedIn() { - return new ApplicationException(9002, "Not logged in"); - } - - public static ApplicationException invalidEmailAddress() { - return new ApplicationException(9005, "Invalid email address"); - } - - public static ApplicationException actionNotPermitted() { - return new ApplicationException(9007, "Action not permitted"); - } - - public static ApplicationException actionNotPermitted(String message) { - return new ApplicationException(9007, "Action not permitted: " + message); - } - - public static ApplicationException passwordsNotEqual() { - return new ApplicationException(9008, "Passwords do not match"); - } - - public static ApplicationException unAuthorized() { - return new ApplicationException(9009, "unauthorized"); - } - - public static ApplicationException duplicateEntry(String message) { - return new ApplicationException(9100, message); - } - - public static ApplicationException duplicateEntry(String messageFmt, Object... args) { - return new ApplicationException(9100, String.format(messageFmt, args)); - } - - public static ApplicationException noEntryExists(String message) { - return new ApplicationException(9101, message); - } - - public static ApplicationException noEntryExists(String messageFmt, Object... items) { - return new ApplicationException(9101, String.format(messageFmt, items)); - } - - public static ApplicationException constraintViolation(String message) { - return new ApplicationException(9102, message); - } - - public static ApplicationException constraintViolation(String messageFmt, Object... items) { - return new ApplicationException(9102, String.format(messageFmt, items)); - } - - public static ApplicationException illegalArgument(String message) { - return new ApplicationException(9103, message); - } - - public static ApplicationException generic(String message) { - return new ApplicationException(9999, message); - } - - public static ApplicationException fromException(Throwable e) { - return new ApplicationException(9999, e); - } - - public ApplicationException(int code, Throwable e) { - this(code, e.getMessage(), e); - } - - public ApplicationException(int code, String message) { - super(message); - this.code = code; - } - - public ApplicationException(int code, String message, Throwable e) { - super(message, e); - this.code = code; - } - - public boolean getSuccess() { - return success; - } - - public Integer getCode() { - return code; - } - - @Override - public String getMessage() { - return super.getMessage(); - } - -} diff --git a/src/main/java/net/locusworks/common/immutables/Pair.java b/src/main/java/net/locusworks/common/immutables/Pair.java deleted file mode 100644 index 33b62cc..0000000 --- a/src/main/java/net/locusworks/common/immutables/Pair.java +++ /dev/null @@ -1,64 +0,0 @@ -package net.locusworks.common.immutables; - -import java.util.Objects; - -/** - * Class that holds two immutable objects as a pair - * - * @param class type of object 1 - * @param class type of object 2 - * @author Isaac Parenteau - * @version 1.0.0 - */ -public class Pair extends Unit { - - private V2 value2; - - /** - * Constructor with no values - */ - public Pair() { - super(); - } - - /** - * Constructor - * - * @param value1 Object 1 - * @param value2 Object 2 - */ - public Pair(V1 value1, V2 value2) { - super(value1); - this.value2 = value2; - } - - /** - * Set value2 - * - * @param value2 value to set it - */ - public void setValue2(V2 value2) { - if (Objects.nonNull(this.value2)) { - throw new IllegalArgumentException("Value2 already set. Cannot change"); - } - this.value2 = value2; - } - - /** - * Get value2 - * - * @return value2 - */ - public V2 getValue2() { - return this.value2; - } - - @Override - public boolean equals(Object other) { - if (other == null) return false; - if (!(other instanceof Pair pair)) return false; - - return this.getValue2().equals(pair.getValue2()) && - this.getValue1().equals(pair.getValue1()); - } -} diff --git a/src/main/java/net/locusworks/common/immutables/Triplet.java b/src/main/java/net/locusworks/common/immutables/Triplet.java deleted file mode 100644 index 3abd5df..0000000 --- a/src/main/java/net/locusworks/common/immutables/Triplet.java +++ /dev/null @@ -1,67 +0,0 @@ -package net.locusworks.common.immutables; - -import java.util.Objects; - -/** - * Class that holds three immutable objects as triplets - * - * @param class type of object 1 - * @param class type of object 2 - * @param class type of object 3 - * @author Isaac Parenteau - * @version 1.0.0 - */ -public class Triplet extends Pair { - - private V3 value3; - - /** - * default constructor with no values - */ - public Triplet() { - super(); - } - - /** - * Constructor - * - * @param value1 Object 1 - * @param value2 Object 2 - * @param value3 Object 3 - */ - public Triplet(V1 value1, V2 value2, V3 value3) { - super(value1, value2); - this.value3 = value3; - } - - /** - * Set value 3 - * - * @param value3 value 3 - */ - public void setValue3(V3 value3) { - if (Objects.nonNull(this.value3)) { - throw new IllegalArgumentException("Value3 already set. Cannot change"); - } - this.value3 = value3; - } - - /** - * Get value 3 - * - * @return value 3 - */ - public V3 getValue3() { - return value3; - } - - @Override - public boolean equals(Object other) { - if (other == null) return false; - if (!(other instanceof Triplet triplet)) return false; - - return this.getValue3().equals(triplet.getValue3()) && - this.getValue2().equals(triplet.getValue2()) && - this.getValue1().equals(triplet.getValue1()); - } -} diff --git a/src/main/java/net/locusworks/common/immutables/Unit.java b/src/main/java/net/locusworks/common/immutables/Unit.java deleted file mode 100644 index 90d667b..0000000 --- a/src/main/java/net/locusworks/common/immutables/Unit.java +++ /dev/null @@ -1,58 +0,0 @@ -package net.locusworks.common.immutables; - -import java.util.Objects; - -/** - * Class that holds three immutable objects as triplets - * - * @param class type of object 1 - * @author Isaac Parenteau - * @version 1.0.0 - */ -public class Unit { - - private V1 value1; - - /** - * Default constructor with no values - */ - public Unit() { - } - - /** - * Constructor - * - * @param value1 value 1 - */ - public Unit(V1 value1) { - this.value1 = value1; - } - - /** - * Set value 1 - * - * @param value1 value 1 - */ - public void setValue1(V1 value1) { - if (Objects.nonNull(this.value1)) { - throw new IllegalArgumentException("Value1 already set. Cannot change"); - } - this.value1 = value1; - } - - /** - * Get value 1 - * - * @return value1 - */ - public V1 getValue1() { - return value1; - } - - @Override - public boolean equals(Object other) { - if (other == null) return false; - if (!(other instanceof Unit)) return false; - return this.getValue1().equals(((Unit) other).getValue1()); - } -} diff --git a/src/main/java/net/locusworks/common/interfaces/AutoCloseableIterator.java b/src/main/java/net/locusworks/common/interfaces/AutoCloseableIterator.java deleted file mode 100644 index af6d1d5..0000000 --- a/src/main/java/net/locusworks/common/interfaces/AutoCloseableIterator.java +++ /dev/null @@ -1,10 +0,0 @@ -package net.locusworks.common.interfaces; - -import java.util.Iterator; - -public interface AutoCloseableIterator extends Iterator, AutoCloseable { - - @Override - void close(); - -} diff --git a/src/main/java/net/locusworks/common/interfaces/PersistableRequest.java b/src/main/java/net/locusworks/common/interfaces/PersistableRequest.java deleted file mode 100644 index 9bbfc69..0000000 --- a/src/main/java/net/locusworks/common/interfaces/PersistableRequest.java +++ /dev/null @@ -1,5 +0,0 @@ -package net.locusworks.common.interfaces; - -public interface PersistableRequest { - -} diff --git a/src/main/java/net/locusworks/common/interfaces/ThrowingConsumer.java b/src/main/java/net/locusworks/common/interfaces/ThrowingConsumer.java deleted file mode 100644 index 85964fa..0000000 --- a/src/main/java/net/locusworks/common/interfaces/ThrowingConsumer.java +++ /dev/null @@ -1,6 +0,0 @@ -package net.locusworks.common.interfaces; - -@FunctionalInterface -public interface ThrowingConsumer { - void accept(T t) throws E; -} diff --git a/src/main/java/net/locusworks/common/io/IOUtils.java b/src/main/java/net/locusworks/common/io/IOUtils.java deleted file mode 100644 index bbebcf4..0000000 --- a/src/main/java/net/locusworks/common/io/IOUtils.java +++ /dev/null @@ -1,359 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package net.locusworks.common.io; - -import java.io.BufferedReader; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.Reader; -import java.io.StringWriter; -import java.io.Writer; -import java.nio.charset.Charset; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import net.locusworks.common.Charsets; - -public class IOUtils { - - private static final int DEFAULT_BUFFER_SIZE = 1024 * 4; - public static final int EOF = -1; - - /** - * Gets the contents of an InputStream as a list of Strings, - * one entry per line, using the specified character encoding. - *

- * This method buffers the input internally, so there is no need to use a - * BufferedInputStream. - * - * @param stream the InputStream to read from, not null - * @param charset the encoding to use, null means platform default - * @return the list of Strings, never null - * @throws NullPointerException if the input is null - * @throws IOException if an I/O error occurs - */ - public static List readLines(final InputStream stream, final Charset charset) throws IOException { - final InputStreamReader reader = new InputStreamReader(stream, charset); - return readLines(reader); - } - - /** - * Gets the contents of a Reader as a list of Strings, - * one entry per line. - *

- * This method buffers the input internally, so there is no need to use a - * BufferedReader. - * - * @param input the Reader to read from, not null - * @return the list of Strings, never null - * @throws NullPointerException if the input is null - * @throws IOException if an I/O error occurs - */ - public static List readLines(final Reader input) throws IOException { - final BufferedReader reader = toBufferedReader(input); - final List list = new ArrayList<>(); - for (String line = reader.readLine(); line != null; line = reader.readLine()) { - list.add(line); - } - return list; - } - - /** - * Returns the given reader if it is a {@link BufferedReader}, otherwise creates a BufferedReader from the given - * reader. - * - * @param reader the reader to wrap or return (not null) - * @return the given reader or a new {@link BufferedReader} for the given reader - * @throws NullPointerException if the input parameter is null - * @see #buffer(Reader) - */ - public static BufferedReader toBufferedReader(final Reader reader) { - return reader instanceof BufferedReader ? (BufferedReader) reader : new BufferedReader(reader); - } - - /** - * Gets the contents of an InputStream as a byte[]. - *

- * This method buffers the input internally, so there is no need to use a - * BufferedInputStream. - * - * @param input the InputStream to read from - * @return the requested byte array - * @throws NullPointerException if the input is null - * @throws IOException if an I/O error occurs - */ - public static byte[] toByteArray(final InputStream input) throws IOException { - try (final ByteArrayOutputStream output = new ByteArrayOutputStream()) { - copy(input, output); - return output.toByteArray(); - } - } - - /** - * Copies bytes from an InputStream to an - * OutputStream. - *

- * This method buffers the input internally, so there is no need to use a - * BufferedInputStream. - *

- * Large streams (over 2GB) will return a bytes copied value of - * -1 after the copy has completed since the correct - * number of bytes cannot be returned as an int. For large streams - * use the copyLarge(InputStream, OutputStream) method. - * - * @param input the InputStream to read from - * @param output the OutputStream to write to - * @return the number of bytes copied, or -1 if > Integer.MAX_VALUE - * @throws NullPointerException if the input or output is null - * @throws IOException if an I/O error occurs - */ - public static int copy(final InputStream input, final OutputStream output) throws IOException { - final long count = copyLarge(input, output); - if (count > Integer.MAX_VALUE) { - return -1; - } - return (int) count; - } - - /** - * Copies bytes from an InputStream to an OutputStream using an internal buffer of the - * given size. - *

- * This method buffers the input internally, so there is no need to use a BufferedInputStream. - *

- * - * @param input the InputStream to read from - * @param output the OutputStream to write to - * @param bufferSize the bufferSize used to copy from the input to the output - * @return the number of bytes copied - * @throws NullPointerException if the input or output is null - * @throws IOException if an I/O error occurs - */ - public static long copy(final InputStream input, final OutputStream output, final int bufferSize) - throws IOException { - return copyLarge(input, output, new byte[bufferSize]); - } - - /** - * Copies bytes from an InputStream to chars on a - * Writer using the specified character encoding. - *

- * This method buffers the input internally, so there is no need to use a - * BufferedInputStream. - *

- * This method uses {@link InputStreamReader}. - * - * @param input the InputStream to read from - * @param output the Writer to write to - * @param inputEncoding the encoding to use for the input stream, null means platform default - * @throws NullPointerException if the input or output is null - * @throws IOException if an I/O error occurs - */ - public static void copy(final InputStream input, final Writer output, final Charset inputEncoding) - throws IOException { - final InputStreamReader in = new InputStreamReader(input, inputEncoding); - copy(in, output); - } - - /** - * Copies chars from a Reader to a Writer. - *

- * This method buffers the input internally, so there is no need to use a - * BufferedReader. - *

- * Large streams (over 2GB) will return a chars copied value of - * -1 after the copy has completed since the correct - * number of chars cannot be returned as an int. For large streams - * use the copyLarge(Reader, Writer) method. - * - * @param input the Reader to read from - * @param output the Writer to write to - * @return the number of characters copied, or -1 if > Integer.MAX_VALUE - * @throws NullPointerException if the input or output is null - * @throws IOException if an I/O error occurs - */ - public static int copy(final Reader input, final Writer output) throws IOException { - final long count = copyLarge(input, output); - if (count > Integer.MAX_VALUE) { - return -1; - } - return (int) count; - } - - /** - * Copies chars from a large (over 2GB) Reader to a Writer. - *

- * This method buffers the input internally, so there is no need to use a - * BufferedReader. - *

- * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}. - * - * @param input the Reader to read from - * @param output the Writer to write to - * @return the number of characters copied - * @throws NullPointerException if the input or output is null - * @throws IOException if an I/O error occurs - */ - public static long copyLarge(final Reader input, final Writer output) throws IOException { - return copyLarge(input, output, new char[DEFAULT_BUFFER_SIZE]); - } - - /** - * Copies bytes from a large (over 2GB) InputStream to an - * OutputStream. - *

- * This method buffers the input internally, so there is no need to use a - * BufferedInputStream. - *

- * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}. - * - * @param input the InputStream to read from - * @param output the OutputStream to write to - * @return the number of bytes copied - * @throws NullPointerException if the input or output is null - * @throws IOException if an I/O error occurs - */ - public static long copyLarge(final InputStream input, final OutputStream output) - throws IOException { - return copy(input, output, DEFAULT_BUFFER_SIZE); - } - - /** - * Copies bytes from a large (over 2GB) InputStream to an - * OutputStream. - *

- * This method uses the provided buffer, so there is no need to use a - * BufferedInputStream. - *

- * - * @param input the InputStream to read from - * @param output the OutputStream to write to - * @param buffer the buffer to use for the copy - * @return the number of bytes copied - * @throws NullPointerException if the input or output is null - * @throws IOException if an I/O error occurs - */ - public static long copyLarge(final InputStream input, final OutputStream output, final byte[] buffer) - throws IOException { - long count = 0; - int n; - while (EOF != (n = input.read(buffer))) { - output.write(buffer, 0, n); - count += n; - } - return count; - } - - /** - * Copies chars from a large (over 2GB) Reader to a Writer. - *

- * This method uses the provided buffer, so there is no need to use a - * BufferedReader. - *

- * - * @param input the Reader to read from - * @param output the Writer to write to - * @param buffer the buffer to be used for the copy - * @return the number of characters copied - * @throws NullPointerException if the input or output is null - * @throws IOException if an I/O error occurs - */ - public static long copyLarge(final Reader input, final Writer output, final char[] buffer) throws IOException { - long count = 0; - int n; - while (EOF != (n = input.read(buffer))) { - output.write(buffer, 0, n); - count += n; - } - return count; - } - - /** - * Gets the contents of an InputStream as a String - * using the specified character encoding. - *

- * This method buffers the input internally, so there is no need to use a - * BufferedInputStream. - *

- * - * @param input the InputStream to read from - * @param encoding the encoding to use, null means platform default - * @return the requested String - * @throws NullPointerException if the input is null - * @throws IOException if an I/O error occurs - */ - public static String toString(final InputStream input, final Charset encoding) throws IOException { - try (final StringWriter sw = new StringWriter()) { - copy(input, sw, encoding); - return sw.toString(); - } - } - - public static void writeStringToFile(String fileName, String data) throws IOException { - writeStringToFile(Paths.get(fileName), data, Charsets.UTF_8); - } - - - public static void writeStringToFile(String fileName, String data, Charset charset) throws IOException { - writeStringToFile(Paths.get(fileName), data, charset); - } - - public static void writeStringToFile(Path file, String data) throws IOException { - writeStringToFile(file, data, Charsets.UTF_8); - } - - @Deprecated - public static void writeStringToFile(File file, String data, Charset charset) throws IOException { - writeStringToFile(file.toPath(), data, charset); - } - - public static void writeStringToFile(Path file, String data, Charset charset) throws IOException { - try (Writer writer = Files.newBufferedWriter(file, charset)) { - writer.write(data); - writer.flush(); - } - } - - public static void deleteFile(String fileName) { - deleteFile(Paths.get(fileName)); - } - - @Deprecated - public static void deleteFile(File file) { - deleteFile(file.toPath()); - } - - public static void deleteFile(Path file) { - try { - Files.deleteIfExists(file); - } catch (IOException ex) { - throw new IllegalArgumentException(ex); - } - } - - public static void deleteFiles(String... fileNames) { - Arrays.asList(fileNames).forEach(file -> deleteFile(file)); - } -} diff --git a/src/main/java/net/locusworks/common/migration/BaseMigrationManager.java b/src/main/java/net/locusworks/common/migration/BaseMigrationManager.java deleted file mode 100644 index c9c5b2f..0000000 --- a/src/main/java/net/locusworks/common/migration/BaseMigrationManager.java +++ /dev/null @@ -1,12 +0,0 @@ -package net.locusworks.common.migration; - -import java.util.ArrayList; -import java.util.List; - -public abstract class BaseMigrationManager { - - protected List migrations = new ArrayList<>(); - - public abstract void migrate() throws Exception; - -} diff --git a/src/main/java/net/locusworks/common/migration/MigrationCallback.java b/src/main/java/net/locusworks/common/migration/MigrationCallback.java deleted file mode 100644 index 0d7f157..0000000 --- a/src/main/java/net/locusworks/common/migration/MigrationCallback.java +++ /dev/null @@ -1,6 +0,0 @@ -package net.locusworks.common.migration; - -@FunctionalInterface -public interface MigrationCallback { - void results(String msg); -} diff --git a/src/main/java/net/locusworks/common/migration/MigrationItem.java b/src/main/java/net/locusworks/common/migration/MigrationItem.java deleted file mode 100644 index ac881b5..0000000 --- a/src/main/java/net/locusworks/common/migration/MigrationItem.java +++ /dev/null @@ -1,74 +0,0 @@ -package net.locusworks.common.migration; - -import java.util.Arrays; - -import org.flywaydb.core.Flyway; -import org.flywaydb.core.api.MigrationInfo; -import org.flywaydb.core.internal.info.MigrationInfoDumper; - -public class MigrationItem { - - protected Flyway flyway = null; - protected MigrationInfo[] pendingMigrations; - protected MigrationInfo[] allMigrations; - private final MigrationCallback callback; - - public MigrationItem(Flyway flyway, MigrationCallback callback) { - this.allMigrations = flyway.info().all(); - this.pendingMigrations = flyway.info().pending(); - this.flyway = flyway; - this.callback = callback; - } - - public MigrationItem(Flyway flyway) { - this(flyway, null); - } - - public String[] getSchemas() { - return flyway.getConfiguration().getSchemas(); - } - - public int qtyPending() { - return pendingMigrations.length; - } - - public void repair() { - // no harm in calling migrate even if none pending, log will contain - // assurance that the migrations were verified - try { - String schemas = Arrays.toString(getSchemas()).replace("[", "").replace("]", ""); - - String status = String.format("Repair status for %s:%n%s", schemas, getAllMigrationsLog()); - - callback(status); - - flyway.repair(); - } catch (Exception e) { - String message = String.format("%nDatabase migration error:%n %s %nPortal webapp cannot continue.", e.getMessage()); - throw new RuntimeException(message, e); - } - } - - public void migrate() { - // no harm in calling migrate even if none pending, log will contain - // assurance that the migrations were verified - try { - String schemas = Arrays.toString(getSchemas()).replace("[", "").replace("]", ""); - String status = String.format("Repair status for %s:%n%s", schemas, getAllMigrationsLog()); - callback(status); - flyway.migrate(); - } catch (Exception e) { - String message = String.format("%nDatabase migration error:%n %s %nPortal webapp cannot continue.", e.getMessage()); - throw new RuntimeException(message, e); - } - } - - public String getAllMigrationsLog() { - return MigrationInfoDumper.dumpToAsciiTable(allMigrations); - } - - private void callback(String msg) { - if (this.callback != null) this.callback.results(msg); - } - -} diff --git a/src/main/java/net/locusworks/common/net/HttpClientHelper.java b/src/main/java/net/locusworks/common/net/HttpClientHelper.java deleted file mode 100644 index 04922ef..0000000 --- a/src/main/java/net/locusworks/common/net/HttpClientHelper.java +++ /dev/null @@ -1,79 +0,0 @@ -package net.locusworks.common.net; - - -import net.locusworks.common.net.ssl.SSLManager; -import org.apache.hc.client5.http.classic.HttpClient; -import org.apache.hc.client5.http.classic.methods.HttpGet; -import org.apache.hc.client5.http.impl.classic.HttpClientBuilder; -import org.apache.hc.core5.http.HttpEntity; -import org.apache.hc.core5.http.io.entity.EntityUtils; - -public class HttpClientHelper { - - public enum HttpSchema { - HTTP, - HTTPS; - - public static HttpSchema findEnum(String value) { - for (HttpSchema schema : values()) { - if (value.equalsIgnoreCase(schema.toString())) { - return schema; - } - } - return null; - } - } - - private static final String[] TLS = new String[]{"TLSv1", "TLSv1.1", "TLSv1.2"}; - - private final HttpClient client; - private final String baseUrl; - - /** - * Constructor to handle http connection - * - * @param protocol protocol to use (http or https) - * @param host the host url - * @param port the host port - * @throws Exception exception - */ - public HttpClientHelper(String protocol, String host, String port) throws Exception { - HttpSchema schema = HttpSchema.findEnum(protocol); - if (schema == null) { - throw new Exception("Unable to find http schema of " + protocol); - } - this.baseUrl = String.format("%s://%s:%s", schema.toString().toLowerCase(), host, port); - this.client = createClient(schema); - } - - private HttpClient createClient(HttpSchema schema) throws Exception { - HttpClientBuilder builder = HttpClientBuilder.create(); - - if (schema == HttpSchema.HTTP) { - return builder.build(); - } - - return SSLManager.getTrustAllTLSClient(); - } - - /** - * Get the http GET response code - * - * @param endpoint endpoint to get the response from - * @return responseCode - * @throws Exception general exception - */ - public Integer getResponseCode(String endpoint) throws Exception { - String url = this.baseUrl + endpoint; - - return this.client.execute(new HttpGet(url), response -> { - HttpEntity entity = response.getEntity(); - int responseCode = response.getCode(); - EntityUtils.consume(entity); - return responseCode; - }); - } - - ; - -} diff --git a/src/main/java/net/locusworks/common/net/certmanagers/TrustAllCertsManager.java b/src/main/java/net/locusworks/common/net/certmanagers/TrustAllCertsManager.java deleted file mode 100644 index 7ef740a..0000000 --- a/src/main/java/net/locusworks/common/net/certmanagers/TrustAllCertsManager.java +++ /dev/null @@ -1,28 +0,0 @@ -package net.locusworks.common.net.certmanagers; - -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; - -import javax.net.ssl.TrustManager; -import javax.net.ssl.X509TrustManager; - -public class TrustAllCertsManager implements X509TrustManager { - - @Override - public void checkClientTrusted(X509Certificate[] arg0, String arg1) { - } - - @Override - public void checkServerTrusted(X509Certificate[] arg0, String arg1) { - } - - @Override - public X509Certificate[] getAcceptedIssuers() { - return null; - } - - public static TrustManager[] trustAllCerts() { - return new TrustManager[]{new TrustAllCertsManager()}; - } - -} diff --git a/src/main/java/net/locusworks/common/net/hostverifiers/AllHostValidVerifier.java b/src/main/java/net/locusworks/common/net/hostverifiers/AllHostValidVerifier.java deleted file mode 100644 index f098cba..0000000 --- a/src/main/java/net/locusworks/common/net/hostverifiers/AllHostValidVerifier.java +++ /dev/null @@ -1,13 +0,0 @@ -package net.locusworks.common.net.hostverifiers; - -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.SSLSession; - -public class AllHostValidVerifier implements HostnameVerifier { - - @Override - public boolean verify(String arg0, SSLSession arg1) { - return true; - } - -} diff --git a/src/main/java/net/locusworks/common/net/ssl/SSLManager.java b/src/main/java/net/locusworks/common/net/ssl/SSLManager.java deleted file mode 100644 index a2e332b..0000000 --- a/src/main/java/net/locusworks/common/net/ssl/SSLManager.java +++ /dev/null @@ -1,41 +0,0 @@ -package net.locusworks.common.net.ssl; - -import java.security.KeyManagementException; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; - -import javax.net.ssl.SSLContext; -import javax.net.ssl.TrustManager; - - -import net.locusworks.common.net.certmanagers.TrustAllCertsManager; -import org.apache.hc.client5.http.classic.HttpClient; -import org.apache.hc.client5.http.impl.classic.HttpClients; -import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder; -import org.apache.hc.client5.http.io.HttpClientConnectionManager; -import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy; -import org.apache.hc.client5.http.ssl.TlsSocketStrategy; - -public class SSLManager { - - public static final String[] TLS = new String[] {"TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3"}; - - public static HttpClient getTrustAllTLSClient() throws NoSuchAlgorithmException, KeyManagementException { - TrustManager[] trustAllCerts = new TrustManager[]{new TrustAllCertsManager()}; - //Setup the ssl instance using tls - SSLContext sslContext = SSLContext.getInstance("TLS"); - sslContext.init(null, trustAllCerts, new SecureRandom()); - TlsSocketStrategy tlsStrategy = new DefaultClientTlsStrategy(sslContext); - - HttpClientConnectionManager connectionManager = PoolingHttpClientConnectionManagerBuilder.create() - .setTlsSocketStrategy(tlsStrategy) - .build(); - - return HttpClients.custom() - .setConnectionManager(connectionManager) - .build(); - } - - private SSLManager() { } - -} diff --git a/src/main/java/net/locusworks/common/objectmapper/ObjectMapperError.java b/src/main/java/net/locusworks/common/objectmapper/ObjectMapperError.java deleted file mode 100644 index 973725e..0000000 --- a/src/main/java/net/locusworks/common/objectmapper/ObjectMapperError.java +++ /dev/null @@ -1,13 +0,0 @@ -package net.locusworks.common.objectmapper; - -/** - * Error handler for the object mapper class - * - * @author Isaac Parenteau - * @version 1.0.0 - * @date 02/15/2018 - * - */ -public interface ObjectMapperError { - void getError(Throwable e); -} diff --git a/src/main/java/net/locusworks/common/objectmapper/ObjectMapperHelper.java b/src/main/java/net/locusworks/common/objectmapper/ObjectMapperHelper.java deleted file mode 100644 index 92fe176..0000000 --- a/src/main/java/net/locusworks/common/objectmapper/ObjectMapperHelper.java +++ /dev/null @@ -1,157 +0,0 @@ -package net.locusworks.common.objectmapper; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.PropertyAccessor; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; - -/** - * Object mapper to map to convert objects to json string or - * json string back to object - * - * @author Isaac Parenteau - * @version 1.0.0 - * @date 02/15/2018 - */ -public class ObjectMapperHelper { - - private static final ObjectMapper mapper; - - static { - mapper = new ObjectMapper(); - mapper.setDefaultPropertyInclusion(Include.NON_NULL); - mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY); - } - - /** - * Write an object out to json - * - * @param object Object to convert to json - * @return return a string representation of the object converted to json - */ - public static ObjectMapperResults writeValue(Object object) { - String results = ""; - try { - results = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(object); - } catch (Exception ex) { - try { - GsonBuilder gsonBuilder = new GsonBuilder(); - gsonBuilder.setPrettyPrinting(); - Gson gson = gsonBuilder.create(); - results = gson.toJson(object); - } catch (Throwable e) { - return new ObjectMapperResults<>(e); - } - } - return new ObjectMapperResults<>(results); - } - - /** - * Convert binary data to an object - * - * @param src Binary data to convert - * @param clazz Class to convert the data to - * @param The expected class of the value - * @return the object populated with the data in the json string - */ - public static ObjectMapperResults readValue(byte[] src, Class clazz) { - try { - return new ObjectMapperResults(mapper.readValue(src, clazz)); - } catch (Exception ex) { - return new ObjectMapperResults(ex); - } - } - - /** - * Convert a json string to an object - * - * @param src Json String - * @param clazz Class to convert the json string to - * @param The expected class of the value - * @return the object populated with the data in the json string - */ - public static ObjectMapperResults readValue(String src, Class clazz) { - try { - return new ObjectMapperResults(mapper.readValue(src, clazz)); - } catch (Exception ex) { - return new ObjectMapperResults(ex); - } - } - - /** - * Convert an java object to a class - * - * @param src Object to convert - * @param clazz Class to convert the object to - * @param The expected class of the value - * @return the object populated with the data in the json string - */ - public static ObjectMapperResults readValue(Object src, Class clazz) { - try { - if (src instanceof String) { - return readValue((String) src, clazz); - } - return readValue(mapper.writeValueAsString(src), clazz); - } catch (Exception ex) { - return new ObjectMapperResults(ex); - } - } - - /** - * Converts an object to a list - * - * @param object Object to convert - * @param objectClass Class to convert the object to - * @param The expected class of the object - * @return the object list populated with the data in the json string - */ - public static > ObjectMapperListResults> readListValue(Object object, Class objectClass) { - return readListValue(object, objectClass, ArrayList.class); - } - - /** - * Converts an object to a list - * - * @param object Object to convert - * @param objectClass Class to convert the object to - * @param listClass List type to make - * @param The expected class of the object - * @param The expect class of the list - * @return the object list populated with the data in the json string - */ - public static > ObjectMapperListResults> readListValue(Object object, Class objectClass, Class listClass) { - try { - if (object instanceof String) { - return readListValue((String) object, objectClass, listClass); - } - return readListValue(mapper.writeValueAsString(object), objectClass, listClass); - } catch (Exception ex) { - return new ObjectMapperListResults<>(ex); - } - } - - /** - * Converts an object to a list - * - * @param src Source to convert - * @param objectClass Class to convert the object to - * @param listClass List type to make - * @param The expected class of the object - * @param The expect class of the list - * @return the object list populated with the data in the json string - */ - public static > ObjectMapperListResults> readListValue(String src, Class objectClass, Class listClass) { - try { - List item = mapper.readValue(src, mapper.getTypeFactory().constructCollectionType(listClass, objectClass)); - return new ObjectMapperListResults<>(item); - } catch (Exception ex) { - return new ObjectMapperListResults<>(ex); - } - } -} diff --git a/src/main/java/net/locusworks/common/objectmapper/ObjectMapperListResults.java b/src/main/java/net/locusworks/common/objectmapper/ObjectMapperListResults.java deleted file mode 100644 index 5bbcd8f..0000000 --- a/src/main/java/net/locusworks/common/objectmapper/ObjectMapperListResults.java +++ /dev/null @@ -1,56 +0,0 @@ -package net.locusworks.common.objectmapper; - -import java.util.Collection; - -/** - * Holds the results from the object mapper list conversion - * - * @param class type of the object mapper - * @author Isaac Parenteau - * @version 1.0.0 - * @date 02/15/2018 - */ -public class ObjectMapperListResults> extends ObjectMapperResults { - - /** - * Constructor - * - * @param results results from the conversion - */ - public ObjectMapperListResults(T results) { - this(results, null); - } - - /** - * Constructor - * - * @param exception exception that was thrown during conversion - */ - public ObjectMapperListResults(Throwable exception) { - this(null, exception); - } - - /** - * Constructor - * - * @param results results from the conversion - * @param exception exception that was thrown during conversion - */ - public ObjectMapperListResults(T results, Throwable exception) { - super(results, exception); - } - - /** - * Add the error handler to the results to retrieve the error that caused - * the exception - * - * @param error the error handler to use - * @return this - */ - public ObjectMapperListResults withErrorHandler(ObjectMapperError error) { - if (this.hasError() && error != null) { - error.getError(this.getException()); - } - return this; - } -} \ No newline at end of file diff --git a/src/main/java/net/locusworks/common/objectmapper/ObjectMapperResults.java b/src/main/java/net/locusworks/common/objectmapper/ObjectMapperResults.java deleted file mode 100644 index 807e5de..0000000 --- a/src/main/java/net/locusworks/common/objectmapper/ObjectMapperResults.java +++ /dev/null @@ -1,103 +0,0 @@ -package net.locusworks.common.objectmapper; - -/** - * Holds the results from the object mapper list conversion - * - * @param class type of the object being converted from json to object - * @author Isaac Parenteau - * @version 1.0.0 - * @date 02/15/2018 - */ -public class ObjectMapperResults { - - private Throwable exception; - private T results; - - /** - * Constructor - * - * @param results results from the conversion - */ - public ObjectMapperResults(T results) { - this(results, null); - } - - /** - * Constructor - * - * @param exception exception that was thrown during conversion - */ - public ObjectMapperResults(Throwable exception) { - this(null, exception); - } - - /** - * Constructor - * - * @param results results from the conversion - * @param exception exception that was thrown during conversion - */ - public ObjectMapperResults(T results, Throwable exception) { - this.results = results; - this.exception = exception; - } - - /** - * get the exception that happened during conversion - * - * @return exception - */ - public Throwable getException() { - return exception; - } - - /** - * Set the exception - * - * @param exception - */ - public void setException(Throwable exception) { - this.exception = exception; - } - - /** - * Get the result - * - * @return the converted results - */ - public T getResults() { - return results; - } - - /** - * set the results - * - * @param results results to set - */ - public void setResults(T results) { - this.results = results; - } - - /** - * Check to see if the conversion caused an error - * - * @return true if there is an error, false otherwise - */ - public boolean hasError() { - return this.exception != null; - } - - /** - * Add the error handler to the results to retrieve the error that caused - * the exception - * - * @param error the error handler to use - * @return this - */ - public ObjectMapperResults withErrorHandler(ObjectMapperError error) { - if (this.hasError() && error != null) { - error.getError(this.getException()); - } - return this; - } -} diff --git a/src/main/java/net/locusworks/common/properties/ImmutableProperties.java b/src/main/java/net/locusworks/common/properties/ImmutableProperties.java deleted file mode 100644 index b8fbe2f..0000000 --- a/src/main/java/net/locusworks/common/properties/ImmutableProperties.java +++ /dev/null @@ -1,33 +0,0 @@ -package net.locusworks.common.properties; - -import java.io.Serial; -import java.util.Properties; - -public class ImmutableProperties extends Properties { - - @Serial - private static final long serialVersionUID = 65942088008978137L; - - public ImmutableProperties() { - super(); - } - - public ImmutableProperties(Properties props) { - super(); - if (props == null || props.isEmpty()) return; - - this.putAll(props); - } - - @Override - public synchronized Object setProperty(String key, String value) { - return put(key, value); - } - - public synchronized Object put(Object key, Object value) { - if (containsKey(key)) - throw new RuntimeException("Cannot change key value once its set: " + key); - return super.put(key, value); - } - -} diff --git a/src/main/java/net/locusworks/common/properties/OrderedProperties.java b/src/main/java/net/locusworks/common/properties/OrderedProperties.java deleted file mode 100644 index a8ca4d3..0000000 --- a/src/main/java/net/locusworks/common/properties/OrderedProperties.java +++ /dev/null @@ -1,977 +0,0 @@ -package net.locusworks.common.properties; - -import java.io.*; -import java.nio.charset.StandardCharsets; -import java.util.Collections; -import java.util.Date; -import java.util.Enumeration; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Set; - -/** - * The {@code Properties} class represents a persistent set of - * properties. The {@code Properties} can be saved to a stream - * or loaded from a stream. Each key and its corresponding value in - * the property list is a string. - *

- * A property list can contain another property list as its - * "defaults"; this second property list is searched if - * the property key is not found in the original property list. - *

- * Because {@code Properties} inherits from {@code Hashtable}, the - * {@code put} and {@code putAll} methods can be applied to a - * {@code Properties} object. Their use is strongly discouraged as they - * allow the caller to insert entries whose keys or values are not - * {@code Strings}. The {@code setProperty} method should be used - * instead. If the {@code store} or {@code save} method is called - * on a "compromised" {@code Properties} object that contains a - * non-{@code String} key or value, the call will fail. Similarly, - * the call to the {@code propertyNames} or {@code list} method - * will fail if it is called on a "compromised" {@code Properties} - * object that contains a non-{@code String} key. - * - *

- * The {@link #load(java.io.Reader) load(Reader)} / - * {@link #store(java.io.Writer, java.lang.String) store(Writer, String)} - * methods load and store properties from and to a character based stream - * in a simple line-oriented format specified below. - *

- * The {@link #load(java.io.InputStream) load(InputStream)} / - * {@link #store(java.io.OutputStream, java.lang.String) store(OutputStream, String)} - * methods work the same way as the load(Reader)/store(Writer, String) pair, except - * the input/output stream is encoded in ISO 8859-1 character encoding. - * Characters that cannot be directly represented in this encoding can be written using - * Unicode escapes as defined in section 3.3 of - * The Java™ Language Specification; - * only a single 'u' character is allowed in an escape - * sequence. The native2ascii tool can be used to convert property files to and - * from other character encodings. - * - *

The {@link #loadFromXML(InputStream)} and {@link - * #storeToXML(OutputStream, String, String)} methods load and store properties - * in a simple XML format. By default the UTF-8 character encoding is used, - * however a specific encoding may be specified if required. Implementations - * are required to support UTF-8 and UTF-16 and may support other encodings. - * An XML properties document has the following DOCTYPE declaration: - * - *

- * <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
- * 
- * Note that the system URI (http://java.sun.com/dtd/properties.dtd) is - * not accessed when exporting or importing properties; it merely - * serves as a string to uniquely identify the DTD, which is: - *
- *    <?xml version="1.0" encoding="UTF-8"?>
- *
- *    <!-- DTD for properties -->
- *
- *    <!ELEMENT properties ( comment?, entry* ) >
- *
- *    <!ATTLIST properties version CDATA #FIXED "1.0">
- *
- *    <!ELEMENT comment (#PCDATA) >
- *
- *    <!ELEMENT entry (#PCDATA) >
- *
- *    <!ATTLIST entry key CDATA #REQUIRED>
- * 
- * - *

This class is thread-safe: multiple threads can share a single - * Properties object without the need for external synchronization. - * - * @author Arthur van Hoff - * @author Michael McCloskey - * @author Xueming Shen - * @see native2ascii tool for Solaris - * @see native2ascii tool for Windows - * @since JDK1.0 - */ -public class OrderedProperties extends LinkedHashMap { - /** - * use serialVersionUID from JDK 1.1.X for interoperability - */ - @Serial - private static final long serialVersionUID = 4112578634023874840L; - - /** - * A property list that contains default values for any keys not - * found in this property list. - * - * @serial - */ - protected OrderedProperties defaults; - - /** - * Creates an empty property list with no default values. - */ - public OrderedProperties() { - this(null); - } - - /** - * Creates an empty property list with the specified defaults. - * - * @param defaults the defaults. - */ - public OrderedProperties(OrderedProperties defaults) { - this.defaults = defaults; - } - - /** - * Calls the Hashtable method {@code put}. Provided for - * parallelism with the getProperty method. Enforces use of - * strings for property keys and values. The value returned is the - * result of the Hashtable call to {@code put}. - * - * @param key the key to be placed into this property list. - * @param value the value corresponding to key. - * @return the previous value of the specified key in this property - * list, or {@code null} if it did not have one. - * @see #getProperty - * @since 1.2 - */ - public synchronized Object setProperty(String key, String value) { - return put(key, value); - } - - - /** - * Reads a property list (key and element pairs) from the input - * character stream in a simple line-oriented format. - *

- * Properties are processed in terms of lines. There are two - * kinds of line, natural lines and logical lines. - * A natural line is defined as a line of - * characters that is terminated either by a set of line terminator - * characters ({@code \n} or {@code \r} or {@code \r\n}) - * or by the end of the stream. A natural line may be either a blank line, - * a comment line, or hold all or some of a key-element pair. A logical - * line holds all the data of a key-element pair, which may be spread - * out across several adjacent natural lines by escaping - * the line terminator sequence with a backslash character - * {@code \}. Note that a comment line cannot be extended - * in this manner; every natural line that is a comment must have - * its own comment indicator, as described below. Lines are read from - * input until the end of the stream is reached. - * - *

- * A natural line that contains only white space characters is - * considered blank and is ignored. A comment line has an ASCII - * {@code '#'} or {@code '!'} as its first non-white - * space character; comment lines are also ignored and do not - * encode key-element information. In addition to line - * terminators, this format considers the characters space - * ({@code ' '}, {@code '\u005Cu0020'}), tab - * ({@code '\t'}, {@code '\u005Cu0009'}), and form feed - * ({@code '\f'}, {@code '\u005Cu000C'}) to be white - * space. - * - *

- * If a logical line is spread across several natural lines, the - * backslash escaping the line terminator sequence, the line - * terminator sequence, and any white space at the start of the - * following line have no affect on the key or element values. - * The remainder of the discussion of key and element parsing - * (when loading) will assume all the characters constituting - * the key and element appear on a single natural line after - * line continuation characters have been removed. Note that - * it is not sufficient to only examine the character - * preceding a line terminator sequence to decide if the line - * terminator is escaped; there must be an odd number of - * contiguous backslashes for the line terminator to be escaped. - * Since the input is processed from left to right, a - * non-zero even number of 2n contiguous backslashes - * before a line terminator (or elsewhere) encodes n - * backslashes after escape processing. - * - *

- * The key contains all of the characters in the line starting - * with the first non-white space character and up to, but not - * including, the first unescaped {@code '='}, - * {@code ':'}, or white space character other than a line - * terminator. All of these key termination characters may be - * included in the key by escaping them with a preceding backslash - * character; for example,

- *

- * {@code \:\=}

- *

- * would be the two-character key {@code ":="}. Line - * terminator characters can be included using {@code \r} and - * {@code \n} escape sequences. Any white space after the - * key is skipped; if the first non-white space character after - * the key is {@code '='} or {@code ':'}, then it is - * ignored and any white space characters after it are also - * skipped. All remaining characters on the line become part of - * the associated element string; if there are no remaining - * characters, the element is the empty string - * {@code ""}. Once the raw character sequences - * constituting the key and element are identified, escape - * processing is performed as described above. - * - *

- * As an example, each of the following three lines specifies the key - * {@code "Truth"} and the associated element value - * {@code "Beauty"}: - *

-     * Truth = Beauty
-     *  Truth:Beauty
-     * Truth: Beauty
-     * 
- * As another example, the following three lines specify a single - * property: - *
-     * fruits apple, banana, pear, \
-     *                                  cantaloupe, watermelon, \
-     *                                  kiwi, mango
-     * 
- * The key is {@code "fruits"} and the associated element is: - *
"apple, banana, pear, cantaloupe, watermelon, kiwi, mango"
- * Note that a space appears before each {@code \} so that a space - * will appear after each comma in the final result; the {@code \}, - * line terminator, and leading white space on the continuation line are - * merely discarded and are not replaced by one or more other - * characters. - *

- * As a third example, the line: - *

cheeses
-     * 
- * specifies that the key is {@code "cheeses"} and the associated - * element is the empty string {@code ""}. - *

- * - * Characters in keys and elements can be represented in escape - * sequences similar to those used for character and string literals - * (see sections 3.3 and 3.10.6 of - * The Java™ Language Specification). - *

- * The differences from the character escape sequences and Unicode - * escapes used for characters and strings are: - * - *

    - *
  • Octal escapes are not recognized. - * - *
  • The character sequence {@code \b} does not - * represent a backspace character. - * - *
  • The method does not treat a backslash character, - * {@code \}, before a non-valid escape character as an - * error; the backslash is silently dropped. For example, in a - * Java string the sequence {@code "\z"} would cause a - * compile time error. In contrast, this method silently drops - * the backslash. Therefore, this method treats the two character - * sequence {@code "\b"} as equivalent to the single - * character {@code 'b'}. - * - *
  • Escapes are not necessary for single and double quotes; - * however, by the rule above, single and double quote characters - * preceded by a backslash still yield single and double quote - * characters, respectively. - * - *
  • Only a single 'u' character is allowed in a Unicode escape - * sequence. - * - *
- *

- * The specified stream remains open after this method returns. - * - * @param reader the input character stream. - * @throws IOException if an error occurred when reading from the - * input stream. - * @throws IllegalArgumentException if a malformed Unicode escape - * appears in the input. - * @since 1.6 - */ - public synchronized void load(Reader reader) throws IOException { - load0(new LineReader(reader)); - } - - /** - * Reads a property list (key and element pairs) from the input - * byte stream. The input stream is in a simple line-oriented - * format as specified in - * {@link #load(java.io.Reader) load(Reader)} and is assumed to use - * the ISO 8859-1 character encoding; that is each byte is one Latin1 - * character. Characters not in Latin1, and certain special characters, - * are represented in keys and elements using Unicode escapes as defined in - * section 3.3 of - * The Java™ Language Specification. - *

- * The specified stream remains open after this method returns. - * - * @param inStream the input stream. - * @throws IOException if an error occurred when reading from the - * input stream. - * @throws IllegalArgumentException if the input stream contains a - * malformed Unicode escape sequence. - * @since 1.2 - */ - public synchronized void load(InputStream inStream) throws IOException { - load0(new LineReader(inStream)); - } - - private void load0(LineReader lr) throws IOException { - char[] convtBuf = new char[1024]; - int limit; - int keyLen; - int valueStart; - char c; - boolean hasSep; - boolean precedingBackslash; - - while ((limit = lr.readLine()) >= 0) { - c = 0; - keyLen = 0; - valueStart = limit; - hasSep = false; - - //System.out.println("line=<" + new String(lineBuf, 0, limit) + ">"); - precedingBackslash = false; - while (keyLen < limit) { - c = lr.lineBuf[keyLen]; - //need check if escaped. - if ((c == '=' || c == ':') && !precedingBackslash) { - valueStart = keyLen + 1; - hasSep = true; - break; - } else if ((c == ' ' || c == '\t' || c == '\f') && !precedingBackslash) { - valueStart = keyLen + 1; - break; - } - if (c == '\\') { - precedingBackslash = !precedingBackslash; - } else { - precedingBackslash = false; - } - keyLen++; - } - while (valueStart < limit) { - c = lr.lineBuf[valueStart]; - if (c != ' ' && c != '\t' && c != '\f') { - if (!hasSep && (c == '=' || c == ':')) { - hasSep = true; - } else { - break; - } - } - valueStart++; - } - String key = loadConvert(lr.lineBuf, 0, keyLen, convtBuf); - String value = loadConvert(lr.lineBuf, valueStart, limit - valueStart, convtBuf); - put(key, value); - } - } - - /* Read in a "logical line" from an InputStream/Reader, skip all comment - * and blank lines and filter out those leading whitespace characters - * (\u0020, \u0009 and \u000c) from the beginning of a "natural line". - * Method returns the char length of the "logical line" and stores - * the line in "lineBuf". - */ - static class LineReader { - public LineReader(InputStream inStream) { - this.inStream = inStream; - inByteBuf = new byte[8192]; - } - - public LineReader(Reader reader) { - this.reader = reader; - inCharBuf = new char[8192]; - } - - byte[] inByteBuf; - char[] inCharBuf; - char[] lineBuf = new char[1024]; - int inLimit = 0; - int inOff = 0; - InputStream inStream; - Reader reader; - - int readLine() throws IOException { - int len = 0; - char c = 0; - - boolean skipWhiteSpace = true; - boolean isCommentLine = false; - boolean isNewLine = true; - boolean appendedLineBegin = false; - boolean precedingBackslash = false; - boolean skipLF = false; - - while (true) { - if (inOff >= inLimit) { - inLimit = (inStream == null) ? reader.read(inCharBuf) - : inStream.read(inByteBuf); - inOff = 0; - if (inLimit <= 0) { - if (len == 0 || isCommentLine) { - return -1; - } - if (precedingBackslash) { - len--; - } - return len; - } - } - if (inStream != null) { - //The line below is equivalent to calling a - //ISO8859-1 decoder. - c = (char) (0xff & inByteBuf[inOff++]); - } else { - c = inCharBuf[inOff++]; - } - if (skipLF) { - skipLF = false; - if (c == '\n') { - continue; - } - } - if (skipWhiteSpace) { - if (c == ' ' || c == '\t' || c == '\f') { - continue; - } - if (!appendedLineBegin && (c == '\r' || c == '\n')) { - continue; - } - skipWhiteSpace = false; - appendedLineBegin = false; - } - if (isNewLine) { - isNewLine = false; - if (c == '#' || c == '!') { - isCommentLine = true; - continue; - } - } - - if (c != '\n' && c != '\r') { - lineBuf[len++] = c; - if (len == lineBuf.length) { - int newLength = lineBuf.length * 2; - char[] buf = new char[newLength]; - System.arraycopy(lineBuf, 0, buf, 0, lineBuf.length); - lineBuf = buf; - } - //flip the preceding backslash flag - if (c == '\\') { - precedingBackslash = !precedingBackslash; - } else { - precedingBackslash = false; - } - } else { - // reached EOL - if (isCommentLine) { - isCommentLine = false; - isNewLine = true; - skipWhiteSpace = true; - len = 0; - continue; - } - if (inOff >= inLimit) { - inLimit = (inStream == null) - ? reader.read(inCharBuf) - : inStream.read(inByteBuf); - inOff = 0; - if (inLimit <= 0) { - if (precedingBackslash) { - len--; - } - return len; - } - } - if (precedingBackslash) { - len -= 1; - //skip the leading whitespace characters in following line - skipWhiteSpace = true; - appendedLineBegin = true; - precedingBackslash = false; - if (c == '\r') { - skipLF = true; - } - } else { - return len; - } - } - } - } - } - - /* - * Converts encoded \uxxxx to unicode chars - * and changes special saved chars to their original forms - */ - private String loadConvert(char[] in, int off, int len, char[] convtBuf) { - if (convtBuf.length < len) { - int newLen = len * 2; - convtBuf = new char[newLen]; - } - char aChar; - char[] out = convtBuf; - int outLen = 0; - int end = off + len; - - while (off < end) { - aChar = in[off++]; - if (aChar == '\\') { - aChar = in[off++]; - if (aChar == 'u') { - // Read the xxxx - int value = 0; - for (int i = 0; i < 4; i++) { - aChar = in[off++]; - value = switch (aChar) { - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' -> (value << 4) + aChar - '0'; - case 'a', 'b', 'c', 'd', 'e', 'f' -> (value << 4) + 10 + aChar - 'a'; - case 'A', 'B', 'C', 'D', 'E', 'F' -> (value << 4) + 10 + aChar - 'A'; - default -> throw new IllegalArgumentException( - "Malformed \\uxxxx encoding."); - }; - } - out[outLen++] = (char) value; - } else { - if (aChar == 't') aChar = '\t'; - else if (aChar == 'r') aChar = '\r'; - else if (aChar == 'n') aChar = '\n'; - else if (aChar == 'f') aChar = '\f'; - out[outLen++] = aChar; - } - } else { - out[outLen++] = aChar; - } - } - return new String(out, 0, outLen); - } - - /* - * Converts unicodes to encoded \uxxxx and escapes - * special characters with a preceding slash - */ - private String saveConvert(String theString, - boolean escapeSpace, - boolean escapeUnicode) { - int len = theString.length(); - int bufLen = len * 2; - StringBuffer outBuffer = new StringBuffer(bufLen); - - for (int x = 0; x < len; x++) { - char aChar = theString.charAt(x); - // Handle common case first, selecting largest block that - // avoids the specials below - if ((aChar > 61) && (aChar < 127)) { - if (aChar == '\\') { - outBuffer.append('\\'); - outBuffer.append('\\'); - continue; - } - outBuffer.append(aChar); - continue; - } - switch (aChar) { - case ' ': - if (x == 0 || escapeSpace) - outBuffer.append('\\'); - outBuffer.append(' '); - break; - case '\t': - outBuffer.append('\\'); - outBuffer.append('t'); - break; - case '\n': - outBuffer.append('\\'); - outBuffer.append('n'); - break; - case '\r': - outBuffer.append('\\'); - outBuffer.append('r'); - break; - case '\f': - outBuffer.append('\\'); - outBuffer.append('f'); - break; - case '=': // Fall through - case ':': // Fall through - case '#': // Fall through - case '!': - outBuffer.append('\\'); - outBuffer.append(aChar); - break; - default: - if (((aChar < 0x0020) || (aChar > 0x007e)) & escapeUnicode) { - outBuffer.append('\\'); - outBuffer.append('u'); - outBuffer.append(toHex((aChar >> 12) & 0xF)); - outBuffer.append(toHex((aChar >> 8) & 0xF)); - outBuffer.append(toHex((aChar >> 4) & 0xF)); - outBuffer.append(toHex(aChar & 0xF)); - } else { - outBuffer.append(aChar); - } - } - } - return outBuffer.toString(); - } - - private static void writeComments(BufferedWriter bw, String comments) - throws IOException { - bw.write("#"); - int len = comments.length(); - int current = 0; - int last = 0; - char[] uu = new char[6]; - uu[0] = '\\'; - uu[1] = 'u'; - while (current < len) { - char c = comments.charAt(current); - if (c > 'ÿ' || c == '\n' || c == '\r') { - if (last != current) - bw.write(comments.substring(last, current)); - if (c > 'ÿ') { - uu[2] = toHex((c >> 12) & 0xf); - uu[3] = toHex((c >> 8) & 0xf); - uu[4] = toHex((c >> 4) & 0xf); - uu[5] = toHex(c & 0xf); - bw.write(new String(uu)); - } else { - bw.newLine(); - if (c == '\r' && - current != len - 1 && - comments.charAt(current + 1) == '\n') { - current++; - } - if (current == len - 1 || - (comments.charAt(current + 1) != '#' && - comments.charAt(current + 1) != '!')) - bw.write("#"); - } - last = current + 1; - } - current++; - } - if (last != current) - bw.write(comments.substring(last, current)); - bw.newLine(); - } - - /** - * Calls the {@code store(OutputStream out, String comments)} method - * and suppresses IOExceptions that were thrown. - * - * @param out an output stream. - * @throws ClassCastException if this {@code Properties} object - * contains any keys or values that are not - * {@code Strings}. - * @deprecated This method does not throw an IOException if an I/O error - * occurs while saving the property list. The preferred way to save a - * properties list is via the {@code store(OutputStream out, - * String comments)} method or the - * {@code storeToXML(OutputStream os, String comment)} method. - */ - @Deprecated - public void save(OutputStream out, String comments) { - try { - store(out, comments); - } catch (IOException ignored) { - } - } - - /** - * Writes this property list (key and element pairs) in this - * {@code Properties} table to the output character stream in a - * format suitable for using the {@link #load(java.io.Reader) load(Reader)} - * method. - *

- * Properties from the defaults table of this {@code Properties} - * table (if any) are not written out by this method. - *

- * If the comments argument is not null, then an ASCII {@code #} - * character, the comments string, and a line separator are first written - * to the output stream. Thus, the {@code comments} can serve as an - * identifying comment. Any one of a line feed ('\n'), a carriage - * return ('\r'), or a carriage return followed immediately by a line feed - * in comments is replaced by a line separator generated by the {@code Writer} - * and if the next character in comments is not character {@code #} or - * character {@code !} then an ASCII {@code #} is written out - * after that line separator. - *

- * Next, a comment line is always written, consisting of an ASCII - * {@code #} character, the current date and time (as if produced - * by the {@code toString} method of {@code Date} for the - * current time), and a line separator as generated by the {@code Writer}. - *

- * Then every entry in this {@code Properties} table is - * written out, one per line. For each entry the key string is - * written, then an ASCII {@code =}, then the associated - * element string. For the key, all space characters are - * written with a preceding {@code \} character. For the - * element, leading space characters, but not embedded or trailing - * space characters, are written with a preceding {@code \} - * character. The key and element characters {@code #}, - * {@code !}, {@code =}, and {@code :} are written - * with a preceding backslash to ensure that they are properly loaded. - *

- * After the entries have been written, the output stream is flushed. - * The output stream remains open after this method returns. - *

- * - * @param writer an output character stream writer. - * @param comments a description of the property list. - * @throws IOException if writing this property list to the specified - * output stream throws an IOException. - * @throws ClassCastException if this {@code Properties} object - * contains any keys or values that are not {@code Strings}. - * @throws NullPointerException if {@code writer} is null. - * @since 1.6 - */ - public void store(Writer writer, String comments) - throws IOException { - store0((writer instanceof BufferedWriter) ? (BufferedWriter) writer - : new BufferedWriter(writer), - comments, - false); - } - - /** - * Writes this property list (key and element pairs) in this - * {@code Properties} table to the output stream in a format suitable - * for loading into a {@code Properties} table using the - * {@link #load(InputStream) load(InputStream)} method. - *

- * Properties from the defaults table of this {@code Properties} - * table (if any) are not written out by this method. - *

- * This method outputs the comments, properties keys and values in - * the same format as specified in - * {@link #store(java.io.Writer, java.lang.String) store(Writer)}, - * with the following differences: - *

    - *
  • The stream is written using the ISO 8859-1 character encoding. - * - *
  • Characters not in Latin-1 in the comments are written as - * {@code \u005Cu}xxxx for their appropriate unicode - * hexadecimal value xxxx. - * - *
  • Characters less than {@code \u005Cu0020} and characters greater - * than {@code \u005Cu007E} in property keys or values are written - * as {@code \u005Cu}xxxx for the appropriate hexadecimal - * value xxxx. - *
- *

- * After the entries have been written, the output stream is flushed. - * The output stream remains open after this method returns. - *

- * - * @param out an output stream. - * @param comments a description of the property list. - * @throws IOException if writing this property list to the specified - * output stream throws an IOException. - * @throws ClassCastException if this {@code Properties} object - * contains any keys or values that are not {@code Strings}. - * @throws NullPointerException if {@code out} is null. - * @since 1.2 - */ - public void store(OutputStream out, String comments) - throws IOException { - store0(new BufferedWriter(new OutputStreamWriter(out, StandardCharsets.ISO_8859_1)), - comments, - true); - } - - private void store0(BufferedWriter bw, String comments, boolean escUnicode) - throws IOException { - if (comments != null) { - writeComments(bw, comments); - } - bw.write("#" + new Date().toString()); - bw.newLine(); - synchronized (this) { - for (Enumeration e = keys(); e.hasMoreElements(); ) { - String key = (String) e.nextElement(); - String val = (String) get(key); - key = saveConvert(key, true, escUnicode); - /* No need to escape embedded and trailing spaces for value, hence - * pass false to flag. - */ - val = saveConvert(val, false, escUnicode); - bw.write(key + "=" + val); - bw.newLine(); - } - } - bw.flush(); - } - - /** - * Searches for the property with the specified key in this property list. - * If the key is not found in this property list, the default property list, - * and its defaults, recursively, are then checked. The method returns - * {@code null} if the property is not found. - * - * @param key the property key. - * @return the value in this property list with the specified key value. - * @see #setProperty - * @see #defaults - */ - public String getProperty(String key) { - Object oval = super.get(key); - String sval = (oval instanceof String) ? (String) oval : null; - return ((sval == null) && (defaults != null)) ? defaults.getProperty(key) : sval; - } - - /** - * Searches for the property with the specified key in this property list. - * If the key is not found in this property list, the default property list, - * and its defaults, recursively, are then checked. The method returns the - * default value argument if the property is not found. - * - * @param key the hashtable key. - * @param defaultValue a default value. - * @return the value in this property list with the specified key value. - * @see #setProperty - * @see #defaults - */ - public String getProperty(String key, String defaultValue) { - String val = getProperty(key); - return (val == null) ? defaultValue : val; - } - - /** - * Returns an enumeration of all the keys in this property list, - * including distinct keys in the default property list if a key - * of the same name has not already been found from the main - * properties list. - * - * @return an enumeration of all the keys in this property list, including - * the keys in the default property list. - * @throws ClassCastException if any key in this property list - * is not a string. - * @see java.util.Enumeration - * @see java.util.Properties#defaults - * @see #stringPropertyNames - */ - public Enumeration propertyNames() { - LinkedHashMap h = new LinkedHashMap<>(); - enumerate(h); - return Collections.enumeration(h.keySet()); - } - - /** - * Returns a set of keys in this property list where - * the key and its corresponding value are strings, - * including distinct keys in the default property list if a key - * of the same name has not already been found from the main - * properties list. Properties whose key or value is not - * of type String are omitted. - *

- * The returned set is not backed by the Properties object. - * Changes to this Properties are not reflected in the set, - * or vice versa. - * - * @return a set of keys in this property list where - * the key and its corresponding value are strings, - * including the keys in the default property list. - * @see java.util.Properties#defaults - * @since 1.6 - */ - public Set stringPropertyNames() { - LinkedHashMap h = new LinkedHashMap<>(); - enumerateStringProperties(h); - return h.keySet(); - } - - /** - * Prints this property list out to the specified output stream. - * This method is useful for debugging. - * - * @param out an output stream. - * @throws ClassCastException if any key in this property list - * is not a string. - */ - public void list(PrintStream out) { - PrintWriter writer = new PrintWriter(out); - list(writer); - writer.flush(); - } - - /** - * Prints this property list out to the specified output stream. - * This method is useful for debugging. - * - * @param out an output stream. - * @throws ClassCastException if any key in this property list - * is not a string. - * @since JDK1.1 - */ - /* - * Rather than use an anonymous inner class to share common code, this - * method is duplicated in order to ensure that a non-1.1 compiler can - * compile this file. - */ - public void list(PrintWriter out) { - out.println("-- listing properties --"); - LinkedHashMap h = new LinkedHashMap<>(); - enumerate(h); - for (Enumeration e = Collections.enumeration(h.keySet()); e.hasMoreElements(); ) { - String key = e.nextElement(); - String val = (String) h.get(key); - if (val.length() > 40) { - val = val.substring(0, 37) + "..."; - } - out.println(key + "=" + val); - } - } - - /** - * Lists all key/value pairs in the specified hashtable. - * - * @param h the hashtable - * @throws ClassCastException if any of the property keys - * is not of the String type. - */ - private synchronized void enumerate(LinkedHashMap h) { - if (defaults != null) { - defaults.enumerate(h); - } - for (Enumeration e = keys(); e.hasMoreElements(); ) { - String key = (String) e.nextElement(); - h.put(key, get(key)); - } - } - - private Enumeration keys() { - return Collections.enumeration(keySet()); - } - - /** - * Enumerates all key/value pairs in the specified hashtable - * and omits the property if the key or value is not a string. - * - * @param h the hashtable - */ - private synchronized void enumerateStringProperties(Map h) { - if (defaults != null) { - defaults.enumerateStringProperties(h); - } - for (Enumeration e = keys(); e.hasMoreElements(); ) { - Object k = e.nextElement(); - Object v = get(k); - if (k instanceof String && v instanceof String) { - h.put((String) k, (String) v); - } - } - } - - /** - * Convert a nibble to a hex character - * - * @param nibble the nibble to convert. - */ - private static char toHex(int nibble) { - return hexDigit[(nibble & 0xF)]; - } - - /** - * A table of hex digits - */ - private static final char[] hexDigit = { - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' - }; -} diff --git a/src/main/java/net/locusworks/common/utils/Checks.java b/src/main/java/net/locusworks/common/utils/Checks.java deleted file mode 100644 index ddc23bd..0000000 --- a/src/main/java/net/locusworks/common/utils/Checks.java +++ /dev/null @@ -1,27 +0,0 @@ -package net.locusworks.common.utils; - -import java.util.Objects; - -public class Checks { - - public static void checkArguments(boolean expression, String error) { - checkArguments(expression, "%s", error); - } - - public static void checkArguments(boolean expression, String errorFmt, Object... args) { - if (!expression) throw new IllegalArgumentException(String.format(errorFmt, args)); - } - - public static void checkState(boolean expression, String error) { - checkState(expression, "%s", error); - } - - public static void checkState(boolean expression, String errorFmt, Object... args) { - if (!expression) throw new IllegalStateException(String.format(errorFmt, args)); - } - - public static void checkNotNull(Object item, String error) { - Objects.requireNonNull(item, error); - } - -} diff --git a/src/main/java/net/locusworks/common/utils/Constants.java b/src/main/java/net/locusworks/common/utils/Constants.java deleted file mode 100644 index 86e8911..0000000 --- a/src/main/java/net/locusworks/common/utils/Constants.java +++ /dev/null @@ -1,20 +0,0 @@ -package net.locusworks.common.utils; - -/** - * Class to hold final static constant values used across the system - * - * @author Isaac Parenteau - * @version 1.0.0 - * @date 02/15/2018 - */ -public class Constants { - - public static final short TRUE = (short) 1; - public static final short FALSE = (short) 0; - - public static final short EXIT_SUCCESS = (short) 0; - public static final short EXIT_FAIL = (short) 1; - - public static final String LOG4J_CONFIG_PROPERTY = "log4j.configurationFile"; - public static final String JUNIT_TEST_CHECK = "junit.test"; -} diff --git a/src/main/java/net/locusworks/common/utils/DataOutputStreamHelper.java b/src/main/java/net/locusworks/common/utils/DataOutputStreamHelper.java deleted file mode 100644 index 023089d..0000000 --- a/src/main/java/net/locusworks/common/utils/DataOutputStreamHelper.java +++ /dev/null @@ -1,51 +0,0 @@ -package net.locusworks.common.utils; - -import java.io.ByteArrayOutputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.Base64; - -import net.locusworks.common.Charsets; - -public class DataOutputStreamHelper extends DataOutputStream implements AutoCloseable { - - public DataOutputStreamHelper() { - this(new ByteArrayOutputStream()); - } - - public DataOutputStreamHelper(OutputStream out) { - super(out); - } - - public byte[] toByteArray() { - if (super.out == null) { - return new byte[0]; - } - if (super.out instanceof ByteArrayOutputStream) { - return ((ByteArrayOutputStream) super.out).toByteArray(); - } - return super.out.toString().getBytes(Charsets.UTF_8); - } - - public String base64Encoded() { - return Base64.getEncoder().encodeToString(this.toByteArray()); - } - - @Override - public String toString() { - return new String(this.toByteArray(), Charsets.UTF_8); - } - - @Override - public void close() throws IOException { - if (super.out != null) { - try { - super.out.close(); - super.out = null; - } catch (Exception ignored) { - } - } - } - -} diff --git a/src/main/java/net/locusworks/common/utils/DateTimeStampDeserializer.java b/src/main/java/net/locusworks/common/utils/DateTimeStampDeserializer.java deleted file mode 100644 index 2118082..0000000 --- a/src/main/java/net/locusworks/common/utils/DateTimeStampDeserializer.java +++ /dev/null @@ -1,111 +0,0 @@ -package net.locusworks.common.utils; - -import java.io.IOException; -import java.text.SimpleDateFormat; -import java.util.Date; - -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; - -/** - * Class to deseralize json data into a Date object back into a class that specifies this deserializer
- * For example the below code: - *

- * {@code @JsonDeserialize(using=DateTimeStampDeserializer.class)
- * private Date purgeEndDate;}
- * 
- * Will specify to use this deserializer class when a json field {@code purgeEndDate} is encountered in the json - * string and will try to convert the string into a date object and inject the value back into the class - * - * @author Isaac Parenteau - * @version 1.0 - * @date 02/15/2018 - * @see com.fasterxml.jackson.databind.annotation.JsonDeserialize - */ -public class DateTimeStampDeserializer extends JsonDeserializer { - - private static final String DEFAULT = "MM/dd/yyyy"; - private static final String EXPANDED = "MM/dd/yyyy HH:mm:ss z"; - private static final String EXPANDED_WITH_TIMEZONE = "MMM d, yyyy HH:mm:ss z"; - private static final String EXPANDED_WITH_AM_PM = "MMM d, yyyy h:mm:ss a"; - - private static final String[] formats = new String[]{ - DEFAULT, - EXPANDED, - EXPANDED_WITH_TIMEZONE, - EXPANDED_WITH_AM_PM, - }; - - private static final Integer[] styles = new Integer[]{ - SimpleDateFormat.LONG, - SimpleDateFormat.FULL, - SimpleDateFormat.MEDIUM, - SimpleDateFormat.SHORT - }; - - @Override - public Date deserialize(JsonParser p, DeserializationContext context) throws IOException { - String value = p.getText(); - - Date date; - //First, try to see if the value can be parsed into along - try { - date = new Date(Long.parseLong(value)); - return date; - } catch (Exception ignored) { - } - - //Next, iterate over the built-in styles to see if it can be converted - for (Integer style : styles) { - date = formatDate(style, value); - if (date != null) { - return date; - } - } - - //Lastly, iterate over the custom styles specified in format to see if it can be converted - for (String fmt : formats) { - date = formatDate(fmt, value); - if (date != null) { - return date; - } - } - - //Return null if date format can't be converted - return null; - } - - /** - * Convert a string value to a date object - * - * @param format The format to use in reference to the source - * @param source the source to convert - * @return Date object if the conversion was success; null otherwise - */ - private static Date formatDate(String format, String source) { - try { - return new SimpleDateFormat(format).parse(source); - } catch (Exception ex) { - return null; - } - } - - /** - * Convert a string value to a date object using SimpleDateFormats - * built in styles - * - * @param style The style to use - * @param source the source to convert - * @return Date object if the conversion was success; null otherwise - */ - private static Date formatDate(Integer style, String source) { - try { - return SimpleDateFormat.getDateInstance(style).parse(source); - } catch (Exception ex) { - return null; - } - } - -} diff --git a/src/main/java/net/locusworks/common/utils/DateTimeStampSerializer.java b/src/main/java/net/locusworks/common/utils/DateTimeStampSerializer.java deleted file mode 100644 index ebb1d96..0000000 --- a/src/main/java/net/locusworks/common/utils/DateTimeStampSerializer.java +++ /dev/null @@ -1,49 +0,0 @@ -package net.locusworks.common.utils; - -import java.io.IOException; -import java.io.Serial; -import java.util.Date; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.fasterxml.jackson.databind.ser.std.StdSerializer; - -/** - * Class to serialize a date object into a json string value
- * This serializer will convert date objects to their timestamp representation
- * For example the below code: - *
- * {@code @JsonSerialize(using=DateTimeStampSerializer.class)
- * private Date purgeEndDate;
- * }
- * 
- * Will specify to use this serializer class when the {@code purgeEndDate} is encountered when converting to json - * and will try to convert the date object to its timestamp equivalent - * - * @author Isaac Parenteau - * @version 1.0 - * @date 02/15/2018 - * @see com.fasterxml.jackson.databind.annotation.JsonSerialize - * @see com.fasterxml.jackson.databind.ser.std.StdSerializer - */ -public class DateTimeStampSerializer extends StdSerializer { - - /** - * - */ - @Serial - private static final long serialVersionUID = -4753139740916300831L; - - public DateTimeStampSerializer() { - this(null); - } - - public DateTimeStampSerializer(Class t) { - super(t); - } - - @Override - public void serialize(Date date, JsonGenerator generator, SerializerProvider provider) throws IOException { - generator.writeNumber(date.getTime()); - } -} diff --git a/src/main/java/net/locusworks/common/utils/FileReader.java b/src/main/java/net/locusworks/common/utils/FileReader.java deleted file mode 100644 index 532de61..0000000 --- a/src/main/java/net/locusworks/common/utils/FileReader.java +++ /dev/null @@ -1,223 +0,0 @@ -package net.locusworks.common.utils; - -import static net.locusworks.common.Charsets.UTF_8; -import static net.locusworks.common.utils.ObjectUtils.getResourceStream; - -import java.io.BufferedReader; -import java.io.File; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Iterator; -import java.util.NoSuchElementException; -import java.util.Objects; - -import net.locusworks.common.interfaces.AutoCloseableIterator; - -/** - * Class to read in a file that can be used in the try-with-resource block - * - * @author Isaac Parenteau - * @version 1.0.0 - * @date 02/15/2018 - */ -public class FileReader implements AutoCloseableIterator, Iterable, AutoCloseable { - - private BufferedReader reader; - private LineInfo info; - private Integer lineNumber; - - /** - * Constructor - * - * @param fileName Name of the file to read - */ - public FileReader(String fileName) { - init(fileName); - } - - /** - * Constructor - * - * @param file File to read - */ - @Deprecated - public FileReader(File file) { - init(file.toPath()); - } - - /** - * Constructor - * - * @param file File to read - */ - public FileReader(Path file) { - init(file); - } - - /** - * Constructor - * - * @param reader Buffered reader to read data from - */ - public FileReader(BufferedReader reader) { - init(reader); - } - - /** - * Initialization helper - * - * @param fileName Name of the file to load - * This will look into the resources directory if it cannot - * find the file directly. - */ - private void init(String fileName) { - if (fileName == null) { - throw new IllegalArgumentException("File name cannot be null"); - } - //check to see if the file exists - Path f = Paths.get(fileName); - if (Files.exists(f)) { - init(f); //If it does. load through the file initializer - return; - } - - //Check to see if the file is in the resources directory - InputStream is = getResourceStream(fileName); - - BufferedReader br = new BufferedReader(new InputStreamReader(is, UTF_8)); - init(br); - } - - /** - * Initializer helper to load file - * - * @param file File to load - */ - private void init(Path file) { - if (file == null) throw new IllegalArgumentException("File cannot be null"); - if (Files.notExists(file)) throw new IllegalArgumentException("File " + file + " does not exist"); - if (!Files.isRegularFile(file)) throw new IllegalArgumentException("File " + file + " is not a file"); - try { - BufferedReader br = Files.newBufferedReader(file); - init(br); - } catch (Exception ex) { - throw new RuntimeException(ex); - } - } - - /** - * Initializer helper for buffered reader - * This is ultimately where all initializers end as a buffered reader - * - * @param reader buffered reader to load - */ - private void init(BufferedReader reader) { - if (reader == null) { - throw new IllegalArgumentException("Buffered Reader cannot be null"); - } - this.reader = reader; - this.lineNumber = 0; - } - - @Override - public boolean hasNext() { - try { - String line = this.reader.readLine(); - if (line == null) { - this.close(); - this.info = null; - return false; - } - this.lineNumber++; - this.info = new LineInfo(this.lineNumber, line); - return true; - } catch (Exception ex) { - throw new RuntimeException(ex); - } - } - - @Override - public LineInfo next() { - if (this.info == null) { - throw new NoSuchElementException("Call to next was initiated but there are no more elements to read"); - } - return this.info; - } - - @Override - public Iterator iterator() { - return this; - } - - @Override - public void close() { - if (this.reader != null) { - try { - this.reader.close(); - } catch (Exception ex) { - throw new RuntimeException(ex); - } - } - } - - public static class LineInfo { - private Integer lineNumber; - private Integer lineLength; - private String line; - - /** - * @param lineNumber the current line number in the file - * @param line the line information from the file - */ - public LineInfo(Integer lineNumber, String line) { - this.lineNumber = lineNumber; - this.line = line; - this.lineLength = line.length(); - } - - /** - * @return the lineNumber - */ - public Integer getLineNumber() { - return lineNumber; - } - - /** - * @param lineNumber the lineNumber to set - */ - public void setLineNumber(Integer lineNumber) { - this.lineNumber = lineNumber; - } - - /** - * @return the lineLength - */ - public Integer getLineLength() { - return lineLength; - } - - /** - * @param lineLength the lineLength to set - */ - public void setLineLength(Integer lineLength) { - this.lineLength = lineLength; - } - - /** - * @return the line - */ - public String getLine() { - return line; - } - - /** - * @param line the line to set - */ - public void setLine(String line) { - this.line = line; - } - } -} diff --git a/src/main/java/net/locusworks/common/utils/HashUtils.java b/src/main/java/net/locusworks/common/utils/HashUtils.java deleted file mode 100644 index c5ffc68..0000000 --- a/src/main/java/net/locusworks/common/utils/HashUtils.java +++ /dev/null @@ -1,200 +0,0 @@ -package net.locusworks.common.utils; - -import java.io.BufferedInputStream; -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.security.MessageDigest; - -/** - * Wrapper class that leverages java's MessageDigest to hash files - * - * @author Isaac Parenteau - * - */ -public class HashUtils { - - private static final Charset UTF_8 = StandardCharsets.UTF_8; - - /** - * Used to build output as Hex - */ - private static final char[] DIGITS_LOWER = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; - - /** - * Used to build output as Hex - */ - private static final char[] DIGITS_UPPER = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; - - /** - * Size of the streaming buffer - */ - public static final Integer STREAM_BUFFER_LENGTH = 1024; - - /** - * Hash a string literal - * - * @param hashType Hash types supported by MessageDigest (i.e MD5, SHA-1, SHA-512) - * @param data String to hash - * @return hash value of the string literal - */ - public static String hash(String hashType, String data) { - return hash(hashType, data, true); - } - - /** - * Hash a string literal - * - * @param hashType Hash types supported by MessageDigest (i.e., MD5, SHA-1, SHA-512) - * @param data String to hash - * @param toLower True to output the hash in lower case. False to output in the upper case - * @return hash value of the string literal - */ - public static String hash(String hashType, String data, boolean toLower) { - byte[] stringData = data.getBytes(UTF_8); - return hash(hashType, stringData, toLower); - } - - @Deprecated - public static String hash(String hashType, File data) { - return hash(hashType, data.toPath()); - } - - /** - * Hash a file - * - * @param hashType Hash types supported by MessageDigest (i.e MD5, SHA-1, SHA-512) - * @param data File to hash - * @return hash value of the file - */ - public static String hash(String hashType, Path data) { - return hash(hashType, data, true); - } - - @Deprecated - public static String hash(String hashType, File data, boolean toLower) { - return hash(hashType, data.toPath(), toLower); - } - - /** - * Hash a file - * - * @param hashType Hash types supported by MessageDigest (i.e MD5, SHA-1, SHA-512) - * @param data File to hash - * @param toLower True to output the hash in lower case. False to output in upper case - * @return hash value of the file - */ - public static String hash(String hashType, Path data, boolean toLower) { - try (InputStream stream = Files.newInputStream(data)) { - return hash(stream, hashType, toLower); - } catch (IOException ex) { - throw new IllegalArgumentException(ex.getMessage()); - } - } - - /** - * Hash a byte array - * - * @param hashType Hash types supported by MessageDigest (i.e MD5, SHA-1, SHA-512) - * @param data data to hash - * @return hash value of the data - */ - public static String hash(String hashType, byte[] data) { - return hash(hashType, data, true); - } - - /** - * Hash a byte array - * - * @param hashType Hash types supported by MessageDigest (i.e MD5, SHA-1, SHA-512) - * @param data data to hash - * @param toLower True to output the hash in lower case. False to output in upper case - * @return hash value of the data - */ - public static String hash(String hashType, byte[] data, boolean toLower) { - return hash(new BufferedInputStream(new ByteArrayInputStream(data)), hashType, toLower); - } - - /** - * Hash an input stream - * - * @param stream Stream with the data to hash - * @param hashType Hash types supported by MessageDigest (i.e MD5, SHA-1, SHA-512) - * @return Hash value of the input stream - */ - public static String hash(InputStream stream, String hashType) { - return hash(stream, hashType, true); - } - - /** - * Hash an input stream - * - * @param stream Stream with the data to hash - * @param hashType Hash types supported by MessageDigest (i.e MD5, SHA-1, SHA-512) - * @param toLower True to output the hash in lower case. False to output in upper case - * @return Hash value of the input stream - */ - public static String hash(InputStream stream, String hashType, boolean toLower) { - MessageDigest digest = null; - try (InputStream is = stream) { - digest = MessageDigest.getInstance(hashType); - - byte[] buffer = new byte[STREAM_BUFFER_LENGTH]; - int read = is.read(buffer, 0, STREAM_BUFFER_LENGTH); - - while (read > -1) { - digest.update(buffer, 0, read); - read = is.read(buffer, 0, STREAM_BUFFER_LENGTH); - } - - return encodeHexString(digest.digest(), toLower); - } catch (Exception ex) { - throw new IllegalArgumentException(ex.getMessage()); - } - } - - /** - * Encode the hash data back to a string - * - * @param data Data to encode - * @param toLower output to lower case - * @return encoded string - */ - private static String encodeHexString(byte[] data, boolean toLower) { - return new String(encodeHex(data, toLower)); - } - - /** - * Encode the hash data to a character array - * - * @param data Data to encode - * @param toLower output to lower case - * @return encoded character array - */ - private static char[] encodeHex(byte[] data, boolean toLower) { - return encodeHex(data, toLower ? DIGITS_LOWER : DIGITS_UPPER); - } - - /** - * Encode the hex to a character array - * - * @param data Data to encode - * @param toDigits digits to use - * @return encoded character array - */ - private static char[] encodeHex(byte[] data, char[] toDigits) { - int l = data.length; - char[] out = new char[l << 1]; - // two characters form the hex value. - for (int i = 0, j = 0; i < l; i++) { - out[j++] = toDigits[(0xF0 & data[i]) >>> 4]; - out[j++] = toDigits[0x0F & data[i]]; - } - return out; - } -} diff --git a/src/main/java/net/locusworks/common/utils/ObjectUtils.java b/src/main/java/net/locusworks/common/utils/ObjectUtils.java deleted file mode 100644 index 88164ef..0000000 --- a/src/main/java/net/locusworks/common/utils/ObjectUtils.java +++ /dev/null @@ -1,38 +0,0 @@ -package net.locusworks.common.utils; - -import java.io.InputStream; -import java.util.Objects; -import java.util.function.Consumer; - -/** - * Object Utils. Functions to perform on objects - */ -public class ObjectUtils { - - /** - * Perform an action if an object is not null otherwise do nothing. - * - * @param object the object to test - * @param consumer the consumer to perform. - * @param the type - */ - public static void performIfNotNull(T object, Consumer consumer) { - if (Objects.isNull(object)) { - return; - } - consumer.accept(object); - } - - public static InputStream getResourceStream(String resourceName) { - InputStream is = ObjectUtils.class.getResourceAsStream(resourceName); - if (is == null) { - is = ObjectUtils.class.getClassLoader().getResourceAsStream(resourceName); - } - - if (is == null) { - throw new NullPointerException("Unable to find resource with name of " + resourceName); - } - return is; - } - -} diff --git a/src/main/java/net/locusworks/common/utils/RandomString.java b/src/main/java/net/locusworks/common/utils/RandomString.java deleted file mode 100644 index a238633..0000000 --- a/src/main/java/net/locusworks/common/utils/RandomString.java +++ /dev/null @@ -1,76 +0,0 @@ -package net.locusworks.common.utils; - -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; -import java.util.Objects; -import java.util.Random; - -import static net.locusworks.common.Charsets.UTF_8; - -public class RandomString { - - public static final String LOWER = "abcdefghijklmnopqrstuvwxyz"; - public static final String UPPER = LOWER.toUpperCase(); - public static final String DIGITS = "0123456789"; - - public static final String ALPHA_NUMERIC = LOWER + UPPER + DIGITS; - - private Random random; - - private char[] symbols; - - private static RandomString instance; - - private RandomString() { - Random random; - try { - random = SecureRandom.getInstance("SHA1PRNG"); - } catch (NoSuchAlgorithmException e) { - random = new SecureRandom(); - } - init(random); - } - - private RandomString(Random random) { - init(random); - } - - private void init(Random random) { - this.random = Objects.requireNonNull(random, "Random generator cannot be null"); - this.symbols = ALPHA_NUMERIC.toCharArray(); - } - - private String nextString(int length) { - if (length < 1) throw new IllegalArgumentException("String Length has to be greater than 0"); - char[] buffer = new char[length]; - for (int index = 0; index < buffer.length; index++) { - buffer[index] = symbols[random.nextInt(symbols.length)]; - } - return new String(buffer); - } - - public String getString(Integer length) { - return this.nextString(length); - } - - public byte[] getBytes(Integer length) { - return getString(length).getBytes(UTF_8); - } - - public static RandomString getInstance() { - if (instance == null) { - instance = new RandomString(); - } - return instance; - } - - public static RandomString newInstance() { - instance = new RandomString(); - return instance; - } - - public static RandomString newInstance(Random random) { - instance = new RandomString(random); - return instance; - } -} diff --git a/src/main/java/net/locusworks/common/utils/Splitter.java b/src/main/java/net/locusworks/common/utils/Splitter.java deleted file mode 100644 index 168584d..0000000 --- a/src/main/java/net/locusworks/common/utils/Splitter.java +++ /dev/null @@ -1,195 +0,0 @@ -package net.locusworks.common.utils; - -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import static net.locusworks.common.utils.Checks.checkArguments; -import static net.locusworks.common.utils.Checks.checkNotNull; - -/** - * Class to help split a string in various ways. - * By partition (fixed length split) or by sequence (look for a specific string sequence). - * it can also split on new line or not. - */ -public class Splitter { - private enum SplitterType { - PARTITION, - SEQUENCE - } - - private String splitSeq; - private boolean omitEmptyStrings = false; - private int partition; - private int limit; - private final SplitterType splitterType; - private static Splitter splitter; - - private Splitter(String seq) { - this.splitSeq = seq; - this.splitterType = SplitterType.SEQUENCE; - } - - private Splitter(int partition) { - this.partition = partition; - this.splitterType = SplitterType.PARTITION; - } - - /** - * Remove empty string from the resulting lists - * - * @return this - */ - public Splitter omitEmptyStrings() { - this.omitEmptyStrings = true; - return this; - } - - /** - * Return a subset of the resulting list - * - * @param limit how many items to retrieve - * @return this - */ - public Splitter withLimit(int limit) { - this.limit = limit; - return this; - } - - /** - * Return an array instead of a list - * - * @param sentence the string sentence to split - * @return this - */ - public String[] splitToArray(String sentence) { - List list = split(sentence); - return list.toArray(new String[0]); - } - - /** - * Split the string - * - * @param sentence the string to split - * @return the resulting list. - */ - public List split(String sentence) { - checkArguments(!Utils.isEmptyString(sentence), "provided value is null or empty"); - List list = new ArrayList<>(); - - if (splitterType == SplitterType.PARTITION) { - populateForFixedWidth(sentence, list); - } else { - populateForTrimmer(sentence, list); - } - - return limit > 0 ? list.subList(0, limit) : list; - } - - private void populateForFixedWidth(String sentence, List list) { - checkArguments(partition > 0, "Partition should be greater than 0"); - int strLength = sentence.length(); - for (int i = 0; i < strLength; i += partition) { - list.add(sentence.substring(i, Math.min(strLength, i + partition))); - } - } - - private void populateForTrimmer(String sentence, List list) { - checkNotNull(splitSeq, "Split value provided was null"); - for (String s : sentence.split(splitSeq)) { - if (omitEmptyStrings && s.trim().isEmpty()) - continue; - list.add(s.trim()); - } - } - - /** - * Split the string on fixed length partitions - * - * @param partition the length to split the string on - * @return this - */ - public static Splitter fixedLengthSplit(int partition) { - splitter = new Splitter(partition); - return splitter; - } - - /** - * Split the length on a specified string sequence - * - * @param split the sequence to split - * @return this - */ - public static Splitter on(String split) { - splitter = new Splitter(split); - return splitter; - } - - /** - * Split on new line sequence - * - * @return this - */ - public static Splitter onNewLine() { - return on("\\r?\\n"); - } - - /** - * Split on spaces - * - * @return this - */ - public static Splitter onSpace() { - return on(" "); - } - - /** - * Separator on what the key value is. return map - * - * @param separator the separator value - * @return this - */ - public MapSplitter withKeyValueSeparator(String separator) { - return new MapSplitter(this, separator); - } - - public static class MapSplitter { - - private final Splitter splitter; - private final String separator; - private boolean skipInvalid = false; - - private MapSplitter(Splitter splitter, String separator) { - checkNotNull(splitter, "Splitter cannot be null"); - checkArguments(!Utils.isEmptyString(separator), - "Key value separator cannot be empty or null"); - this.splitter = splitter; - this.separator = separator; - } - - public MapSplitter skipInvalidKeyValues() { - this.skipInvalid = true; - return this; - } - - public Map split(String sentence) { - checkArguments(!Utils.isEmptyString(sentence), "provided value is null or empty"); - Map map = new LinkedHashMap<>(); - - for (String s : splitter.split(sentence)) { - String[] keyValue = s.split(separator); - try { - checkArguments(keyValue.length == 2, "invalid length found for key value mapping"); - } catch (IllegalArgumentException ex) { - if (!skipInvalid) - throw ex; - continue; - } - map.put(keyValue[0], keyValue[1]); - } - - return map; - } - } -} diff --git a/src/main/java/net/locusworks/common/utils/StreamUtils.java b/src/main/java/net/locusworks/common/utils/StreamUtils.java deleted file mode 100644 index 9014f15..0000000 --- a/src/main/java/net/locusworks/common/utils/StreamUtils.java +++ /dev/null @@ -1,71 +0,0 @@ -package net.locusworks.common.utils; - -import java.util.Arrays; -import java.util.Iterator; -import java.util.stream.Stream; -import java.util.stream.StreamSupport; - -/** - * Utility class to make iterators streamable - * - * @author Isaac Parenteau - * @version 1.0.0 - * @date 02/15/2018 - */ -public class StreamUtils { - - /** - * Convert an iterator to a stream - * - * @param iterator the iterator to convert - * @param the class type - * @return stream of the iterator - */ - public static Stream asStream(Iterator iterator) { - return asStream(iterator, false); - } - - public static Stream asStream(Iterable iterable) { - return asStream(iterable, false); - } - - /** - * Converts an array to a stream - * - * @param items the items to convert - * @param the class type - * @return stream of the array - */ - public static Stream asStream(T[] items) { - return asStream(Arrays.asList(items).iterator(), false); - } - - /** - * Converts an array to a stream - * - * @param items the items to convert - * @param parallel make the stream parallel if set to true - * @param the class type - * @return stream of the array - */ - public static Stream asStream(T[] items, boolean parallel) { - return asStream(Arrays.asList(items).iterator(), parallel); - } - - public static Stream asStream(Iterable iterable, boolean parallel) { - return StreamSupport.stream(iterable.spliterator(), parallel); - } - - /** - * Convert an iterator to a stream - * - * @param iterator iterator to convert - * @param parallel make the stream parallel if set to true. - * @param the class type - * @return stream of the iterator - */ - public static Stream asStream(Iterator iterator, boolean parallel) { - Iterable iterable = () -> iterator; - return StreamSupport.stream(iterable.spliterator(), parallel); - } -} diff --git a/src/main/java/net/locusworks/common/utils/Success.java b/src/main/java/net/locusworks/common/utils/Success.java deleted file mode 100644 index 0560ef2..0000000 --- a/src/main/java/net/locusworks/common/utils/Success.java +++ /dev/null @@ -1,41 +0,0 @@ -package net.locusworks.common.utils; - -/*** - * Success class to return data back to the client - * @author Isaac Parenteau - * @version 1.0.0 - * @date 02/15/2018 - */ -public class Success { - private boolean success = true; - private final Object body; - - protected Success() { - this(true, true); - } - - protected Success(boolean success) { - this(success, success); - } - - public Success(boolean success, Object body) { - this.success = success; - this.body = body; - } - - public Object getBody() { - return body; - } - - public boolean getSuccess() { - return success; - } - - public static Success success() { - return new Success(); - } - - public static Success fail() { - return new Success(false); - } -} diff --git a/src/main/java/net/locusworks/common/utils/Utils.java b/src/main/java/net/locusworks/common/utils/Utils.java deleted file mode 100644 index bf501f2..0000000 --- a/src/main/java/net/locusworks/common/utils/Utils.java +++ /dev/null @@ -1,1005 +0,0 @@ -package net.locusworks.common.utils; - -import java.lang.reflect.Array; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Modifier; -import java.util.*; -import java.util.Map.Entry; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Consumer; -import java.util.stream.Collectors; -import java.util.stream.IntStream; - -import net.locusworks.common.annotations.MapValue; -import net.locusworks.common.interfaces.ThrowingConsumer; - -/*** - * Utils class with generic methods - * @author Isaac Parenteau - * @version 1.0.0 - * @date 02/15/2018 - */ -public class Utils { - - - /** - * Finds if all the values are equal - * - * @param or first value is equal to at least one other value - * @param values the values to compare - * @return true if the first value is equal to at least one other value; false otherwise - */ - @SafeVarargs - public static boolean areEqual(Boolean or, E... values) { - if (values.length < 2) { - throw new IllegalArgumentException("Not enough values to compare"); - } - - E firstVal = values[0]; - boolean equal = !or; - - for (int i = 1; i < values.length; i++) { - if (or) - equal |= firstVal.equals(values[i]); - else - equal &= firstVal.equals(values[i]); - } - - return equal; - } - - /** - * Checks to see if values entered are all equal - * - * @param the type parameter - * @param values the values - * @return boolean - */ - @SafeVarargs - public static boolean areEqual(E... values) { - return areEqual(false, values); - } - - /** - * Checks to see if a group of values are not valid. All values have to be invalid to return true - * One valid value will return false - * - * @param values Values to check - * @param the expected class type of the objects passed in. All objects need to be of same type - * @return true if all values are invalid, false otherwise - */ - @SuppressWarnings("unchecked") - public static boolean areNotValid(V... values) { - return !areValid(values); - } - - /** - * Checks to see if a group of values are valid. All values have to be valid to return true - * One invalid value will return false - * - * @param the expected class type of the objects passed in. All objects need to be of same type - * @param values the values to check - * @return true if the values are valid, false otherwise - */ - @SuppressWarnings("unchecked") - public static boolean areValid(V... values) { - return validateValues(values); - } - - /** - * Build a map class - * - * @param the type parameter - * @param the type parameter - * @param mapClass The map class to map to i.e. HashMap, TreeMap etc - * @param mapKey the map key - * @param mapValue the map value - * @param data The data to place in the map - * @return map The map with the objects - */ - @SuppressWarnings("unchecked") - public static Map buildMap(Class mapClass, Class mapKey, Class mapValue, Object... data) { - Objects.requireNonNull(mapKey, "Null key value"); - Objects.requireNonNull(mapValue, "Null map value"); - - Map results; - try { - results = (Map) mapClass.getDeclaredConstructor().newInstance(); - } catch (Exception ex) { - throw new IllegalArgumentException("Unable to create instance of " + mapClass.getSimpleName() + " e: " + ex.getMessage()); - } - - if (data.length % 2 != 0) { - throw new IllegalArgumentException("Odd number of arguments provided"); - } - - for (int i = 0; i < data.length; i += 2) { - Object key = data[i]; - Object value = data[i + 1]; - - if (!mapKey.isInstance(key)) { - throw new IllegalArgumentException("Key is not the correct instance. Expecting " + mapKey.getName() + " Received " + key.getClass().getName()); - } - - if (!mapValue.isInstance(value)) { - throw new IllegalArgumentException("Value is not the correct instance. Expecting " + mapValue.getName() + " Received " + value.getClass().getName()); - } - results.put((K) key, (V) value); - - } - return results; - } - - /** - * Builds a set of objects - * - * @param setClass Class type of the set to create - * @param setValue Class type of the objects being placed in the set - * @param Class type of the return object (should be the same as setValue) - * @param data Data to place inside the set - * @return Set filled with the data - * @deprecated since JDk11 can use Set.of - */ - @SuppressWarnings("unchecked") - public static Set buildSet(Class setClass, Class setValue, E... data) { - return buildSet(data); - } - - /** - * Builds a set of objects - * - * @param data the data to set - * @param the type - * @return the set - */ - @SafeVarargs - public static Set buildSet(E... data) { - return Set.of(data); - } - - /** - * Public method of type HashMap called "buildStringHashMap". - * The method takes String parameters and a data parameter. - * The method returns a new HashMap that uses String types as key / value pairs. - * - * @param data - The data - * @return - Returns a HashMap using the data. - */ - public static HashMap buildStringHashMap(String... data) { - return new HashMap<>(buildMap(HashMap.class, String.class, String.class, (Object[]) data)); - } - - /** - * Clone list and makes it unmodifiable. - * - * @return unmodifiable list - */ - public static List cloneList(List list) { - return Collections.unmodifiableList(list); - } - - /** - * Clone object object. - * - * @param obj the obj - * @return the object - * @throws IllegalAccessException thrown when the filed cannot be access - * @throws InstantiationException Thrown when the object cannot be instantiated - */ - @SuppressWarnings("unchecked") - public static O cloneObject(O obj) - throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { - Object clone = obj.getClass().getDeclaredConstructor().newInstance(); - for (Field field : obj.getClass().getDeclaredFields()) { - field.setAccessible(true); - if (field.get(obj) == null || Modifier.isFinal(field.getModifiers())) { - continue; - } - - Class type = field.getType(); - - if (isPrimitiveOrWrapper(type)) { - field.set(clone, field.get(obj)); - } else { - field.set(clone, cloneObject(field.get(obj))); - } - } - return (O) clone; - } - - /*** - * Convert an object to a map. Checks to see if there is a MapValue annotation - * and uses the values found to convert the fields to the key and the field value as the value - * @param obj Object to convert - * @return A map representation of the object - * @throws Exception exception - */ - public static Map convertToMap(Object obj) throws Exception { - Class clazz = obj.getClass(); - Map map = new LinkedHashMap<>(); - - - for (Field field : clazz.getDeclaredFields()) { - field.setAccessible(true); - boolean hasAnnotations = field.isAnnotationPresent(MapValue.class); - - String key = field.getName(); - Object value = field.get(obj); - if (value == null) continue; - - if (hasAnnotations) { - MapValue annotation = field.getDeclaredAnnotation(MapValue.class); - if (annotation.ignore()) { - continue; - } - - if (!isEmptyString(annotation.value())) { - key = annotation.value(); - } - } - map.put(key, value); - } - - return map; - } - - /** - * Convert a generic map to Stringed map where the key and value are both strings - * - * @param map map to convert - * @param The expected class of the key - * @param The expected class of the value - * @return convertedMap - */ - public static Map convertToStringMap(Map map) { - Map convert = new LinkedHashMap<>(); - for (Entry item : map.entrySet()) { - convert.put(String.valueOf(item.getKey()), String.valueOf(item.getValue())); - } - - return convert; - } - - /** - * Converts an object toa string map; - * - * @param obj the object to convert - * @return the map - * @throws Exception thrown if something happens - */ - public static Map convertToStringMap(Object obj) throws Exception { - return convertToStringMap(convertToMap(obj)); - } - - /*** - * Takes an input list and converts it to another list denoted by what is grabbed from the fieldName - * @param fieldName Name of the field in the object to retrieve - * @param list the list to retrieve values from - * @param The expected class of the List - * @param The expected class of the Iterable list - * @return The converted list - */ - public static Set extractFieldToSet(String fieldName, Iterable list) { - return listToSet(extractFieldToList(fieldName, list)); - } - - /** - * Extract a field from an iterable object and place them in a set - * - * @param fieldName field to check - * @param list list to iterate - * @param The expected class of the Set - * @param The Expected class of the iterable list - * @return set with the desired items - */ - @SuppressWarnings("unchecked") - public static List extractFieldToList(String fieldName, Iterable list) { - List newSet = new ArrayList<>(); - Field field; - for (K item : Utils.safeIterable(list)) { - try { - field = getField(item.getClass(), fieldName); - - if (field == null) { - throw new IllegalArgumentException("Unable to find field with name " + fieldName); - } - - E val = (E) field.get(item); - newSet.add(val); - - } catch (Exception ex) { - throw new IllegalArgumentException(ex); - } - } - return newSet; - } - - /** - * Filters out items in a list with the given parameters - * - * @param fieldName the field name to inspect for the filter value - * @param filter the filter value to retrieve - * @param list the list to inspect - * @param the expected class of the iterable list - * @return List of items that met the criteria of the filter - */ - @SuppressWarnings("unchecked") - public static List filterList(String fieldName, Object filter, Iterable list) { - List newList = new ArrayList<>(); - - Field field; - - for (E item : safeIterable(list)) { - try { - field = getField(item.getClass(), fieldName); - - if (field == null) { - throw new IllegalArgumentException("Unable to find field with name " + fieldName); - } - - E val = (E) field.get(item); - if (val.equals(filter)) { - newList.add(item); - } - } catch (Exception ex) { - throw new IllegalArgumentException(ex); - } - } - - return newList; - } - - /** - * Find a value within the list. - * Public method of type E called "findValue". - * The method takes a parameter of type E called "itemToFind" and a String parameter called "fieldName" and a parameter of type List called "list". - * The method loops through each item in the list and tries to get the class name and return it as an item. - * The method the takes each item and searches for it in the list. - * - * @param itemToFind - The Item to find - * @param fieldName - The field name where the item is in - * @param list - The list to search - * @param - The expected class of item to be found - * @param - The expected class of the Iterable list - * @return - Returns the value of the specified field or null if there is no value. - * - */ - @SuppressWarnings({"unlikely-arg-type"}) - public static E findValue(E itemToFind, String fieldName, List list) { - return findValues(itemToFind, fieldName, list).stream().findFirst().orElse(null); - } - - /** - * Find values list. - * Public method of type List called "findValues". - * The method takes an E type parameter called "valueToFind" and a String parameter called "fieldName" and a List parameter called "list". - * The method creates a new array list called "tmpList". - * The method then iterates through the list and gets all the classes as items. - * If it can't find the fields, it will throw an illegal argument exception. - * - * @param valueToFind - The value to find - * @param fieldName - The field name - * @param list - The list - * @param - The expected class of item to be found - * @param - The expected class of the Iterable list - * @return - Returns the list. - */ - @SuppressWarnings({"unlikely-arg-type"}) - public static List findValues(E valueToFind, String fieldName, List list) { - List extracted = extractFieldToList(fieldName, list); - return extracted.stream() - .filter(Objects::nonNull) - .filter(v -> v.equals(valueToFind)).collect(Collectors.toList()); - } - - /** - * Use reflection to get the field values - * - * @param clazz the class to find the field - * @param fieldName the field name - * @return field - */ - private static Field getField(Class clazz, String fieldName) { - Field field = null; - while (clazz != null) { - try { - field = clazz.getDeclaredField(fieldName); - field.setAccessible(true); - break; - } catch (Exception ex) { - clazz = clazz.getSuperclass(); - } - } - - return field; - } - - /** - * A replacement for String.format. Allows for to many parameters or too few - * Replaces {} in the string in order. - * - * @param message the message - * @param args the args - * @return string - */ - public static String formatString(String message, Object... args) { - String tmp = message; - - for (Object arg : args) { - tmp = tmp.replaceFirst("\\{\\}", String.valueOf(arg)); - } - - return tmp; - } - - /** - * Get a class name - * - * @param the type parameter - * @param obj the obj - * @return class name - */ - public static String getClassName(V obj) { - return getClassName(obj, false); - } - - /** - * Get a class name - * - * @param the type parameter - * @param obj the obj - * @param verbose the verbose - * @return class name - */ - public static String getClassName(V obj, boolean verbose) { - return obj == null ? "Unknown" : (verbose ? obj.getClass().getName() : obj.getClass().getSimpleName()); - } - - /** - * Get a value from a map - * - * @param the type parameter - * @param the type parameter - * @param map the map with values - * @param key the key to find - * @return map value - */ - public static T getMapValue(Map map, K key) { - return getMapValue(map, key, null); - } - - /** - * Get a value from a map - * - * @param the type parameter - * @param the type parameter - * @param map the map with the values - * @param key the key to find - * @param defaultValue the default value if the key is not found - * @return map value - */ - public static T getMapValue(Map map, K key, T defaultValue) { - return map.getOrDefault(key, defaultValue); - } - - /** - * Checks to see if the proved string is empty - * new String(null) = true - * new String("") = true - * new String(" ") = true - * new String("foo") = false - * new String(" bar ") = false - * - * @param string String to check - * @return true if the string is empty false otherwise - */ - public static boolean isEmptyString(String string) { - return string == null || string.trim().isEmpty(); - } - - /** - * Checks to see if a passed in value is not a valid value - * For Strings checks to see if they are empty or not null - * For collections checks to see if they are null or empty - * for all others just checks if they are null - * - * @param the expected class type of the object - * @param values The value to check - * @return true if the value is not valid, false otherwise - */ - @SafeVarargs - public static boolean isNotValid(V... values) { - return !validateValues(values); - } - - /** - * Checks to see if a passed in value is a valid value - * For Strings checks to see if they are not empty or not null - * For collections checks to see if they are not null and not empty - * for all others just checks if they are not null - * - * @param the expected class type of the object - * @param values The value to check - * @return true if the value is valid, false otherwise - */ - @SafeVarargs - public static boolean isValid(V... values) { - return validateValues(values); - } - - /** - * Is primitive or wrapper boolean. - * - * @param clazz the clazz - * @return the boolean - */ - public static boolean isPrimitiveOrWrapper(Class clazz) { - return clazz.isPrimitive() || getWrapperTypes().contains(clazz); - } - - /** - * Converts a list of items into a map. - * - * @param the type parameter - * @param the type parameter - * @param keyFieldName the name of the field that will be used as the key - * @param list the list to convert - * @return a map - */ - @SuppressWarnings("unchecked") - public static Map listToMap(String keyFieldName, List list) { - Map map = new HashMap<>(); - - for (V value : Utils.safeList(list)) { - try { - Field field = getField(value.getClass(), keyFieldName); - K key = (K) field.get(value); - map.put(key, value); - } catch (Exception e) { - throw new IllegalArgumentException(String.format("Unable to find field %s. -> %s", keyFieldName, e.getMessage())); - } - } - - return map; - } - - /** - * List to set. - * - * @param the type parameter - * @param valueSet the value set - * @return the set - */ - public static Set listToSet(Collection valueSet) { - return toSet(valueSet); - } - - /** - * Creates an array from a collection - * Public method of type array called "makeArray". - * The method takes a Collection object parameter called "collection" and a Class object parameter called "clazz". - * The method first checks to see if the Collection object is null. If so, it returns null. - * The method then creates an array called "results" and populates it with a new instance of "clazz" and the size of the collection. - * The method then creates an Int variable called "index" and sets the value to zero. - * The method then iterates through the collection and adds all the items to the results array. - * The method then returns the results array. - * - * @param - The type parameter - * @param collection - The collection - * @param clazz - The clazz - * @return e[] - Returns the array of results. - */ - @SuppressWarnings("unchecked") - public static E[] makeArray(Collection collection, Class clazz) { - if (collection == null) { - return null; - } - - E[] results = (E[]) Array.newInstance(clazz, collection.size()); - - int index = 0; - for (E item : collection) { - results[index++] = item; - } - - return results; - } - - /** - * Creates a list from a collection. - * Public method of type List called "makeList". - * The method takes a Collection object parameter called "collection". - * The method checks to see if the Collection Object is null. If so, it returns null. - * Otherwise, it creates an ArrayList object called "list". - * It then iterates through the Collection Object and adds all the collection items to that list. - * The method then returns the list. - * - * @param - The type parameter - * @param collection - The collection - * @return - Returns the list. - */ - public static List makeList(Collection collection) { - if (collection == null) { - return null; - } - return new ArrayList<>(collection); - } - - /** - * Public method of type List called "makeList". - * The method takes a parameter of type E array called "array". - * The method checks to see if the array is null. If so, it returns null. - * Otherwise, it creates an ArrayList object called "newList". - * It then iterates through the array and adds all the items to the new list. - * The method then returns the list. - * - * @param - The type parameter - * @param array - The array - * @return - Returns the list. - */ - public static List makeList(E[] array) { - if (array == null) { - return null; - } - - return List.of(array); - } - - /** - * Creates a list from an iterable object - * Public method of type List called "makeList". - * The method takes an Iterable object parameter called "iter". - * The method checks to see if the object is null. If so, it returns null. - * Otherwise, it creates a new ArrayList object called "list". - * It then iterates through the Iterable object and adds items to it. - * After that it returns the list. - * - * @param iter - The object to iterate over. - * @param - The expected class of the Iterable object - * @return - Returns the list. - */ - public static List makeList(Iterable iter) { - if (iter == null) { - return null; - } - List list = new ArrayList<>(); - for (E item : iter) { - list.add(item); - } - return list; - } - - /** - * Public method of type Set called "makeSet". - * The method takes an Iterable object parameter called "collection". - * The method first creates a new HashSet called "set". - * The method then iterates through the collection and adds all the items from it to the HashSet. - * The method then returns the HashSet. - * - * @param - The type parameter - * @param collection - The iterable object name. - * @return - Returns the HashSet with all the items of the collection inside of it. - */ - public static Set makeSet(Iterable collection) { - Set set = new HashSet<>(); - for (E item : safeIterable(collection)) { - set.add(item); - } - return set; - } - - /** - * Map to list. - * - * @param the type parameter - * @param the type parameter - * @param map the map - * @return the list - */ - public static List mapToList(Map map) { - - return new ArrayList<>(map.values()); - } - - /** - * Map to set. - * - * @param the type parameter - * @param the type parameter - * @param map the map - * @return the set - */ - public static Set mapToSet(Map map) { - - return new HashSet<>(map.values()); - } - - /** - * Reverse a map switching key value pairs - * - * @param the type parameter - * @param the type parameter - * @param map the map - * @return map with reverse key value pairs - */ - public static Map reverseMap(Map map) { - return map.entrySet().stream().collect(Collectors.toMap(Entry::getValue, Entry::getKey)); - } - - /** - * create safe array e [ ]. - * - * @param the type parameter - * @param list the list - * @return the e [ ] - */ - @SuppressWarnings("unchecked") - public static E[] safeArray(E[] list) { - if (!validateValue(list)) { - return (E[]) new Object[0]; - } - return list; - } - - - /** - * Creates a safe list - * - * @param the type parameter - * @param list The list to check - * @return an empty list if list is invalid or the list if its valid - */ - public static Collection safeList(Collection list) { - if (!validateValue(list)) { - return new ArrayList<>(); - } - return list; - } - - - /** - * Creates a safe list - * - * @param the type parameter - * @param list The list to check - * @return an empty list if list is invalid or the list if its valid - */ - public static Iterable safeIterable(Iterable list) { - if (!validateValue(list)) { - return new ArrayList<>(); - } - return list; - } - - /** - * Creates a safe set - * - * @param the type parameter - * @param set the set to check - * @return an empty set if the set is null otherwise the set - */ - public static Set safeSet(Set set) { - if (set == null) { - return new HashSet<>(); - } - return set; - } - - /** - * Checks to see if a string is not blank or null. - * if it's not blank it will return the string - * otherwise it will return an empty string - * - * @param string The string to check - * @return the passed in string if it's not null either empty string - */ - public static String safeString(String string) { - return isEmptyString(string) ? "" : string; - } - - /** - * Sets to list. - * - * @param the type parameter - * @param valueSet the value set - * @return the to list - */ - public static List setToList(Set valueSet) { - return new ArrayList<>(valueSet); - } - - /** - * Converts a String into an integer without exception - * - * @param value The string value to convert - * @param defaultValue The default value to return if the string cant be converted - * @return the integer representation of the passed in string or the default value if an exception occurred - */ - public static Integer toInteger(String value, Integer defaultValue) { - try { - return Integer.parseInt(value); - } catch (Exception ex) { - return defaultValue; - } - } - - /** - * Create a list from given values - * - * @param the type parameter - * @param values the values to add the list - * @return List containing said values - */ - @SafeVarargs - public static List toList(E... values) { - return Arrays.asList(values); - } - - public static List toList(Iterable iterable) { - List list = new ArrayList<>(); - for (E item : iterable) { - list.add(item); - } - return list; - } - - /** - * Create a set from given values - * - * @param the type parameter - * @param values the values to add the set - * @return Set containing said values - */ - @SafeVarargs - public static Set toSet(E... values) { - return new LinkedHashSet<>(Arrays.asList(values)); - } - - public static List toByteList(byte[] bytes) { - return IntStream.range(0, bytes.length) - .mapToObj(index -> bytes[index]) - .collect(Collectors.toList()); - } - - /** - * Converts an iterable object to a hash set - * - * @param iterable The Iterable object to convert - * @param the class type of the set - * @return set with the iterable items inside - */ - public static Set toSet(Iterable iterable) { - Set set = new HashSet<>(); - for (E value : iterable) { - set.add(value); - } - return set; - } - - public static long size(Iterable iterable) { - long count = 0; - for (Iterator iter = iterable.iterator(); iter.hasNext(); iter.next()) { - count++; - } - return count; - } - - public static E get(Iterable iterable, int index) { - AtomicInteger count = new AtomicInteger(0); - Optional test = StreamUtils.asStream(iterable) - .filter(item -> count.getAndIncrement() == index) - .findFirst(); - return test.orElse(null); - } - - public static Consumer handleExceptionWrapper(ThrowingConsumer consumer) { - return i -> { - try { - consumer.accept(i); - } catch (Exception ex) { - throw new RuntimeException(ex); - } - }; - } - - /** - * Public method of type Boolean called "validateValue". - * The method takes an Object parameter called "value". - * The method loops through and checks to see if value is empty. - * If so, it will return that the value is not null and that it is not empty. - * Otherwise, it will check to see the value is an instance of Map. - * If so, it will return that the value is not null and that it is not empty. - * Otherwise, it will check to see if value is an instance of a String. - * If so, it will return that the value is not null and that it is not empty. - * Otherwise, it will check to see if value is an instance of a Collection Object. - * If so, it will return that the value is not null and if the value size is greater than zero. - * Otherwise, it will just return that the value is not null and not empty. - * - * @param - The type parameter - * @param value - Value to validate - * @return - Returns true if it is valid; false otherwise - */ - @SuppressWarnings("rawtypes") - public static boolean validateValue(V value) { - if (value == null) { - return false; - } - if (value instanceof Collection) { - return !((Collection) value).isEmpty(); - } else if (value instanceof Map) { - return !((Map) value).isEmpty(); - } else if (value instanceof Boolean) { - return ((Boolean) value); - } - - return !value.toString().trim().isEmpty(); - } - - /** - * Validates all given values. - * Public method of type Boolean called "validateValues". - * The method takes multiple V type objects called "objectToValidate". - * The method creates a boolean type variable called "valid" and sets it to true. - * The method then loops through all the objects and validates each value in the object. - * The method sets valid equal to the result of true and false. - * If the method cannot validate the object values, it will throw an exception. If so, it returns false. - * Otherwise, the method will return the variable called "valid". - * - * @param - The type parameter - * @param objectsToValidate - Objects to validate - * @return - Returns true if all objects are valid false otherwise. - */ - @SafeVarargs - public static boolean validateValues(V... objectsToValidate) { - return validateValues(false, toList(objectsToValidate)); - } - - @SafeVarargs - public static boolean validateValuesOr(V... objectsToValidate) { - return validateValues(true, toList(objectsToValidate)); - } - - /** - * Validates all given values to - * - * @param or Set the or flag to check for at least one validated value - * @param objectsToValidate objects to validate. - * @param the expected class type of the objects passed in. All objects need to be of same type - * @return true if the values are valid, false otherwise - */ - public static boolean validateValues(boolean or, List objectsToValidate) { - boolean valid = !or; - for (Object obj : objectsToValidate) { - if (or && validateValue(obj)) { - return true; - } - valid &= validateValue(obj); - } - - return valid; - } - - public static boolean isJUnitRunning() { - StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); - Optional junit = StreamUtils.asStream(stackTrace) - .map(StackTraceElement::getClassName) - .filter(className -> className.startsWith("org.junit.")) - .findFirst(); - return junit.isPresent(); - } - - private static Set> getWrapperTypes() { - return Set.of( - Boolean.class, - Character.class, - Byte.class, - Short.class, - Integer.class, - Long.class, - Float.class, - Double.class, - String.class - ); - } -} diff --git a/src/main/resources/log4j.xml b/src/main/resources/log4j.xml deleted file mode 100644 index f381635..0000000 --- a/src/main/resources/log4j.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - %d{dd-MMM-yyyy HH:mm:ss.SSS} %m%n - - - - - - - - - - - - - - diff --git a/src/test/java/net/locusworks/common/configuration/ConfigurationCoverageTest.java b/src/test/java/net/locusworks/common/configuration/ConfigurationCoverageTest.java deleted file mode 100644 index c20e127..0000000 --- a/src/test/java/net/locusworks/common/configuration/ConfigurationCoverageTest.java +++ /dev/null @@ -1,165 +0,0 @@ -package net.locusworks.common.configuration; - -import net.locusworks.common.exceptions.ApplicationException; -import net.locusworks.common.interfaces.PersistableRequest; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.io.TempDir; - -import java.io.BufferedReader; -import java.io.StringReader; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; -import java.util.Properties; -import java.util.Set; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.Mockito.CALLS_REAL_METHODS; -import static org.mockito.Mockito.mockStatic; - -import org.mockito.MockedStatic; - -class ConfigurationCoverageTest { - @TempDir - Path tempDir; - - static class Manager extends ConfigurationManager { - void initialize(Path base, byte[] key, ConfigurationCallback callback) throws Exception { - init(base.toString(), "test.properties", key, callback); - } - - void initialize(Path base, ConfigurationCallback callback) throws Exception { - init(base.toString(), "test.properties", callback); - } - } - - static class Request implements PersistableRequest { - private String dbHost; - private String dbPort; - private String ignored; - - Request(String dbHost, String dbPort, String ignored) { - this.dbHost = dbHost; - this.dbPort = dbPort; - this.ignored = ignored; - } - } - - @Test - void managerCreatesLoadsReconcilesSavesAndReportsConfiguration() throws Exception { - List messages = new ArrayList<>(); - Manager manager = new Manager(); - manager.initialize(tempDir, "seed".getBytes(), messages::add); - - assertEquals("localhost", manager.getPropertyValue("dbHost")); - assertEquals("fallback", manager.getPropertyValue("missing", "fallback")); - assertNull(manager.getPropertyValue("missing")); - assertEquals(4, manager.getConfiguration().size()); - assertTrue(Files.exists(tempDir.resolve("test.properties"))); - assertTrue(messages.stream().anyMatch(m -> m.contains("Added new configuration"))); - - Properties changed = new Properties(); - changed.putAll(manager.getConfiguration()); - changed.setProperty("dbHost", "remote"); - changed.setProperty("obsolete", "remove me"); - manager.saveToConf(changed); - assertEquals("remote", manager.getPropertyValue("dbHost")); - assertFalse(manager.getConfiguration().containsKey("obsolete")); - assertTrue(messages.stream().anyMatch(m -> m.contains("Saved config file"))); - } - - @Test - void managerPersistsSelectedPlainAndEncryptedFieldsAndSkipsUnchangedOnes() throws Exception { - Manager manager = new Manager(); - manager.initialize(tempDir, new byte[0], null); - - assertThrows(ApplicationException.class, - () -> manager.saveConfiguration(new Request("x", "1", "x"), null, null)); - assertThrows(ApplicationException.class, - () -> manager.saveConfiguration(new Request("x", "1", "x"), Set.of(), null)); - - manager.saveConfiguration(new Request("new-host", "3306", "ignored"), - Set.of("dbHost", "dbPort"), null); - assertEquals("new-host", manager.getPropertyValue("dbHost")); - assertEquals("3306", manager.getPropertyValue("dbPort")); - - manager.saveConfiguration(new Request("encrypted-host", "3306", "ignored"), - Set.of("dbHost", "dbPort", "ignored"), Set.of("dbHost")); - assertNotEquals("encrypted-host", manager.getPropertyValue("dbHost")); - - assertThrows(ApplicationException.class, - () -> manager.saveConfiguration(null, Set.of("dbHost"), Set.of())); - - assertDoesNotThrow(() -> manager.saveConfiguration( - new Request("ignored", "3306", "ignored"), Set.of("dbPort"), Set.of())); - } - - @Test - void managerConvenienceInitializationAndBothLoadFailuresAreCovered() throws Exception { - Path convenience = Files.createDirectory(tempDir.resolve("convenience")); - Manager normal = new Manager(); - normal.initialize(convenience, null); - assertNotNull(normal.getConfiguration()); - - try (MockedStatic properties = mockStatic(PropertiesManager.class, CALLS_REAL_METHODS)) { - properties.when(() -> PropertiesManager.loadConfiguration(Manager.class, "test.properties")) - .thenThrow(new java.io.IOException("template failed")); - assertThrows(java.io.IOException.class, - () -> new Manager().initialize(tempDir, "seed".getBytes(), null)); - } - - Path activeFailure = Files.createDirectory(tempDir.resolve("active-failure")); - try (MockedStatic properties = mockStatic(PropertiesManager.class, CALLS_REAL_METHODS)) { - Path activeFile = activeFailure.resolve("test.properties"); - properties.when(() -> PropertiesManager.loadConfiguration(activeFile)) - .thenThrow(new java.io.IOException("active failed")); - Manager recovered = new Manager(); - recovered.initialize(activeFailure, "seed".getBytes(), null); - assertEquals(4, recovered.getConfiguration().size()); - } - } - - @SuppressWarnings("deprecation") - @Test - void propertiesManagerCoversResourcesFilesReadersMergeRemovalAndSaveFailures() throws Exception { - assertNotNull(new PropertiesManager()); - assertNull(PropertiesManager.loadConfiguration(getClass(), "missing.properties")); - Properties resource = PropertiesManager.loadConfiguration(getClass(), "/test.properties"); - assertEquals(4, resource.size()); - - Path missing = tempDir.resolve("missing.properties"); - assertTrue(PropertiesManager.loadConfiguration(missing).isEmpty()); - - Properties parsed = PropertiesManager.loadConfiguration( - new BufferedReader(new StringReader("one=1\ntwo=2"))); - assertEquals("1", parsed.getProperty("one")); - - Properties destination = new Properties(); - destination.setProperty("one", "existing"); - Properties additions = new Properties(); - additions.setProperty("one", "replacement"); - additions.setProperty("two", "2"); - assertEquals(1, PropertiesManager.addConfiguration(destination, additions).size()); - assertEquals("existing", destination.getProperty("one")); - - destination.setProperty("obsolete", "old"); - Properties expected = new Properties(); - expected.setProperty("one", "existing"); - assertEquals(2, PropertiesManager.removeConfiguration(destination, expected).size()); - assertEquals(Set.of("one"), destination.keySet()); - - Path saved = tempDir.resolve("saved.properties"); - PropertiesManager.saveConfiguration(expected, saved.toFile(), null); - assertEquals("existing", PropertiesManager.loadConfiguration(saved.toFile()).getProperty("one")); - assertThrows(RuntimeException.class, - () -> PropertiesManager.saveConfiguration(expected, tempDir, "failure")); - } -} diff --git a/src/test/java/net/locusworks/common/crypto/AESAndHashSaltCoverageTest.java b/src/test/java/net/locusworks/common/crypto/AESAndHashSaltCoverageTest.java deleted file mode 100644 index 1c5f324..0000000 --- a/src/test/java/net/locusworks/common/crypto/AESAndHashSaltCoverageTest.java +++ /dev/null @@ -1,80 +0,0 @@ -package net.locusworks.common.crypto; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertInstanceOf; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertSame; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import org.junit.jupiter.api.Test; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - - -class AESAndHashSaltCoverageTest { - @Test - void aesFactoriesSeedChangesEmptyValuesAndFailures() throws Exception { - AES bytes = AES.createInstance("byte seed".getBytes()); - assertEquals("byte seed", bytes.getSeed()); - assertEquals("", bytes.decrypt(bytes.encrypt(null))); - assertEquals("", bytes.decrypt(null)); - - String encrypted = bytes.encrypt("value"); - assertSame(bytes, bytes.withSeed("byte seed")); - assertEquals("value", bytes.decrypt(encrypted)); - assertSame(bytes, bytes.withSeed("different seed")); - assertEquals("different seed", bytes.getSeed()); - assertThrows(IllegalArgumentException.class, () -> bytes.decrypt(encrypted)); - assertThrows(IllegalArgumentException.class, () -> bytes.decrypt("AA==")); - assertNotNull(AES.createInstance()); - assertThrows(IllegalArgumentException.class, () -> AES.createInstance((String) null)); - - AES uninitialized = new AES(); - assertThrows(IllegalArgumentException.class, () -> uninitialized.encrypt("value")); - Method init = AES.class.getDeclaredMethod("init", byte[].class); - init.setAccessible(true); - InvocationTargetException initFailure = assertThrows(InvocationTargetException.class, - () -> init.invoke(uninitialized, (Object) new byte[16])); - assertInstanceOf(IllegalArgumentException.class, initFailure.getCause()); - } - - @Test - void aesMainValidatesArgumentsAndSupportsEncryptAndDecryptModes() throws Exception { - assertThrows(IllegalArgumentException.class, () -> AES.main(null)); - assertThrows(IllegalArgumentException.class, () -> AES.main(new String[0])); - assertDoesNotThrow(() -> AES.main(new String[]{"plain"})); - - AES aes = AES.createInstance("seed"); - assertDoesNotThrow(() -> AES.main(new String[]{aes.encrypt("plain"), "seed"})); - } - - @Test - void hashSaltSupportsStringAndCharacterPasswordsAndInvalidInputs() throws Exception { - assertNotNull(new HashSalt()); - String hash = HashSalt.createHash("password".toCharArray()); - assertTrue(HashSalt.validatePassword("password".toCharArray(), hash)); - assertFalse(HashSalt.validatePassword("wrong", hash)); - assertFalse(HashSalt.validatePassword("wrong".toCharArray(), hash)); - assertThrows(RuntimeException.class, () -> HashSalt.validatePassword("password", "bad")); - - Method toHex = HashSalt.class.getDeclaredMethod("toHex", byte[].class); - toHex.setAccessible(true); - assertEquals("0001", toHex.invoke(null, (Object) new byte[]{0, 1})); - - Method slowEquals = HashSalt.class.getDeclaredMethod("slowEquals", byte[].class, byte[].class); - slowEquals.setAccessible(true); - assertEquals(false, slowEquals.invoke(null, new byte[]{1}, new byte[]{1, 2})); - assertEquals(false, slowEquals.invoke(null, new byte[]{1, 2}, new byte[]{1})); - } - - @Test - void hashSaltMainValidatesArgumentsAndPrintsHash() { - assertThrows(IllegalArgumentException.class, () -> HashSalt.main(null)); - assertThrows(IllegalArgumentException.class, () -> HashSalt.main(new String[0])); - assertDoesNotThrow(() -> HashSalt.main(new String[]{"password"})); - } -} diff --git a/src/test/java/net/locusworks/common/crypto/CryptoCoverageTest.java b/src/test/java/net/locusworks/common/crypto/CryptoCoverageTest.java deleted file mode 100644 index f3b6371..0000000 --- a/src/test/java/net/locusworks/common/crypto/CryptoCoverageTest.java +++ /dev/null @@ -1,227 +0,0 @@ -package net.locusworks.common.crypto; - -import net.locusworks.common.crypto.KeyFile.EncryptionType; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.io.TempDir; - -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.security.KeyPair; -import java.security.spec.InvalidKeySpecException; -import java.util.Base64; -import java.io.IOException; -import java.io.Writer; -import java.lang.reflect.Field; - -import static org.junit.jupiter.api.Assertions.assertArrayEquals; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertInstanceOf; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertSame; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.Mockito.CALLS_REAL_METHODS; -import static org.mockito.Mockito.mockStatic; - -import org.mockito.MockedStatic; - -class CryptoCoverageTest { - @TempDir - Path tempDir; - - @Test - void aesKeyAndSpecRoundTripAndRejectMalformedData() throws Exception { - AESKey key = new AESKey("repeatable seed"); - assertEquals("aes", key.getAlgorithm()); - assertEquals("aes-seed", key.getFormat()); - assertArrayEquals("repeatable seed".getBytes(StandardCharsets.UTF_8), key.getEncoded()); - - String encoded = "aes-seed " + Base64.getEncoder().encodeToString(key.getEncoded()); - AESKeySpec spec = new AESKeySpec(encoded.getBytes(StandardCharsets.UTF_8)); - assertEquals("aes", spec.getFormat()); - assertArrayEquals(key.getEncoded(), spec.generateKey().getEncoded()); - assertThrows(InvalidKeySpecException.class, - () -> new AESKeySpec("wrong value".getBytes(StandardCharsets.UTF_8)).generateKey()); - assertThrows(InvalidKeySpecException.class, - () -> new AESKeySpec("aes-seed !!!".getBytes(StandardCharsets.UTF_8)).generateKey()); - } - - @Test - void encryptionKeyFactoryHandlesAesRsaAndSshSpecs() throws Exception { - EncryptionKeyFactory factory = EncryptionKeyFactory.getInstance("RSA"); - String aes = "aes-seed " + Base64.getEncoder().encodeToString("seed".getBytes(StandardCharsets.UTF_8)); - assertInstanceOf(AESKey.class, factory.generatePrivateKey(new AESKeySpec(aes.getBytes(StandardCharsets.UTF_8)))); - - KeyPair pair = RSA.generateKeyPair(1024); - assertEquals(pair.getPrivate(), factory.generatePrivateKey( - new java.security.spec.PKCS8EncodedKeySpec(pair.getPrivate().getEncoded()))); - assertEquals(pair.getPublic(), factory.generatePublicKey( - new java.security.spec.X509EncodedKeySpec(pair.getPublic().getEncoded()))); - - Path ssh = tempDir.resolve("public.ssh"); - try (KeyFile file = new KeyFile(pair.getPublic(), "test", EncryptionType.SSH)) { - file.write(ssh.toString()); - } - SSHEncodedKeySpec sshSpec = new SSHEncodedKeySpec(Files.readAllBytes(ssh)); - assertNull(sshSpec.getFormat()); - assertEquals(pair.getPublic(), factory.generatePublicKey(sshSpec)); - assertEquals(pair.getPublic(), KeyFile.read(ssh.toString()).getKey()); - assertThrows(InvalidKeySpecException.class, - () -> new SSHEncodedKeySpec("ssh-ed25519 bad".getBytes(StandardCharsets.UTF_8)).convertToRSAPubKeySpec()); - assertThrows(InvalidKeySpecException.class, - () -> new SSHEncodedKeySpec("ssh-rsa !!!".getBytes(StandardCharsets.UTF_8)).convertToRSAPubKeySpec()); - } - - @Test - void rsaGeneratesCalculatesEncryptsDecryptsAndRejectsOversizedMessages() { - assertNotNull(new RSA()); - KeyPair defaultPair = RSA.generateKeyPair(); - assertNotNull(defaultPair.getPrivate()); - KeyPair pair = RSA.generateKeyPair(1024); - assertEquals(("hello".getBytes(StandardCharsets.UTF_8).length + 11) * 8, - RSA.calculateRequiredKeyLength("hello")); - - String encrypted = RSA.encrypt(pair.getPublic(), "hello RSA"); - assertEquals("hello RSA", RSA.decrypt(pair.getPrivate(), encrypted)); - assertThrows(RuntimeException.class, () -> RSA.decrypt(pair.getPrivate(), "not base64")); - assertThrows(RuntimeException.class, () -> RSA.encrypt(pair.getPublic(), "x".repeat(200))); - assertThrows(RuntimeException.class, () -> RSA.generateKeyPair(1)); - } - - @Test - void keyFileWritesAesPemAndSshFormatsAndProvidesDescriptions() throws Exception { - AESKey aesKey = new AESKey("seed"); - Path aesPath = tempDir.resolve("aes.key"); - try (KeyFile file = new KeyFile(aesKey)) { - assertEquals("PRIVATE KEY", file.getDescription()); - file.setDescription("AES KEY"); - assertEquals("AES KEY", file.getDescription()); - assertSame(aesKey, file.getKey()); - file.write(aesPath.toString()); - } - assertEquals("aes-seed c2VlZA==", Files.readString(aesPath)); - - KeyPair pair = RSA.generateKeyPair(1024); - Path privatePath = tempDir.resolve("private.pem"); - try (KeyFile file = new KeyFile(pair.getPrivate())) { - file.write(privatePath.toString()); - } - assertTrue(Files.readString(privatePath).contains("BEGIN RSA PRIVATE KEY")); - - Path publicPath = tempDir.resolve("public.pem"); - try (KeyFile file = new KeyFile(pair.getPublic(), "CUSTOM")) { - file.write(publicPath.toString()); - } - assertTrue(Files.readString(publicPath).contains("BEGIN RSA CUSTOM")); - assertEquals("PUBLIC KEY", new KeyFile(pair.getPublic()).getDescription()); - - Path sshPath = tempDir.resolve("id.pub"); - try (KeyFile file = new KeyFile(pair.getPublic(), "comment", EncryptionType.SSH)) { - file.write(sshPath.toString()); - } - assertTrue(Files.readString(sshPath).startsWith("ssh-rsa ")); - assertTrue(Files.readString(sshPath).endsWith(" comment")); - } - - @Test - void keyFileReadHandlesEmptyMissingRecognizedAndInvalidFiles() throws Exception { - assertNull(KeyFile.read(null).getKey()); - RuntimeException missing = assertThrows(RuntimeException.class, - () -> KeyFile.read(tempDir.resolve("missing").toString())); - assertInstanceOf(IllegalArgumentException.class, missing.getCause()); - - Path aesPath = tempDir.resolve("recognized-aes.key"); - new KeyFile(new AESKey("seed")).write(aesPath.toString()); - assertArrayEquals("seed".getBytes(StandardCharsets.UTF_8), KeyFile.read(aesPath.toString()).getKey().getEncoded()); - - Path invalid = tempDir.resolve("invalid.key"); - Files.writeString(invalid, "not a key"); - assertThrows(RuntimeException.class, () -> KeyFile.read(invalid.toString())); - } - - @Test - void rsaWriteConvenienceOverloadsUseRequestedPaths() { - KeyPair pair = RSA.generateKeyPair(1024); - Path privatePath = tempDir.resolve("private.key"); - Path publicPath = tempDir.resolve("public.key"); - assertTrue(RSA.writePrivateKey(pair, privatePath.toString(), "PRIVATE KEY")); - assertTrue(RSA.writePublicKey(pair, publicPath.toString(), "PUBLIC KEY")); - assertTrue(Files.exists(privatePath)); - assertTrue(Files.exists(publicPath)); - - Path sshPath = tempDir.resolve("rsa-ssh.pub"); - assertTrue(RSA.writePublicKey(pair, sshPath.toString(), "comment", true)); - - assertTrue(RSA.generateAndWriteKeyPair(tempDir.resolve("generated").toString(), 1024)); - assertNotNull(RSA.loadKeyPair(publicPath.toString(), privatePath.toString())); - assertNotNull(RSA.loadPublicKey(publicPath.toString()).getPublic()); - assertNotNull(RSA.loadPrivateKey(privatePath.toString()).getPrivate()); - } - - @Test - void keyFileWrapsWritePemAndCloseFailures() throws Exception { - KeyPair pair = RSA.generateKeyPair(1024); - KeyFile invalidWrite = new KeyFile(pair.getPrivate()); - assertThrows(IllegalArgumentException.class, () -> invalidWrite.write(tempDir.toString())); - - KeyFile closeFailure = new KeyFile(pair.getPrivate()); - Field writerField = KeyFile.class.getDeclaredField("writer"); - writerField.setAccessible(true); - writerField.set(closeFailure, new Writer() { - @Override - public void write(char[] cbuf, int off, int len) { - } - - @Override - public void flush() throws IOException { - throw new IOException("flush failed"); - } - - @Override - public void close() { - } - }); - assertThrows(RuntimeException.class, closeFailure::close); - } - - @Test - void rsaConvenienceDelegatesAndShortCircuitPaths() { - KeyPair pair = RSA.generateKeyPair(1024); - try (MockedStatic rsa = mockStatic(RSA.class, CALLS_REAL_METHODS)) { - rsa.when(RSA::generateKeyPair).thenReturn(pair); - rsa.when(() -> RSA.writePrivateKey(pair)).thenReturn(true); - rsa.when(() -> RSA.writePublicKey(pair, true)).thenReturn(true); - assertTrue(RSA.generateAndWriteSSHKeys()); - rsa.when(() -> RSA.writePrivateKey(pair)).thenReturn(false); - assertFalse(RSA.generateAndWriteSSHKeys()); - rsa.when(() -> RSA.writePrivateKey(pair)).thenReturn(true); - rsa.when(() -> RSA.writePublicKey(pair, true)).thenReturn(false); - assertFalse(RSA.generateAndWriteSSHKeys()); - - rsa.when(() -> RSA.generateAndWriteKeyPair(2048)).thenReturn(true); - assertTrue(RSA.generateAndWriteKeyPair()); - rsa.when(() -> RSA.generateAndWriteKeyPair("named", 2048)).thenReturn(true); - assertTrue(RSA.generateAndWriteKeyPair("named")); - rsa.when(() -> RSA.generateAndWriteKeyPair("id_rsa", 1024)).thenReturn(true); - assertTrue(RSA.generateAndWriteKeyPair(1024)); - - rsa.when(() -> RSA.generateKeyPair(512)).thenReturn(pair); - rsa.when(() -> RSA.writePrivateKey(pair, "short", "PRIVATE KEY")).thenReturn(false); - assertFalse(RSA.generateAndWriteKeyPair("short", 512)); - rsa.when(() -> RSA.writePrivateKey(pair, "short", "PRIVATE KEY")).thenReturn(true); - rsa.when(() -> RSA.writePublicKey(pair, "short.pub", "PUBLIC KEY")).thenReturn(false); - assertFalse(RSA.generateAndWriteKeyPair("short", 512)); - - rsa.when(() -> RSA.writePrivateKey(pair, "id_rsa", "PRIVATE KEY")).thenReturn(true); - assertTrue(RSA.writePrivateKey(pair)); - rsa.when(() -> RSA.writePublicKey(pair, false)).thenReturn(true); - assertTrue(RSA.writePublicKey(pair)); - rsa.when(() -> RSA.writePublicKey(pair, "id_rsa.pub", "PUBLIC KEY", true)).thenReturn(true); - rsa.when(() -> RSA.writePublicKey(pair, true)).thenCallRealMethod(); - assertTrue(RSA.writePublicKey(pair, true)); - } - } -} diff --git a/src/test/java/net/locusworks/common/exceptions/ApplicationExceptionTest.java b/src/test/java/net/locusworks/common/exceptions/ApplicationExceptionTest.java deleted file mode 100644 index 4d430fb..0000000 --- a/src/test/java/net/locusworks/common/exceptions/ApplicationExceptionTest.java +++ /dev/null @@ -1,43 +0,0 @@ -package net.locusworks.common.exceptions; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertSame; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import org.junit.jupiter.api.Test; - -import java.util.List; - -class ApplicationExceptionTest { - @Test - void factoryMethodsExposeExpectedCodesAndMessages() { - List exceptions = List.of( - ApplicationException.egregiousServer(), ApplicationException.invalidCreds(), - ApplicationException.notLoggedIn(), ApplicationException.invalidEmailAddress(), - ApplicationException.actionNotPermitted(), ApplicationException.actionNotPermitted("delete"), - ApplicationException.passwordsNotEqual(), ApplicationException.unAuthorized(), - ApplicationException.duplicateEntry("duplicate"), ApplicationException.duplicateEntry("duplicate %s", "item"), - ApplicationException.noEntryExists("missing"), ApplicationException.noEntryExists("missing %s", "item"), - ApplicationException.constraintViolation("constraint"), ApplicationException.constraintViolation("constraint %s", "x"), - ApplicationException.illegalArgument("illegal"), ApplicationException.generic("generic")); - - assertTrue(exceptions.stream().noneMatch(ApplicationException::getSuccess)); - assertTrue(exceptions.stream().allMatch(e -> e.getCode() != null && e.getMessage() != null)); - } - - @Test - void constructorsAndThrowableFactoryPreserveCause() { - IllegalStateException cause = new IllegalStateException("failure"); - ApplicationException fromCause = ApplicationException.fromException(cause); - assertEquals(9999, fromCause.getCode()); - assertSame(cause, fromCause.getCause()); - - ApplicationException direct = new ApplicationException(42, cause); - assertEquals("failure", direct.getMessage()); - assertSame(cause, direct.getCause()); - - ApplicationException explicit = new ApplicationException(43, "message", cause); - assertEquals(43, explicit.getCode()); - assertSame(cause, explicit.getCause()); - } -} diff --git a/src/test/java/net/locusworks/common/immutables/ImmutablesTest.java b/src/test/java/net/locusworks/common/immutables/ImmutablesTest.java deleted file mode 100644 index 6b68f34..0000000 --- a/src/test/java/net/locusworks/common/immutables/ImmutablesTest.java +++ /dev/null @@ -1,69 +0,0 @@ -package net.locusworks.common.immutables; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import org.junit.jupiter.api.Test; - - -class ImmutablesTest { - - @Test - void testUnit() { - Unit unit1 = new Unit<>(); - unit1.setValue1("123"); - - Unit unit2 = new Unit<>("123"); - Unit unit3 = new Unit<>("1234"); - - assertEquals(unit1, unit2); - - assertNotEquals(null, unit1); - assertNotEquals(new Object(), unit1); - assertNotEquals(unit3, unit1); - - assertThrows(IllegalArgumentException.class, () -> unit1.setValue1("value")); - } - - @Test - void testPair() { - Pair unit1 = new Pair<>(); - unit1.setValue2("value2"); - unit1.setValue1("123"); - - Pair unit2 = new Pair<>("123", "value2"); - Pair unit3 = new Pair<>("1234", "value2"); - - assertEquals(unit1, unit2); - - assertNotEquals(null, unit1); - assertNotEquals(new Object(), unit1); - assertNotEquals(unit3, unit1); - - assertThrows(IllegalArgumentException.class, () -> unit1.setValue1("value")); - assertThrows(IllegalArgumentException.class, () -> unit1.setValue2("value")); - } - - @Test - void testTriplet() { - Triplet unit1 = new Triplet<>(); - unit1.setValue3("value3"); - unit1.setValue2("value2"); - unit1.setValue1("123"); - - Triplet unit2 = new Triplet<>("123", "value2", "value3"); - Triplet unit3 = new Triplet<>("1234", "value2", "value3"); - - assertEquals(unit1, unit2); - - assertNotEquals(null, unit1); - assertNotEquals(new Object(), unit1); - assertNotEquals(unit3, unit1); - - assertThrows(IllegalArgumentException.class, () -> unit1.setValue1("value")); - assertThrows(IllegalArgumentException.class, () -> unit1.setValue2("value")); - assertThrows(IllegalArgumentException.class, () -> unit1.setValue3("value")); - } - -} diff --git a/src/test/java/net/locusworks/common/io/IOUtilsTest.java b/src/test/java/net/locusworks/common/io/IOUtilsTest.java deleted file mode 100644 index 6c81a65..0000000 --- a/src/test/java/net/locusworks/common/io/IOUtilsTest.java +++ /dev/null @@ -1,158 +0,0 @@ -package net.locusworks.common.io; - -import net.locusworks.common.Charsets; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.io.TempDir; -import org.mockito.MockedStatic; - -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.Reader; -import java.io.StringReader; -import java.io.StringWriter; -import java.io.Writer; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.CALLS_REAL_METHODS; -import static org.mockito.Mockito.mockStatic; - -class IOUtilsTest { - @TempDir - Path tempDir; - - @Test - void readsLinesFromStreamsAndBothReaderKinds() throws Exception { - byte[] text = "first\nsecond\nthird".getBytes(StandardCharsets.UTF_8); - assertEquals(List.of("first", "second", "third"), - IOUtils.readLines(new ByteArrayInputStream(text), StandardCharsets.UTF_8)); - assertEquals(List.of("first", "second", "third"), IOUtils.readLines(new StringReader(new String(text)))); - - BufferedReader buffered = new BufferedReader(new StringReader("line")); - assertSame(buffered, IOUtils.toBufferedReader(buffered)); - assertNotNull(IOUtils.toBufferedReader(new StringReader("line"))); - assertThrows(NullPointerException.class, () -> IOUtils.readLines((Reader) null)); - } - - @Test - void convertsStreamsAndCopiesBytesThroughEveryOverload() throws Exception { - byte[] source = "some binary data".getBytes(StandardCharsets.UTF_8); - assertArrayEquals(source, IOUtils.toByteArray(new ByteArrayInputStream(source))); - - ByteArrayOutputStream defaultCopy = new ByteArrayOutputStream(); - assertEquals(source.length, IOUtils.copy(new ByteArrayInputStream(source), defaultCopy)); - assertArrayEquals(source, defaultCopy.toByteArray()); - - ByteArrayOutputStream sizedCopy = new ByteArrayOutputStream(); - assertEquals(source.length, IOUtils.copy(new ByteArrayInputStream(source), sizedCopy, 2)); - assertArrayEquals(source, sizedCopy.toByteArray()); - - ByteArrayOutputStream bufferedCopy = new ByteArrayOutputStream(); - assertEquals(source.length, - IOUtils.copyLarge(new ByteArrayInputStream(source), bufferedCopy, new byte[3])); - assertArrayEquals(source, bufferedCopy.toByteArray()); - - ByteArrayOutputStream largeCopy = new ByteArrayOutputStream(); - assertEquals(source.length, IOUtils.copyLarge(new ByteArrayInputStream(source), largeCopy)); - assertArrayEquals(source, largeCopy.toByteArray()); - assertEquals(0, IOUtils.copyLarge(new ByteArrayInputStream(new byte[0]), new ByteArrayOutputStream())); - } - - @Test - void copiesCharactersThroughEveryOverload() throws Exception { - String source = "characters-å"; - StringWriter encoded = new StringWriter(); - IOUtils.copy(new ByteArrayInputStream(source.getBytes(StandardCharsets.UTF_8)), encoded, - StandardCharsets.UTF_8); - assertEquals(source, encoded.toString()); - - StringWriter regular = new StringWriter(); - assertEquals(source.length(), IOUtils.copy(new StringReader(source), regular)); - assertEquals(source, regular.toString()); - - StringWriter buffered = new StringWriter(); - assertEquals(source.length(), IOUtils.copyLarge(new StringReader(source), buffered, new char[2])); - assertEquals(source, buffered.toString()); - - StringWriter large = new StringWriter(); - assertEquals(source.length(), IOUtils.copyLarge(new StringReader(source), large)); - assertEquals(source, large.toString()); - assertEquals(0, IOUtils.copyLarge(new StringReader(""), new StringWriter())); - assertEquals(source, IOUtils.toString( - new ByteArrayInputStream(source.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8)); - } - - @Test - void integerCopyMethodsReturnEofMarkerForCountsOverIntegerMaximum() throws Exception { - try (MockedStatic mocked = mockStatic(IOUtils.class, CALLS_REAL_METHODS)) { - mocked.when(() -> IOUtils.copyLarge(any(InputStream.class), any(OutputStream.class))) - .thenReturn((long) Integer.MAX_VALUE + 1); - assertEquals(IOUtils.EOF, - IOUtils.copy(new ByteArrayInputStream(new byte[0]), new ByteArrayOutputStream())); - - mocked.when(() -> IOUtils.copyLarge(any(Reader.class), any(Writer.class))) - .thenReturn((long) Integer.MAX_VALUE + 1); - assertEquals(IOUtils.EOF, IOUtils.copy(new StringReader(""), new StringWriter())); - } - } - - @SuppressWarnings("deprecation") - @Test - void writesFilesUsingEveryOverload() throws Exception { - Path byName = tempDir.resolve("name.txt"); - IOUtils.writeStringToFile(byName.toString(), "default"); - assertEquals("default", Files.readString(byName)); - - Path namedCharset = tempDir.resolve("name-charset.txt"); - IOUtils.writeStringToFile(namedCharset.toString(), "named", StandardCharsets.UTF_16); - assertEquals("named", Files.readString(namedCharset, StandardCharsets.UTF_16)); - - Path byPath = tempDir.resolve("path.txt"); - IOUtils.writeStringToFile(byPath, "path"); - assertEquals("path", Files.readString(byPath, Charsets.UTF_8)); - - Path byFile = tempDir.resolve("file.txt"); - IOUtils.writeStringToFile(byFile.toFile(), "file", StandardCharsets.UTF_8); - assertEquals("file", Files.readString(byFile)); - } - - @SuppressWarnings("deprecation") - @Test - void deletesFilesUsingEveryOverloadAndWrapsIoFailures() throws Exception { - Path byName = Files.createFile(tempDir.resolve("name-delete.txt")); - IOUtils.deleteFile(byName.toString()); - assertFalse(Files.exists(byName)); - - Path byFile = Files.createFile(tempDir.resolve("file-delete.txt")); - IOUtils.deleteFile(byFile.toFile()); - assertFalse(Files.exists(byFile)); - - Path first = Files.createFile(tempDir.resolve("first.txt")); - Path second = Files.createFile(tempDir.resolve("second.txt")); - IOUtils.deleteFiles(first.toString(), second.toString()); - assertFalse(Files.exists(first)); - assertFalse(Files.exists(second)); - - Path nonEmptyDirectory = Files.createDirectory(tempDir.resolve("non-empty")); - Files.createFile(nonEmptyDirectory.resolve("child")); - IllegalArgumentException error = assertThrows(IllegalArgumentException.class, - () -> IOUtils.deleteFile(nonEmptyDirectory)); - assertInstanceOf(IOException.class, error.getCause()); - } - - @Test - void constructorAndInvalidInputsAreCovered() { - assertNotNull(new IOUtils()); - assertThrows(NullPointerException.class, () -> IOUtils.toByteArray(null)); - assertThrows(NegativeArraySizeException.class, - () -> IOUtils.copy(new ByteArrayInputStream(new byte[0]), new ByteArrayOutputStream(), -1)); - } -} diff --git a/src/test/java/net/locusworks/common/migration/MigrationItemTest.java b/src/test/java/net/locusworks/common/migration/MigrationItemTest.java deleted file mode 100644 index 35d613a..0000000 --- a/src/test/java/net/locusworks/common/migration/MigrationItemTest.java +++ /dev/null @@ -1,83 +0,0 @@ -package net.locusworks.common.migration; - -import static org.junit.jupiter.api.Assertions.assertArrayEquals; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import org.flywaydb.core.Flyway; -import org.flywaydb.core.api.MigrationInfo; -import org.flywaydb.core.api.MigrationInfoService; -import org.flywaydb.core.api.configuration.Configuration; -import org.junit.jupiter.api.Test; - -import java.util.ArrayList; -import java.util.List; - - -class MigrationItemTest { - private static Flyway flyway(MigrationInfo[] all, MigrationInfo[] pending) { - Flyway flyway = mock(Flyway.class); - MigrationInfoService info = mock(MigrationInfoService.class); - Configuration configuration = mock(Configuration.class); - when(flyway.info()).thenReturn(info); - when(info.all()).thenReturn(all); - when(info.pending()).thenReturn(pending); - when(flyway.getConfiguration()).thenReturn(configuration); - when(configuration.getSchemas()).thenReturn(new String[]{"first", "second"}); - return flyway; - } - - @Test - void exposesSchemasPendingCountAndMigrationLog() { - Flyway flyway = flyway(new MigrationInfo[0], new MigrationInfo[]{mock(MigrationInfo.class)}); - MigrationItem item = new MigrationItem(flyway); - assertArrayEquals(new String[]{"first", "second"}, item.getSchemas()); - assertEquals(1, item.qtyPending()); - assertNotNull(item.getAllMigrationsLog()); - } - - @Test - void repairAndMigrateInvokeCallbackAndFlyway() { - Flyway flyway = flyway(new MigrationInfo[0], new MigrationInfo[0]); - List messages = new ArrayList<>(); - MigrationItem item = new MigrationItem(flyway, messages::add); - item.repair(); - item.migrate(); - verify(flyway).repair(); - verify(flyway).migrate(); - assertEquals(2, messages.size()); - assertTrue(messages.stream().allMatch(s -> s.contains("first, second"))); - } - - @Test - void repairAndMigrateWrapFlywayFailures() { - Flyway repairFlyway = flyway(new MigrationInfo[0], new MigrationInfo[0]); - doThrow(new IllegalStateException("repair failed")).when(repairFlyway).repair(); - RuntimeException repair = assertThrows(RuntimeException.class, () -> new MigrationItem(repairFlyway).repair()); - assertTrue(repair.getMessage().contains("repair failed")); - - Flyway migrateFlyway = flyway(new MigrationInfo[0], new MigrationInfo[0]); - doThrow(new IllegalStateException("migrate failed")).when(migrateFlyway).migrate(); - RuntimeException migrate = assertThrows(RuntimeException.class, () -> new MigrationItem(migrateFlyway).migrate()); - assertTrue(migrate.getMessage().contains("migrate failed")); - } - - @Test - void baseManagerInitializesMutableMigrationList() { - class Manager extends BaseMigrationManager { - @Override - public void migrate() { - } - } - Manager manager = new Manager(); - assertNotNull(manager.migrations); - assertDoesNotThrow(manager::migrate); - } -} diff --git a/src/test/java/net/locusworks/common/net/HttpClientHelperTest.java b/src/test/java/net/locusworks/common/net/HttpClientHelperTest.java deleted file mode 100644 index 610f3d7..0000000 --- a/src/test/java/net/locusworks/common/net/HttpClientHelperTest.java +++ /dev/null @@ -1,45 +0,0 @@ -package net.locusworks.common.net; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import com.sun.net.httpserver.HttpServer; -import org.junit.jupiter.api.Test; - -import java.net.InetSocketAddress; - -class HttpClientHelperTest { - @Test - void schemaLookupHandlesBothProtocolsAndUnknownValue() { - assertEquals(HttpClientHelper.HttpSchema.HTTP, HttpClientHelper.HttpSchema.findEnum("http")); - assertEquals(HttpClientHelper.HttpSchema.HTTPS, HttpClientHelper.HttpSchema.findEnum("HtTpS")); - assertNull(HttpClientHelper.HttpSchema.findEnum("ftp")); - } - - @Test - void constructorRejectsUnknownProtocol() { - Exception error = assertThrows(Exception.class, () -> new HttpClientHelper("ftp", "localhost", "21")); - assertEquals("Unable to find http schema of ftp", error.getMessage()); - } - - @Test - void executesHttpGetAndConsumesResponse() throws Exception { - HttpServer server = HttpServer.create(new InetSocketAddress("localhost", 0), 0); - server.createContext("/status", exchange -> { - byte[] body = "ok".getBytes(); - exchange.sendResponseHeaders(202, body.length); - exchange.getResponseBody().write(body); - exchange.close(); - }); - server.start(); - try { - HttpClientHelper helper = new HttpClientHelper("http", "localhost", Integer.toString(server.getAddress().getPort())); - assertEquals(202, helper.getResponseCode("/status")); - assertNotNull(new HttpClientHelper("https", "localhost", "443")); - } finally { - server.stop(0); - } - } -} diff --git a/src/test/java/net/locusworks/common/net/certmanagers/TrustAllCertsManagerTest.java b/src/test/java/net/locusworks/common/net/certmanagers/TrustAllCertsManagerTest.java deleted file mode 100644 index ac285bd..0000000 --- a/src/test/java/net/locusworks/common/net/certmanagers/TrustAllCertsManagerTest.java +++ /dev/null @@ -1,25 +0,0 @@ -package net.locusworks.common.net.certmanagers; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertInstanceOf; -import static org.junit.jupiter.api.Assertions.assertNull; - -import org.junit.jupiter.api.Test; - -import javax.net.ssl.TrustManager; - - -class TrustAllCertsManagerTest { - @Test - void trustsClientsAndServersAndBuildsTrustManagerArray() throws Exception { - TrustAllCertsManager manager = new TrustAllCertsManager(); - assertDoesNotThrow(() -> manager.checkClientTrusted(null, null)); - assertDoesNotThrow(() -> manager.checkServerTrusted(null, null)); - assertNull(manager.getAcceptedIssuers()); - - TrustManager[] managers = TrustAllCertsManager.trustAllCerts(); - assertEquals(1, managers.length); - assertInstanceOf(TrustAllCertsManager.class, managers[0]); - } -} diff --git a/src/test/java/net/locusworks/common/net/hostverifiers/AllHostValidVerifierTest.java b/src/test/java/net/locusworks/common/net/hostverifiers/AllHostValidVerifierTest.java deleted file mode 100644 index 2c13522..0000000 --- a/src/test/java/net/locusworks/common/net/hostverifiers/AllHostValidVerifierTest.java +++ /dev/null @@ -1,17 +0,0 @@ -package net.locusworks.common.net.hostverifiers; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertTrue; - -class AllHostValidVerifierTest { - - @Test - public void testVerify() { - AllHostValidVerifier verifier = new AllHostValidVerifier(); - assertTrue(verifier.verify("localhost", null)); - assertTrue(verifier.verify("127.0.0.1", null)); - assertTrue(verifier.verify("::1", null)); - } - -} \ No newline at end of file diff --git a/src/test/java/net/locusworks/common/net/ssl/SSLManagerTest.java b/src/test/java/net/locusworks/common/net/ssl/SSLManagerTest.java deleted file mode 100644 index 66266e0..0000000 --- a/src/test/java/net/locusworks/common/net/ssl/SSLManagerTest.java +++ /dev/null @@ -1,25 +0,0 @@ -package net.locusworks.common.net.ssl; - -import org.junit.jupiter.api.Test; - -import java.security.KeyManagementException; -import java.security.NoSuchAlgorithmException; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; - - -class SSLManagerTest { - - @Test - public void testCreateSSLContext() throws NoSuchAlgorithmException, KeyManagementException { - assertNotNull(SSLManager.getTrustAllTLSClient()); - } - - @Test - public void testTLS() { - assertNotNull(SSLManager.TLS); - assertEquals(4, SSLManager.TLS.length); - } - -} \ No newline at end of file diff --git a/src/test/java/net/locusworks/common/objectmapper/ObjectMapperCoverageTest.java b/src/test/java/net/locusworks/common/objectmapper/ObjectMapperCoverageTest.java deleted file mode 100644 index a56d2d5..0000000 --- a/src/test/java/net/locusworks/common/objectmapper/ObjectMapperCoverageTest.java +++ /dev/null @@ -1,119 +0,0 @@ -package net.locusworks.common.objectmapper; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertInstanceOf; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertSame; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; - -import org.junit.jupiter.api.Test; - -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; -import java.util.concurrent.atomic.AtomicReference; - - -class ObjectMapperCoverageTest { - static class Value { - public String name; - - Value() { - } - - Value(String name) { - this.name = name; - } - } - - static class SelfReference { - SelfReference self = this; - } - - static class CyclicReference { - Object next; - } - - static class ThrowingGetter { - String name = "field value"; - - public String getName() { - throw new IllegalStateException("Jackson getter failure"); - } - } - - @Test - void resultContainersSupportEveryConstructorMutationAndHandlerPath() { - RuntimeException error = new RuntimeException("bad json"); - ObjectMapperResults result = new ObjectMapperResults<>("value", null); - assertEquals("value", result.getResults()); - assertFalse(result.hasError()); - assertSame(result, result.withErrorHandler(e -> fail("handler must not run"))); - - result.setResults("changed"); - result.setException(error); - AtomicReference handled = new AtomicReference<>(); - assertSame(result, result.withErrorHandler(handled::set)); - assertSame(error, handled.get()); - assertSame(result, result.withErrorHandler(null)); - - assertEquals("simple", new ObjectMapperResults<>("simple").getResults()); - assertSame(error, new ObjectMapperResults(error).getException()); - - ObjectMapperListResults> list = new ObjectMapperListResults<>(List.of("a"), null); - assertEquals(List.of("a"), list.getResults()); - assertFalse(list.hasError()); - assertSame(list, list.withErrorHandler(e -> fail("handler must not run"))); - - ObjectMapperListResults> failed = new ObjectMapperListResults<>(error); - handled.set(null); - assertSame(failed, failed.withErrorHandler(handled::set)); - assertSame(error, handled.get()); - assertSame(failed, failed.withErrorHandler(null)); - assertEquals(List.of("b"), new ObjectMapperListResults<>(List.of("b")).getResults()); - } - - @Test - void readsBytesStringsObjectsAndCollectionImplementations() { - Value fromBytes = ObjectMapperHelper.readValue("{\"name\":\"bytes\"}".getBytes(), Value.class).getResults(); - assertEquals("bytes", fromBytes.name); - assertEquals("string", ObjectMapperHelper.readValue("{\"name\":\"string\"}", Value.class).getResults().name); - assertEquals("object", ObjectMapperHelper.readValue(new Value("object"), Value.class).getResults().name); - Object delegatedJson = "{\"name\":\"delegated\"}"; - assertEquals("delegated", ObjectMapperHelper.readValue(delegatedJson, Value.class).getResults().name); - - List values = List.of(new Value("one"), new Value("two")); - assertEquals(2, ObjectMapperHelper.readListValue(values, Value.class).getResults().size()); - assertEquals(2, ObjectMapperHelper.readListValue("[{\"name\":\"one\"},{\"name\":\"two\"}]", Value.class, LinkedList.class).getResults().size()); - assertInstanceOf(LinkedList.class, - ObjectMapperHelper.readListValue(values, Value.class, LinkedList.class).getResults()); - } - - @Test - void malformedInputReturnsErrorsForEveryReadOverload() { - assertTrue(ObjectMapperHelper.readValue(new byte[]{1, 2}, Value.class).hasError()); - assertTrue(ObjectMapperHelper.readValue("not-json", Value.class).hasError()); - assertTrue(ObjectMapperHelper.readValue(new Object(), Thread.class).hasError()); - assertTrue(ObjectMapperHelper.readListValue("not-json", Value.class, ArrayList.class).hasError()); - assertTrue(ObjectMapperHelper.readListValue(new Object(), Value.class, List.class).hasError()); - } - - @Test - void writeFallsBackWhenJacksonAndGsonRejectCircularObject() { - CyclicReference first = new CyclicReference(); - CyclicReference second = new CyclicReference(); - first.next = second; - second.next = first; - ObjectMapperResults result = ObjectMapperHelper.writeValue(first); - assertTrue(result.hasError()); - - ObjectMapperResults fallback = ObjectMapperHelper.writeValue(new ThrowingGetter()); - assertFalse(fallback.hasError()); - assertTrue(fallback.getResults().contains("field value")); - - assertNotNull(new ObjectMapperHelper()); - assertTrue(ObjectMapperHelper.readValue(new SelfReference(), Value.class).hasError()); - } -} diff --git a/src/test/java/net/locusworks/common/properties/ImmutablePropertiesTest.java b/src/test/java/net/locusworks/common/properties/ImmutablePropertiesTest.java deleted file mode 100644 index f2182cd..0000000 --- a/src/test/java/net/locusworks/common/properties/ImmutablePropertiesTest.java +++ /dev/null @@ -1,41 +0,0 @@ -package net.locusworks.common.properties; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import org.junit.jupiter.api.Test; - -import java.util.Properties; - - -class ImmutablePropertiesTest { - - @Test - public void testImmutableProperties() { - assertNotNull(new ImmutableProperties()); - } - - @Test - public void testImmutablePropertiesWithEmptyOrNullProperties() { - assertNotNull(new ImmutableProperties(new Properties())); - assertNotNull(new ImmutableProperties(null)); - } - - @Test - public void testImmutablePropertiesWthProperties() { - final Properties properties = new Properties(); - properties.put("Hello", "World"); - assertNotNull(new ImmutableProperties(properties)); - } - - @Test - public void testSetProperties() { - final ImmutableProperties properties = new ImmutableProperties(new Properties()); - properties.setProperty("Hello", "World"); - assertEquals("World", properties.getProperty("Hello")); - - assertThrows(RuntimeException.class, () -> properties.setProperty("Hello", "World")); - } - -} \ No newline at end of file diff --git a/src/test/java/net/locusworks/common/properties/OrderedPropertiesCoverageTest.java b/src/test/java/net/locusworks/common/properties/OrderedPropertiesCoverageTest.java deleted file mode 100644 index 038af67..0000000 --- a/src/test/java/net/locusworks/common/properties/OrderedPropertiesCoverageTest.java +++ /dev/null @@ -1,196 +0,0 @@ -package net.locusworks.common.properties; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import org.junit.jupiter.api.Test; - -import java.io.BufferedWriter; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.io.PrintStream; -import java.io.PrintWriter; -import java.io.StringReader; -import java.io.StringWriter; -import java.lang.reflect.Method; -import java.nio.charset.StandardCharsets; -import java.util.Enumeration; -import java.util.List; -import java.util.Properties; - -class OrderedPropertiesCoverageTest { - @Test - void loadsAllPropertySyntaxFromReaderAndInputStream() throws Exception { - String source = "# comment\n! another\n" + - "simple=value\ncolon:value2\nspace value3\n" + - "spaced = spaced-value\n" + - "tabbed\t:\tvalue5\nform\f=\fvalue6\n" + - "slashes\\\\key:value4\n" + - "escaped\\:colon=value7\n" + - "escaped\\ key=escaped\\ value\n" + - "unicode=\\u0041\\tB\\nC\\rD\\fE\n" + - "continued=first\\\n second\n" + - "emptyKey\n=empty-key-value\n"; - - OrderedProperties readerProperties = new OrderedProperties(); - readerProperties.load(new StringReader(source)); - assertEquals("value", readerProperties.getProperty("simple")); - assertEquals("value2", readerProperties.getProperty("colon")); - assertEquals("value3", readerProperties.getProperty("space")); - assertEquals("spaced-value", readerProperties.getProperty("spaced")); - assertEquals("value4", readerProperties.getProperty("slashes\\key")); - assertEquals("value5", readerProperties.getProperty("tabbed")); - assertEquals("value6", readerProperties.getProperty("form")); - assertEquals("value7", readerProperties.getProperty("escaped:colon")); - assertEquals("escaped value", readerProperties.getProperty("escaped key")); - assertEquals("A\tB\nC\rD\fE", readerProperties.getProperty("unicode")); - assertEquals("firstsecond", readerProperties.getProperty("continued")); - assertEquals("", readerProperties.getProperty("emptyKey")); - assertEquals("empty-key-value", readerProperties.getProperty("")); - - OrderedProperties streamProperties = new OrderedProperties(); - streamProperties.load(new ByteArrayInputStream(source.getBytes(StandardCharsets.ISO_8859_1))); - assertEquals(readerProperties, streamProperties); - assertThrows(IllegalArgumentException.class, - () -> streamProperties.load(new StringReader("bad=\\u12G4"))); - } - - @Test - void storesToWriterAndStreamWithCommentsUnicodeAndEscapes() throws Exception { - OrderedProperties properties = new OrderedProperties(); - properties.setProperty(" leading:=#!", " value\t\n\r\f\\é"); - - StringWriter writer = new StringWriter(); - properties.store(writer, "first\nsecond\rthird\r\nfourth\u0100"); - String writerText = writer.toString(); - assertTrue(writerText.contains("#first")); - assertTrue(writerText.contains("#second")); - assertTrue(writerText.contains("\\ leading\\:\\=\\#\\!")); - assertTrue(writerText.contains("é")); - - StringWriter bufferedTarget = new StringWriter(); - properties.store(new BufferedWriter(bufferedTarget), "\u0100first\rsolo\n#already\n!also\nlast\r\nend\r"); - assertTrue(bufferedTarget.toString().contains("#already")); - - ByteArrayOutputStream bytes = new ByteArrayOutputStream(); - properties.store(bytes, null); - String streamText = bytes.toString(StandardCharsets.ISO_8859_1); - assertTrue(streamText.contains("\\u00E9")); - - assertDoesNotThrow(() -> properties.save(new OutputStream() { - @Override - public void write(int b) throws IOException { - throw new IOException("expected"); - } - }, "ignored error")); - } - - @Test - void defaultsEnumerationListingAndNonStringValuesAreHandled() { - OrderedProperties defaults = new OrderedProperties(); - defaults.setProperty("default", "value"); - defaults.put("nonStringDefault", 1); - OrderedProperties properties = new OrderedProperties(defaults); - properties.setProperty("local", "x".repeat(50)); - properties.put("nonString", 2); - - assertEquals("value", properties.getProperty("default")); - assertEquals("fallback", properties.getProperty("missing", "fallback")); - assertEquals("value", properties.getProperty("default", "fallback")); - Enumeration names = properties.propertyNames(); - assertTrue(java.util.Collections.list(names).containsAll(List.of("default", "local"))); - properties.put(3, "nonStringKey"); - assertTrue(properties.stringPropertyNames().containsAll(java.util.Set.of("default", "local"))); - - properties.remove("nonString"); - properties.remove(3); - defaults.remove("nonStringDefault"); - - ByteArrayOutputStream printBytes = new ByteArrayOutputStream(); - properties.list(new PrintStream(printBytes)); - assertTrue(printBytes.toString().contains("...")); - StringWriter output = new StringWriter(); - properties.list(new PrintWriter(output)); - assertTrue(output.toString().contains("-- listing properties --")); - } - - @Test - void lineReaderHandlesCommentsWhitespaceContinuationLongLinesAndEndings() throws Exception { - String longValue = "x".repeat(9000); - String input = " #comment\r\n\t!comment\n key=value\\\r\n continued\r" + longValue; - OrderedProperties.LineReader reader = new OrderedProperties.LineReader(new StringReader(input)); - int length = reader.readLine(); - assertEquals("key=valuecontinued", new String(reader.lineBuf, 0, length)); - assertEquals(9000, reader.readLine()); - - OrderedProperties.LineReader stream = new OrderedProperties.LineReader( - new ByteArrayInputStream(("a=b\n" + longValue).getBytes(StandardCharsets.ISO_8859_1))); - assertEquals(3, stream.readLine()); - assertEquals(9000, stream.readLine()); - assertEquals(-1, stream.readLine()); - - OrderedProperties.LineReader trailingReader = new OrderedProperties.LineReader(new StringReader("key=value\\")); - assertEquals("key=value", new String(trailingReader.lineBuf, 0, trailingReader.readLine())); - OrderedProperties.LineReader trailingStream = new OrderedProperties.LineReader( - new ByteArrayInputStream("key=value\\\n".getBytes(StandardCharsets.ISO_8859_1))); - assertEquals("key=value", new String(trailingStream.lineBuf, 0, trailingStream.readLine())); - OrderedProperties.LineReader whiteContinuation = new OrderedProperties.LineReader( - new StringReader("key=value\\\n \t\fcontinued\n")); - int continuedLength = whiteContinuation.readLine(); - assertEquals("key=valuecontinued", new String(whiteContinuation.lineBuf, 0, continuedLength)); - assertEquals(-1, new OrderedProperties.LineReader(new StringReader("#comment without newline")).readLine()); - - OrderedProperties.LineReader crWithoutLf = new OrderedProperties.LineReader(new StringReader("a\\\rb\n")); - int crLength = crWithoutLf.readLine(); - assertEquals("ab", new String(crWithoutLf.lineBuf, 0, crLength)); - - OrderedProperties.LineReader blankEndings = new OrderedProperties.LineReader(new StringReader("\n\r\nvalue\n")); - assertEquals("value", new String(blankEndings.lineBuf, 0, blankEndings.readLine())); - - String boundaryInput = "z".repeat(8191) + "\nnext\n"; - OrderedProperties.LineReader boundary = new OrderedProperties.LineReader(new StringReader(boundaryInput)); - assertEquals(8191, boundary.readLine()); - assertEquals(4, boundary.readLine()); - } - - @Test - void privateConversionHelpersCoverEveryEscapeAndHexPath() throws Exception { - OrderedProperties properties = new OrderedProperties(); - Method load = OrderedProperties.class.getDeclaredMethod("loadConvert", char[].class, int.class, int.class, char[].class); - Method save = OrderedProperties.class.getDeclaredMethod("saveConvert", String.class, boolean.class, boolean.class); - Method hex = OrderedProperties.class.getDeclaredMethod("toHex", int.class); - load.setAccessible(true); - save.setAccessible(true); - hex.setAccessible(true); - - String escaped = "a\\tb\\nc\\rd\\fe\\\\f\\ g\\:h\\=i\\#j\\!k\\u0041"; - assertEquals("a\tb\nc\rd\fe\\f g:h=i#j!kA", - load.invoke(properties, escaped.toCharArray(), 0, escaped.length(), new char[1])); - String hexCases = "\\u00af\\u00AF"; - assertEquals("¯¯", load.invoke(properties, hexCases.toCharArray(), 0, hexCases.length(), new char[1])); - assertEquals("\\ a\\:\\=\\#\\!\\t\\n\\r\\f\\\\\\u0100", - save.invoke(properties, " a:=#!\t\n\r\f\\\u0100", true, true)); - assertEquals("\\ a\\:\\=\\#\\!\\t\\n\\r\\f\\\\\u0100", - save.invoke(properties, " a:=#!\t\n\r\f\\\u0100", false, false)); - assertEquals("a\\ b", save.invoke(properties, "a b", true, false)); - assertEquals("a b", save.invoke(properties, "a b", false, false)); - assertEquals("\\u0001", save.invoke(properties, "\u0001", false, true)); - assertEquals("\u0001", save.invoke(properties, "\u0001", false, false)); - assertEquals("0", save.invoke(properties, "0", false, true)); - assertEquals('0', hex.invoke(null, 0)); - assertEquals('F', hex.invoke(null, 15)); - } - - @Test - void immutablePropertiesCopiesValuesAndRejectsReplacement() { - Properties source = new Properties(); - source.setProperty("key", "value"); - ImmutableProperties immutable = new ImmutableProperties(source); - assertEquals("value", immutable.getProperty("key")); - assertThrows(RuntimeException.class, () -> immutable.setProperty("key", "changed")); - } -} diff --git a/src/test/java/net/locusworks/common/properties/OrderedPropertiesTest.java b/src/test/java/net/locusworks/common/properties/OrderedPropertiesTest.java deleted file mode 100644 index 49bebbd..0000000 --- a/src/test/java/net/locusworks/common/properties/OrderedPropertiesTest.java +++ /dev/null @@ -1,75 +0,0 @@ -package net.locusworks.common.properties; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; - -import org.junit.jupiter.api.Test; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.PrintStream; - - -class OrderedPropertiesTest { - - @Test - void testSetProperty() { - OrderedProperties properties = new OrderedProperties(); - properties.setProperty("Hello", "World"); - assertEquals("World", properties.getProperty("Hello")); - } - - @Test - void testLoad() throws IOException { - OrderedProperties properties = new OrderedProperties(); - properties.load(new ByteArrayInputStream("Hello=World".getBytes())); - assertEquals("World", properties.getProperty("Hello")); - } - - @Test - void testSave() { - OrderedProperties properties = new OrderedProperties(); - properties.setProperty("Hello", "World"); - properties.save(new ByteArrayOutputStream(), ""); - } - - @Test - void testStore() { - OrderedProperties properties = new OrderedProperties(); - properties.setProperty("Hello", "World"); - try { - properties.store(new ByteArrayOutputStream(), ""); - } catch (IOException e) { - fail("IOException should not be thrown"); - } - } - - @Test - void testGetProperty() { - OrderedProperties properties = new OrderedProperties(); - properties.setProperty("Hello", "World"); - assertEquals("World", properties.getProperty("Hello")); - } - - @Test - void testPropertyNames() { - OrderedProperties properties = new OrderedProperties(); - properties.setProperty("Hello", "World"); - var propertyNames = properties.stringPropertyNames(); - assertFalse(propertyNames.isEmpty()); - assertTrue(propertyNames.contains("Hello")); - assertEquals(1, propertyNames.size()); - } - - @Test - void testList() { - PrintStream ps = new PrintStream(new ByteArrayOutputStream()); - OrderedProperties properties = new OrderedProperties(); - properties.setProperty("Hello", "World"); - properties.list(ps); - ps.flush(); - } -} \ No newline at end of file diff --git a/src/test/java/net/locusworks/common/utils/ChecksTest.java b/src/test/java/net/locusworks/common/utils/ChecksTest.java deleted file mode 100644 index 891668b..0000000 --- a/src/test/java/net/locusworks/common/utils/ChecksTest.java +++ /dev/null @@ -1,28 +0,0 @@ -package net.locusworks.common.utils; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import org.junit.jupiter.api.Test; - - -class ChecksTest { - - @Test - void testCheckArgument() { - Throwable ex = assertThrows(IllegalArgumentException.class, () -> Checks.checkArguments(false, "One does not equal 2")); - assertEquals("One does not equal 2", ex.getMessage()); - - assertDoesNotThrow(() -> Checks.checkArguments(true, "One does not equal 2")); - } - - @Test - void testCheckState() { - Throwable ex = assertThrows(IllegalStateException.class, () -> Checks.checkState(false, "One does not equal 2")); - assertEquals("One does not equal 2", ex.getMessage()); - - assertDoesNotThrow(() -> Checks.checkState(true, "One does not equal 2")); - } - -} diff --git a/src/test/java/net/locusworks/common/utils/DateTimeStampSerializerTest.java b/src/test/java/net/locusworks/common/utils/DateTimeStampSerializerTest.java deleted file mode 100644 index f2268d0..0000000 --- a/src/test/java/net/locusworks/common/utils/DateTimeStampSerializerTest.java +++ /dev/null @@ -1,286 +0,0 @@ -package net.locusworks.common.utils; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; - -import com.fasterxml.jackson.annotation.ObjectIdGenerator; -import com.fasterxml.jackson.core.Base64Variant; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonStreamContext; -import com.fasterxml.jackson.core.ObjectCodec; -import com.fasterxml.jackson.core.SerializableString; -import com.fasterxml.jackson.core.TreeNode; -import com.fasterxml.jackson.core.Version; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.fasterxml.jackson.databind.introspect.Annotated; -import com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition; -import com.fasterxml.jackson.databind.ser.impl.WritableObjectId; -import org.junit.jupiter.api.Test; - -import java.io.InputStream; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.Date; -import java.util.concurrent.atomic.AtomicLong; - - -class DateTimeStampSerializerTest { - - static AtomicLong atomicLong = new AtomicLong(0); - - @Test - void testSerializer() { - DateTimeStampSerializer serializer = new DateTimeStampSerializer(); - assertDoesNotThrow(() -> serializer.serialize(new Date(), new MyJsonGenerator(), new MySerializerProvider())); - assertTrue(atomicLong.get() > 0); - } - - private static class MyJsonGenerator extends JsonGenerator { - @Override - public JsonGenerator setCodec(ObjectCodec objectCodec) { - return null; - } - - @Override - public ObjectCodec getCodec() { - return null; - } - - @Override - public Version version() { - return null; - } - - @Override - public JsonStreamContext getOutputContext() { - return null; - } - - @Override - public JsonGenerator enable(Feature feature) { - return null; - } - - @Override - public JsonGenerator disable(Feature feature) { - return null; - } - - @Override - public boolean isEnabled(Feature feature) { - return false; - } - - @Override - public int getFeatureMask() { - return 0; - } - - @Override - public JsonGenerator setFeatureMask(int i) { - return null; - } - - @Override - public JsonGenerator useDefaultPrettyPrinter() { - return null; - } - - @Override - public void writeStartArray() { - fail(); - } - - @Override - public void writeEndArray() { - fail(); - } - - @Override - public void writeStartObject() { - fail(); - } - - @Override - public void writeEndObject() { - fail(); - } - - @Override - public void writeFieldName(String s) { - fail(); - } - - @Override - public void writeFieldName(SerializableString serializableString) { - fail(); - } - - @Override - public void writeString(String s) { - fail(); - } - - @Override - public void writeString(char[] chars, int i, int i1) { - fail(); - } - - @Override - public void writeString(SerializableString serializableString) { - fail(); - } - - @Override - public void writeRawUTF8String(byte[] bytes, int i, int i1) { - fail(); - } - - @Override - public void writeUTF8String(byte[] bytes, int i, int i1) { - fail(); - } - - @Override - public void writeRaw(String s) { - fail(); - } - - @Override - public void writeRaw(String s, int i, int i1) { - fail(); - } - - @Override - public void writeRaw(char[] chars, int i, int i1) { - fail(); - } - - @Override - public void writeRaw(char c) { - fail(); - } - - @Override - public void writeRawValue(String s) { - fail(); - } - - @Override - public void writeRawValue(String s, int i, int i1) { - fail(); - } - - @Override - public void writeRawValue(char[] chars, int i, int i1) { - fail(); - } - - @Override - public void writeBinary(Base64Variant base64Variant, byte[] bytes, int i, int i1) { - fail(); - } - - @Override - public int writeBinary(Base64Variant base64Variant, InputStream inputStream, int i) { - fail(); - return 0; - } - - @Override - public void writeNumber(int i) { - fail(); - } - - @Override - public void writeNumber(long l) { - atomicLong.set(l); - } - - @Override - public void writeNumber(BigInteger bigInteger) { - fail(); - } - - @Override - public void writeNumber(double v) { - fail(); - } - - @Override - public void writeNumber(float v) { - fail(); - } - - @Override - public void writeNumber(BigDecimal bigDecimal) { - fail(); - } - - @Override - public void writeNumber(String s) { - fail(); - } - - @Override - public void writeBoolean(boolean b) { - fail(); - } - - @Override - public void writeNull() { - fail(); - } - - @Override - public void writeObject(Object o) { - fail(); - } - - @Override - public void writeTree(TreeNode treeNode) { - fail(); - } - - @Override - public void flush() { - fail(); - } - - @Override - public boolean isClosed() { - return false; - } - - @Override - public void close() { - fail(); - } - } - - - private static class MySerializerProvider extends SerializerProvider { - @Override - public WritableObjectId findObjectId(Object o, ObjectIdGenerator objectIdGenerator) { - return null; - } - - @Override - public JsonSerializer serializerInstance(Annotated annotated, Object o) { - return null; - } - - @Override - public Object includeFilterInstance(BeanPropertyDefinition beanPropertyDefinition, - Class aClass) { - return null; - } - - @Override - public boolean includeFilterSuppressNulls(Object o) { - return false; - } - } -} diff --git a/src/test/java/net/locusworks/common/utils/FileReaderTest.java b/src/test/java/net/locusworks/common/utils/FileReaderTest.java deleted file mode 100644 index 18b1ee6..0000000 --- a/src/test/java/net/locusworks/common/utils/FileReaderTest.java +++ /dev/null @@ -1,275 +0,0 @@ -package net.locusworks.common.utils; - -import net.locusworks.common.interfaces.AutoCloseableIterator; -import net.locusworks.common.utils.FileReader.LineInfo; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.MockedStatic; - -import java.io.*; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.NoSuchElementException; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.mockStatic; - -public class FileReaderTest { - - private static final String TEST_FILE = "test_file.txt"; - private static final Map numLines = new LinkedHashMap<>(); - private BufferedReader testBufferedReader; - - private static final String[] TEST_CONTENT = new String[]{ - "Line 1", - "Line 2", - "Line 3" - }; - - - @BeforeAll - public static void setUpBeforeClass() throws Exception { - File testFile = new File(TEST_FILE); - FileOutputStream fos = new FileOutputStream(testFile); - - for (int i = 1; i <= TEST_CONTENT.length; i++) { - String randomString = TEST_CONTENT[i - 1] + "\n"; - numLines.put(i, randomString.length()); - fos.write(randomString.getBytes()); - } - - fos.close(); - } - - @BeforeEach - void setUp() throws FileNotFoundException { - testBufferedReader = new BufferedReader(new java.io.FileReader(TEST_FILE)); - } - - @AfterEach - void tearDown() { - try { - if (testBufferedReader != null) { - testBufferedReader.close(); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - - @AfterAll - public static void tearDownAfterClass() { - File file = new File(TEST_FILE); - file.delete(); - } - - @Test - public void testForLoop() { - int lineCount = 0; - try (FileReader fr = new FileReader(Paths.get(TEST_FILE))) { - for (LineInfo s : fr) { - lineCount++; - Integer lineNumber = s.getLineNumber(); - int lineLength = s.getLine().length(); - Integer mapLineLength = numLines.get(lineNumber); - assertEquals(lineLength, (mapLineLength - 1)); - } - } - assertEquals(lineCount, numLines.size()); - } - - @Test - void testDeprecatedConstructor() { - try (FileReader fr = new FileReader(new File(TEST_FILE))) { - assertNotNull(fr); - } - } - - @Test - void testInit() { - - } - - @Test - public void testIterator() { - int lineCount = 0; - - try (AutoCloseableIterator iter = new FileReader(Paths.get(TEST_FILE))) { - while (iter.hasNext()) { - lineCount++; - LineInfo s = iter.next(); - Integer lineNumber = s.getLineNumber(); - int lineLength = s.getLine().length(); - Integer mapLineLength = numLines.get(lineNumber); - assertEquals(lineLength, (mapLineLength - 1)); - } - } - assertEquals(lineCount, numLines.size()); - } - - @Test - public void testForIterator() { - int lineCount = 0; - try (FileReader fr = new FileReader(Paths.get(TEST_FILE))) { - while (((Iterator) fr).hasNext()) { - lineCount++; - LineInfo s = ((Iterator) fr).next(); - Integer lineNumber = s.getLineNumber(); - int lineLength = s.getLine().length(); - Integer mapLineLength = numLines.get(lineNumber); - assertEquals(lineLength, (mapLineLength - 1)); - } - assertEquals(lineCount, numLines.size()); - } - } - - @Test - public void testNoAlgorithmException() { - try (MockedStatic mocked = mockStatic(SecureRandom.class)) { - mocked.when(() -> SecureRandom.getInstance(anyString())).thenThrow(NoSuchAlgorithmException.class); - assertDoesNotThrow(() -> RandomString.newInstance()); - } - } - - @Test - void testFileReaderWithBufferedReader() { - try (FileReader fileReader = new FileReader(testBufferedReader)) { - Iterator iterator = fileReader.iterator(); - - assertTrue(iterator.hasNext()); - FileReader.LineInfo lineInfo = iterator.next(); - assertEquals(1, lineInfo.getLineNumber()); - assertEquals("Line 1", lineInfo.getLine()); - - assertTrue(iterator.hasNext()); - lineInfo = iterator.next(); - assertEquals(2, lineInfo.getLineNumber()); - assertEquals("Line 2", lineInfo.getLine()); - - assertTrue(iterator.hasNext()); - lineInfo = iterator.next(); - assertEquals(3, lineInfo.getLineNumber()); - assertEquals("Line 3", lineInfo.getLine()); - - assertFalse(iterator.hasNext()); - } - } - - @Test - void testFileReaderWithFile() { - try (FileReader fileReader = new FileReader(TEST_FILE)) { - // Add assertions based on the content of the file - Iterator iterator = fileReader.iterator(); - - assertTrue(iterator.hasNext()); - FileReader.LineInfo lineInfo = iterator.next(); - assertNotNull(lineInfo); - } - } - - @Test - void testFileReaderWithNonexistentFile() { - // Provide the path to a nonexistent file for testing - String filePath = "path/to/nonexistent/file.txt"; - - // Ensure that the constructor throws an IllegalArgumentException - assertThrows(NullPointerException.class, () -> new FileReader(filePath)); - } - - @Test - void testFileReaderInitWithNullFile() { - // Ensure that the constructor throws an IllegalArgumentException with a null file - assertThrows(IllegalArgumentException.class, () -> new FileReader((String) null)); - } - - @Test - void testFileReaderInitWithNullBufferedReader() { - // Ensure that the constructor throws an IllegalArgumentException with a null BufferedReader - assertThrows(IllegalArgumentException.class, () -> new FileReader((BufferedReader) null)); - } - - @Test - void testFileReaderInitWithNonexistentResource() { - // Provide the name of a nonexistent resource for testing - String resourceName = "nonexistent_resource.txt"; - - // Ensure that the constructor throws an IllegalArgumentException - assertThrows(NullPointerException.class, () -> new FileReader(resourceName)); - } - - @Test - void testFileReaderInitWithInvalidResource() { - // Provide the name of an invalid resource for testing - String resourceName = "invalid_resource.txt"; - - // Ensure that the constructor throws a RuntimeException - assertThrows(RuntimeException.class, () -> new FileReader(resourceName)); - } - - @Test - void testFileReaderInitWithNullPath() { - // Ensure that the constructor throws an IllegalArgumentException with a null path - assertThrows(IllegalArgumentException.class, () -> new FileReader((Path) null)); - } - - @Test - void testFileReaderInitWithNonexistentPath() { - // Provide a nonexistent path for testing - Path path = Paths.get("nonexistent_path.txt"); - - // Ensure that the constructor throws a RuntimeException - assertThrows(RuntimeException.class, () -> new FileReader(path)); - } - - @Test - void testFileReaderInitWithNonRegularFile() { - // Provide the path to a non-regular file for testing - Path path = Paths.get("path/to/non_regular_file"); - - // Ensure that the constructor throws an IllegalArgumentException - assertThrows(IllegalArgumentException.class, () -> new FileReader(path)); - } - - @Test - void testFileReaderHasNextIOException() { - // Provide a BufferedReader that throws an IOException when reading - BufferedReader bufferedReader = new BufferedReader(new StringReader(TEST_FILE)) { - @Override - public String readLine() throws IOException { - throw new IOException("Simulated IOException"); - } - }; - - try (FileReader fileReader = new FileReader(bufferedReader)) { - Iterator iterator = fileReader.iterator(); - - assertThrows(RuntimeException.class, iterator::hasNext); - } - } - - @Test - void testFileReaderNextNoMoreElements() { - // Provide a BufferedReader with no more elements for testing - BufferedReader bufferedReader = new BufferedReader(new StringReader("")); - - try (FileReader fileReader = new FileReader(bufferedReader)) { - Iterator iterator = fileReader.iterator(); - - assertThrows(NoSuchElementException.class, iterator::next); - } - } -} diff --git a/src/test/java/net/locusworks/common/utils/HashUtilsTest.java b/src/test/java/net/locusworks/common/utils/HashUtilsTest.java deleted file mode 100644 index 1729300..0000000 --- a/src/test/java/net/locusworks/common/utils/HashUtilsTest.java +++ /dev/null @@ -1,36 +0,0 @@ -package net.locusworks.common.utils; - -import org.apache.commons.codec.digest.DigestUtils; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -public class HashUtilsTest { - - private static final String TEST_STRING = "Hello World"; - - @Test - public void testMD5() { - String digestUtilsMD5 = DigestUtils.md5Hex(TEST_STRING.getBytes()); - String hashUtilsMD5 = HashUtils.hash("MD5", TEST_STRING); - - assertEquals(digestUtilsMD5, hashUtilsMD5); - } - - @Test - public void testSHA1() { - String digestUtilsMD5 = DigestUtils.sha1Hex(TEST_STRING.getBytes()); - String hashUtilsMD5 = HashUtils.hash("SHA-1", TEST_STRING); - - assertEquals(digestUtilsMD5, hashUtilsMD5); - } - - @Test - public void testSHA512() { - String digestUtilsMD5 = DigestUtils.sha512Hex(TEST_STRING.getBytes()); - String hashUtilsMD5 = HashUtils.hash("SHA-512", TEST_STRING); - - assertEquals(digestUtilsMD5, hashUtilsMD5); - } - -} diff --git a/src/test/java/net/locusworks/common/utils/ObjectUtilsTest.java b/src/test/java/net/locusworks/common/utils/ObjectUtilsTest.java deleted file mode 100644 index 7b7b739..0000000 --- a/src/test/java/net/locusworks/common/utils/ObjectUtilsTest.java +++ /dev/null @@ -1,81 +0,0 @@ -package net.locusworks.common.utils; - -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -import java.io.InputStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Objects; - -import static net.locusworks.common.utils.ObjectUtils.performIfNotNull; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.fail; - -class ObjectUtilsTest { - - private static final String TEST_FILE = "object-utils-test.txt"; - private static Path testFile; - - @BeforeAll - public static void setUpBeforeClass() throws Exception { - Path classpathRoot = Paths.get(Objects.requireNonNull(ObjectUtilsTest.class.getResource("/")).toURI()); - testFile = classpathRoot.resolve(TEST_FILE); - Files.writeString(testFile, "test resource"); - } - - @AfterAll - public static void tearDownAfterClass() throws Exception { - Files.deleteIfExists(testFile); - } - - @Test - void testNullObject() { - performIfNotNull(null, str -> fail()); - } - - @Test - void testNotNullObject() { - String str = "hello world"; - performIfNotNull(str, obj -> assertEquals(str, obj)); - } - - @Test - void getResourceStream_whenResourceExists_ReturnsInputStream() throws Exception { - try (InputStream result = ObjectUtils.getResourceStream("/" + TEST_FILE)) { - assertNotNull(result); - } - } - - @Test - void getResourceStream_whenResourceDoesNotExist_ThrowsException() { - // Arrange - String resourceName = "nonexistent.txt"; - - // Act & Assert - assertThrows(NullPointerException.class, - () -> ObjectUtils.getResourceStream(resourceName)); - } - - @Test - void getResourceStream_whenResourceExistsInClassLoader_ReturnsInputStream() throws Exception { - try (InputStream result = ObjectUtils.getResourceStream(TEST_FILE)) { - assertNotNull(result); - } - } - - @Test - void getResourceStream_whenResourceDoesNotExistInClassLoader_ThrowsException() { - // Arrange - String resourceName = "nonexistent.txt"; - - // Act & Assert - assertThrows(NullPointerException.class, - () -> ObjectUtils.getResourceStream(resourceName)); - } - -} diff --git a/src/test/java/net/locusworks/common/utils/RandomStringTest.java b/src/test/java/net/locusworks/common/utils/RandomStringTest.java deleted file mode 100644 index e27c52d..0000000 --- a/src/test/java/net/locusworks/common/utils/RandomStringTest.java +++ /dev/null @@ -1,30 +0,0 @@ -package net.locusworks.common.utils; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -public class RandomStringTest { - - @Test - public void testStaticBytes() { - for (int length = 3; length < 50; length++) { - assertEquals(RandomString.getInstance().getBytes(length).length, length); - } - } - - @Test - public void testStaticString() { - for (int length = 3; length < 50; length++) { - String random = RandomString.getInstance().getString(length); - assertEquals(random.length(), length); - } - } - - @Test - public void testExceptions() { - assertThrows(IllegalArgumentException.class, () -> RandomString.newInstance().getString(0)); - } - -} diff --git a/src/test/java/net/locusworks/common/utils/SplitterTest.java b/src/test/java/net/locusworks/common/utils/SplitterTest.java deleted file mode 100644 index 1ce0999..0000000 --- a/src/test/java/net/locusworks/common/utils/SplitterTest.java +++ /dev/null @@ -1,83 +0,0 @@ -package net.locusworks.common.utils; - -import org.junit.jupiter.api.Test; - -import java.util.List; -import java.util.Map; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; - -class SplitterTest { - - @Test - void testBasicSplitter() { - List split = Splitter.onSpace().split("Hello World"); - assertNotNull(split); - assertEquals(2, split.size()); - assertEquals("Hello", split.get(0)); - assertEquals("World", split.get(1)); - - split = Splitter.fixedLengthSplit(5).split("HelloWorld"); - assertNotNull(split); - assertEquals(2, split.size()); - assertEquals("Hello", split.get(0)); - assertEquals("World", split.get(1)); - - split = Splitter.onNewLine().split("Hello\nWorld"); - assertNotNull(split); - assertEquals(2, split.size()); - assertEquals("Hello", split.get(0)); - assertEquals("World", split.get(1)); - - split = Splitter.onNewLine().split("Hello\r\nWorld"); - assertNotNull(split); - assertEquals(2, split.size()); - assertEquals("Hello", split.get(0)); - assertEquals("World", split.get(1)); - - String[] array = Splitter.onSpace().splitToArray("Hello World"); - assertNotNull(array); - assertEquals(2, array.length); - assertEquals("Hello", array[0]); - assertEquals("World", array[1]); - } - - @Test - void testOmitEmptyStringWithLimits() { - List split = Splitter.onSpace().split("Hello World"); - assertEquals(3, split.size()); - split = Splitter.onSpace().omitEmptyStrings().withLimit(1).split("Hello World"); - assertNotNull(split); - assertEquals(1, split.size()); - } - - @Test - void testExceptions() { - assertThrows(IllegalArgumentException.class, () -> Splitter.onSpace().split("")); - assertThrows(IllegalArgumentException.class, () -> Splitter.fixedLengthSplit(0).split("Hello World")); - assertThrows(NullPointerException.class, () -> Splitter.on(null).split("Hello World")); - - } - - @Test - void testWithKeyValueSeparator() { - Map map = Splitter.on(";").withKeyValueSeparator("=").split("Hello=World;bubba=hotep"); - assertEquals(2, map.size()); - assertEquals("World", map.get("Hello")); - assertEquals("hotep", map.get("bubba")); - } - - @Test - void testWithMapSplitterErrors() { - assertThrows(IllegalArgumentException.class, () -> Splitter.on(";").withKeyValueSeparator("").split("Hello=;bubba=hotep")); - assertThrows(IllegalArgumentException.class, () -> Splitter.on(";").withKeyValueSeparator("=").split("Hello=;bubba=hotep")); - assertThrows(IllegalArgumentException.class, () -> Splitter.on(";").withKeyValueSeparator("=").split(null)); - Map map = Splitter.on(";").withKeyValueSeparator("=").skipInvalidKeyValues().split("Hello=;bubba=hotep"); - assertEquals(1, map.size()); - assertEquals("hotep", map.get("bubba")); - } - - -} diff --git a/src/test/java/net/locusworks/common/utils/StreamUtilsTest.java b/src/test/java/net/locusworks/common/utils/StreamUtilsTest.java deleted file mode 100644 index 8f2a9c1..0000000 --- a/src/test/java/net/locusworks/common/utils/StreamUtilsTest.java +++ /dev/null @@ -1,19 +0,0 @@ -package net.locusworks.common.utils; - -import org.junit.jupiter.api.Test; - -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -class StreamUtilsTest { - - @Test - void testAsStream() { - List list = List.of("Hello", "World"); - assertEquals(2, StreamUtils.asStream(list).count()); - assertEquals(2, StreamUtils.asStream(list.iterator()).count()); - assertEquals(2, StreamUtils.asStream(list.toArray(), false).count()); - } - -} diff --git a/src/test/java/net/locusworks/common/utils/UtilityWrappersTest.java b/src/test/java/net/locusworks/common/utils/UtilityWrappersTest.java deleted file mode 100644 index d94b977..0000000 --- a/src/test/java/net/locusworks/common/utils/UtilityWrappersTest.java +++ /dev/null @@ -1,65 +0,0 @@ -package net.locusworks.common.utils; - -import org.junit.jupiter.api.Test; - -import java.io.ByteArrayOutputStream; -import java.io.OutputStream; -import java.nio.charset.StandardCharsets; - -import static org.junit.jupiter.api.Assertions.assertArrayEquals; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -class UtilityWrappersTest { - @Test - void successFactoriesAndConstructorExposeBodyAndStatus() { - assertTrue(Success.success().getSuccess()); - assertEquals(true, Success.success().getBody()); - assertFalse(Success.fail().getSuccess()); - assertEquals(false, Success.fail().getBody()); - Success value = new Success(true, "body"); - assertEquals("body", value.getBody()); - } - - @Test - void dataOutputStreamConvertsAndClosesByteArrayOutput() throws Exception { - DataOutputStreamHelper stream = new DataOutputStreamHelper(); - stream.write("hello".getBytes(StandardCharsets.UTF_8)); - assertArrayEquals("hello".getBytes(StandardCharsets.UTF_8), stream.toByteArray()); - assertEquals("hello", stream.toString()); - assertEquals("aGVsbG8=", stream.base64Encoded()); - stream.close(); - assertArrayEquals(new byte[0], stream.toByteArray()); - assertDoesNotThrow(stream::close); - } - - @Test - void dataOutputStreamSupportsOtherOutputsAndSwallowsCloseFailure() throws Exception { - OutputStream custom = new OutputStream() { - @Override - public void write(int b) { - } - - @Override - public String toString() { - return "custom"; - } - - @Override - public void close() { - throw new IllegalStateException("expected"); - } - }; - DataOutputStreamHelper stream = new DataOutputStreamHelper(custom); - assertEquals("custom", stream.toString()); - assertDoesNotThrow(stream::close); - - ByteArrayOutputStream bytes = new ByteArrayOutputStream(); - try (DataOutputStreamHelper explicit = new DataOutputStreamHelper(bytes)) { - explicit.writeByte(1); - assertArrayEquals(new byte[]{1}, explicit.toByteArray()); - } - } -} diff --git a/src/test/java/net/locusworks/common/utils/UtilsPackageCoverageTest.java b/src/test/java/net/locusworks/common/utils/UtilsPackageCoverageTest.java deleted file mode 100644 index 70f8b5b..0000000 --- a/src/test/java/net/locusworks/common/utils/UtilsPackageCoverageTest.java +++ /dev/null @@ -1,161 +0,0 @@ -package net.locusworks.common.utils; - -import com.fasterxml.jackson.core.JsonParser; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.io.TempDir; - -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.IOException; -import java.io.StringReader; -import java.lang.reflect.Field; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.List; -import java.util.Locale; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertSame; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.mockStatic; -import static org.mockito.Mockito.CALLS_REAL_METHODS; -import static org.mockito.Mockito.when; -import org.mockito.MockedStatic; - -class UtilsPackageCoverageTest { - @TempDir - Path tempDir; - - private static java.util.Date deserialize(String value) throws Exception { - JsonParser parser = mock(JsonParser.class); - when(parser.getText()).thenReturn(value); - return new DateTimeStampDeserializer().deserialize(parser, null); - } - - @Test - void dateDeserializerHandlesEpochBuiltInCustomAndInvalidFormats() throws Exception { - assertEquals(1234L, deserialize("1234").getTime()); - - Locale original = Locale.getDefault(); - Locale.setDefault(Locale.US); - try { - assertNotNull(deserialize("January 1, 2020")); - assertNotNull(deserialize("12/31/2020")); - assertNotNull(deserialize("Dec 31, 2020 1:02:03 PM")); - assertNull(deserialize("definitely-not-a-date")); - - Field stylesField = DateTimeStampDeserializer.class.getDeclaredField("styles"); - stylesField.setAccessible(true); - Integer[] styles = (Integer[]) stylesField.get(null); - Integer[] originalStyles = styles.clone(); - java.util.Arrays.fill(styles, -1); - try { - assertNotNull(deserialize("12/31/2020")); - } finally { - System.arraycopy(originalStyles, 0, styles, 0, styles.length); - } - } finally { - Locale.setDefault(original); - } - } - - @SuppressWarnings("deprecation") - @Test - void hashUtilsCoversEveryInputOverloadCaseAndFailure() throws Exception { - String expected = HashUtils.hash("SHA-256", "content"); - byte[] bytes = "content".getBytes(StandardCharsets.UTF_8); - Path path = tempDir.resolve("hash.txt"); - Files.write(path, bytes); - File file = path.toFile(); - - assertEquals(expected, HashUtils.hash("SHA-256", bytes)); - assertEquals(expected, HashUtils.hash("SHA-256", path)); - assertEquals(expected, HashUtils.hash("SHA-256", file)); - assertEquals(expected.toUpperCase(Locale.ROOT), HashUtils.hash("SHA-256", file, false)); - assertEquals(expected.toUpperCase(Locale.ROOT), HashUtils.hash("SHA-256", path, false)); - assertEquals(expected, HashUtils.hash(new ByteArrayInputStream(bytes), "SHA-256")); - assertEquals(expected.toUpperCase(Locale.ROOT), - HashUtils.hash(new ByteArrayInputStream(bytes), "SHA-256", false)); - assertThrows(IllegalArgumentException.class, - () -> HashUtils.hash("SHA-256", tempDir.resolve("missing"))); - assertThrows(IllegalArgumentException.class, - () -> HashUtils.hash(new ByteArrayInputStream(bytes), "not-an-algorithm")); - assertThrows(IllegalArgumentException.class, - () -> HashUtils.hash(new java.io.InputStream() { - @Override public int read() throws IOException { throw new IOException("read failed"); } - }, "SHA-256")); - } - - @Test - void fileReaderCoversResourceValidationIterationMutationAndFailures() throws Exception { - try (FileReader resource = new FileReader("test.properties")) { - assertTrue(resource.hasNext()); - assertSame(resource, resource.iterator()); - assertNotNull(resource.next()); - } - - assertThrows(IllegalArgumentException.class, () -> new FileReader((String) null)); - assertThrows(IllegalArgumentException.class, () -> new FileReader((Path) null)); - assertThrows(IllegalArgumentException.class, () -> new FileReader(tempDir.resolve("missing"))); - assertThrows(IllegalArgumentException.class, () -> new FileReader(tempDir)); - assertThrows(IllegalArgumentException.class, () -> new FileReader((BufferedReader) null)); - - BufferedReader readFailure = new BufferedReader(new StringReader("")) { - @Override public String readLine() throws IOException { throw new IOException("read failed"); } - }; - assertThrows(RuntimeException.class, () -> new FileReader(readFailure).hasNext()); - - BufferedReader closeFailure = new BufferedReader(new StringReader("")) { - @Override public void close() throws IOException { throw new IOException("close failed"); } - }; - assertThrows(RuntimeException.class, () -> new FileReader(closeFailure).close()); - - FileReader nullReader = new FileReader(new BufferedReader(new StringReader(""))); - Field readerField = FileReader.class.getDeclaredField("reader"); - readerField.setAccessible(true); - readerField.set(nullReader, null); - assertDoesNotThrow(nullReader::close); - - Path simulated = tempDir.resolve("simulated.txt"); - try (MockedStatic files = mockStatic(Files.class, CALLS_REAL_METHODS)) { - files.when(() -> Files.notExists(simulated)).thenReturn(false); - files.when(() -> Files.isRegularFile(simulated)).thenReturn(true); - files.when(() -> Files.newBufferedReader(simulated)).thenThrow(new IOException("open failed")); - assertThrows(RuntimeException.class, () -> new FileReader(simulated)); - } - - FileReader.LineInfo info = new FileReader.LineInfo(1, "line"); - info.setLineNumber(2); - info.setLineLength(10); - info.setLine("changed"); - assertEquals(2, info.getLineNumber()); - assertEquals(10, info.getLineLength()); - assertEquals("changed", info.getLine()); - } - - @Test - void singletonAndUtilityClassConstructorsAreCovered() throws Exception { - Field instance = RandomString.class.getDeclaredField("instance"); - instance.setAccessible(true); - instance.set(null, null); - assertNotNull(RandomString.getInstance()); - - assertNotNull(new HashUtils()); - assertNotNull(new Checks()); - assertNotNull(new Utils()); - assertNotNull(new Constants()); - assertNotNull(new ObjectUtils()); - assertNotNull(new StreamUtils()); - assertNotNull(ObjectUtils.getResourceStream("/test.properties")); - - assertEquals(List.of("a", "b"), StreamUtils.asStream(List.of("a", "b"), true).toList()); - assertTrue(StreamUtils.asStream(new String[]{"a"}, true).isParallel()); - } -} diff --git a/src/test/java/net/locusworks/common/utils/UtilsTest.java b/src/test/java/net/locusworks/common/utils/UtilsTest.java deleted file mode 100644 index 1360bae..0000000 --- a/src/test/java/net/locusworks/common/utils/UtilsTest.java +++ /dev/null @@ -1,520 +0,0 @@ -package net.locusworks.common.utils; - -import net.locusworks.common.annotations.MapValue; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.ParameterizedTest; - -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Collection; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; -import java.util.Set; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.*; - -/** - * Test cases for the Utils class - * @author Isaac Parenteau - * @since 1.0.0-RELEASE - * - */ -public class UtilsTest { - - @Test - public void testSafeString() { - assertNotNull(Utils.safeString(null)); - assertTrue(Utils.safeString(null).isEmpty()); - assertFalse(Utils.safeString("hello world").isEmpty()); - } - - - @Test - public void testAreEqual() { - String val1 = "H"; - String val2 = "H"; - assertTrue(Utils.areEqual(val1, val2)); - - assertThrows(IllegalArgumentException.class, () -> Utils.areEqual("1")); - } - @ParameterizedTest - @MethodSource("areEqualParams") - public void testAreEqualWithParams(List objectList, boolean or, boolean equal) { - assertEquals(equal, Utils.areEqual(or, objectList.toArray())); - } - - static Stream areEqualParams() { - return Stream.of( - Arguments.of(List.of("Hello", "Hello"), false, true), - Arguments.of(List.of("Hello", "World"), false, false), - Arguments.of(List.of("Hello", "World", "Hello"), true, true), - Arguments.of(List.of("Hello", "World", "Fair"), true, false) - ); - } - - @Test - public void testEmptyString() { - assertTrue(Utils.isEmptyString(null)); - assertTrue(Utils.isEmptyString("")); - assertTrue(Utils.isEmptyString(" ")); - assertFalse(Utils.isEmptyString("foo")); - assertFalse(Utils.isEmptyString(" bar ")); - } - - @Test - public void testToInteger() { - assertEquals(2, (int) Utils.toInteger("Hello word", 2)); - assertEquals(23, (int) Utils.toInteger("23", 5023)); - } - - @ParameterizedTest - @MethodSource("validateValueParams") - public void testValidateValue(V value, boolean valid) { - assertEquals(valid, Utils.validateValue(value)); - } - - static Stream validateValueParams() { - return Stream.of( - Arguments.of(null, false), - Arguments.of(Collections.emptyList(), false), - Arguments.of(Map.of(), false), - Arguments.of(false, false), - Arguments.of("", false), - Arguments.of("Hello", true), - Arguments.of(List.of("Hello"), true), - Arguments.of(Map.of("Hello", "World"), true), - Arguments.of(true, true) - ); - } - - @ParameterizedTest - @MethodSource("areValidParams") - public void testValidateValues(List objects, boolean or, boolean valid) { - assertEquals(valid, Utils.areValid(objects.toArray())); - assertEquals(!valid, Utils.areNotValid(objects.toArray())); - } - - static Stream areValidParams() { - return Stream.of( - Arguments.of(List.of("Hello", List.of("Hello"), Map.of("Hello", "World"), true), false, true), - Arguments.of(List.of(Collections.emptyList(), Map.of(), false), false, false) - ); - } - - @Test - public void testBuildMap() { - Map mymap = Utils.buildMap(TreeMap.class, String.class, String.class, "Hello", "World"); - assertNotNull(mymap); - assertEquals(1, mymap.size()); - assertEquals("World", mymap.get("Hello")); - } - - - - @Test - public void testCloneList() { - String[] values = new String[]{ - "Hello", - "world" - }; - List cloned = Utils.cloneList(new ArrayList<>(Arrays.stream(values).toList())); - assertEquals(2, cloned.size()); - assertThrows(UnsupportedOperationException.class, () -> cloned.add("asdf")); - } - - @Test - public void testCloneObject() - throws InvocationTargetException, InstantiationException, IllegalAccessException, - NoSuchMethodException { - TestClass clazz = new TestClass(); - clazz.field1 = "hi"; - clazz.field2 = "low"; - clazz.field3 = "world"; - - TestClass clazz3 = new TestClass(); - clazz3.field1 = "hi"; - clazz3.field2 = "smash"; - clazz3.field3 = "world"; - - clazz.testClass = clazz3; - - TestClass clazz2 = Utils.cloneObject(clazz); - assertNotNull(clazz2); - assertEquals(clazz.field1, clazz2.field1); - assertEquals(clazz.field2, clazz2.field2); - assertEquals(clazz.field3, clazz2.field3); - assertEquals(clazz.field5, clazz2.field5); - assertEquals(clazz.number, clazz2.number); - assertEquals(clazz.aBoolean, clazz2.aBoolean); - assertNotNull(clazz2.field4); - assertNull(clazz2.nullField); - } - - @Test - public void testCovertToMap() throws Exception { - TestClass clazz = new TestClass(); - clazz.field1 = "hi"; - clazz.field2 = "low"; - clazz.field3 = "world"; - - TestClass clazz3 = new TestClass(); - clazz.field1 = "hi"; - clazz.field2 = "low"; - clazz.field3 = "world"; - clazz.testClass = clazz3; - - Map converted = Utils.convertToMap(clazz); - - assertEquals(7, converted.size()); - assertEquals("hi", converted.get("other_field")); - } - - @Test - public void testConvertToStringMap() throws Exception { - TestClass clazz = new TestClass(); - clazz.field1 = "hi"; - clazz.field2 = "low"; - clazz.field3 = "world"; - Map converted = Utils.convertToStringMap(clazz); - assertEquals(6, converted.size()); - assertEquals("hi", converted.get("other_field")); - - converted = Utils.convertToStringMap(converted); - assertEquals(6, converted.size()); - assertEquals("hi", converted.get("other_field")); - } - - @Test - public void testBuildStringMap() { - Map myMap = Utils.buildStringHashMap("hello", "world"); - assertNotNull(myMap); - assertEquals(1, myMap.size()); - } - - @Test - public void testExtractFieldToList() { - List list = new ArrayList<>(); - for (int i = 0; i < 10; i++) { - TestClass clazz = new TestClass(); - clazz.field5 = i; - list.add(clazz); - } - - List extractedList = Utils.extractFieldToList("field5", list); - java.util.Set extractedSet = Utils.extractFieldToSet("field5", list); - - assertEquals(10, extractedList.size()); - assertEquals(10, extractedSet.size()); - - for (int i = 0; i < 10; i++) { - assertEquals(i, extractedList.get(i)); - assertTrue(extractedSet.contains(i)); - } - - assertThrows(IllegalArgumentException.class, () -> Utils.extractFieldToList("fieldName", list)); - assertThrows(IllegalArgumentException.class, () -> Utils.extractFieldToSet("fieldName", list)); - } - - - @Test - public void testFilterList() { - List list = new ArrayList<>(); - for (int i = 0; i < 10; i++) { - TestClass clazz = new TestClass(); - clazz.field5 = i; - list.add(clazz); - } - - list.get(0).testClass = list.get(1); - - List filteredList = Utils.filterList("field5", 5, list); - assertEquals(1, filteredList.size()); - assertEquals(5, filteredList.get(0).field5); - assertThrows(IllegalArgumentException.class, () -> Utils.filterList("fieldName", 5, list)); - - int value = Utils.findValue(5, "field5", list); - assertEquals(5, value); - - TestClass tc = Utils.findValue(list.get(1), "testClass", list); - assertNotNull(tc); - assertEquals(1, tc.field5); - } - - @Test - public void testFindValues() { - List list = new ArrayList<>(); - for (int i = 0; i < 10; i++) { - TestClass clazz = new TestClass(); - clazz.field5 = i % 2; - list.add(clazz); - } - - List values = Utils.findValues(0, "field5", list); - assertEquals(5, values.size()); - - } - - @Test - public void testBuildMapExceptions() { - Throwable ex = assertThrows(IllegalArgumentException.class, () -> Utils.buildMap(String.class, String.class, String.class, "" )); - - assertNotNull(ex); - - ex = assertThrows(IllegalArgumentException.class, () -> Utils.buildMap(TreeMap.class, String.class, String.class, "Hello")); - - assertEquals("Odd number of arguments provided", ex.getMessage()); - - assertThrows(IllegalArgumentException.class, () -> Utils.buildMap(TreeMap.class, String.class, String.class, new Object(), "Hello")); - - assertThrows(IllegalArgumentException.class, () -> Utils.buildMap(TreeMap.class, String.class, String.class, "Hello", new Object())); - - assertThrows(IllegalArgumentException.class, () -> Utils.buildMap(TreeMap.class, Object.class, String.class, "Hello", new Object())); - } - - @Test - public void testBuildSet() { - java.util.Set myset = Utils.buildSet(HashSet.class, String.class, "Hello", "World"); - assertNotNull(myset); - assertEquals(2, myset.size()); - } - - @Test - public void testFormatString() { - String formatted = Utils.formatString("{} {}", "Hi", 1); - assertEquals("Hi 1", formatted); - } - - @Test - public void testGetClassName() { - TestClass tc = new TestClass(); - assertEquals(tc.getClass().getSimpleName(), Utils.getClassName(tc)); - assertEquals(tc.getClass().getName(), Utils.getClassName(tc, true)); - assertEquals("Unknown", Utils.getClassName(null)); - } - - @Test - public void testGetMapValue() { - Integer value = Utils.getMapValue(Map.of("hi", 1), "hi"); - assertEquals(1, value); - - value = Utils.getMapValue(Map.of("hi", 1), "low", 0); - - assertEquals(0, value); - } - - @Test - public void testIsNotValid() { - assertTrue(Utils.isNotValid(null, null, null)); - assertFalse(Utils.isNotValid("null", "null", "null")); - } - - @Test - public void testIsValid() { - assertFalse(Utils.isValid(null, null, null)); - assertTrue(Utils.isValid("null", "null", "null")); - } - - @Test - public void testListToMap() { - List list = new ArrayList<>(); - for (int i = 0; i < 10; i++) { - TestClass clazz = new TestClass(); - clazz.field5 = i; - list.add(clazz); - } - - Map values = Utils.listToMap("field5", list); - assertEquals(10, values.size()); - assertEquals(1, values.get(1).field5); - - assertThrows(Throwable.class, () -> Utils.listToMap("fieldasdf5", list)); - } - - @Test - public void testMakeArray() { - List list = new ArrayList<>(); - for (int i = 0; i < 10; i++) { - TestClass clazz = new TestClass(); - clazz.field5 = i; - list.add(clazz); - } - - assertNull(Utils.makeArray(null, String.class)); - - TestClass[] array = Utils.makeArray(list, TestClass.class); - assertEquals(10, array.length); - for(int i = 0; i < 10; i++) { - assertEquals(list.get(i), array[i]); - } - - assertNull(Utils.makeList((Collection) null)); - assertNull(Utils.makeList((Iterable) null)); - assertNull(Utils.makeList((String[]) null)); - - List testList = Utils.makeList(list); - for(int i = 0; i < 10; i++) { - assertEquals(list.get(i), testList.get(i)); - } - - TestClassList tcl = new TestClassList(); - tcl.testClassList = testList; - - List testClassList = Utils.makeList(tcl); - for(int i = 0; i < 10; i++) { - assertEquals(list.get(i), testClassList.get(i)); - } - - List testArrayList = Utils.makeList(array); - for(int i = 0; i < 10; i++) { - assertEquals(list.get(i), testArrayList.get(i)); - } - - Set testSet = Utils.makeSet(list); - assertEquals(10, testSet.size()); - } - - @Test - public void testMapToList() { - List values = Utils.mapToList(Map.of("Hello", 1)); - assertEquals(1, values.size()); - assertEquals(1, values.get(0)); - - Set setValues = Utils.mapToSet(Map.of("Hello", 1)); - assertEquals(1, setValues.size()); - assertTrue(setValues.contains(1)); - } - - @Test - public void testReverseMap() { - Map map = Utils.reverseMap(Map.of("Hello", 1)); - assertEquals(1, map.size()); - assertEquals("Hello", map.get(1)); - } - - @Test - public void testSafeList() { - assertEquals(0, Utils.safeArray(null).length); - assertTrue(Utils.safeList(null).isEmpty()); - assertFalse(Utils.safeIterable(null).iterator().hasNext()); - assertTrue(Utils.safeSet(null).isEmpty()); - - List list = List.of("Hello", "World"); - - String[] stringArray = list.toArray(new String[0]); - - assertEquals(list, Utils.safeList(list)); - assertEquals(stringArray, Utils.safeArray(stringArray)); - assertEquals(list, Utils.safeIterable(list)); - - Set testSet = Set.of("Hello", "World"); - - assertEquals(testSet, Utils.safeSet(testSet)); - } - - @Test - public void testSetToList() { - List list = Utils.setToList(Set.of("Hello", "World")); - assertEquals(2, list.size()); - - list = Utils.toList(Set.of("Hello", "World")); - assertEquals(2, list.size()); - - Set set = Utils.toSet("Hello", "World"); - - assertEquals(2, set.size()); - - assertTrue(set.contains("Hello")); - assertTrue(set.contains("World")); - } - - @Test - public void testToByteList() { - byte[] bytes = new byte[10]; - - for (int i = 0; i < bytes.length; i++) { - bytes[i] = (byte)i; - } - - List byteList = Utils.toByteList(bytes); - assertEquals(bytes.length, byteList.size()); - - for(int i = 0; i < bytes.length; i++) { - assertEquals(bytes[i], byteList.get(i)); - } - } - - @Test - public void testIterableSize() { - List stringList = List.of("Hello", "World"); - assertEquals(stringList.size(), (int)Utils.size(stringList)); - assertEquals(stringList.get(1), Utils.get(stringList, 1)); - } - - @Test - public void testExceptionWrapper() { - assertThrows(RuntimeException.class, () -> List.of("Hi", "Low").forEach(Utils.handleExceptionWrapper(o -> { - throw new Exception("bleh"); - }))); - - AtomicInteger atomicInteger = new AtomicInteger(0); - List.of("Hi", "Low").forEach(Utils.handleExceptionWrapper(o -> { - atomicInteger.incrementAndGet(); - })); - - assertEquals(2, atomicInteger.get()); - } - - @Test - public void testValidateValues() { - assertTrue(Utils.validateValues("Hello", "World")); - assertTrue(Utils.validateValuesOr("Hello", null)); - assertTrue(Utils.validateValuesOr(null, "Hello")); - assertFalse(Utils.validateValuesOr(null, null)); - } - - @Test - public void testIsJunitRunning() { - assertTrue(Utils.isJUnitRunning()); - } - - static class TestClassList implements Iterable { - private List testClassList; - @Override public Iterator iterator() { - return testClassList.iterator(); - } - - } - - public static class TestClass { - @MapValue("other_field") - private String field1; - - @MapValue(ignore = true) - private String field2; - - private String field3; - - private final String field4 = "final"; - @MapValue - private int field5 = 5; - - private Boolean aBoolean = Boolean.valueOf("true"); - - private Double number = 1.0d; - - private String nullField = null; - - private TestClass testClass; - - } - -} diff --git a/src/test/java/net/locusworks/test/AESEncryptionTest.java b/src/test/java/net/locusworks/test/AESEncryptionTest.java deleted file mode 100644 index 0271f48..0000000 --- a/src/test/java/net/locusworks/test/AESEncryptionTest.java +++ /dev/null @@ -1,44 +0,0 @@ -package net.locusworks.test; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.fail; - -import net.locusworks.common.crypto.AES; -import net.locusworks.common.utils.Utils; -import org.junit.jupiter.api.Test; - - -public class AESEncryptionTest { - - @Test - public void testEncryption() { - try { - String encrypted = AES.createInstance().encrypt("hello world"); - assertFalse(Utils.isEmptyString(encrypted), String.format("Encrypted String is not blank? :%s", encrypted)); - } catch (Exception ex) { - ex.printStackTrace(System.err); - fail(); - } - } - - @Test - public void testDecryption() { - String testString = "hello world"; - try { - AES aes = AES.createInstance(); - String encrypted = aes.encrypt(testString); - assertFalse(Utils.isEmptyString(encrypted), String.format("Encrypted String is not blank? :%s", encrypted)); - - String decrypted = aes.decrypt(encrypted); - assertFalse(Utils.isEmptyString(encrypted), String.format("Decrypted String is not blank? :%s", decrypted)); - - assertEquals(testString, decrypted, "Test String and Original String the same? :%s"); - - } catch (Exception ex) { - ex.printStackTrace(System.err); - fail(); - } - } - -} diff --git a/src/test/java/net/locusworks/test/HashSaltTest.java b/src/test/java/net/locusworks/test/HashSaltTest.java deleted file mode 100644 index ea6e8fd..0000000 --- a/src/test/java/net/locusworks/test/HashSaltTest.java +++ /dev/null @@ -1,36 +0,0 @@ -package net.locusworks.test; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; - -import net.locusworks.common.crypto.HashSalt; -import net.locusworks.common.utils.Utils; -import org.junit.jupiter.api.Test; - -public class HashSaltTest { - - private static final String samplePassword = "Hello World"; - - @Test - public void testEncryption() { - try { - String hashSalt = HashSalt.createHash(samplePassword); - assertFalse(Utils.isEmptyString(hashSalt), String.format("Encrypted String is not blank? :%s", hashSalt)); - } catch (Exception ex) { - fail(); - } - } - - @Test - public void testDecryption() { - try { - String hashSalt = HashSalt.createHash(samplePassword); - boolean decrypted = HashSalt.validatePassword(samplePassword, hashSalt); - assertTrue(decrypted, "Test String and Original String the same? :%s"); - } catch (Exception ex) { - fail(); - } - } - -} diff --git a/src/test/java/net/locusworks/test/ImmutablesTest.java b/src/test/java/net/locusworks/test/ImmutablesTest.java deleted file mode 100644 index 782665d..0000000 --- a/src/test/java/net/locusworks/test/ImmutablesTest.java +++ /dev/null @@ -1,63 +0,0 @@ -package net.locusworks.test; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotEquals; - -import net.locusworks.common.immutables.Pair; -import net.locusworks.common.immutables.Triplet; -import net.locusworks.common.immutables.Unit; -import org.junit.jupiter.api.Test; - - -public class ImmutablesTest { - - @Test - public void testUnit() { - Unit unit1 = new Unit<>("Hello World"); - Unit unit3 = new Unit<>("Hello World"); - assertEquals("Hello World", unit1.getValue1()); - - Unit unit2 = new Unit<>(2); - assertEquals(2, (int) unit2.getValue1()); - - assertEquals(unit1, unit3); - assertNotEquals(unit1, unit2); - assertNotEquals(unit1, new Object()); - assertNotEquals(unit1, null); - - } - - @Test - public void testPair() { - Pair pair1 = new Pair<>("Hello", "World"); - Pair pair2 = new Pair<>("Hello", "World"); - Pair pair3 = new Pair<>("Hello", "World2"); - assertEquals("Hello", pair1.getValue1()); - assertEquals("World", pair1.getValue2()); - assertEquals(pair1, pair2); - - assertNotEquals(pair1, pair3); - assertNotEquals(pair1, new Object()); - assertNotEquals(pair1, null); - - } - - @Test - public void testTriplet() { - Triplet triplet1 = new Triplet<>("Hello", 24, "World"); - Triplet triplet2 = new Triplet<>("Hello", 25, "World"); - Triplet triplet3 = new Triplet<>("Hello", 24, "World2"); - Triplet triplet4 = new Triplet<>("Hello", 24, "World"); - - assertEquals("Hello", triplet1.getValue1()); - assertEquals(24, (int) triplet1.getValue2()); - assertEquals("World", triplet1.getValue3()); - assertEquals(triplet1, triplet4); - - assertNotEquals(triplet1, triplet2); - assertNotEquals(triplet1, triplet3); - assertNotEquals(triplet1, new Object()); - assertNotEquals(triplet1, null); - } - -} diff --git a/src/test/java/net/locusworks/test/ObjectMapperHelperTest.java b/src/test/java/net/locusworks/test/ObjectMapperHelperTest.java deleted file mode 100644 index 93a6146..0000000 --- a/src/test/java/net/locusworks/test/ObjectMapperHelperTest.java +++ /dev/null @@ -1,73 +0,0 @@ -/** - * - */ -package net.locusworks.test; - -import java.util.List; - -import net.locusworks.common.immutables.Triplet; -import net.locusworks.common.objectmapper.ObjectMapperHelper; -import net.locusworks.common.utils.Utils; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -import static net.locusworks.common.utils.Constants.JUNIT_TEST_CHECK; -import static net.locusworks.common.utils.Constants.LOG4J_CONFIG_PROPERTY; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - -/** - * Test cases to test ObjectMapperHelper.class - * @author Isaac Parenteau - * @since 1.0.0-RELEASE - * - */ -public class ObjectMapperHelperTest { - - private static Triplet test; - - /** - * @throws java.lang.Exception exception - */ - @BeforeAll - public static void setUpBeforeClass() throws Exception { - System.setProperty(LOG4J_CONFIG_PROPERTY, "log4j2-test.xml"); - System.setProperty(JUNIT_TEST_CHECK, "true"); - test = new Triplet("Hello", 24, "World"); - } - - @AfterAll - public static void tearDownAfterClass() throws Exception { - System.clearProperty(LOG4J_CONFIG_PROPERTY); - System.clearProperty(JUNIT_TEST_CHECK); - } - - @Test - public void testWrite() { - String value = ObjectMapperHelper.writeValue(test).getResults(); - assertTrue(value != null && !value.trim().isEmpty()); - } - - @Test - public void testRead() { - String value = ObjectMapperHelper.writeValue(test).getResults(); - assertTrue(value != null && !value.trim().isEmpty()); - - Triplet tmp = ObjectMapperHelper.readValue(value, Triplet.class).getResults(); - assertNotNull(tmp); - assertEquals(tmp, test); - } - - @SuppressWarnings("rawtypes") - @Test - public void testListWriteRead() { - List> htrList = Utils.toList(test); - String value = ObjectMapperHelper.writeValue(htrList).getResults(); - assertTrue(value != null && !value.trim().isEmpty()); - List tmpList = ObjectMapperHelper.readListValue(value, Triplet.class).getResults(); - assertTrue(tmpList != null && !tmpList.isEmpty()); - } - -} diff --git a/src/test/java/net/locusworks/test/PropertiesManagerTest.java b/src/test/java/net/locusworks/test/PropertiesManagerTest.java deleted file mode 100644 index 8f85101..0000000 --- a/src/test/java/net/locusworks/test/PropertiesManagerTest.java +++ /dev/null @@ -1,129 +0,0 @@ -package net.locusworks.test; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Properties; - -import net.locusworks.common.configuration.PropertiesManager; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.Test; - -/** - * Test cases for the properties manager class - * - * @author Isaac Parenteau - * @since 1.0.0-RELEASE - * - */ -public class PropertiesManagerTest { - - private static final String PROPERTIES_FILE = "test.properties"; - private static final String TMP_PROPS = "temp.properties"; - private static final int ENTRY_SIZE = 4; - - public enum Configuration { - DB_HOST("dbHost"), - DB_PORT("dbPort"), - USER_EXPIRATION_DAYS("userExpirationDays"), - LOG_LEVEL("logLevel"); - - private final String value; - - private Configuration(String value) { - this.value = value; - } - - /** - * Get the current value of the enumeration - * - * @return value - */ - public String getValue() { - return this.value; - } - - @Override - public String toString() { - return this.value; - } - } - - @AfterAll - public static void removeSavedProps() { - File tmp = new File(TMP_PROPS); - if (tmp.exists()) { - tmp.delete(); - } - } - - @Test - public void testPropertiesLoad() { - try { - Properties props = PropertiesManager.loadConfiguration(this.getClass(), PROPERTIES_FILE); - assertNotNull(props); - assertTrue(props.containsKey(Configuration.USER_EXPIRATION_DAYS.toString())); - assertTrue(props.containsKey(Configuration.DB_HOST.toString())); - assertTrue(props.containsKey(Configuration.DB_PORT.toString())); - assertTrue(props.containsKey(Configuration.LOG_LEVEL.toString())); - } catch (IOException e) { - fail(e.getMessage()); - } - } - - @Test - public void testAddConfiguration() { - try { - Properties props = PropertiesManager.loadConfiguration(this.getClass(), PROPERTIES_FILE); - Properties tmp = new Properties(); - assertEquals(0, tmp.size()); - PropertiesManager.addConfiguration(tmp, props); - assertEquals(ENTRY_SIZE, tmp.size()); - assertTrue(tmp.containsKey(Configuration.USER_EXPIRATION_DAYS.toString())); - assertTrue(tmp.containsKey(Configuration.DB_HOST.toString())); - assertTrue(tmp.containsKey(Configuration.DB_PORT.toString())); - assertTrue(tmp.containsKey(Configuration.LOG_LEVEL.toString())); - } catch (IOException e) { - fail(e.getMessage()); - } - } - - @Test - public void testRemoveConfiguration() { - try { - Properties props = PropertiesManager.loadConfiguration(this.getClass(), PROPERTIES_FILE); - Properties tmp = new Properties(); - assert props != null; - assertEquals(ENTRY_SIZE, props.size()); - assertEquals(0, tmp.size()); - PropertiesManager.removeConfiguration(props, tmp); - assertEquals(0, props.size()); - assertEquals(0, tmp.size()); - } catch (IOException e) { - fail(e.getMessage()); - } - } - - @Test - public void testSaveConfiguration() { - try { - Properties props = PropertiesManager.loadConfiguration(this.getClass(), PROPERTIES_FILE); - Path tmpFile = Paths.get(TMP_PROPS); - PropertiesManager.saveConfiguration(props, tmpFile, "test propertis"); - Properties tmp = PropertiesManager.loadConfiguration(tmpFile); - assertEquals(ENTRY_SIZE, tmp.size()); - assertTrue(tmp.containsKey(Configuration.USER_EXPIRATION_DAYS.toString())); - assertTrue(tmp.containsKey(Configuration.DB_HOST.toString())); - assertTrue(tmp.containsKey(Configuration.DB_PORT.toString())); - assertTrue(tmp.containsKey(Configuration.LOG_LEVEL.toString())); - } catch (IOException e) { - fail(e.getMessage()); - } - } -} diff --git a/src/test/resources/log4j2-test.xml b/src/test/resources/log4j2-test.xml deleted file mode 100644 index a2c3fe0..0000000 --- a/src/test/resources/log4j2-test.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff --git a/src/test/resources/test.properties b/src/test/resources/test.properties deleted file mode 100644 index 292c3da..0000000 --- a/src/test/resources/test.properties +++ /dev/null @@ -1,4 +0,0 @@ -userExpirationDays=3650 -dbHost=localhost -dbPort=3306 -logLevel=INFO