diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 4662abe..f081061 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -19,12 +19,12 @@ jobs: steps: - name: Checkout source - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up JDK - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: '17' distribution: 'zulu' @@ -34,21 +34,21 @@ jobs: run: java -version && ./mvnw -version && gpg --version - name: Cache SonarCloud packages - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ~/.sonar/cache key: ${{ runner.os }}-sonar restore-keys: ${{ runner.os }}-sonar - name: Cache Maven packages - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-m2 - name: Import GPG key - uses: crazy-max/ghaction-import-gpg@v5 + uses: crazy-max/ghaction-import-gpg@v6 with: gpg_private_key: ${{ secrets.OSS_SONATYPE_GPG_PRIVATE_KEY }} passphrase: ${{ secrets.OSS_SONATYPE_GPG_PASSPHRASE }} diff --git a/.gitignore b/.gitignore index 3dbc3f0..74a3cc5 100644 --- a/.gitignore +++ b/.gitignore @@ -3,8 +3,10 @@ !.gitkeep !.mvn !.github +!.sonarlint !.devcontainer target META-INF *.log +*.iml pom.xml.versionsBackup diff --git a/.mvn/maven.config b/.mvn/maven.config index d023e53..fd083ed 100644 --- a/.mvn/maven.config +++ b/.mvn/maven.config @@ -1 +1,2 @@ --s settings.xml \ No newline at end of file +-s +settings.xml \ No newline at end of file diff --git a/.sonarlint/connectedMode.json b/.sonarlint/connectedMode.json new file mode 100644 index 0000000..0291107 --- /dev/null +++ b/.sonarlint/connectedMode.json @@ -0,0 +1,5 @@ +{ + "sonarCloudOrganization": "fuinorg", + "projectKey": "org.fuin:utils4j", + "region": "EU" +} \ No newline at end of file diff --git a/README.md b/README.md index 6e3f086..9496c95 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ A small Java library that contains several helpful utility classes. [![Java Development Kit 17](https://img.shields.io/badge/JDK-17-green.svg)](https://openjdk.java.net/projects/jdk/17/) ## Versions +- 0.14.0 = See [release-notes](release-notes.md) - 0.13.x (or later) = **Java 17** - 0.12.0 = **Java 11** with new **jakarta** namespace - 0.11.x = **Java 11** before namespace change from 'javax' to 'jakarta' @@ -42,7 +43,7 @@ Directly create a URL using a utility method: ```Java URL url = Utils4J.url("classpath:org/fuin/utils4j/test.properties"); ``` -A full example can be found here: [ClasspathURLExample.java](https://github.com/fuinorg/utils4j/blob/master/src/test/java/org/fuin/utils4j/examples/ClasspathURLExample.java) +A full example can be found here: [ClasspathURLExample.java](src/test/java/org/fuin/utils4j/examples/ClasspathURLExample.java) If you register the URL stream handler, all URLs (no matter how they were constructed) will work: ```Java @@ -63,7 +64,7 @@ a=1 b=1/2 c=1/2/3 ``` -A full example can be found here: [VariableResolverExample.java](https://github.com/fuinorg/utils4j/blob/master/src/test/java/org/fuin/utils4j/examples/VariableResolverExample.java) +A full example can be found here: [VariableResolverExample.java](src/test/java/org/fuin/utils4j/examples/VariableResolverExample.java) ### ZIP and UNZIP @@ -74,7 +75,7 @@ final File zipFile = new File(Utils4J.getTempDir(), "myfile1.zip"); Utils4J.zipDir(zipDir, "abc/def", zipFile); Utils4J.unzip(zipFile, Utils4J.getTempDir()); ``` -A full example can be found here: [ZipDirExample.java](https://github.com/fuinorg/utils4j/blob/master/src/test/java/org/fuin/utils4j/examples/ZipDirExample.java) +A full example can be found here: [ZipDirExample.java](src/test/java/org/fuin/utils4j/examples/ZipDirExample.java) ### Tracking changes of a list / map @@ -87,8 +88,8 @@ System.out.println(trackingList.getDeleted()); System.out.println(trackingList.getAdded()); trackingList.revert(); ``` -A list example can be found here: [ChangeTrackingUniqueListExample.java](https://github.com/fuinorg/utils4j/blob/master/src/test/java/org/fuin/utils4j/examples/ChangeTrackingUniqueListExample.java) -A map example can be found here: [ChangeTrackingMapExample.java](https://github.com/fuinorg/utils4j/blob/master/src/test/java/org/fuin/utils4j/examples/ChangeTrackingMapExample.java) +A list example can be found here: [ChangeTrackingUniqueListExample.java](src/test/java/org/fuin/utils4j/examples/ChangeTrackingUniqueListExample.java) +A map example can be found here: [ChangeTrackingMapExample.java](src/test/java/org/fuin/utils4j/examples/ChangeTrackingMapExample.java) ### Easy file locking @@ -101,7 +102,7 @@ try { lock.release(); } ``` -A full example can be found here: [LockFileExample.java](https://github.com/fuinorg/utils4j/blob/master/src/test/java/org/fuin/utils4j/examples/LockFileExample.java) +A full example can be found here: [LockFileExample.java](src/test/java/org/fuin/utils4j/examples/LockFileExample.java) ### Properties file preferences @@ -110,7 +111,7 @@ Shows the use of a directory and properties file based [Preferences API](http:// System.setProperty("java.util.prefs.PreferencesFactory", PropertiesFilePreferencesFactory.class.getName()); Preferences userPrefs = Preferences.userRoot(); ``` -A full example can be found here: [PropertiesFilePreferencesFactoryExample.java](https://github.com/fuinorg/utils4j/blob/master/src/test/java/org/fuin/utils4j/examples/PropertiesFilePreferencesFactoryExample.java) +A full example can be found here: [PropertiesFilePreferencesFactoryExample.java](src/test/java/org/fuin/utils4j/examples/PropertiesFilePreferencesFactoryExample.java) ### JAXB CDATA Stream Writer @@ -163,7 +164,7 @@ System.out.println(copy.getContent()); // ``` -A full example can be found here: [CDataJaxbExample.java](https://github.com/fuinorg/utils4j/blob/master/src/test/java/org/fuin/utils4j/examples/CDataJaxbExample.java) +A full example can be found here: [CDataJaxbExample.java](src/test/java/org/fuin/utils4j/examples/CDataJaxbExample.java) **Caution** - You must explicitly add the xml.bind-api dependency to your POM if you want to use this feature, because it's defined as optional here. @@ -180,7 +181,7 @@ A full example can be found here: [CDataJaxbExample.java](https://github.com/fui > :warning: Deprecated in favour of [Awaitility](https://github.com/awaitility/awaitility) -The [WaitHelper](https://github.com/fuinorg/utils4j/blob/master/src/main/java/org/fuin/utils4j/WaitHelper.java) class supports waiting for some condition. +The [WaitHelper](src/main/java/org/fuin/utils4j/WaitHelper.java) class supports waiting for some condition. Example of waiting for a function to finish without an exception: ```Java @@ -208,7 +209,7 @@ waitHelper.waitUntilResult(() -> { }, Arrays.asList("Peter Parker, Inc")); ``` -A full example can be found here: [WaitHelperExample.java](https://github.com/fuinorg/utils4j/blob/master/src/test/java/org/fuin/utils4j/examples/WaitHelperExample.java) +A full example can be found here: [WaitHelperExample.java](src/test/java/org/fuin/utils4j/examples/WaitHelperExample.java) ### Find all JARs and classes in the classpath @@ -234,7 +235,7 @@ for (final File file : Utils4J.pathsFiles(System.getProperty("sun.boot.class.pat System.out.println(file); } ``` -A full example can be found here: [FindJarsAndClassesInClasspath.java](https://github.com/fuinorg/utils4j/blob/master/src/test/java/org/fuin/utils4j/examples/FindJarsAndClassesInClasspath.java) +A full example can be found here: [FindJarsAndClassesInClasspath.java](src/test/java/org/fuin/utils4j/examples/FindJarsAndClassesInClasspath.java) ### Analyze classes in the classpath with Jandex Easily find matching types from all classes or JAR files in the classpath using [Jandex](https://github.com/wildfly/jandex) @@ -255,7 +256,7 @@ for (File file : knownFiles) { System.out.println(file); } ``` -A test that shows the usage can be found here: [JandexUtilsTest](https://github.com/fuinorg/utils4j/blob/master/src/test/java/org/fuin/utils4j/JandexUtilsTest.java) +A test that shows the usage can be found here: [JandexUtilsTest](src/test/java/org/fuin/utils4j/jandex/JandexUtilsTest.java) **Caution** - You must explicitly add the Jandex dependency to your POM if you want to use this feature, because it's defined as optional here. diff --git a/pom.xml b/pom.xml index 5e0381a..694e31a 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ utils4j bundle - 0.13.0 + 0.14.0-SNAPSHOT A small Java library that contains several helpful utility classes. http://www.fuin.org/utils4j/ @@ -40,14 +40,14 @@ io.smallrye jandex - 3.1.6 + 3.2.7 true jakarta.xml.bind jakarta.xml.bind-api - 4.0.1 + 4.0.2 true @@ -56,42 +56,42 @@ org.junit.jupiter junit-jupiter - 5.10.1 + 5.10.5 test org.assertj assertj-core - 3.24.2 + 3.26.3 test nl.jqno.equalsverifier equalsverifier - 3.15.4 + 3.19.2 test org.xmlunit xmlunit-core - 2.8.2 + 2.10.0 test commons-io commons-io - 2.15.1 + 2.18.0 test org.glassfish.jaxb jaxb-runtime - 4.0.4 + 4.0.5 test @@ -111,6 +111,14 @@ maven-source-plugin + + org.apache.maven.plugins + maven-surefire-plugin + + ${argLine} -Duser.language=en -Duser.region=US + + + org.apache.maven.plugins maven-javadoc-plugin @@ -141,6 +149,20 @@ jacoco-maven-plugin + + io.smallrye + jandex-maven-plugin + 3.0.6 + + + make-index + + jandex + + + + + diff --git a/release-notes.md b/release-notes.md new file mode 100644 index 0000000..d8ed268 --- /dev/null +++ b/release-notes.md @@ -0,0 +1,17 @@ +# Release Notes + +## 0.14.0 + +### General +- Dependency updates +- New [MultipleCommands](src/main/java/org/fuin/utils4j/MultipleCommands.java) class +- New [TestCommand](src/main/java/org/fuin/utils4j/TestCommand.java) class +- New [TestOmitted](src/main/java/org/fuin/utils4j/TestOmitted.java) annotation + +### Jandex +- [JandexUtils](src/main/java/org/fuin/utils4j/jandex/JandexUtils.java) moved to "jandex" subdirectory +- New [JandexIndexFileReader](src/main/java/org/fuin/utils4j/jandex/JandexIndexFileReader.java) and [JandexIndexFileWriter](src/main/java/org/fuin/utils4j/jandex/JandexIndexWriter.java) + +### JAX-B +- [MarshallerBuilder](src/main/java/org/fuin/utils4j/jaxb/MarshallerBuilder.java) +- Several static methods in [JaxbUtils](src/main/java/org/fuin/utils4j/jaxb/JaxbUtils.java) are now deprecated in favour of [MarshallerBuilder](src/main/java/org/fuin/utils4j/jaxb/MarshallerBuilder.java) and [UnmarshallerBuilder](src/main/java/org/fuin/utils4j/jaxb/UnmarshallerBuilder.java) diff --git a/settings.xml b/settings.xml index b3ba5b6..311de47 100644 --- a/settings.xml +++ b/settings.xml @@ -66,7 +66,7 @@ sonatype.oss.snapshots Sonatype OSS Snapshot Repository - http://oss.sonatype.org/content/repositories/snapshots + https://oss.sonatype.org/content/repositories/snapshots false diff --git a/src/main/java/org/fuin/utils4j/ChangeTrackingMap.java b/src/main/java/org/fuin/utils4j/ChangeTrackingMap.java index c4e3b8d..f0713b2 100644 --- a/src/main/java/org/fuin/utils4j/ChangeTrackingMap.java +++ b/src/main/java/org/fuin/utils4j/ChangeTrackingMap.java @@ -65,7 +65,7 @@ public ChangeTrackingMap(final Map map) { * @return If elements have been added or deleted true else false. */ public final boolean isChanged() { - return (added.size() > 0) || (changed.size() > 0) || (removed.size() > 0); + return (!added.isEmpty()) || (changed.size() > 0) || (removed.size() > 0); } /** diff --git a/src/main/java/org/fuin/utils4j/MultipleCommands.java b/src/main/java/org/fuin/utils4j/MultipleCommands.java new file mode 100644 index 0000000..777e47d --- /dev/null +++ b/src/main/java/org/fuin/utils4j/MultipleCommands.java @@ -0,0 +1,118 @@ +/** + * Copyright (C) 2015 Michael Schnell. All rights reserved. + * http://www.fuin.org/ + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 3 of the License, or (at your option) any + * later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see http://www.gnu.org/licenses/. + */ +package org.fuin.utils4j; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Combines multiple test commands into one. + * + * @param + * Type of the test context. + */ +public final class MultipleCommands implements TestCommand { + + private final List> commands; + + /** + * Default constructor. + */ + public MultipleCommands() { + super(); + this.commands = new ArrayList<>(); + } + + /** + * Constructor with command array. + * + * @param commands + * One or more commands to execute. Not {@literal null}. + */ + @SafeVarargs + public MultipleCommands(final TestCommand... commands) { + this(Arrays.asList(commands)); + } + + /** + * Constructor with command list. + * + * @param commands + * List of commands to execute. Not {@literal null}. + */ + public MultipleCommands(final List> commands) { + super(); + Utils4J.checkNotNull("commands", commands); + this.commands = new ArrayList<>(commands); + } + + /** + * Adds a new command. + * + * @param command + * Command to add. Not {@literal null}. + */ + public void add(final TestCommand command) { + this.commands.add(command); + } + + @Override + public void init(final CONTEXT context) { + for (final TestCommand command : commands) { + command.init(context); + } + } + + @Override + public final void execute() { + for (final TestCommand command : commands) { + command.execute(); + } + } + + @Override + public final boolean isSuccessful() { + for (final TestCommand command : commands) { + if (!command.isSuccessful()) { + return false; + } + } + return true; + } + + @Override + public final String getFailureDescription() { + final StringBuilder sb = new StringBuilder(); + for (final TestCommand command : commands) { + if (!command.isSuccessful()) { + sb.append(command.getFailureDescription()); + sb.append("\n"); + } + } + return sb.toString(); + } + + @Override + public final void verify() { + if (!isSuccessful()) { + throw new RuntimeException("There was at least one failure:\n" + getFailureDescription()); + } + } + +} diff --git a/src/main/java/org/fuin/utils4j/TestCommand.java b/src/main/java/org/fuin/utils4j/TestCommand.java new file mode 100644 index 0000000..b3dc59f --- /dev/null +++ b/src/main/java/org/fuin/utils4j/TestCommand.java @@ -0,0 +1,61 @@ +/** + * Copyright (C) 2015 Michael Schnell. All rights reserved. + * http://www.fuin.org/ + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 3 of the License, or (at your option) any + * later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see http://www.gnu.org/licenses/. + */ +package org.fuin.utils4j; + +/** + * A command used in a test scenario. + * + * @param + * Type of the context. + */ +public interface TestCommand { + + /** + * Initializes the command before executing it. + * + * @param context + * Context with specific information that may be used by the command. Not {@literal null}. + */ + public void init(CONTEXT context); + + /** + * Executes the command. Exceptions will be catched used for creating a nice failure description. They are also logged. + */ + public void execute(); + + /** + * Returns if the command execution was successful. If this method is called before {@link #execute()} was executed, an illegal state + * exception will be thrown. + * + * @return TRUE if it was successful, else FALSE if it was a failure. + */ + public boolean isSuccessful(); + + /** + * Returns a description of the failure condition. + * + * @return Expected and current result. + */ + public String getFailureDescription(); + + /** + * Verifies that the command was successful and throws a runtime exception otherwise. + */ + public void verify(); + +} diff --git a/src/main/java/org/fuin/utils4j/TestOmitted.java b/src/main/java/org/fuin/utils4j/TestOmitted.java new file mode 100644 index 0000000..3fb92b6 --- /dev/null +++ b/src/main/java/org/fuin/utils4j/TestOmitted.java @@ -0,0 +1,42 @@ +/** + * Copyright (C) 2015 Michael Schnell. All rights reserved. + * http://www.fuin.org/ + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 3 of the License, or (at your option) any + * later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see http://www.gnu.org/licenses/. + */ +package org.fuin.utils4j; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * States that the annotated test class contains no tests by intention. + * This avoids test failures when test coverage checks are done. + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface TestOmitted { + + /** + * Short description why the test class was not implemented. + * + * @return Explanation why the test was skipped + */ + String value(); + +} diff --git a/src/main/java/org/fuin/utils4j/Utils4J.java b/src/main/java/org/fuin/utils4j/Utils4J.java index 5ec08b4..11be3fe 100644 --- a/src/main/java/org/fuin/utils4j/Utils4J.java +++ b/src/main/java/org/fuin/utils4j/Utils4J.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2015 Michael Schnell. All rights reserved. + * Copyright (C) 2015 Michael Schnell. All rights reserved. * http://www.fuin.org/ * * This library is free software; you can redistribute it and/or modify it under @@ -22,7 +22,26 @@ import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.PBEParameterSpec; -import java.io.*; +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.BufferedWriter; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileFilter; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.RandomAccessFile; +import java.io.Reader; +import java.io.Writer; +import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.MalformedURLException; @@ -35,7 +54,16 @@ import java.security.GeneralSecurityException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.Semaphore; +import java.util.function.Consumer; import java.util.function.Predicate; import java.util.stream.Stream; import java.util.zip.ZipEntry; @@ -71,7 +99,7 @@ public final class Utils4J { /** * Used building output as Hex. */ - private static final char[] DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + private static final char[] DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; /** * Private default constructor. @@ -82,10 +110,8 @@ private Utils4J() { /** * Returns the package path of a class. - * - * @param clasz - * Class to determine the path for - Cannot be null. - * + * + * @param clasz Class to determine the path for - Cannot be null. * @return Package path for the class. */ public static String getPackagePath(final Class clasz) { @@ -95,12 +121,9 @@ public static String getPackagePath(final Class clasz) { /** * Get the path to a resource located in the same package as a given class. - * - * @param clasz - * Class with the same package where the resource is located - Cannot be null. - * @param name - * Filename of the resource - Cannot be null. - * + * + * @param clasz Class with the same package where the resource is located - Cannot be null. + * @param name Filename of the resource - Cannot be null. * @return Resource URL. */ public static URL getResource(final Class clasz, final String name) { @@ -112,9 +135,8 @@ public static URL getResource(final Class clasz, final String name) { /** * Check if the argument is an existing file. If the check fails an IllegalArgumentException is thrown. - * - * @param file - * File to check - Cannot be null. + * + * @param file File to check - Cannot be null. */ public static void checkValidFile(final File file) { checkNotNull("file", file); @@ -128,9 +150,8 @@ public static void checkValidFile(final File file) { /** * Check if the argument is an existing directory. If the check fails an IllegalArgumentException is thrown. - * - * @param dir - * Directory to check - Cannot be null. + * + * @param dir Directory to check - Cannot be null. */ public static void checkValidDir(final File dir) { checkNotNull("dir", dir); @@ -144,10 +165,8 @@ public static void checkValidDir(final File dir) { /** * Create an instance with Class.forName(..) and wrap all exceptions into RuntimeExceptions. The class loader of this class is used. - * - * @param className - * Full qualified class name - Cannot be null. - * + * + * @param className Full qualified class name - Cannot be null. * @return New instance of the class. */ public static Object createInstance(final String className) { @@ -156,12 +175,9 @@ public static Object createInstance(final String className) { /** * Create an instance with Class.forName(..) and wrap all exceptions into RuntimeExceptions. - * - * @param className - * Full qualified class name - Cannot be null. - * @param classLoader - * Dedicated class loader to use - Cannot be NULL. - * + * + * @param className Full qualified class name - Cannot be null. + * @param classLoader Dedicated class loader to use - Cannot be NULL. * @return New instance of the class. */ public static Object createInstance(final String className, final ClassLoader classLoader) { @@ -189,12 +205,9 @@ public static Object createInstance(final String className, final ClassLoader cl /** * Checks if the array or URLs contains the given URL. - * - * @param urls - * Array of URLs - Cannot be null. - * @param url - * URL to find - Cannot be null. - * + * + * @param urls Array of URLs - Cannot be null. + * @param url URL to find - Cannot be null. * @return If the URL is in the array TRUE else FALSE. */ public static boolean containsURL(final URL[] urls, final URL url) { @@ -213,10 +226,8 @@ public static boolean containsURL(final URL[] urls, final URL url) { /** * Creates an MD5 hash from a file. - * - * @param file - * File to create an hash for - Cannot be null. - * + * + * @param file File to create an hash for - Cannot be null. * @return Hash as text. */ public static String createHashMD5(final File file) { @@ -225,12 +236,9 @@ public static String createHashMD5(final File file) { /** * Creates a HEX encoded hash from a file. - * - * @param file - * File to create a hash for - Cannot be null. - * @param algorithm - * Hash algorithm like "MD5" or "SHA" - Cannot be null. - * + * + * @param file File to create a hash for - Cannot be null. + * @param algorithm Hash algorithm like "MD5" or "SHA" - Cannot be null. * @return HEX encoded hash. */ public static String createHash(final File file, final String algorithm) { @@ -247,12 +255,9 @@ public static String createHash(final File file, final String algorithm) { /** * Creates a HEX encoded hash from a stream. - * - * @param inputStream - * Stream to create a hash for - Cannot be null. - * @param algorithm - * Hash algorithm like "MD5" or "SHA" - Cannot be null. - * + * + * @param inputStream Stream to create a hash for - Cannot be null. + * @param algorithm Hash algorithm like "MD5" or "SHA" - Cannot be null. * @return HEX encoded hash. */ public static String createHash(final InputStream inputStream, final String algorithm) { @@ -275,22 +280,14 @@ public static String createHash(final InputStream inputStream, final String algo /** * Creates a cipher for encryption or decryption. - * - * @param algorithm - * PBE algorithm like "PBEWithMD5AndDES" or "PBEWithMD5AndTripleDES". - * @param mode - * Encyrption or decyrption. - * @param password - * Password. - * @param salt - * Salt usable with algorithm. - * @param count - * Iterations. - * + * + * @param algorithm PBE algorithm like "PBEWithMD5AndDES" or "PBEWithMD5AndTripleDES". + * @param mode Encyrption or decyrption. + * @param password Password. + * @param salt Salt usable with algorithm. + * @param count Iterations. * @return Ready initialized cipher. - * - * @throws GeneralSecurityException - * Error creating the cipher. + * @throws GeneralSecurityException Error creating the cipher. */ private static Cipher createCipher(final String algorithm, final int mode, final char[] password, final byte[] salt, final int count) throws GeneralSecurityException { @@ -307,22 +304,16 @@ private static Cipher createCipher(final String algorithm, final int mode, final /** * Encrypts some data based on a password. - * - * @param algorithm - * PBE algorithm like "PBEWithMD5AndDES" or "PBEWithMD5AndTripleDES" - Cannot be null. - * @param data - * Data to encrypt - Cannot be null. - * @param password - * Password - Cannot be null. - * @param salt - * Salt usable with algorithm - Cannot be null. - * @param count - * Iterations. - * + * + * @param algorithm PBE algorithm like "PBEWithMD5AndDES" or "PBEWithMD5AndTripleDES" - Cannot be null. + * @param data Data to encrypt - Cannot be null. + * @param password Password - Cannot be null. + * @param salt Salt usable with algorithm - Cannot be null. + * @param count Iterations. * @return Encrypted data. */ public static byte[] encryptPasswordBased(final String algorithm, final byte[] data, final char[] password, final byte[] salt, - final int count) { + final int count) { checkNotNull("algorithm", algorithm); checkNotNull("data", data); @@ -339,22 +330,16 @@ public static byte[] encryptPasswordBased(final String algorithm, final byte[] d /** * Decrypts some data based on a password. - * - * @param algorithm - * PBE algorithm like "PBEWithMD5AndDES" or "PBEWithMD5AndTripleDES" - Cannot be null. - * @param encryptedData - * Data to decrypt - Cannot be null. - * @param password - * Password - Cannot be null. - * @param salt - * Salt usable with algorithm - Cannot be null. - * @param count - * Iterations. - * + * + * @param algorithm PBE algorithm like "PBEWithMD5AndDES" or "PBEWithMD5AndTripleDES" - Cannot be null. + * @param encryptedData Data to decrypt - Cannot be null. + * @param password Password - Cannot be null. + * @param salt Salt usable with algorithm - Cannot be null. + * @param count Iterations. * @return Encrypted data. */ public static byte[] decryptPasswordBased(final String algorithm, final byte[] encryptedData, final char[] password, final byte[] salt, - final int count) { + final int count) { checkNotNull("algorithm", algorithm); checkNotNull("encryptedData", encryptedData); @@ -371,15 +356,11 @@ public static byte[] decryptPasswordBased(final String algorithm, final byte[] e /** * Creates an URL based on a directory a relative path and a filename. - * - * @param baseUrl - * Directory URL with or without slash ("/") at the end of the string - Cannot be null. - * @param path - * Relative path inside the base URL (with or without slash ("/") at the end of the string) - Can be null or an - * empty string. - * @param filename - * Filename without path - Cannot be null. - * + * + * @param baseUrl Directory URL with or without slash ("/") at the end of the string - Cannot be null. + * @param path Relative path inside the base URL (with or without slash ("/") at the end of the string) - Can be null or an + * empty string. + * @param filename Filename without path - Cannot be null. * @return URL. */ public static URL createUrl(final URL baseUrl, final String path, final String filename) { @@ -409,12 +390,9 @@ public static URL createUrl(final URL baseUrl, final String path, final String f /** * Returns a relative path based on a base directory. If the dir is not inside baseDir an * IllegalArgumentException is thrown. - * - * @param baseDir - * Base directory the path is relative to - Cannot be null. - * @param dir - * Directory inside the base directory - Cannot be null. - * + * + * @param baseDir Base directory the path is relative to - Cannot be null. + * @param dir Directory inside the base directory - Cannot be null. * @return Path of dir relative to baseDir. If both are equal an empty string is returned. */ public static String getRelativePath(final File baseDir, final File dir) { @@ -434,12 +412,9 @@ public static String getRelativePath(final File baseDir, final File dir) { /** * Checks if a given file is inside the given directory. - * - * @param dir - * Base directory - Cannot be null. - * @param file - * File - Cannot be null. - * + * + * @param dir Base directory - Cannot be null. + * @param file File - Cannot be null. * @return If the file is inside the directory TRUE, else FALSE. */ public static boolean fileInsideDirectory(final File dir, final File file) { @@ -454,10 +429,8 @@ public static boolean fileInsideDirectory(final File dir, final File file) { /** * Returns the canonical path for the file without throwing a checked exception. A potential {@link IOException} is converted into a * {@link RuntimeException} - * - * @param file - * File to return the canonical path for or null. - * + * + * @param file File to return the canonical path for or null. * @return Canonical path for the given argument or null if the input was null. */ public static String getCanonicalPath(final File file) { @@ -474,10 +447,8 @@ public static String getCanonicalPath(final File file) { /** * Returns the canonical file for the file without throwing a checked exception. A potential {@link IOException} is converted into a * {@link RuntimeException} - * - * @param file - * File to return the canonical file for or null. - * + * + * @param file File to return the canonical file for or null. * @return Canonical file for the given argument or null if the input was null. */ public static File getCanonicalFile(final File file) { @@ -498,12 +469,9 @@ public static File getCanonicalFile(final File file) { * "a/b/c" => "../../.."
* "my-dir" => ".."
* "my-dir/other/" => "../../".
- * - * @param relativePath - * Relative path to convert - Expected to be a directory and NOT a file - Cannot be NULL. - * @param fileSeparatorChar - * See {@link File#separatorChar}. - * + * + * @param relativePath Relative path to convert - Expected to be a directory and NOT a file - Cannot be NULL. + * @param fileSeparatorChar See {@link File#separatorChar}. * @return Relative path with ".." (dot dot) */ public static String getBackToRootPath(final String relativePath, final char fileSeparatorChar) { @@ -527,11 +495,9 @@ public static String getBackToRootPath(final String relativePath, final char fil /** * Checks if a variable is not null and throws an IllegalNullArgumentException if this rule is violated. - * - * @param name - * Name of the variable to be displayed in an error message. - * @param value - * Value to check for null. + * + * @param name Name of the variable to be displayed in an error message. + * @param value Value to check for null. */ public static void checkNotNull(final String name, final Object value) { if (value == null) { @@ -542,11 +508,9 @@ public static void checkNotNull(final String name, final Object value) { /** * Checks if a variable is not empty and throws an IllegalNullArgumentException if this rule is violated. A * String with spaces is NOT considered empty! - * - * @param name - * Name of the variable to be displayed in an error message. - * @param value - * Value to check for an empty String - Cannot be null. + * + * @param name Name of the variable to be displayed in an error message. + * @param value Value to check for an empty String - Cannot be null. */ public static void checkNotEmpty(final String name, final String value) { if (value.length() == 0) { @@ -556,14 +520,10 @@ public static void checkNotEmpty(final String name, final String value) { /** * Creates a textual representation of the method. - * - * @param returnType - * Return type of the method - Can be null. - * @param methodName - * Name of the method - Cannot be null. - * @param argTypes - * The list of parameters - Can be null. - * + * + * @param returnType Return type of the method - Can be null. + * @param methodName Name of the method - Cannot be null. + * @param argTypes The list of parameters - Can be null. * @return Textual signature of the method. */ private static String getMethodSignature(final String returnType, final String methodName, final Class[] argTypes) { @@ -588,20 +548,13 @@ private static String getMethodSignature(final String returnType, final String m /** * Calls a method with reflection and maps all errors into one exception. - * - * @param obj - * The object the underlying method is invoked from - Cannot be null. - * @param methodName - * Name of the Method - Cannot be null. - * @param argTypes - * The list of parameters - May be null. - * @param args - * Arguments the arguments used for the method call - May be null if "argTypes" is also null. - * + * + * @param obj The object the underlying method is invoked from - Cannot be null. + * @param methodName Name of the Method - Cannot be null. + * @param argTypes The list of parameters - May be null. + * @param args Arguments the arguments used for the method call - May be null if "argTypes" is also null. * @return The result of dispatching the method represented by this object on obj with parameters args. - * - * @throws InvokeMethodFailedException - * Invoking the method failed for some reason. + * @throws InvokeMethodFailedException Invoking the method failed for some reason. */ public static Object invoke(final Object obj, final String methodName, final Class[] argTypes, final Object[] args) throws InvokeMethodFailedException { @@ -612,11 +565,11 @@ public static Object invoke(final Object obj, final String methodName, final Cla final Class[] argTypesIntern; final Object[] argsIntern; if (argTypes == null) { - argTypesIntern = new Class[] {}; + argTypesIntern = new Class[]{}; if (args != null) { throw new IllegalArgumentException("The argument 'argTypes' is null but " + "'args' containes values!"); } - argsIntern = new Object[] {}; + argsIntern = new Object[]{}; } else { argTypesIntern = argTypes; if (args == null) { @@ -663,14 +616,10 @@ private static void checkSameLength(final Class[] argTypes, final Object[] ar /** * Unzips a file into a given directory. WARNING: Only relative path entries are allowed inside the archive! - * - * @param zipFile - * Source ZIP file - Cannot be null and must be a valid ZIP file. - * @param destDir - * Destination directory - Cannot be null and must exist. - * - * @throws IOException - * Error unzipping the file. + * + * @param zipFile Source ZIP file - Cannot be null and must be a valid ZIP file. + * @param destDir Destination directory - Cannot be null and must exist. + * @throws IOException Error unzipping the file. */ public static void unzip(final File zipFile, final File destDir) throws IOException { unzip(zipFile, destDir, null, null); @@ -678,19 +627,13 @@ public static void unzip(final File zipFile, final File destDir) throws IOExcept /** * Unzips a file into a given directory. WARNING: Only relative path entries are allowed inside the archive! - * - * @param zipFile - * Source ZIP file - Cannot be null and must be a valid ZIP file. - * @param destDir - * Destination directory - Cannot be null and must exist. - * @param wrapper - * Callback interface to give the caller the chance to wrap the ZIP input stream into another one. This is useful for example - * to display a progress bar - Can be null if no wrapping is required. - * @param cancelable - * Signals if the unzip should be canceled - Can be null if no cancel option is required. - * - * @throws IOException - * Error unzipping the file. + * + * @param zipFile Source ZIP file - Cannot be null and must be a valid ZIP file. + * @param destDir Destination directory - Cannot be null and must exist. + * @param wrapper Callback interface to give the caller the chance to wrap the ZIP input stream into another one. This is useful for example + * to display a progress bar - Can be null if no wrapping is required. + * @param cancelable Signals if the unzip should be canceled - Can be null if no cancel option is required. + * @throws IOException Error unzipping the file. */ public static void unzip(final File zipFile, final File destDir, final UnzipInputStreamWrapper wrapper, final Cancelable cancelable) throws IOException { @@ -740,7 +683,7 @@ private static void createIfNecessary(final File dir) throws IOException { /** * Returns the user home directory and checks if it is valid and exists. If not a IllegalStateException is thrown. - * + * * @return Directory. */ public static File getUserHomeDir() { @@ -764,7 +707,7 @@ public static File getUserHomeDir() { /** * Returns the temporary directory and checks if it is valid and exists. If not a IllegalStateException is thrown. - * + * * @return Directory. */ public static File getTempDir() { @@ -787,12 +730,9 @@ public static File getTempDir() { /** * Replaces all variables inside a string with values from a map. - * - * @param str - * Text with variables (Format: ${key} ) - May be null or empty. - * @param vars - * Map with key/values (both of type String - May be null. - * + * + * @param str Text with variables (Format: ${key} ) - May be null or empty. + * @param vars Map with key/values (both of type String - May be null. * @return String with replaced variables. Unknown variables will remain unchanged. */ public static String replaceVars(final String str, final Map vars) { @@ -836,9 +776,8 @@ public static String replaceVars(final String str, final Map var * Converts Date into a Windows FILETIME. The Windows FILETIME structure holds a date and time associated with a file. The structure * identifies a 64-bit integer specifying the number of 100-nanosecond intervals which have passed since January 1, 1601. This code is * copied from the org.apache.poi.hpsf.Util class. - * - * @param date - * The date to be converted - Cannot be null. + * + * @param date The date to be converted - Cannot be null. * @return The file time */ public static long dateToFileTime(final Date date) { @@ -851,43 +790,31 @@ public static long dateToFileTime(final Date date) { /** * Creates an URL Link on the Windows Desktop. This is done by creating a file (URL File Format) with an ".url" extension. For a * description see http://www.cyanwerks.com/file-format-url.html . - * - * @param baseUrl - * Base URL for the link - Cannot be null or empty. - * @param url - * Target URL - Cannot be null or empty. - * @param workingDir - * It's the "working folder" that your URL file uses. The working folder is possibly the folder to be set as the current - * folder for the application that would open the file. However Internet Explorer does not seem to be affected by this field - * - Can be null. - * @param showCommand - * Normal=null, Minimized=7, Maximized=3 - * @param iconIndex - * The Icon Index within the icon library specified by IconFile. In an icon library, which can be generally be either a ICO, - * DLL or EXE file, the icons are indexed with numbers. The first icon index starts at 0 - Can be null if the - * file is not indexed. - * @param iconFile - * Specifies the path of the icon library file. Generally the icon library can be an ICO, DLL or EXE file. The default icon - * library used tends to be the URL.DLL library on the system's Windows\System directory - Can be null if no - * icon is required. - * @param hotKey - * The HotKey field specifies what is the shortcut key used to automatically launch the Internet shortcut. The field uses a - * number to specify what hotkey is used. To get the appropriate code simply create a shortcut with MSIE and examine the - * file's content. - * @param linkFilenameWithoutExtension - * Name for the link file (displayed as text) - Cannot be null or empty. - * @param overwrite - * Overwrite an existing ".url" file. - * @param modified - * Timestamp. - * - * @throws IOException - * Error writing the file. + * + * @param baseUrl Base URL for the link - Cannot be null or empty. + * @param url Target URL - Cannot be null or empty. + * @param workingDir It's the "working folder" that your URL file uses. The working folder is possibly the folder to be set as the current + * folder for the application that would open the file. However Internet Explorer does not seem to be affected by this field + * - Can be null. + * @param showCommand Normal=null, Minimized=7, Maximized=3 + * @param iconIndex The Icon Index within the icon library specified by IconFile. In an icon library, which can be generally be either a ICO, + * DLL or EXE file, the icons are indexed with numbers. The first icon index starts at 0 - Can be null if the + * file is not indexed. + * @param iconFile Specifies the path of the icon library file. Generally the icon library can be an ICO, DLL or EXE file. The default icon + * library used tends to be the URL.DLL library on the system's Windows\System directory - Can be null if no + * icon is required. + * @param hotKey The HotKey field specifies what is the shortcut key used to automatically launch the Internet shortcut. The field uses a + * number to specify what hotkey is used. To get the appropriate code simply create a shortcut with MSIE and examine the + * file's content. + * @param linkFilenameWithoutExtension Name for the link file (displayed as text) - Cannot be null or empty. + * @param overwrite Overwrite an existing ".url" file. + * @param modified Timestamp. + * @throws IOException Error writing the file. */ // CHECKSTYLE:OFF Maximum Parameters public static void createWindowsDesktopUrlLink(final String baseUrl, final String url, final File workingDir, final Integer showCommand, - final Integer iconIndex, final File iconFile, final Integer hotKey, final String linkFilenameWithoutExtension, - final boolean overwrite, final Date modified) throws IOException { + final Integer iconIndex, final File iconFile, final Integer hotKey, final String linkFilenameWithoutExtension, + final boolean overwrite, final Date modified) throws IOException { // CHECKSTYLE:ON checkNotNull("baseUrl", baseUrl); @@ -915,37 +842,28 @@ public static void createWindowsDesktopUrlLink(final String baseUrl, final Strin /** * Creates the content of an URL Link file (.url) on the Windows Desktop. For a description see * http://www.cyanwerks.com/file-format-url.html . - * - * @param baseUrl - * Base URL for the link - Cannot be null or empty. - * @param url - * Target URL - Cannot be null or empty. - * @param workingDir - * It's the "working folder" that your URL file uses. The working folder is possibly the folder to be set as the current - * folder for the application that would open the file. However Internet Explorer does not seem to be affected by this field - * - Can be null. - * @param showCommand - * Normal=null, Minimized=7, Maximized=3 - * @param iconIndex - * The Icon Index within the icon library specified by IconFile. In an icon library, which can be generally be either a ICO, - * DLL or EXE file, the icons are indexed with numbers. The first icon index starts at 0 - Can be null if the - * file is not indexed. - * @param iconFile - * Specifies the path of the icon library file. Generally the icon library can be an ICO, DLL or EXE file. The default icon - * library used tends to be the URL.DLL library on the system's Windows\System directory - Can be null if no - * icon is required. - * @param hotKey - * The HotKey field specifies what is the shortcut key used to automatically launch the Internet shortcut. The field uses a - * number to specify what hotkey is used. To get the appropriate code simply create a shortcut with MSIE and examine the - * file's content. - * @param modified - * Timestamp. - * + * + * @param baseUrl Base URL for the link - Cannot be null or empty. + * @param url Target URL - Cannot be null or empty. + * @param workingDir It's the "working folder" that your URL file uses. The working folder is possibly the folder to be set as the current + * folder for the application that would open the file. However Internet Explorer does not seem to be affected by this field + * - Can be null. + * @param showCommand Normal=null, Minimized=7, Maximized=3 + * @param iconIndex The Icon Index within the icon library specified by IconFile. In an icon library, which can be generally be either a ICO, + * DLL or EXE file, the icons are indexed with numbers. The first icon index starts at 0 - Can be null if the + * file is not indexed. + * @param iconFile Specifies the path of the icon library file. Generally the icon library can be an ICO, DLL or EXE file. The default icon + * library used tends to be the URL.DLL library on the system's Windows\System directory - Can be null if no + * icon is required. + * @param hotKey The HotKey field specifies what is the shortcut key used to automatically launch the Internet shortcut. The field uses a + * number to specify what hotkey is used. To get the appropriate code simply create a shortcut with MSIE and examine the + * file's content. + * @param modified Timestamp. * @return INI file text. */ // CHECKSTYLE:OFF public static String createWindowsDesktopUrlLinkContent(final String baseUrl, final String url, final File workingDir, - final Integer showCommand, final Integer iconIndex, final File iconFile, final Integer hotKey, final Date modified) { + final Integer showCommand, final Integer iconIndex, final File iconFile, final Integer hotKey, final Date modified) { // CHECKSTYLE:ON checkNotNull("baseUrl", baseUrl); @@ -982,14 +900,10 @@ public static String createWindowsDesktopUrlLinkContent(final String baseUrl, fi /** * Concatenate a path and a filename taking null and empty string values into account. - * - * @param path - * Path - Can be null or an empty string. - * @param filename - * Filename - Cannot be null. - * @param separator - * Separator for directories - Can be null or an empty string. - * + * + * @param path Path - Can be null or an empty string. + * @param filename Filename - Cannot be null. + * @param separator Separator for directories - Can be null or an empty string. * @return Path and filename divided by the separator. */ public static String concatPathAndFilename(final String path, final String filename, final String separator) { @@ -1016,12 +930,10 @@ public static String concatPathAndFilename(final String path, final String filen /** * Converts an array of bytes into an array of characters representing the hexidecimal values of each byte in order. The returned array * will be double the length of the passed array, as it takes two characters to represent any given byte. - * + *

* Author: Apache Software Foundation See: org.apache.commons.codec.binary.Hex - * - * @param data - * A byte[] to convert to Hex characters - Cannot be null. - * + * + * @param data A byte[] to convert to Hex characters - Cannot be null. * @return A string containing hexidecimal characters */ // CHECKSTYLE:OFF Orginal Apache code @@ -1046,13 +958,11 @@ public static String encodeHex(final byte[] data) { * Converts an array of characters representing hexidecimal values into an array of bytes of those same values. The returned array will * be half the length of the passed array, as it takes two characters to represent any given byte. An exception is thrown if the passed * char array has an odd number of elements. - * - * @param data - * An array of characters containing hexidecimal digits - Cannot be null. - * + * + * @param data An array of characters containing hexidecimal digits - Cannot be null. * @return A byte array containing binary data decoded from the supplied char array. - * - * Author: Apache Software Foundation See: org.apache.commons.codec.binary.Hex + *

+ * Author: Apache Software Foundation See: org.apache.commons.codec.binary.Hex */ // CHECKSTYLE:OFF Orginal Apache code public static byte[] decodeHex(final String data) { @@ -1083,13 +993,10 @@ public static byte[] decodeHex(final String data) { /** * Converts a hexadecimal character to an integer. - * - * @param ch - * A character to convert to an integer digit - * @param index - * The index of the character in the source + * + * @param ch A character to convert to an integer digit + * @param index The index of the character in the source * @return An integer - * * @author Apache Software Foundation * @see org.apache.commons.codec.binary.Hex */ @@ -1103,18 +1010,12 @@ private static int toDigit(final char ch, final int index) { /** * Lock the file. - * - * @param file - * File to lock - Cannot be null. - * @param tryLockMax - * Number of tries to lock before throwing an exception. - * @param tryWaitMillis - * Milliseconds to sleep between retries. - * + * + * @param file File to lock - Cannot be null. + * @param tryLockMax Number of tries to lock before throwing an exception. + * @param tryWaitMillis Milliseconds to sleep between retries. * @return FileLock. - * - * @throws LockingFailedException - * Locking the file failed. + * @throws LockingFailedException Locking the file failed. */ public static FileLock lockRandomAccessFile(final RandomAccessFile file, final int tryLockMax, final long tryWaitMillis) throws LockingFailedException { @@ -1152,16 +1053,11 @@ private static void ignore() { /** * Adds a file to a ZIP output stream. - * - * @param srcFile - * File to add - Cannot be null. - * @param destPath - * Path to use for the file - May be null or empty. - * @param out - * Destination stream - Cannot be null. - * - * @throws IOException - * Error writing to the output stream. + * + * @param srcFile File to add - Cannot be null. + * @param destPath Path to use for the file - May be null or empty. + * @param out Destination stream - Cannot be null. + * @throws IOException Error writing to the output stream. */ private static void zipFile(final File srcFile, final String destPath, final ZipOutputStream out) throws IOException { @@ -1180,12 +1076,9 @@ private static void zipFile(final File srcFile, final String destPath, final Zip /** * List all files for a directory. - * - * @param srcDir - * Directory to list the files for - Cannot be null and must be a valid directory. - * @param filter - * Filter or null for all files. - * + * + * @param srcDir Directory to list the files for - Cannot be null and must be a valid directory. + * @param filter Filter or null for all files. * @return List of child entries of the directory. */ private static File[] listFiles(final File srcDir, final FileFilter filter) { @@ -1202,18 +1095,12 @@ private static File[] listFiles(final File srcDir, final FileFilter filter) { /** * Add a directory to a ZIP output stream. - * - * @param srcDir - * Directory to add - Cannot be null and must be a valid directory. - * @param filter - * Filter or null for all files. - * @param destPath - * Path to use for the ZIP archive - May be null or an empyt string. - * @param out - * Destination stream - Cannot be null. - * - * @throws IOException - * Error writing to the output stream. + * + * @param srcDir Directory to add - Cannot be null and must be a valid directory. + * @param filter Filter or null for all files. + * @param destPath Path to use for the ZIP archive - May be null or an empyt string. + * @param out Destination stream - Cannot be null. + * @throws IOException Error writing to the output stream. */ private static void zipDir(final File srcDir, final FileFilter filter, final String destPath, final ZipOutputStream out) throws IOException { @@ -1232,18 +1119,12 @@ private static void zipDir(final File srcDir, final FileFilter filter, final Str /** * Creates a ZIP file and adds all files in a directory and all it's sub directories to the archive. Only entries are added that comply * to the file filter. - * - * @param srcDir - * Directory to add - Cannot be null and must be a valid directory. - * @param filter - * Filter or null for all files/directories. - * @param destPath - * Path to use for the ZIP archive - May be null or an empyt string. - * @param destFile - * Target ZIP file - Cannot be null. - * - * @throws IOException - * Error writing to the output stream. + * + * @param srcDir Directory to add - Cannot be null and must be a valid directory. + * @param filter Filter or null for all files/directories. + * @param destPath Path to use for the ZIP archive - May be null or an empyt string. + * @param destFile Target ZIP file - Cannot be null. + * @throws IOException Error writing to the output stream. */ public static void zipDir(final File srcDir, final FileFilter filter, final String destPath, final File destFile) throws IOException { @@ -1259,16 +1140,11 @@ public static void zipDir(final File srcDir, final FileFilter filter, final Stri /** * Creates a ZIP file and adds all files in a directory and all it's sub directories to the archive. - * - * @param srcDir - * Directory to add - Cannot be null and must be a valid directory. - * @param destPath - * Path to use for the ZIP archive - May be null or an empyt string. - * @param destFile - * Target ZIP file - Cannot be null. - * - * @throws IOException - * Error writing to the output stream. + * + * @param srcDir Directory to add - Cannot be null and must be a valid directory. + * @param destPath Path to use for the ZIP archive - May be null or an empyt string. + * @param destFile Target ZIP file - Cannot be null. + * @throws IOException Error writing to the output stream. */ public static void zipDir(final File srcDir, final String destPath, final File destFile) throws IOException { @@ -1278,10 +1154,8 @@ public static void zipDir(final File srcDir, final String destPath, final File d /** * Serializes the given object. A null argument returns null. - * - * @param obj - * Object to serialize or null. - * + * + * @param obj Object to serialize or null. * @return Serialized object or null. */ public static byte[] serialize(final Object obj) { @@ -1299,14 +1173,10 @@ public static byte[] serialize(final Object obj) { /** * Deserializes a byte array to an object. A null argument returns null. - * - * @param data - * Byte array to deserialize or null. - * + * + * @param data Byte array to deserialize or null. + * @param Type of returned data. * @return Object created from data or null. - * - * @param - * Type of returned data. */ @SuppressWarnings("unchecked") public static T deserialize(final byte[] data) { @@ -1323,14 +1193,10 @@ public static T deserialize(final byte[] data) { /** * Reads a given URL and returns the content as String. - * - * @param url - * URL to read. - * @param encoding - * Encoding (like 'utf-8'). - * @param bufSize - * Size of the buffer to use. - * + * + * @param url URL to read. + * @param encoding Encoding (like 'utf-8'). + * @param bufSize Size of the buffer to use. * @return File content as String. */ public static String readAsString(final URL url, final String encoding, final int bufSize) { @@ -1349,10 +1215,8 @@ public static String readAsString(final URL url, final String encoding, final in /** * Returns a given string as URL and supports "classpath:" scheme. A null argument returns null. - * - * @param url - * String to convert into an URL or null. - * + * + * @param url String to convert into an URL or null. * @return URL or null */ public static URL url(final String url) { @@ -1371,10 +1235,8 @@ public static URL url(final String url) { /** * Replaces the strings "\r", "\n" and "\t" with "carriage return", "new line" and "tab" character. - * - * @param str - * String to replace or null. - * + * + * @param str String to replace or null. * @return Replaced string or null. */ public static String replaceCrLfTab(final String str) { @@ -1410,9 +1272,8 @@ public static String replaceCrLfTab(final String str) { * Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds, subject to the * precision and accuracy of system timers and schedulers. The thread does not lose ownership of any monitors. The * {@link InterruptedException} is wrapped into a {@link RuntimeException}. - * - * @param millis - * The length of time to sleep in milliseconds. + * + * @param millis The length of time to sleep in milliseconds. */ public static void sleep(final long millis) { try { @@ -1424,12 +1285,9 @@ public static void sleep(final long millis) { /** * Verifies if the cause of an exception is of a given type. - * - * @param actualException - * Actual exception that was caused by something else - Cannot be null. - * @param expectedExceptions - * Expected exceptions - May be null if any cause is expected. - * + * + * @param actualException Actual exception that was caused by something else - Cannot be null. + * @param expectedExceptions Expected exceptions - May be null if any cause is expected. * @return TRUE if the actual exception is one of the expected exceptions. */ public static boolean expectedCause(final Exception actualException, final Collection> expectedExceptions) { @@ -1453,16 +1311,13 @@ public static boolean expectedCause(final Exception actualException, final Colle /** * Verifies if an exception is of a given type. - * - * @param actualException - * Actual exception - Cannot be null. - * @param expectedExceptions - * Expected exceptions - May be null if any exception is expected. - * + * + * @param actualException Actual exception - Cannot be null. + * @param expectedExceptions Expected exceptions - May be null if any exception is expected. * @return TRUE if the actual exception is one of the expected exceptions. */ public static boolean expectedException(final Exception actualException, - final Collection> expectedExceptions) { + final Collection> expectedExceptions) { checkNotNull("actualException", actualException); @@ -1483,10 +1338,8 @@ public static boolean expectedException(final Exception actualException, /** * Determines if the file is a file from the Java runtime and exists. - * - * @param file - * File to test. - * + * + * @param file File to test. * @return TRUE if the file is in the 'java.home' directory. */ public static boolean jreFile(final File file) { @@ -1500,10 +1353,8 @@ public static boolean jreFile(final File file) { /** * Determines if the file is a class file. - * - * @param file - * File to test. - * + * + * @param file File to test. * @return TRUE if the file ends with '.class'. */ public static boolean classFile(final File file) { @@ -1512,10 +1363,8 @@ public static boolean classFile(final File file) { /** * Determines if the file is a JAR file. - * - * @param file - * File to test. - * + * + * @param file File to test. * @return TRUE if the file ends with '.jar'. */ public static boolean jarFile(final File file) { @@ -1524,10 +1373,8 @@ public static boolean jarFile(final File file) { /** * Determines if the file is a JAR file not located in the JRE directory. - * - * @param file - * File to test. - * + * + * @param file File to test. * @return TRUE if the file ends with '.jar' and is not located in the 'java.home' directory. */ public static boolean nonJreJarFile(final File file) { @@ -1536,10 +1383,8 @@ public static boolean nonJreJarFile(final File file) { /** * Determines if the file is a JAR file located in the JRE directory. - * - * @param file - * File to test. - * + * + * @param file File to test. * @return TRUE if the file ends with '.jar' and is located in the 'java.home' directory. */ public static boolean jreJarFile(final File file) { @@ -1548,10 +1393,8 @@ public static boolean jreJarFile(final File file) { /** * Returns a list of filtered files from the classpath including content of directories and sub directories. - * - * @param predicate - * Condition that returns files from the classpath. - * + * + * @param predicate Condition that returns files from the classpath. * @return List of files in the classpath (from property "java.class.path"). */ public static List classpathFiles(final Predicate predicate) { @@ -1561,7 +1404,7 @@ public static List classpathFiles(final Predicate predicate) { /** * Returns a list of all files from the classpath. Only returns the files itself and no files in directories. - * + * * @return List of files in the classpath (from property "java.class.path"). */ public static List classpathFiles() { @@ -1576,11 +1419,8 @@ public static List classpathFiles() { /** * Returns a list of files from all given paths. * - * @param paths - * Paths to search (Paths separated by {@link File#pathSeparator}. - * @param predicate - * Condition for files to return. - * + * @param paths Paths to search (Paths separated by {@link File#pathSeparator}. + * @param predicate Condition for files to return. * @return List of files in the given paths. */ public static List pathsFiles(final String paths, final Predicate predicate) { @@ -1589,13 +1429,15 @@ public static List pathsFiles(final String paths, final Predicate pr final File file = new File(filePathAndName); if (file.isDirectory()) { try (final Stream stream = Files.walk(file.toPath(), Integer.MAX_VALUE)) { - stream.map(f -> f.toFile()).filter(predicate).forEach(files::add); + stream.map(Path::toFile).filter(predicate).forEach(files::add); } catch (final IOException ex) { throw new RuntimeException("Error walking path: " + file, ex); } } else { if (predicate.test(file)) { files.add(file); + } else { + System.err.println("Ignoring file: " + file); } } } @@ -1609,18 +1451,90 @@ public static interface UnzipInputStreamWrapper { /** * Wraps the input stream into another one. - * - * @param in - * Stream to create a wrapping stream for. - * @param entry - * Zip entry the input stream is reading. - * @param destFile - * Destination file. - * + * + * @param in Stream to create a wrapping stream for. + * @param entry Zip entry the input stream is reading. + * @param destFile Destination file. * @return Wrapped input stream. */ public InputStream wrapInputStream(InputStream in, ZipEntry entry, File destFile); } + /** + * Loads the class using the current thread's context class loader. + * + * @param name Name of the class to load. + * @return Loaded class. + */ + public static Class loadClass(String name) { + try { + return Thread.currentThread().getContextClassLoader().loadClass(name); + } catch (final ClassNotFoundException ex) { + throw new RuntimeException("Failed to load class: " + name, ex); + } + } + + /** + * Sets a private field in an object by using reflection. + * + * @param obj Object with the attribute to set. + * @param name Name of the attribute to set. + * @param value Value to set for the attribute. + */ + public static void setPrivateField(final Object obj, final String name, final Object value) { + try { + final Field field = obj.getClass().getDeclaredField(name); + field.setAccessible(true); + field.set(obj, value); + } catch (final Exception ex) { + throw new RuntimeException("Couldn't set field '" + name + "' in class '" + obj.getClass() + "'", ex); + } + } + + /** + * Tries to acquire a lock and runs the code. If no lock can be acquired, the method + * terminates immediately without executing anything. + * + * @param lock Semaphore to use. Must be a {@literal null} value. + * @param code Code to run. Must be a {@literal null} value. + */ + public static void tryLocked(final Semaphore lock, final Runnable code) { + Objects.requireNonNull(lock, "lock==null"); + Objects.requireNonNull(code, "code==null"); + if (lock.tryAcquire()) { + try { + code.run(); + } finally { + lock.release(); + } + } + } + + /** + * Waits until a lock is available and executes the code after it was acquired. + * + * @param lock Semaphore to use. Must be a {@literal null} value. + * @param code Code to run. Must be a {@literal null} value. + * @param failedToLockListener Gets informed in case it was not possible to get a lock. May be {@literal null}. + */ + public static void runLocked(final Semaphore lock, + final Runnable code, + final Consumer failedToLockListener) { + Objects.requireNonNull(lock, "lock==null"); + Objects.requireNonNull(code, "code==null"); + try { + lock.acquire(); + try { + code.run(); + } finally { + lock.release(); + } + } catch (final InterruptedException ex) { // NOSONAR + if (failedToLockListener != null) { + failedToLockListener.accept(ex); + } + } + } + } diff --git a/src/main/java/org/fuin/utils4j/jandex/JandexIndexFileReader.java b/src/main/java/org/fuin/utils4j/jandex/JandexIndexFileReader.java new file mode 100644 index 0000000..7747983 --- /dev/null +++ b/src/main/java/org/fuin/utils4j/jandex/JandexIndexFileReader.java @@ -0,0 +1,168 @@ +package org.fuin.utils4j.jandex; + +import org.jboss.jandex.CompositeIndex; +import org.jboss.jandex.IndexReader; +import org.jboss.jandex.IndexView; + +import java.io.*; +import java.net.URL; +import java.util.*; + +/** + * Helps to read Jandex index files. + */ +public final class JandexIndexFileReader { + + private final List files; + + private final List resources; + + private JandexIndexFileReader() { + this.files = new ArrayList<>(); + this.resources = new ArrayList<>(); + } + + /** + * Loads the configured index files. + * + * @return Index created from all index files. + * @throws IOException Failed to read index files or resources. + */ + public IndexView load() throws IOException { + final List indexes = new ArrayList<>(); + for (final File file : files) { + indexes.add(loadFile(file)); + } + for (final String resource : resources) { + indexes.add(loadResources(resource)); + } + return CompositeIndex.create(indexes); + } + + /** + * Loads the configured index files. + * Wraps the possible {@link IOException} into a {@link RuntimeException}. + * + * @return Index created from all index files. + */ + public IndexView loadR() { + try { + return load(); + } catch (final IOException ex) { + throw new RuntimeException("Failed to read index files or resources", ex); + } + } + + private IndexView loadFile(final File file) throws IOException { + try (final InputStream input = new FileInputStream(file)) { + return new IndexReader(input).read(); + } + } + + private IndexView loadResources(final String indexFilePathAndName) throws IOException { + final Enumeration enu = Thread.currentThread().getContextClassLoader().getResources(indexFilePathAndName); + final List indexes = new ArrayList<>(); + final List urlList = Collections.list(enu); + for (final URL url : urlList) { + try (final InputStream input = url.openStream()) { + indexes.add(new IndexReader(input).read()); + } + } + return CompositeIndex.create(indexes); + } + + /** + * Creates a new instance of the outer class. + */ + public static final class Builder { + + private JandexIndexFileReader delegate; + + /** + * Default constructor. + */ + public Builder() { + this.delegate = new JandexIndexFileReader(); + } + + /** + * Adds one or more files. + * + * @param files Index files to read (must exist). + * @return Builder. + */ + public Builder addFiles(final File...files) { + return addFiles(Arrays.asList(files)); + } + + /** + * Adds one or more files. + * + * @param files Index files to read (must exist). + * @return Builder. + */ + public Builder addFiles(final List files) { + for (final File file : Objects.requireNonNull(files, "files==null")) { + if (!file.exists()) { + throw new IllegalStateException("Index file does not exist: " + file); + } + if (!file.isFile()) { + throw new IllegalStateException("No file: " + file); + } + delegate.files.add(Objects.requireNonNull(file, "file==null")); + } + return this; + } + + /** + * Adds a default resource named "META-INF/jandex.idx". + * + * @return Builder. + */ + public Builder addDefaultResource() { + addResources("META-INF/jandex.idx"); + return this; + } + + /** + * Adds one or more resources. + * + * @param resources Array with resources to add. + * + * @return Builder. + */ + public Builder addResources(final String...resources) { + return addResources(Arrays.asList(resources)); + } + + /** + * Adds one or more resources. + * + * @param resources List of resources to add. + * + * @return Builder. + */ + public Builder addResources(final List resources) { + for (final String resource : Objects.requireNonNull(resources, "resources==null")) { + delegate.resources.add(Objects.requireNonNull(resource, "resource==null")); + } + return this; + } + + /** + * Builds an instance of the outer class. + * + * @return New instance. + */ + public JandexIndexFileReader build() { + if (delegate.resources.isEmpty() && delegate.files.isEmpty()) { + addDefaultResource(); + } + final JandexIndexFileReader tmp = delegate; + delegate = new JandexIndexFileReader(); + return tmp; + } + + } + +} diff --git a/src/main/java/org/fuin/utils4j/jandex/JandexIndexFileWriter.java b/src/main/java/org/fuin/utils4j/jandex/JandexIndexFileWriter.java new file mode 100644 index 0000000..98c8239 --- /dev/null +++ b/src/main/java/org/fuin/utils4j/jandex/JandexIndexFileWriter.java @@ -0,0 +1,40 @@ +package org.fuin.utils4j.jandex; + +import org.jboss.jandex.*; + +import java.io.*; + +/** + * Helps to write Jandex index files. + */ +public final class JandexIndexFileWriter { + + /** + * Writes the index to a file. + * Wraps the possible {@link IOException} into a {@link RuntimeException}. + * + * @param file File to write to. + * @param index Index to save. + */ + public void writeIndexR(final File file, final Index index) { + try { + writeIndex(file, index); + } catch (final IOException ex) { + throw new RuntimeException("Failed to write index to: " + file, ex); + } + } + + /** + * Writes the index to a file. + * + * @param file File to write to. + * @param index Index to save. + * @throws IOException Failed to write to the file. + */ + public void writeIndex(final File file, final Index index) throws IOException { + try (final OutputStream out = new FileOutputStream(file)) { + new IndexWriter(out).write(index); + } + } + +} diff --git a/src/main/java/org/fuin/utils4j/JandexUtils.java b/src/main/java/org/fuin/utils4j/jandex/JandexUtils.java similarity index 86% rename from src/main/java/org/fuin/utils4j/JandexUtils.java rename to src/main/java/org/fuin/utils4j/jandex/JandexUtils.java index e600b62..125ccbf 100644 --- a/src/main/java/org/fuin/utils4j/JandexUtils.java +++ b/src/main/java/org/fuin/utils4j/jandex/JandexUtils.java @@ -15,13 +15,17 @@ * You should have received a copy of the GNU Lesser General Public License * along with this library. If not, see http://www.gnu.org/licenses/. */ -package org.fuin.utils4j; +package org.fuin.utils4j.jandex; +import org.fuin.utils4j.Utils4J; +import org.jboss.jandex.DotName; +import org.jboss.jandex.Index; import org.jboss.jandex.Indexer; import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.jar.JarEntry; @@ -68,7 +72,20 @@ public static boolean indexClassFile(final Indexer indexer, final List kno } /** - * Indexes all classes in a directory or it's sub directories. + * Indexes all classes in a directory or it's subdirectories. + * + * @param dir + * Directory to analyze. + * @return Index of all classes in the directory. + */ + public static Index indexDir(final File dir) { + final Indexer indexer = new Indexer(); + indexDir(indexer, new ArrayList<>(), dir); + return indexer.complete(); + } + + /** + * Indexes all classes in a directory or it's subdirectories. * * @param indexer * Indexer to use. @@ -166,4 +183,16 @@ public static void indexFiles(final List files, final Indexer indexer, fin } + /** + * Loads the class using the current thread's context class loader. + * + * @param name Name of the class to load. + * + * @return Loaded class. + */ + public static Class loadClass(DotName name) { + return Utils4J.loadClass(name.toString()); + } + + } diff --git a/src/main/java/org/fuin/utils4j/jaxb/JaxbUtils.java b/src/main/java/org/fuin/utils4j/jaxb/JaxbUtils.java index b42763f..9c4653c 100644 --- a/src/main/java/org/fuin/utils4j/jaxb/JaxbUtils.java +++ b/src/main/java/org/fuin/utils4j/jaxb/JaxbUtils.java @@ -55,6 +55,7 @@ private JaxbUtils() { * Type of the data. * @deprecated Use method {@link #marshal(Marshaller, Object)} together with {@link MarshallerBuilder} instead */ + @Deprecated public static String marshal(final T data, final Class... classesToBeBound) { return marshal(data, null, classesToBeBound); } @@ -75,6 +76,7 @@ public static String marshal(final T data, final Class... classesToBeBoun * Type of the data. * @deprecated Use method {@link #marshal(Marshaller, Object)} together with {@link MarshallerBuilder} instead */ + @Deprecated public static String marshal(final T data, final XmlAdapter[] adapters, final Class... classesToBeBound) { if (data == null) { return null; @@ -101,6 +103,7 @@ public static String marshal(final T data, final XmlAdapter[] adapters * Type of the data. * @deprecated Use method {@link #marshal(Marshaller, Object)} together with {@link MarshallerBuilder} instead */ + @Deprecated public static String marshal(final JAXBContext ctx, final T data) { return marshal(ctx, data, null); } @@ -121,6 +124,7 @@ public static String marshal(final JAXBContext ctx, final T data) { * Type of the data. * @deprecated Use method {@link #marshal(Marshaller, Object)} together with {@link MarshallerBuilder} instead */ + @Deprecated public static String marshal(final JAXBContext ctx, final T data, final XmlAdapter[] adapters) { if (data == null) { return null; @@ -146,6 +150,7 @@ public static String marshal(final JAXBContext ctx, final T data, final XmlA * Type of the data to write. * @deprecated Use method {@link #marshal(Marshaller, Object, Writer)} together with {@link MarshallerBuilder} instead */ + @Deprecated public static void marshal(final JAXBContext ctx, final T data, final XmlAdapter[] adapters, final Writer writer) { if (data == null) { return; @@ -179,6 +184,7 @@ public static void marshal(final JAXBContext ctx, final T data, final XmlAda * Type of the data to write. * @deprecated Use method {@link #marshal(Marshaller, Object, XMLStreamWriter)} together with {@link MarshallerBuilder} instead */ + @Deprecated public static void marshal(final JAXBContext ctx, final T data, final XmlAdapter[] adapters, final XMLStreamWriter writer) { if (data == null) { return; @@ -211,12 +217,13 @@ public static void marshal(final JAXBContext ctx, final T data, final XmlAda * * @deprecated Use method {@link #unmarshal(Unmarshaller, String)} together with {@link UnmarshallerBuilder} instead */ + @Deprecated public static T unmarshal(final String xmlData, final Class... classesToBeBound) { final UnmarshallerBuilder builder = new UnmarshallerBuilder(); if (classesToBeBound != null) { builder.addClassesToBeBound(classesToBeBound); } - builder.withHandler(event -> { return false; }); + builder.withHandler(event -> false); return unmarshal(builder.build(), xmlData); } @@ -237,13 +244,14 @@ public static T unmarshal(final String xmlData, final Class... classesToB * * @deprecated Use method {@link #unmarshal(Unmarshaller, String)} together with {@link UnmarshallerBuilder} instead */ + @Deprecated public static T unmarshal(final String xmlData, final XmlAdapter[] adapters, final Class... classesToBeBound) { final UnmarshallerBuilder builder = new UnmarshallerBuilder(); if (classesToBeBound != null) { builder.addClassesToBeBound(classesToBeBound); } builder.addAdapters(adapters); - builder.withHandler(event -> { return false; }); + builder.withHandler(event -> false); return unmarshal(builder.build(), xmlData); } @@ -264,12 +272,13 @@ public static T unmarshal(final String xmlData, final XmlAdapter[] ada * * @deprecated Use method {@link #unmarshal(Unmarshaller, String)} together with {@link UnmarshallerBuilder} instead */ + @Deprecated public static T unmarshal(final JAXBContext ctx, final String xmlData, final XmlAdapter[] adapters) { final UnmarshallerBuilder builder = new UnmarshallerBuilder().withContext(ctx); if (adapters != null) { builder.addAdapters(adapters); } - builder.withHandler(event -> { return false; }); + builder.withHandler(event -> false); return unmarshal(builder.build(), xmlData); } @@ -290,12 +299,13 @@ public static T unmarshal(final JAXBContext ctx, final String xmlData, final * * @deprecated Use method {@link #unmarshal(Unmarshaller, Reader)} together with {@link UnmarshallerBuilder} instead */ + @Deprecated public static T unmarshal(final JAXBContext ctx, final Reader reader, final XmlAdapter[] adapters) { final UnmarshallerBuilder builder = new UnmarshallerBuilder().withContext(ctx); if (adapters != null) { builder.addAdapters(adapters); } - builder.withHandler(event -> { return false; }); + builder.withHandler(event -> false); return unmarshal(builder.build(), reader); } diff --git a/src/main/java/org/fuin/utils4j/jaxb/MarshallerBuilder.java b/src/main/java/org/fuin/utils4j/jaxb/MarshallerBuilder.java index 4e0a9fb..00c17c1 100644 --- a/src/main/java/org/fuin/utils4j/jaxb/MarshallerBuilder.java +++ b/src/main/java/org/fuin/utils4j/jaxb/MarshallerBuilder.java @@ -29,8 +29,6 @@ public class MarshallerBuilder { private ValidationEventHandler handler; - private boolean formattedOutput; - private JAXBContext ctx; diff --git a/src/test/java/org/fuin/utils4j/MultipleCommandsTest.java b/src/test/java/org/fuin/utils4j/MultipleCommandsTest.java new file mode 100644 index 0000000..147412c --- /dev/null +++ b/src/test/java/org/fuin/utils4j/MultipleCommandsTest.java @@ -0,0 +1,106 @@ +/** + * Copyright (C) 2015 Michael Schnell. All rights reserved. + * http://www.fuin.org/ + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 3 of the License, or (at your option) any + * later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see http://www.gnu.org/licenses/. + */ +package org.fuin.utils4j; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +//CHECKSTYLE:OFF Test code +public class MultipleCommandsTest { + + @Test + public void testCreate() { + + final MyCmd cmd1 = new MyCmd(true, null); + final MultipleCommands testee1 = new MultipleCommands<>(cmd1); + testee1.init("Hello1"); + testee1.execute(); + + assertThat(testee1.getFailureDescription()).isEmpty(); + assertThat(testee1.isSuccessful()).isTrue(); + assertThat(cmd1.getContext()).isEqualTo("Hello1"); + assertThat(cmd1.isExecuted()).isTrue();; + + final MyCmd cmd2 = new MyCmd(false, "Oops"); + final MultipleCommands testee2 = new MultipleCommands<>(cmd1, cmd2); + testee2.init("Hello2"); + testee2.execute(); + + assertThat(testee2.isSuccessful()).isFalse(); + assertThat(testee2.getFailureDescription()).isEqualTo("Oops\n"); + assertThat(cmd1.getContext()).isEqualTo("Hello2"); + assertThat(cmd1.isExecuted()).isTrue();; + assertThat(cmd2.getContext()).isEqualTo("Hello2"); + assertThat(cmd2.isExecuted()).isTrue();; + + } + + public static final class MyCmd implements TestCommand { + + private String context; + + private boolean executed; + + private boolean successful; + + private String failureDescription; + + public MyCmd(boolean successful, String failureDescription) { + super(); + this.successful = successful; + this.failureDescription = failureDescription; + } + + @Override + public void init(String context) { + this.context = context; + } + + @Override + public void execute() { + executed = true; + } + + @Override + public boolean isSuccessful() { + return successful; + } + + @Override + public String getFailureDescription() { + return failureDescription; + } + + public String getContext() { + return context; + } + + public boolean isExecuted() { + return executed; + } + + @Override + public void verify() { + // DO nothing + } + + } + +} +// CHECKSTYLE:ON diff --git a/src/test/java/org/fuin/utils4j/Utils4JTest.java b/src/test/java/org/fuin/utils4j/Utils4JTest.java index 7cb04d4..8893331 100644 --- a/src/test/java/org/fuin/utils4j/Utils4JTest.java +++ b/src/test/java/org/fuin/utils4j/Utils4JTest.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2015 Michael Schnell. All rights reserved. + * Copyright (C) 2015 Michael Schnell. All rights reserved. * http://www.fuin.org/ * * This library is free software; you can redistribute it and/or modify it under @@ -11,7 +11,7 @@ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this library. If not, see http://www.gnu.org/licenses/. */ @@ -29,10 +29,21 @@ import java.net.MalformedURLException; import java.net.URL; import java.nio.channels.FileLock; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.TimeZone; +import java.util.concurrent.Semaphore; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.AssertionsKt.fail; /** * Tests for Utils4J. @@ -211,7 +222,7 @@ public final void testCreateInstanceIllegalAccess() { @Test public final void testContainsURL() throws IOException { - final URL[] urls = new URL[] { new URL("http://www.google.com"), new URL("http://www.yahoo.com"), new URL("file:/foobar.txt") }; + final URL[] urls = new URL[]{new URL("http://www.google.com"), new URL("http://www.yahoo.com"), new URL("file:/foobar.txt")}; assertThat(Utils4J.containsURL(urls, new URL("http://www.google.com"))).isTrue(); assertThat(Utils4J.containsURL(urls, new URL("http://www.google.com/"))).isFalse(); assertThat(Utils4J.containsURL(urls, new URL("http://www.abc.com"))).isFalse(); @@ -298,14 +309,14 @@ public final void testCheckNotEmptyFail() { @Test public final void testInvokeOK() throws InvokeMethodFailedException { - assertThat(Utils4J.invoke(new IllegalNullArgumentException("abc"), "getArgument", new Class[] {}, new Object[] {})) + assertThat(Utils4J.invoke(new IllegalNullArgumentException("abc"), "getArgument", new Class[]{}, new Object[]{})) .isEqualTo("abc"); } @Test public final void testInvokeFail() throws InvokeMethodFailedException { assertThatThrownBy(() -> { - Utils4J.invoke(new IllegalNullArgumentException("abc"), "getArgument", new Class[] { String.class }, new Object[] { "" }); + Utils4J.invoke(new IllegalNullArgumentException("abc"), "getArgument", new Class[]{String.class}, new Object[]{""}); }).isInstanceOf(InvokeMethodFailedException.class); } @@ -524,8 +535,8 @@ public final void testEncryptDecryptPasswordBased() { final String str1 = "This is a secret text 1234567890-ÄÖÜäöüß"; final byte[] data1 = str1.getBytes(); final char[] password = "MyVerySecretPw!".toCharArray(); - final byte[] salt = new byte[] { (byte) 0xc7, (byte) 0x73, (byte) 0x21, (byte) 0x8c, (byte) 0x7e, (byte) 0xc8, (byte) 0xee, - (byte) 0x99 }; + final byte[] salt = new byte[]{(byte) 0xc7, (byte) 0x73, (byte) 0x21, (byte) 0x8c, (byte) 0x7e, (byte) 0xc8, (byte) 0xee, + (byte) 0x99}; final int count = 100; final byte[] encrypted = Utils4J.encryptPasswordBased(algorithm, data1, password, salt, count); @@ -670,7 +681,7 @@ private static class ExceptionContainer { /** * Create a runnable that locks the file. - * + * * @param file * File to lock. * @param ec @@ -681,11 +692,11 @@ private static class ExceptionContainer { * Milliseconds to sleep between retries. * @param sleepMillis * Number of milliseconds to hold the lock. - * + * * @return New runnable instance. */ private Runnable createLockRunnable(final File file, final ExceptionContainer ec, final int tryLockMax, final long tryWaitMillis, - final long sleepMillis) { + final long sleepMillis) { return new Runnable() { @Override public void run() { @@ -711,7 +722,7 @@ public void run() { /** * Start the two threads and wait until both finished. - * + * * @param thread1 * First thread. * @param thread2 @@ -858,10 +869,14 @@ public void testClasspathFilesPredicate() throws IOException { } @Test - public void testPathsFiles() { + public void testPathsFiles() throws IOException { final File javaHomeDir = new File(System.getProperty("java.home")); - final List bootJarFiles = Utils4J.pathsFiles(System.getProperty("sun.boot.library.path"), Utils4J::jreJarFile); + String path = System.getProperty("sun.boot.library.path"); + if (path.endsWith("bin")) { + path = path.substring(0, path.length() - 4) + File.separator + "lib"; + } + final List bootJarFiles = Utils4J.pathsFiles(path, Utils4J::jreJarFile); final File rtJar = new File(javaHomeDir, "lib/jrt-fs.jar"); assertThat(bootJarFiles).contains(rtJar); @@ -876,5 +891,130 @@ public void testClasspathFiles() throws IOException { } + @Test + public final void loadClassOK() { + assertThat(Utils4J.loadClass(Utils4J.class.getName())).isEqualTo(Utils4J.class); + } + + @Test + public final void loadClassFailure() { + assertThatThrownBy(() -> Utils4J.loadClass("a.b.c.d.DoesNotExist")) + .isInstanceOf(RuntimeException.class) + .hasMessageContaining("Failed to load class"); + } + + @Test + public final void testSetPrivateField() { + + // PREPARE + final MyTestClass original = new MyTestClass("Test"); + final String name = "Changed"; + + // TEST + Utils4J.setPrivateField(original, "name", name); + + // VERIFY + assertThat(original.getName()).isEqualTo(name); + + } + + @Test + public final void testTryLockedOK() { + + // PREPARE + final Semaphore semaphore = new Semaphore(1); + final AtomicBoolean executed = new AtomicBoolean(); + + // TEST + Utils4J.tryLocked(semaphore, () -> executed.set(true)); + + // VERIFY + assertThat(executed.get()).isTrue(); + + } + + + @Test + public final void testTryLockedFails() { + + // PREPARE + final Semaphore semaphore = new Semaphore(1); + final AtomicBoolean executed = new AtomicBoolean(); + + Utils4J.runLocked(semaphore, () -> { + + // TEST + Utils4J.tryLocked(semaphore, () -> executed.set(true)); + + // VERIFY + assertThat(executed.get()).isFalse(); + + }, ex -> fail("First lock is not expected to fail", ex)); + + } + + @Test + public final void testRunLockedOK() { + + // PREPARE + final Semaphore semaphore = new Semaphore(1); + final AtomicBoolean executed = new AtomicBoolean(); + + // TEST + Utils4J.runLocked(semaphore, () -> executed.set(true), ex -> fail("Lock is not expected to fail", ex)); + + // VERIFY + assertThat(executed.get()).isTrue(); + + } + + + @Test + public final void testRunLockedFails() { + + // PREPARE + final List executionOrder = Collections.synchronizedList(new ArrayList<>()); + final Semaphore semaphore = new Semaphore(1); + final AtomicReference firstFailed = new AtomicReference<>(); + final Thread t1 = new Thread(() -> { + Utils4J.runLocked(semaphore, () -> { + executionOrder.add("1A"); + Utils4J.sleep(2000); + executionOrder.add("1B"); + }, firstFailed::set); + }); + t1.start(); + + final AtomicBoolean secondExecuted = new AtomicBoolean(); + final AtomicReference secondFailed = new AtomicReference<>(); + + // TEST + Utils4J.sleep(1000); // Wait until 1st thread started + executionOrder.add("2A"); + Utils4J.runLocked(semaphore, () -> secondExecuted.set(true), secondFailed::set); + executionOrder.add("2B"); + + // VERIFY + assertThat(firstFailed.get()).isNull(); + assertThat(secondFailed.get()).isNull(); + assertThat(secondExecuted.get()).isTrue(); + assertThat(executionOrder).containsExactly("1A", "2A", "1B", "2B"); + + } + + private static class MyTestClass { + + private String name; + + public MyTestClass(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } + + } // CHECKSTYLE:ON diff --git a/src/test/java/org/fuin/utils4j/fileprocessor/FileProcessorTest.java b/src/test/java/org/fuin/utils4j/fileprocessor/FileProcessorTest.java index bfdb71a..c0860a8 100644 --- a/src/test/java/org/fuin/utils4j/fileprocessor/FileProcessorTest.java +++ b/src/test/java/org/fuin/utils4j/fileprocessor/FileProcessorTest.java @@ -17,7 +17,6 @@ */ package org.fuin.utils4j.fileprocessor; -import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import java.io.File; diff --git a/src/test/java/org/fuin/utils4j/jandex/JandexIndexFileReaderTest.java b/src/test/java/org/fuin/utils4j/jandex/JandexIndexFileReaderTest.java new file mode 100644 index 0000000..489e4e8 --- /dev/null +++ b/src/test/java/org/fuin/utils4j/jandex/JandexIndexFileReaderTest.java @@ -0,0 +1,66 @@ +/** + * Copyright (C) 2015 Michael Schnell. All rights reserved. + * http://www.fuin.org/ + *

+ * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 3 of the License, or (at your option) any + * later version. + *

+ * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + *

+ * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see http://www.gnu.org/licenses/. + */ +package org.fuin.utils4j.jandex; + +import org.fuin.utils4j.jandex.JandexIndexFileReader.Builder; + +import org.jboss.jandex.IndexView; +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.io.IOException; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link JandexIndexFileReader} class. + */ +public class JandexIndexFileReaderTest { + + @Test + public final void loadIndexFile() throws IOException { + final IndexView index = new Builder().addFiles(new File("src/test/resources/sample.index")).build().load(); + assertThat(index.getClassByName(JandexUtils.class.getName())).isNotNull(); + assertThat(index.getClassByName(JandexUtils.class.getName()).name().toString()).isEqualTo(JandexUtils.class.getName()); + } + + @Test + public final void loadIndexResource() throws IOException { + final IndexView index = new Builder().addResources("sample.index").build().load(); + assertThat(index.getClassByName(JandexUtils.class.getName())).isNotNull(); + assertThat(index.getClassByName(JandexUtils.class.getName()).name().toString()).isEqualTo(JandexUtils.class.getName()); + } + + @Test + public final void loadIndexResourceR() { + final IndexView index = new Builder().addResources("sample.index").build().loadR(); + assertThat(index.getClassByName(JandexUtils.class.getName())).isNotNull(); + assertThat(index.getClassByName(JandexUtils.class.getName()).name().toString()).isEqualTo(JandexUtils.class.getName()); + } + + @Test + public final void loadIndexResourceFailure() throws IOException { + assertThat(new Builder().addResources("does-not-exist.index").build().load().getKnownClasses()).isEmpty(); + } + + @Test + public final void loadIndexResourceRFailure() { + assertThat(new Builder().addResources("does-not-exist.index").build().loadR().getKnownClasses()).isEmpty(); + } + +} diff --git a/src/test/java/org/fuin/utils4j/jandex/JandexIndexFileWriterTest.java b/src/test/java/org/fuin/utils4j/jandex/JandexIndexFileWriterTest.java new file mode 100644 index 0000000..2efc735 --- /dev/null +++ b/src/test/java/org/fuin/utils4j/jandex/JandexIndexFileWriterTest.java @@ -0,0 +1,64 @@ +/** + * Copyright (C) 2015 Michael Schnell. All rights reserved. + * http://www.fuin.org/ + *

+ * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 3 of the License, or (at your option) any + * later version. + *

+ * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + *

+ * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see http://www.gnu.org/licenses/. + */ +package org.fuin.utils4j.jandex; + +import org.fuin.utils4j.jandex.JandexIndexFileReader; +import org.fuin.utils4j.jandex.JandexIndexFileWriter; +import org.fuin.utils4j.jandex.JandexUtils; +import org.jboss.jandex.Index; +import org.jboss.jandex.IndexView; +import org.jboss.jandex.Indexer; +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.io.IOException; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link JandexIndexFileWriter}. + */ +public class JandexIndexFileWriterTest { + + private static final File TARGET_DIR = new File("target"); + + private static final File TEST_CLASSES_DIR = new File(TARGET_DIR, "test-classes"); + + @Test + void testWriteIndexR() throws IOException { + + // PREPARE + final Indexer indexer = new Indexer(); + indexer.indexClass(JandexUtils.class); + final Index index = indexer.complete(); + final String filename = this.getClass().getSimpleName() + ".index"; + final File file = new File(TEST_CLASSES_DIR, filename); + file.delete(); + + // TEST + new JandexIndexFileWriter().writeIndexR(file, index); + + // VERIFY + assertThat(file).exists(); + final IndexView result = new JandexIndexFileReader.Builder().addResources(filename).build().loadR(); + assertThat(result.getClassByName(JandexUtils.class.getName())).isNotNull(); + assertThat(result.getClassByName(JandexUtils.class.getName()).name().toString()).isEqualTo(JandexUtils.class.getName()); + + } + +} diff --git a/src/test/java/org/fuin/utils4j/JandexUtilsTest.java b/src/test/java/org/fuin/utils4j/jandex/JandexUtilsTest.java similarity index 70% rename from src/test/java/org/fuin/utils4j/JandexUtilsTest.java rename to src/test/java/org/fuin/utils4j/jandex/JandexUtilsTest.java index 867873c..86e5e6e 100644 --- a/src/test/java/org/fuin/utils4j/JandexUtilsTest.java +++ b/src/test/java/org/fuin/utils4j/jandex/JandexUtilsTest.java @@ -1,118 +1,149 @@ -/** - * Copyright (C) 2015 Michael Schnell. All rights reserved. - * http://www.fuin.org/ - * - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 3 of the License, or (at your option) any - * later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more - * details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see http://www.gnu.org/licenses/. - */ -package org.fuin.utils4j; - -import org.jboss.jandex.DotName; -import org.jboss.jandex.Index; -import org.jboss.jandex.Indexer; -import org.junit.jupiter.api.Test; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link JandexUtils}. - */ -// CHECKSTYLE:OFF -public class JandexUtilsTest { - - @Test - public final void testIndexClassFile() { - - // PREPARE - final List knownFiles = new ArrayList(); - final File classFile = new File("target/classes/" + JandexUtils.class.getName().replace('.', '/') + ".class"); - final Indexer indexer = new Indexer(); - - // TEST - assertThat(JandexUtils.indexClassFile(indexer, knownFiles, classFile)).isTrue(); - assertThat(JandexUtils.indexClassFile(indexer, knownFiles, classFile)).isFalse(); - - // VERIFY - final Index index = indexer.complete(); - assertThat(knownFiles).contains(classFile); - assertThat(index.getClassByName(DotName.createSimple(JandexUtils.class.getName()))).isNotNull(); - - } - - @Test - public final void testIndexDir() { - - // PREPARE - final File jandexClassFile = new File("target/classes/" + JandexUtils.class.getName().replace('.', '/') + ".class"); - final File utils4JClassFile = new File("target/classes/" + Utils4J.class.getName().replace('.', '/') + ".class"); - final List knownFiles = new ArrayList(); - final File classesDir = new File("target/classes"); - final Indexer indexer = new Indexer(); - - // TEST - JandexUtils.indexDir(indexer, knownFiles, classesDir); - - // VERIFY - final Index index = indexer.complete(); - assertThat(knownFiles).contains(jandexClassFile); - assertThat(knownFiles).contains(utils4JClassFile); - assertThat(index.getClassByName(DotName.createSimple(JandexUtils.class.getName()))).isNotNull(); - assertThat(index.getClassByName(DotName.createSimple(Utils4J.class.getName()))).isNotNull(); - - } - - @Test - public final void testIndexJar() { - - // PREPARE - final File jarFile = new File("src/test/resources/ext4logback-0.2.0.jar"); - final List knownFiles = new ArrayList(); - final Indexer indexer = new Indexer(); - - // TEST - assertThat(JandexUtils.indexJar(indexer, knownFiles, jarFile)).isTrue(); - assertThat(JandexUtils.indexJar(indexer, knownFiles, jarFile)).isFalse(); - - // VERIFY - final Index index = indexer.complete(); - assertThat(knownFiles).contains(jarFile); - assertThat(index.getClassByName(DotName.createSimple("org.fuin.ext4logback.LogbackStandalone"))).isNotNull(); - - } - - @Test - public final void testIndexClasspath() throws IOException { - - // PREPARE - final File jandexClassFile = new File("target/classes/" + JandexUtils.class.getName().replace('.', '/') + ".class") - .getCanonicalFile(); - final List knownFiles = new ArrayList(); - final Indexer indexer = new Indexer(); - - // TEST - JandexUtils.indexClasspath(indexer, knownFiles); - - // VERIFY - final Index index = indexer.complete(); - assertThat(index.getClassByName(DotName.createSimple(JandexUtils.class.getName()))).isNotNull(); - assertThat(knownFiles).contains(jandexClassFile); - - } - -} -// CHECKSTYLE:ON +/** + * Copyright (C) 2015 Michael Schnell. All rights reserved. + * http://www.fuin.org/ + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 3 of the License, or (at your option) any + * later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see http://www.gnu.org/licenses/. + */ +package org.fuin.utils4j.jandex; + +import org.fuin.utils4j.Utils4J; +import org.fuin.utils4j.jandex.JandexUtils; +import org.jboss.jandex.DotName; +import org.jboss.jandex.Index; +import org.jboss.jandex.Indexer; +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +/** + * Tests for {@link JandexUtils}. + */ +// CHECKSTYLE:OFF +public class JandexUtilsTest { + + private static final File TARGET_DIR = new File("target"); + + private static final File CLASSES_DIR = new File(TARGET_DIR, "classes"); + + @Test + public final void testIndexClassFile() { + + // PREPARE + final List knownFiles = new ArrayList(); + final File classFile = new File(CLASSES_DIR, JandexUtils.class.getName().replace('.', '/') + ".class"); + final Indexer indexer = new Indexer(); + + // TEST + assertThat(JandexUtils.indexClassFile(indexer, knownFiles, classFile)).isTrue(); + assertThat(JandexUtils.indexClassFile(indexer, knownFiles, classFile)).isFalse(); + + // VERIFY + final Index index = indexer.complete(); + assertThat(knownFiles).contains(classFile); + assertThat(index.getClassByName(DotName.createSimple(JandexUtils.class.getName()))).isNotNull(); + + } + + @Test + public final void testIndexDirSimple() { + + // TEST + final Index index = JandexUtils.indexDir(CLASSES_DIR); + + // VERIFY + assertThat(index.getClassByName(DotName.createSimple(JandexUtils.class.getName()))).isNotNull(); + assertThat(index.getClassByName(DotName.createSimple(Utils4J.class.getName()))).isNotNull(); + + } + + @Test + public final void testIndexDir() { + + // PREPARE + final File jandexClassFile = new File(CLASSES_DIR, JandexUtils.class.getName().replace('.', '/') + ".class"); + final File utils4JClassFile = new File(CLASSES_DIR, Utils4J.class.getName().replace('.', '/') + ".class"); + final List knownFiles = new ArrayList(); + final File classesDir = new File("target/classes"); + final Indexer indexer = new Indexer(); + + // TEST + JandexUtils.indexDir(indexer, knownFiles, classesDir); + + // VERIFY + final Index index = indexer.complete(); + assertThat(knownFiles).contains(jandexClassFile); + assertThat(knownFiles).contains(utils4JClassFile); + assertThat(index.getClassByName(DotName.createSimple(JandexUtils.class.getName()))).isNotNull(); + assertThat(index.getClassByName(DotName.createSimple(Utils4J.class.getName()))).isNotNull(); + + } + + @Test + public final void testIndexJar() { + + // PREPARE + final File jarFile = new File("src/test/resources/ext4logback-0.2.0.jar"); + final List knownFiles = new ArrayList(); + final Indexer indexer = new Indexer(); + + // TEST + assertThat(JandexUtils.indexJar(indexer, knownFiles, jarFile)).isTrue(); + assertThat(JandexUtils.indexJar(indexer, knownFiles, jarFile)).isFalse(); + + // VERIFY + final Index index = indexer.complete(); + assertThat(knownFiles).contains(jarFile); + assertThat(index.getClassByName(DotName.createSimple("org.fuin.ext4logback.LogbackStandalone"))).isNotNull(); + + } + + @Test + public final void testIndexClasspath() throws IOException { + + // PREPARE + final File jandexClassFile = new File(CLASSES_DIR, JandexUtils.class.getName().replace('.', '/') + ".class") + .getCanonicalFile(); + final List knownFiles = new ArrayList(); + final Indexer indexer = new Indexer(); + + // TEST + JandexUtils.indexClasspath(indexer, knownFiles); + + // VERIFY + final Index index = indexer.complete(); + assertThat(index.getClassByName(DotName.createSimple(JandexUtils.class.getName()))).isNotNull(); + assertThat(knownFiles).contains(jandexClassFile); + + } + + @Test + public final void loadClassOK() { + assertThat(JandexUtils.loadClass(DotName.createSimple(Utils4J.class))).isEqualTo(Utils4J.class); + } + + @Test + public final void loadClassFailure() { + assertThatThrownBy(() -> JandexUtils.loadClass(DotName.createSimple("a.b.c.d.DoesNotExist"))) + .isInstanceOf(RuntimeException.class) + .hasMessageContaining("Failed to load class"); + } + +} +// CHECKSTYLE:ON diff --git a/src/test/java/org/fuin/utils4j/jaxb/MarshallerBuilderTest.java b/src/test/java/org/fuin/utils4j/jaxb/MarshallerBuilderTest.java index de4adc1..00eba2a 100644 --- a/src/test/java/org/fuin/utils4j/jaxb/MarshallerBuilderTest.java +++ b/src/test/java/org/fuin/utils4j/jaxb/MarshallerBuilderTest.java @@ -19,11 +19,9 @@ import jakarta.xml.bind.JAXBContext; import jakarta.xml.bind.JAXBException; -import jakarta.xml.bind.MarshalException; import jakarta.xml.bind.Marshaller; import jakarta.xml.bind.annotation.adapters.XmlAdapter; import org.junit.jupiter.api.Test; -import org.xml.sax.SAXParseException; import org.xmlunit.builder.DiffBuilder; import org.xmlunit.diff.Diff; @@ -201,9 +199,11 @@ public void testWithListener() throws JAXBException { final AtomicBoolean afterCalled = new AtomicBoolean(false); final Marshaller marshaller = new MarshallerBuilder().withContext(ctx).addAdapters(new MyId.Adapter()) .withListener(new Marshaller.Listener() { + @Override public void beforeMarshal(Object source) { beforeCalled.set(true); } + @Override public void afterMarshal(Object source) { afterCalled.set(true); } diff --git a/src/test/resources/sample.index b/src/test/resources/sample.index new file mode 100644 index 0000000..5f0dbb6 Binary files /dev/null and b/src/test/resources/sample.index differ