2
0
Fork 0
mirror of https://github.com/ethauvin/rife2.git synced 2025-04-29 18:18:12 -07:00

Compare commits

...

18 commits

Author SHA1 Message Date
6d58222546 Updated version to 1.5.19 2023-04-10 07:56:16 -04:00
7163c396b6 Javadocs 2023-04-10 07:16:20 -04:00
efd54f480d Added FileUtils tests and javadocs 2023-04-09 21:53:30 -04:00
cf03a8c02a Test fix.
Updated wrapper.
2023-04-09 17:43:51 -04:00
6bb7b1d3be Added DirBuilder and FileBuilder classes to help creating dir and file hierarchies, adapted RIFE2's build file to use this for the bld.zip file.
Changed FileUtilsErrorException to extend from IOException instead of regular Exception.
2023-04-09 17:00:49 -04:00
9b00641d1a Added CLI option to print stacktrace.
Added CLI options for printing help.
Added CLI help for additional options.
2023-04-09 01:24:58 -04:00
08a7e24516 Handle gpg sign failures and report errors 2023-04-08 19:56:19 -04:00
cf9e3fd13a
Update bld.yml (#24)
Changed job name from Gradle to bld.
2023-04-08 15:05:46 -04:00
70fbc5860e Updated version to 1.5.19-SNAPSHOT 2023-04-08 14:32:34 -04:00
a8bef2a5c8 Don't start the template precompilation if no types are defined. 2023-04-08 14:32:14 -04:00
b4f23220a3 Updated bld-tests-badge 2023-04-08 13:09:10 -04:00
469ec9332a Updated version to 1.5.18 2023-04-08 09:12:32 -04:00
ee830c0cf2 Regression fix for activating RIFE2 agent through bld. 2023-04-08 08:17:34 -04:00
1370f40701 Include standalone classpath back into the test classpath 2023-04-08 07:53:18 -04:00
ec684a510a Moved zip operation to a bld extension that uses commons compress 2023-04-07 21:41:00 -04:00
abbe5bda6c Fixed regression since caching change 2023-04-07 18:57:26 -04:00
5d21df72d5 Reworked the artifact cache to not use a single static collection for everything 2023-04-07 18:30:05 -04:00
f00298f1b4 Reworked the artifact cache to not use a single static collection for everything 2023-04-07 18:29:51 -04:00
44 changed files with 3634 additions and 866 deletions

View file

@ -3,7 +3,7 @@ name: bld-ci
on: [push, pull_request, workflow_dispatch]
jobs:
build-gradle-project:
build-bld-project:
runs-on: ubuntu-latest
services:

View file

@ -2,11 +2,11 @@
<library name="bld">
<CLASSES>
<root url="file://$PROJECT_DIR$/lib/bld" />
<root url="jar://$USER_HOME$/.rife2/dist/rife2-1.5.18-SNAPSHOT6.jar!/" />
<root url="jar://$USER_HOME$/.rife2/dist/rife2-1.5.19.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$USER_HOME$/.rife2/dist/rife2-1.5.18-SNAPSHOT6-sources.jar!/" />
<root url="jar://$USER_HOME$/.rife2/dist/rife2-1.5.19-sources.jar!/" />
</SOURCES>
<excluded>
<root url="jar://$PROJECT_DIR$/lib/bld/bld-wrapper.jar!/" />

Binary file not shown.

View file

@ -1,6 +1,8 @@
bld.downloadExtensionJavadoc=false
bld.downloadExtensionSources=true
bld.extensions=com.uwyn.rife2:bld-antlr4:0.9.7-SNAPSHOT,com.uwyn.rife2:bld-tests-badge:0.9.5-SNAPSHOT
bld.repositories=MAVEN_CENTRAL,https://repo.rife2.com/snapshots,RIFE2
rife2.downloadLocation=https://uwyn.com
rife2.version=1.5.18-SNAPSHOT6
bld.extension-antlr=com.uwyn.rife2:bld-antlr4:1.0.0
bld.extension-archive=com.uwyn.rife2:bld-archive:0.2.0
bld.extension-tests=com.uwyn.rife2:bld-tests-badge:1.1.0
bld.repositories=MAVEN_CENTRAL,RIFE2_RELEASES
rife2.downloadLocation=
rife2.version=1.5.19

View file

@ -6,16 +6,19 @@ package rife;
import rife.bld.BuildCommand;
import rife.bld.Project;
import rife.bld.dependencies.VersionNumber;
import rife.bld.extension.Antlr4Operation;
import rife.bld.extension.TestsBadgeOperation;
import rife.bld.extension.ZipOperation;
import rife.bld.operations.*;
import rife.bld.publish.*;
import rife.bld.wrapper.Wrapper;
import rife.tools.DirBuilder;
import rife.tools.FileUtils;
import rife.tools.StringUtils;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.jar.Attributes;
@ -23,6 +26,7 @@ import static rife.bld.dependencies.Repository.*;
import static rife.bld.dependencies.Scope.*;
import static rife.bld.operations.JavadocOptions.DocLinkOption.NO_MISSING;
import static rife.bld.operations.TemplateType.*;
import static rife.tools.FileUtils.path;
public class Rife2Build extends Project {
public Rife2Build()
@ -36,7 +40,7 @@ public class Rife2Build extends Project {
downloadSources = true;
autoDownloadPurge = true;
repositories = List.of(MAVEN_CENTRAL, RIFE2_SNAPSHOTS, RIFE2_RELEASES);
repositories = List.of(MAVEN_CENTRAL, RIFE2_RELEASES);
scope(provided)
.include(dependency("org.jsoup", "jsoup", version(1,15,4)))
.include(dependency("org.eclipse.jetty", "jetty-server", version(11,0,14)))
@ -239,28 +243,31 @@ public class Rife2Build extends Project {
jar();
var tmp = Files.createTempDirectory("bld").toFile();
try {
new RunOperation().fromProject(this)
.workDirectory(tmp)
.runOptions("upgrade")
.outputProcessor(s -> true )
.execute();
var bld_dir = new File(tmp, "bld");
var bld_bin_dir = new File(bld_dir, "bin");
var bld_lib_dir = new File(bld_dir, "lib");
bld_bin_dir.mkdirs();
bld_lib_dir.mkdirs();
Files.copy(Path.of(srcMainDirectory().getAbsolutePath(), "bld", "bld"), Path.of(bld_bin_dir.getAbsolutePath(), "bld"));
Files.copy(Path.of(srcMainDirectory().getAbsolutePath(), "bld", "bld.bat"), Path.of(bld_bin_dir.getAbsolutePath(), "bld.bat"));
Files.move(Path.of(tmp.getAbsolutePath(), "lib", "bld", "bld-wrapper.jar"), Path.of(bld_lib_dir.getAbsolutePath(), "bld-wrapper.jar"));
FileUtils.deleteDirectory(new File(tmp, "lib"));
new Wrapper().createWrapperFiles(path(tmp, "lib").toFile(), VersionNumber.UNKNOWN.toString());
new DirBuilder(tmp, t -> {
t.dir("bld", b -> {
b.dir("bin", i -> {
i.file("bld", f -> {
f.copy(path(srcMainDirectory(), "bld", "bld"));
f.perms(0755);
});
i.file("bld.bat", f -> {
f.copy(path(srcMainDirectory(), "bld", "bld.bat"));
f.perms(0755);
});
});
b.dir("lib", l -> {
l.file("bld-wrapper.jar", f -> f.move(path(tmp, "lib", "bld-wrapper.jar")));
});
});
t.dir("lib", l -> l.delete());
});
zipBldOperation
.sourceDirectories(tmp)
.execute();
} finally {
tmp.delete();
FileUtils.deleteDirectory(tmp);
}
}

View file

@ -33,6 +33,12 @@ public class BuildExecutor {
public static final String BLD_PROPERTIES = "bld.properties";
public static final String LOCAL_PROPERTIES = "local.properties";
private static final String ARG_HELP1 = "--help";
private static final String ARG_HELP2 = "-h";
private static final String ARG_HELP3 = "-?";
private static final String ARG_STACKTRACE1 = "--stacktrace";
private static final String ARG_STACKTRACE2 = "-s";
private final HierarchicalProperties properties_;
private List<String> arguments_ = Collections.emptyList();
private Map<String, CommandDefinition> buildCommands_ = null;
@ -40,6 +46,17 @@ public class BuildExecutor {
private final AtomicReference<CommandDefinition> currentCommandDefinition_ = new AtomicReference<>();
private int exitStatus_ = 0;
/**
* Show the full Java stacktrace when exceptions occur, as opposed
* to the chain of messages.
* <p>
* Defaults to {@code false}, can be set to {@code true} by setting
* through code or by adding {@code --stacktrace} as a CLI argument.
*
* @since 1.5.19
*/
protected boolean showStacktrace = false;
/**
* Creates a new build executor instance.
*
@ -190,10 +207,12 @@ public class BuildExecutor {
* @since 1.5.1
*/
public int execute(String[] arguments) {
DependencyResolver.clearArtifactCache();
arguments_ = new ArrayList<>(Arrays.asList(arguments));
var show_help = arguments_.isEmpty();
var show_help = false;
show_help |= arguments_.removeAll(List.of(ARG_HELP1, ARG_HELP2, ARG_HELP3));
showStacktrace |= arguments_.removeAll(List.of(ARG_STACKTRACE1, ARG_STACKTRACE2));
show_help |= arguments_.isEmpty();
while (!arguments_.isEmpty()) {
var command = arguments_.remove(0);
@ -206,21 +225,26 @@ public class BuildExecutor {
exitStatus(1);
System.err.println();
boolean first = true;
var e2 = e;
while (e2 != null) {
if (e2.getMessage() != null) {
if (!first) {
System.err.print("> ");
}
System.err.println(e2.getMessage());
first = false;
}
e2 = e2.getCause();
}
if (first) {
if (showStacktrace) {
System.err.println(ExceptionUtils.getExceptionStackTrace(e));
} else {
boolean first = true;
var e2 = e;
while (e2 != null) {
if (e2.getMessage() != null) {
if (!first) {
System.err.print("> ");
}
System.err.println(e2.getMessage());
first = false;
}
e2 = e2.getCause();
}
if (first) {
System.err.println(ExceptionUtils.getExceptionStackTrace(e));
}
}
}
}

View file

@ -325,20 +325,22 @@ public class Project extends BuildExecutor {
* Standard build commands
*/
private final ArtifactRetriever retriever_ = ArtifactRetriever.cachingInstance();
private final CleanOperation cleanOperation_ = new CleanOperation();
private final CompileOperation compileOperation_ = new CompileOperation();
private final DownloadOperation downloadOperation_ = new DownloadOperation();
private final DownloadOperation downloadOperation_ = new DownloadOperation().artifactRetriever(retriever_);
private final JavadocOperation javadocOperation_ = new JavadocOperation();
private final PrecompileOperation precompileOperation_ = new PrecompileOperation();
private final JarOperation jarOperation_ = new JarOperation();
private final JarOperation jarSourcesOperation_ = new JarOperation();
private final JarOperation jarJavadocOperation_ = new JarOperation();
private final PurgeOperation purgeOperation_ = new PurgeOperation();
private final PurgeOperation purgeOperation_ = new PurgeOperation().artifactRetriever(retriever_);
private final RunOperation runOperation_ = new RunOperation();
private final TestOperation testOperation_ = new TestOperation();
private final UberJarOperation uberJarOperation_ = new UberJarOperation();
private final UpdatesOperation updatesOperation_ = new UpdatesOperation();
private final PublishOperation publishOperation_ = new PublishOperation();
private final UpdatesOperation updatesOperation_ = new UpdatesOperation().artifactRetriever(retriever_);
private final PublishOperation publishOperation_ = new PublishOperation().artifactRetriever(retriever_);
private final VersionOperation versionOperation_ = new VersionOperation();
/**
@ -1623,7 +1625,7 @@ public class Project extends BuildExecutor {
* @since 1.5
*/
public List<String> testClasspath() {
var paths = FileUtils.combineToAbsolutePaths(compileClasspathJars(), runtimeClasspathJars(), testClasspathJars());
var paths = FileUtils.combineToAbsolutePaths(compileClasspathJars(), runtimeClasspathJars(), standaloneClasspathJars(), testClasspathJars());
paths.add(srcMainResourcesDirectory().getAbsolutePath());
paths.add(srcTestResourcesDirectory().getAbsolutePath());
paths.add(buildMainDirectory().getAbsolutePath());

View file

@ -0,0 +1,202 @@
/*
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
* Licensed under the Apache License, Version 2.0 (the "License")
*/
package rife.bld.dependencies;
import rife.tools.FileUtils;
import rife.tools.exceptions.FileUtilsErrorException;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.nio.channels.Channels;
import java.security.MessageDigest;
import java.util.*;
import static rife.tools.HttpUtils.HEADER_AUTHORIZATION;
import static rife.tools.HttpUtils.basicAuthorizationHeader;
import static rife.tools.StringUtils.encodeHexLower;
/**
* Retrieves artifact data.
* <p>
* To instantiate, use either {@link #instance()} for direct retrieval of
* each request, or {@link #cachingInstance()} where previous retrievals
* of remote string content will be cached for faster future retrieval.
*
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
* @since 1.5.18
*/
public abstract class ArtifactRetriever {
private final static ArtifactRetriever UNCACHED = new ArtifactRetriever() {
String getCached(RepositoryArtifact artifact) {
return null;
}
void cache(RepositoryArtifact artifact, String content) {
}
};
/**
* Gets an artifact retriever that does direct retrieval of each request.
*
* @return the direct retrieval instance
* @since 1.5.18
*/
public static ArtifactRetriever instance() {
return UNCACHED;
}
/**
* Creates a caching artifact retriever where previous retrievals
* of remote string content will be cached for faster future retrieval.
*
* @return a caching instance
* @since 1.5.18
*/
public static ArtifactRetriever cachingInstance() {
return new ArtifactRetriever() {
private final Map<RepositoryArtifact, String> artifactCache = new HashMap<>();
String getCached(RepositoryArtifact artifact) {
return artifactCache.get(artifact);
}
void cache(RepositoryArtifact artifact, String content) {
artifactCache.put(artifact, content);
}
};
}
private ArtifactRetriever() {
}
abstract String getCached(RepositoryArtifact artifact);
abstract void cache(RepositoryArtifact artifact, String content);
/**
* Reads the contents of an artifact as a string.
*
* @param artifact the artifact who's content to retrieve
* @return the string content of the artifact
* @throws FileUtilsErrorException when an error occurred when reading the contents
* @since 1.5.18
*/
public String readString(RepositoryArtifact artifact)
throws FileUtilsErrorException {
if (artifact.repository().isLocal()) {
return FileUtils.readString(new File(artifact.location()));
} else {
var cached = getCached(artifact);
if (cached != null) {
return cached;
}
try {
var connection = new URL(artifact.location()).openConnection();
connection.setUseCaches(false);
if (artifact.repository().username() != null && artifact.repository().password() != null) {
connection.setRequestProperty(
HEADER_AUTHORIZATION,
basicAuthorizationHeader(artifact.repository().username(), artifact.repository().password()));
}
try (var input_stream = connection.getInputStream()) {
var result = FileUtils.readString(input_stream);
cache(artifact, result);
return result;
}
} catch (IOException e) {
throw new FileUtilsErrorException("Error while reading URL '" + artifact.location() + ".", e);
}
}
}
/**
* Transfers artifact into the provided directory.
* <p>
* The destination directory must exist and be writable.
*
* @param artifact the artifact to transfer
* @param directory the directory to transfer the artifact into
* @return {@code true} when the artifact is present in the directory (it could already have been
* there and be validated as correct); or {@code false} when the artifact couldn't be transferred
* @throws IOException when an error occurred during the transfer
* @throws FileUtilsErrorException when an error occurred during the transfer
* @since 1.5.18
*/
public boolean transferIntoDirectory(RepositoryArtifact artifact, File directory)
throws IOException, FileUtilsErrorException {
if (directory == null) throw new IllegalArgumentException("directory can't be null");
if (!directory.exists()) throw new IllegalArgumentException("directory '" + directory + "' doesn't exit");
if (!directory.canWrite()) throw new IllegalArgumentException("directory '" + directory + "' can't be written to");
if (!directory.isDirectory()) throw new IllegalArgumentException("directory '" + directory + "' is not a directory");
var download_filename = artifact.location().substring(artifact.location().lastIndexOf("/") + 1);
var download_file = new File(directory, download_filename);
System.out.print("Downloading: " + artifact.location() + " ... ");
System.out.flush();
try {
if (artifact.repository().isLocal()) {
var source = new File(artifact.location());
if (source.exists()) {
FileUtils.copy(source, download_file);
System.out.print("done");
return true;
} else {
System.out.print("not found");
return false;
}
} else {
try {
if (download_file.exists() && download_file.canRead()) {
if (checkHash(artifact, download_file, ".sha256", "SHA-256") ||
checkHash(artifact, download_file, ".md5", "MD5")) {
System.out.print("exists");
return true;
}
}
var connection = new URL(artifact.location()).openConnection();
connection.setUseCaches(false);
if (artifact.repository().username() != null && artifact.repository().password() != null) {
connection.setRequestProperty(
HEADER_AUTHORIZATION,
basicAuthorizationHeader(artifact.repository().username(), artifact.repository().password()));
}
try (var input_stream = connection.getInputStream()) {
var readableByteChannel = Channels.newChannel(input_stream);
try (var fileOutputStream = new FileOutputStream(download_file)) {
var fileChannel = fileOutputStream.getChannel();
fileChannel.transferFrom(readableByteChannel, 0, Long.MAX_VALUE);
System.out.print("done");
return true;
}
}
} catch (FileNotFoundException e) {
System.out.print("not found");
return false;
}
}
} finally {
System.out.println();
}
}
private boolean checkHash(RepositoryArtifact artifact, File downloadFile, String extension, String algorithm) {
try {
var hash_sum = readString(artifact.appendPath(extension));
var digest = MessageDigest.getInstance(algorithm);
digest.update(FileUtils.readBytes(downloadFile));
return hash_sum.equals(encodeHexLower(digest.digest()));
} catch (Exception e) {
// no-op, the hash file couldn't be found or calculated, so it couldn't be checked
}
return false;
}
}

View file

@ -28,8 +28,7 @@ import static rife.tools.StringUtils.encodeHexLower;
* @since 1.5
*/
public class DependencyResolver {
private final static ConcurrentMap<RepositoryArtifact, String> ARTIFACT_CACHE = new ConcurrentHashMap<>();
private final ArtifactRetriever retriever_;
private final List<Repository> repositories_;
private final Dependency dependency_;
@ -41,11 +40,13 @@ public class DependencyResolver {
* <p>
* The repositories will be checked in the order they're listed.
*
* @param retriever the retriever to use to get artifacts
* @param repositories the repositories to use for the resolution
* @param dependency the dependency to resolve
* @since 1.5
* @since 1.5.18
*/
public DependencyResolver(List<Repository> repositories, Dependency dependency) {
public DependencyResolver(ArtifactRetriever retriever, List<Repository> repositories, Dependency dependency) {
retriever_ = retriever;
if (repositories == null) {
repositories = Collections.emptyList();
}
@ -159,7 +160,7 @@ public class DependencyResolver {
// dependencies so that they can be added to the queue after
// filtering
parent = candidate;
next_dependencies = new DependencyResolver(repositories_, dependency).getMavenPom(parent).getDependencies(scopes);
next_dependencies = new DependencyResolver(retriever_, repositories_, dependency).getMavenPom(parent).getDependencies(scopes);
break;
}
}
@ -224,7 +225,7 @@ public class DependencyResolver {
}
/**
* Transfers the artifact for the resolved dependency into the provided directory.
* Transfers the artifacts for the resolved dependency into the provided directory.
* <p>
* The destination directory must exist and be writable.
*
@ -234,85 +235,17 @@ public class DependencyResolver {
*/
public void transferIntoDirectory(File directory)
throws DependencyTransferException {
if (directory == null) throw new IllegalArgumentException("directory can't be null");
if (!directory.exists()) throw new IllegalArgumentException("directory '" + directory + "' doesn't exit");
if (!directory.canWrite())
throw new IllegalArgumentException("directory '" + directory + "' can't be written to");
if (!directory.isDirectory())
throw new IllegalArgumentException("directory '" + directory + "' is not a directory");
boolean retrieved = false;
var artifacts = getTransferArtifacts();
for (var artifact : artifacts) {
var download_filename = artifact.location().substring(artifact.location().lastIndexOf("/") + 1);
var download_file = new File(directory, download_filename);
System.out.print("Downloading: " + artifact.location() + " ... ");
System.out.flush();
for (var artifact : getTransferArtifacts()) {
try {
if (artifact.repository().isLocal()) {
var source = new File(artifact.location());
if (source.exists()) {
FileUtils.copy(source, download_file);
System.out.print("done");
break;
} else {
System.out.print("not found");
}
} else {
try {
if (download_file.exists() && download_file.canRead()) {
if (checkHash(artifact, download_file, ".sha256", "SHA-256") ||
checkHash(artifact, download_file, ".md5", "MD5")) {
retrieved = true;
System.out.print("exists");
break;
}
}
if (!retrieved) {
var connection = new URL(artifact.location()).openConnection();
connection.setUseCaches(false);
if (artifact.repository().username() != null && artifact.repository().password() != null) {
connection.setRequestProperty(
HEADER_AUTHORIZATION,
basicAuthorizationHeader(artifact.repository().username(), artifact.repository().password()));
}
try (var input_stream = connection.getInputStream()) {
var readableByteChannel = Channels.newChannel(input_stream);
try (var fileOutputStream = new FileOutputStream(download_file)) {
var fileChannel = fileOutputStream.getChannel();
fileChannel.transferFrom(readableByteChannel, 0, Long.MAX_VALUE);
retrieved = true;
System.out.print("done");
break;
}
}
}
} catch (FileNotFoundException e) {
System.out.print("not found");
}
if (retriever_.transferIntoDirectory(artifact, directory)) {
return;
}
} catch (IOException | FileUtilsErrorException e) {
throw new DependencyTransferException(dependency_, artifact.location(), download_file, e);
} finally {
System.out.println();
} catch (IOException e) {
throw new DependencyTransferException(dependency_, artifact.location(), directory, e);
}
}
}
private static boolean checkHash(RepositoryArtifact artifact, File downloadFile, String extension, String algorithm) {
try {
var hash_sum = readString(artifact.appendPath(extension));
var digest = MessageDigest.getInstance(algorithm);
digest.update(FileUtils.readBytes(downloadFile));
return hash_sum.equals(encodeHexLower(digest.digest()));
} catch (Exception e) {
// no-op, the hash file couldn't be found or calculated, so it couldn't be checked
}
return false;
}
/**
* Retrieve the repositories that are used by this dependency resolver.
*
@ -436,7 +369,7 @@ public class DependencyResolver {
String metadata = null;
for (var artifact : artifacts) {
try {
var content = readString(artifact);
var content = retriever_.readString(artifact);
if (content == null) {
throw new ArtifactNotFoundException(dependency_, artifact.location());
}
@ -485,7 +418,7 @@ public class DependencyResolver {
for (var artifact : artifacts) {
try {
var content = readString(artifact);
var content = retriever_.readString(artifact);
if (content == null) {
throw new ArtifactNotFoundException(dependency_, artifact.location());
}
@ -506,49 +439,11 @@ public class DependencyResolver {
throw new ArtifactNotFoundException(dependency_, artifacts.stream().map(RepositoryArtifact::location).collect(Collectors.joining(", ")));
}
var xml = new Xml2MavenPom(parent, repositories_);
var xml = new Xml2MavenPom(parent, retriever_, repositories_);
if (!xml.processXml(pom)) {
throw new DependencyXmlParsingErrorException(dependency_, retrieved_artifact.location(), xml.getErrors());
}
return xml;
}
private static String readString(RepositoryArtifact artifact)
throws FileUtilsErrorException {
if (artifact.repository().isLocal()) {
return FileUtils.readString(new File(artifact.location()));
} else {
var cached = ARTIFACT_CACHE.get(artifact);
if (cached != null) {
return cached;
}
try {
var connection = new URL(artifact.location()).openConnection();
connection.setUseCaches(false);
if (artifact.repository().username() != null && artifact.repository().password() != null) {
connection.setRequestProperty(
HEADER_AUTHORIZATION,
basicAuthorizationHeader(artifact.repository().username(), artifact.repository().password()));
}
try (var input_stream = connection.getInputStream()) {
var result = FileUtils.readString(input_stream);
ARTIFACT_CACHE.put(artifact, result);
return result;
}
} catch (IOException e) {
throw new FileUtilsErrorException("Error while reading URL '" + artifact.location() + ".", e);
}
}
}
/**
* Clears the artifact cache.
*
* @since 1.5.18
*/
public static void clearArtifactCache() {
ARTIFACT_CACHE.clear();
}
}

View file

@ -84,13 +84,14 @@ public class DependencySet extends AbstractSet<Dependency> implements Set<Depend
* <p>
* The destination directory must exist and be writable.
*
* @param retriever the retriever to use to get artifacts
* @param repositories the repositories to use for the transfer
* @param directory the directory to transfer the artifacts into
* @throws DependencyTransferException when an error occurred during the transfer
* @since 1.5.10
*/
public void transferIntoDirectory(List<Repository> repositories, File directory) {
transferIntoDirectory(repositories, directory, (String[]) null);
public void transferIntoDirectory(ArtifactRetriever retriever, List<Repository> repositories, File directory) {
transferIntoDirectory(retriever, repositories, directory, (String[]) null);
}
/**
@ -99,19 +100,20 @@ public class DependencySet extends AbstractSet<Dependency> implements Set<Depend
* <p>
* The destination directory must exist and be writable.
*
* @param retriever the retriever to use to get artifacts
* @param repositories the repositories to use for the download
* @param directory the directory to download the artifacts into
* @param classifiers the additional classifiers to transfer
* @throws DependencyTransferException when an error occurred during the transfer
* @since 1.5.10
*/
public void transferIntoDirectory(List<Repository> repositories, File directory, String... classifiers) {
public void transferIntoDirectory(ArtifactRetriever retriever, List<Repository> repositories, File directory, String... classifiers) {
for (var dependency : this) {
new DependencyResolver(repositories, dependency).transferIntoDirectory(directory);
new DependencyResolver(retriever, repositories, dependency).transferIntoDirectory(directory);
if (classifiers != null) {
for (var classifier : classifiers) {
if (classifier != null) {
new DependencyResolver(repositories, dependency.withClassifier(classifier)).transferIntoDirectory(directory);
new DependencyResolver(retriever, repositories, dependency.withClassifier(classifier)).transferIntoDirectory(directory);
}
}
}

View file

@ -18,6 +18,7 @@ import java.util.regex.Pattern;
*/
class Xml2MavenPom extends Xml2Data {
private final PomDependency parent_;
private final ArtifactRetriever retriever_;
private final List<Repository> repositories_;
private Map<Scope, Set<PomDependency>> resolvedDependencies_ = null;
@ -44,8 +45,9 @@ class Xml2MavenPom extends Xml2Data {
private String lastExclusionGroupId_ = null;
private String lastExclusionArtifactId_ = null;
Xml2MavenPom(PomDependency parent, List<Repository> repositories) {
Xml2MavenPom(PomDependency parent, ArtifactRetriever retriever, List<Repository> repositories) {
parent_ = parent;
retriever_ = retriever;
repositories_ = repositories;
}
@ -159,7 +161,7 @@ class Xml2MavenPom extends Xml2Data {
case "parent" -> {
if (isChildOfProject()) {
var parent_dependency = new Dependency(lastGroupId_, lastArtifactId_, VersionNumber.parse(lastVersion_));
var parent = new DependencyResolver(repositories_, parent_dependency).getMavenPom(parent_);
var parent = new DependencyResolver(retriever_, repositories_, parent_dependency).getMavenPom(parent_);
parent.properties_.keySet().removeAll(properties_.keySet());

View file

@ -4,8 +4,6 @@
*/
package rife.bld.operations;
import java.util.function.Consumer;
/**
* Provides common features across all operations
*

View file

@ -24,6 +24,7 @@ import static rife.bld.dependencies.Dependency.CLASSIFIER_SOURCES;
* @since 1.5
*/
public class DownloadOperation extends AbstractOperation<DownloadOperation> {
private ArtifactRetriever retriever_ = null;
private final List<Repository> repositories_ = new ArrayList<>();
private final DependencyScopes dependencies_ = new DependencyScopes();
private File libCompileDirectory_;
@ -67,13 +68,13 @@ public class DownloadOperation extends AbstractOperation<DownloadOperation> {
var provided_dependencies = dependencies().get(Scope.provided);
if (provided_dependencies != null) {
for (var dependency : provided_dependencies) {
excluded.addAll(new DependencyResolver(repositories(), dependency).getAllDependencies(Scope.compile));
excluded.addAll(new DependencyResolver(artifactRetriever(), repositories(), dependency).getAllDependencies(Scope.compile));
}
}
var compile_dependencies = dependencies().get(Scope.compile);
if (compile_dependencies != null) {
for (var dependency : compile_dependencies) {
excluded.addAll(new DependencyResolver(repositories(), dependency).getAllDependencies(Scope.compile));
excluded.addAll(new DependencyResolver(artifactRetriever(), repositories(), dependency).getAllDependencies(Scope.compile));
}
}
executeDownloadScopedDependencies(libRuntimeDirectory(), new Scope[]{Scope.provided, Scope.compile, Scope.runtime}, new Scope[]{Scope.runtime}, excluded);
@ -118,7 +119,7 @@ public class DownloadOperation extends AbstractOperation<DownloadOperation> {
var scoped_dependencies = dependencies().get(scope);
if (scoped_dependencies != null) {
for (var dependency : scoped_dependencies) {
dependencies.addAll(new DependencyResolver(repositories(), dependency).getAllDependencies(transitiveScopes));
dependencies.addAll(new DependencyResolver(artifactRetriever(), repositories(), dependency).getAllDependencies(transitiveScopes));
}
}
}
@ -136,7 +137,7 @@ public class DownloadOperation extends AbstractOperation<DownloadOperation> {
additional_classifiers = classifiers.toArray(new String[0]);
}
dependencies.transferIntoDirectory(repositories(), destinationDirectory, additional_classifiers);
dependencies.transferIntoDirectory(artifactRetriever(), repositories(), destinationDirectory, additional_classifiers);
}
/**
@ -268,6 +269,18 @@ public class DownloadOperation extends AbstractOperation<DownloadOperation> {
return this;
}
/**
* Provides the artifact retriever to use.
*
* @param retriever the artifact retriever
* @return this operation instance
* @since 1.5.18
*/
public DownloadOperation artifactRetriever(ArtifactRetriever retriever) {
retriever_ = retriever;
return this;
}
/**
* Retrieves the repositories in which the dependencies will be resolved.
* <p>
@ -353,4 +366,17 @@ public class DownloadOperation extends AbstractOperation<DownloadOperation> {
public boolean downloadJavadoc() {
return downloadJavadoc_;
}
/**
* Returns the artifact retriever that is used.
*
* @return the artifact retriever
* @since 1.5.18
*/
public ArtifactRetriever artifactRetriever() {
if (retriever_ == null) {
return ArtifactRetriever.instance();
}
return retriever_;
}
}

View file

@ -94,5 +94,12 @@ public class HelpOperation {
System.err.print(build_help.getSummary());
System.err.println();
}
System.err.println("""
-?, -h, --help Shows this help message.
-D<name>=<value> Set a JVM system property.
-s, --stacktrace Print out the stacktrace for exceptions.
""");
}
}

View file

@ -30,6 +30,10 @@ public class PrecompileOperation extends AbstractOperation<PrecompileOperation>
* @since 1.5
*/
public void execute() {
if (templateTypes_.isEmpty()) {
return;
}
if (destinationDirectory() != null) {
destinationDirectory().mkdirs();
}

View file

@ -9,6 +9,7 @@ import rife.bld.Project;
import rife.bld.dependencies.*;
import rife.bld.dependencies.exceptions.DependencyException;
import rife.bld.operations.exceptions.OperationOptionException;
import rife.bld.operations.exceptions.SignException;
import rife.bld.operations.exceptions.UploadException;
import rife.bld.publish.*;
import rife.tools.FileUtils;
@ -37,6 +38,7 @@ import static rife.tools.StringUtils.encodeHexLower;
* @since 1.5.7
*/
public class PublishOperation extends AbstractOperation<PublishOperation> {
private ArtifactRetriever retriever_ = null;
private final HttpClient client_ = HttpClient.newHttpClient();
private ZonedDateTime moment_ = null;
@ -118,7 +120,7 @@ public class PublishOperation extends AbstractOperation<PublishOperation> {
// determine which build number to use
var snapshot_build_number = 1;
try {
var resolver = new DependencyResolver(List.of(repository), new Dependency(info().groupId(), info().artifactId(), info().version()));
var resolver = new DependencyResolver(artifactRetriever(), List.of(repository), new Dependency(info().groupId(), info().artifactId(), info().version()));
var snapshot_meta = resolver.getSnapshotMavenMetadata();
snapshot_build_number = snapshot_meta.getSnapshotBuildNumber() + 1;
} catch (DependencyException e) {
@ -201,7 +203,7 @@ public class PublishOperation extends AbstractOperation<PublishOperation> {
*/
protected void executePublishMetadata(Repository repository, ZonedDateTime moment) {
var current_versions = new ArrayList<VersionNumber>();
var resolver = new DependencyResolver(List.of(repository), new Dependency(info().groupId(), info().artifactId(), info().version()));
var resolver = new DependencyResolver(artifactRetriever(), List.of(repository), new Dependency(info().groupId(), info().artifactId(), info().version()));
try {
current_versions.addAll(resolver.getMavenMetadata().getVersions());
} catch (DependencyException e) {
@ -234,14 +236,6 @@ public class PublishOperation extends AbstractOperation<PublishOperation> {
protected void executePublishStringArtifact(Repository repository, String content, String path, boolean sign)
throws UploadException {
try {
executeTransferArtifact(repository, content, path);
if (!repository.isLocal()) {
executeTransferArtifact(repository, generateHash(content, "MD5"), path + ".md5");
executeTransferArtifact(repository, generateHash(content, "SHA-1"), path + ".sha1");
executeTransferArtifact(repository, generateHash(content, "SHA-256"), path + ".sha256");
executeTransferArtifact(repository, generateHash(content, "SHA-512"), path + ".sha512");
}
if (sign && info().signKey() != null) {
var tmp_file = File.createTempFile(path, "gpg");
FileUtils.writeString(content, tmp_file);
@ -251,7 +245,16 @@ public class PublishOperation extends AbstractOperation<PublishOperation> {
tmp_file.delete();
}
}
} catch (NoSuchAlgorithmException | IOException | FileUtilsErrorException e) {
if (!repository.isLocal()) {
executeTransferArtifact(repository, generateHash(content, "MD5"), path + ".md5");
executeTransferArtifact(repository, generateHash(content, "SHA-1"), path + ".sha1");
executeTransferArtifact(repository, generateHash(content, "SHA-256"), path + ".sha256");
executeTransferArtifact(repository, generateHash(content, "SHA-512"), path + ".sha512");
}
executeTransferArtifact(repository, content, path);
} catch (NoSuchAlgorithmException | IOException e) {
throw new UploadException(path, e);
}
}
@ -299,18 +302,20 @@ public class PublishOperation extends AbstractOperation<PublishOperation> {
digest_sha512.update(buffer, 0, return_value);
}
executeTransferArtifact(repository, file, path);
if (info().signKey() != null) {
executeTransferArtifact(repository, executeSignFile(file), path + ".asc");
}
if (!repository.isLocal()) {
executeTransferArtifact(repository, encodeHexLower(digest_md5.digest()), path + ".md5");
executeTransferArtifact(repository, encodeHexLower(digest_sha1.digest()), path + ".sha1");
executeTransferArtifact(repository, encodeHexLower(digest_sha256.digest()), path + ".sha256");
executeTransferArtifact(repository, encodeHexLower(digest_sha512.digest()), path + ".sha512");
}
if (info().signKey() != null) {
executeTransferArtifact(repository, executeSignFile(file), path + ".asc");
}
executeTransferArtifact(repository, file, path);
}
} catch (IOException | NoSuchAlgorithmException | FileUtilsErrorException e) {
} catch (IOException | NoSuchAlgorithmException e) {
throw new UploadException(path, e);
}
}
@ -340,6 +345,16 @@ public class PublishOperation extends AbstractOperation<PublishOperation> {
builder.redirectOutput(ProcessBuilder.Redirect.PIPE);
builder.redirectError(ProcessBuilder.Redirect.PIPE);
var process = builder.start();
try {
process.waitFor();
} catch (InterruptedException e) {
throw new SignException(file, e.getMessage());
}
if (process.exitValue() != 0) {
var error = FileUtils.readString(process.getErrorStream());
throw new SignException(file, error);
}
return FileUtils.readString(process.getInputStream());
}
@ -616,6 +631,18 @@ public class PublishOperation extends AbstractOperation<PublishOperation> {
return this;
}
/**
* Provides the artifact retriever to use.
*
* @param retriever the artifact retriever
* @return this operation instance
* @since 1.5.18
*/
public PublishOperation artifactRetriever(ArtifactRetriever retriever) {
retriever_ = retriever;
return this;
}
/**
* Retrieves the repositories to which will be published.
* <p>
@ -663,4 +690,17 @@ public class PublishOperation extends AbstractOperation<PublishOperation> {
public List<PublishArtifact> artifacts() {
return artifacts_;
}
/**
* Returns the artifact retriever that is used.
*
* @return the artifact retriever
* @since 1.5.18
*/
public ArtifactRetriever artifactRetriever() {
if (retriever_ == null) {
return ArtifactRetriever.instance();
}
return retriever_;
}
}

View file

@ -24,6 +24,7 @@ import static rife.bld.dependencies.Dependency.CLASSIFIER_SOURCES;
* @since 1.5
*/
public class PurgeOperation extends AbstractOperation<PurgeOperation> {
private ArtifactRetriever retriever_ = null;
private final List<Repository> repositories_ = new ArrayList<>();
private final DependencyScopes dependencies_ = new DependencyScopes();
private File libCompileDirectory_;
@ -67,13 +68,13 @@ public class PurgeOperation extends AbstractOperation<PurgeOperation> {
var provided_dependencies = dependencies().get(Scope.provided);
if (provided_dependencies != null) {
for (var dependency : provided_dependencies) {
excluded.addAll(new DependencyResolver(repositories(), dependency).getAllDependencies(Scope.compile));
excluded.addAll(new DependencyResolver(artifactRetriever(), repositories(), dependency).getAllDependencies(Scope.compile));
}
}
var compile_dependencies = dependencies().get(Scope.compile);
if (compile_dependencies != null) {
for (var dependency : compile_dependencies) {
excluded.addAll(new DependencyResolver(repositories(), dependency).getAllDependencies(Scope.compile));
excluded.addAll(new DependencyResolver(artifactRetriever(), repositories(), dependency).getAllDependencies(Scope.compile));
}
}
executePurgeScopedDependencies(libRuntimeDirectory(), new Scope[]{Scope.provided, Scope.compile, Scope.runtime}, new Scope[]{Scope.runtime}, excluded);
@ -115,7 +116,7 @@ public class PurgeOperation extends AbstractOperation<PurgeOperation> {
var scoped_dependencies = dependencies().get(scope);
if (scoped_dependencies != null) {
for (var dependency : scoped_dependencies) {
all_dependencies.addAll(new DependencyResolver(repositories(), dependency).getAllDependencies(transitiveScopes));
all_dependencies.addAll(new DependencyResolver(artifactRetriever(), repositories(), dependency).getAllDependencies(transitiveScopes));
}
}
}
@ -143,7 +144,7 @@ public class PurgeOperation extends AbstractOperation<PurgeOperation> {
}
private void addTransferLocations(HashSet<String> filenames, Dependency dependency) {
for (var location : new DependencyResolver(repositories(), dependency).getTransferLocations()) {
for (var location : new DependencyResolver(artifactRetriever(), repositories(), dependency).getTransferLocations()) {
filenames.add(location.substring(location.lastIndexOf("/") + 1));
}
}
@ -277,6 +278,18 @@ public class PurgeOperation extends AbstractOperation<PurgeOperation> {
return this;
}
/**
* Provides the artifact retriever to use.
*
* @param retriever the artifact retriever
* @return this operation instance
* @since 1.5.18
*/
public PurgeOperation artifactRetriever(ArtifactRetriever retriever) {
retriever_ = retriever;
return this;
}
/**
* Retrieves the repositories in which the dependencies will be resolved.
* <p>
@ -362,4 +375,17 @@ public class PurgeOperation extends AbstractOperation<PurgeOperation> {
public boolean preserveJavadoc() {
return preserveJavadoc_;
}
/**
* Returns the artifact retriever that is used.
*
* @return the artifact retriever
* @since 1.5.18
*/
public ArtifactRetriever artifactRetriever() {
if (retriever_ == null) {
return ArtifactRetriever.instance();
}
return retriever_;
}
}

View file

@ -48,7 +48,7 @@ public class RunOperation extends AbstractProcessOperation<RunOperation> {
.classpath(project.runClasspath())
.mainClass(project.mainClass());
if (project.usesRife2Agent()) {
operation.javaOptions().agentPath(project.getRife2AgentFile());
operation.javaOptions().javaAgent(project.getRife2AgentFile());
}
return operation;
}

View file

@ -64,7 +64,7 @@ public class TestOperation extends AbstractProcessOperation<TestOperation> {
.javaTool(project.javaTool())
.classpath(project.testClasspath());
if (project.usesRife2Agent()) {
operation.javaOptions().agentPath(project.getRife2AgentFile());
operation.javaOptions().javaAgent(project.getRife2AgentFile());
}
return operation;
}

View file

@ -17,6 +17,7 @@ import java.util.List;
* @since 1.5
*/
public class UpdatesOperation extends AbstractOperation<UpdatesOperation> {
private ArtifactRetriever retriever_ = null;
private final List<Repository> repositories_ = new ArrayList<>();
private final DependencyScopes dependencies_ = new DependencyScopes();
private DependencyScopes updates_ = new DependencyScopes();
@ -31,7 +32,7 @@ public class UpdatesOperation extends AbstractOperation<UpdatesOperation> {
for (var entry : dependencies_.entrySet()) {
var scope = entry.getKey();
for (var dependency : entry.getValue()) {
var latest = new DependencyResolver(repositories(), dependency).latestVersion();
var latest = new DependencyResolver(artifactRetriever(), repositories(), dependency).latestVersion();
if (latest.compareTo(dependency.version()) > 0) {
var latest_dependency = new Dependency(dependency.groupId(), dependency.artifactId(), latest,
dependency.classifier(), dependency.type());
@ -106,6 +107,18 @@ public class UpdatesOperation extends AbstractOperation<UpdatesOperation> {
return this;
}
/**
* Provides the artifact retriever to use.
*
* @param retriever the artifact retriever
* @return this operation instance
* @since 1.5.18
*/
public UpdatesOperation artifactRetriever(ArtifactRetriever retriever) {
retriever_ = retriever;
return this;
}
/**
* Retrieves the repositories in which the dependencies will be resolved.
* <p>
@ -140,4 +153,16 @@ public class UpdatesOperation extends AbstractOperation<UpdatesOperation> {
return updates_;
}
/**
* Returns the artifact retriever that is used.
*
* @return the artifact retriever
* @since 1.5.18
*/
public ArtifactRetriever artifactRetriever() {
if (retriever_ == null) {
return ArtifactRetriever.instance();
}
return retriever_;
}
}

View file

@ -1,345 +0,0 @@
/*
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
* Licensed under the Apache License, Version 2.0 (the "License")
*/
package rife.bld.operations;
import rife.bld.NamedFile;
import rife.tools.FileUtils;
import rife.tools.StringUtils;
import java.io.*;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import java.util.regex.Pattern;
/**
* Creates a zip archive of the provided sources and directories.
*
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
* @since 1.5.18
*/
public class ZipOperation extends AbstractOperation<ZipOperation> {
private final List<File> sourceDirectories_ = new ArrayList<>();
private final List<NamedFile> sourceFiles_ = new ArrayList<>();
private File destinationDirectory_;
private String destinationFileName_;
private final List<Pattern> included_ = new ArrayList<>();
private final List<Pattern> excluded_ = new ArrayList<>();
private final byte[] buffer_ = new byte[1024];
/**
* Performs the zip operation.
*
* @throws IOException when an exception occurred during the zip creation process
* @since 1.5.18
*/
public void execute()
throws IOException {
executeCreateDestinationDirectory();
executeCreateZipArchive();
if (!silent()) {
System.out.println("The zip archive was created at '" + destinationFile() + "'");
}
}
/**
* Part of the {@link #execute} operation, create the destination directory.
*
* @since 1.5.18
*/
protected void executeCreateDestinationDirectory() {
destinationDirectory().mkdirs();
}
/**
* Part of the {@link #execute} operation, create the zip archive.
*
* @since 1.5.18
*/
protected void executeCreateZipArchive()
throws IOException {
var out_file = new File(destinationDirectory(), destinationFileName());
try (var zip = new ZipOutputStream(new FileOutputStream(out_file))) {
for (var source_dir : sourceDirectories()) {
for (var file_name : FileUtils.getFileList(source_dir)) {
var file = new File(source_dir, file_name);
if (StringUtils.filter(file.getAbsolutePath(), included(), excluded(), false)) {
executeAddFileToZip(zip, new NamedFile(file_name, file));
}
}
}
for (var source_file : sourceFiles()) {
if (StringUtils.filter(source_file.file().getAbsolutePath(), included(), excluded(), false)) {
executeAddFileToZip(zip, source_file);
}
}
zip.flush();
}
}
/**
* Part of the {@link #execute} operation, add a single file to the zip archive.
*
* @since 1.5.18
*/
protected void executeAddFileToZip(ZipOutputStream zip, NamedFile file)
throws IOException {
var entry = new ZipEntry(file.name().replace('\\', '/'));
entry.setTime(file.file().lastModified());
zip.putNextEntry(entry);
try (var in = new BufferedInputStream(new FileInputStream(file.file()))) {
int count;
while ((count = in.read(buffer_)) != -1) {
zip.write(buffer_, 0, count);
}
zip.closeEntry();
}
}
/**
* Provides source directories that will be used for the zip archive creation.
*
* @param directories source directories
* @return this operation instance
* @since 1.5.18
*/
public ZipOperation sourceDirectories(File... directories) {
sourceDirectories_.addAll(List.of(directories));
return this;
}
/**
* Provides a list of source directories that will be used for the zip archive creation.
* <p>
* A copy will be created to allow this list to be independently modifiable.
*
* @param directories a list of source directories
* @return this operation instance
* @since 1.5.18
*/
public ZipOperation sourceDirectories(List<File> directories) {
sourceDirectories_.addAll(directories);
return this;
}
/**
* Provides source files that will be used for the zip archive creation.
*
* @param files source files
* @return this operation instance
* @since 1.5.18
*/
public ZipOperation sourceFiles(NamedFile... files) {
sourceFiles_.addAll(List.of(files));
return this;
}
/**
* Provides a list of source files that will be used for the zip archive creation.
* <p>
* A copy will be created to allow this list to be independently modifiable.
*
* @param files a list of source files
* @return this operation instance
* @since 1.5.18
*/
public ZipOperation sourceFiles(List<NamedFile> files) {
sourceFiles_.addAll(files);
return this;
}
/**
* Provides the destination directory in which the zip archive will be created.
*
* @param directory the zip destination directory
* @return this operation instance
* @since 1.5.18
*/
public ZipOperation destinationDirectory(File directory) {
destinationDirectory_ = directory;
return this;
}
/**
* Provides the destination file name that will be used for the zip archive creation.
*
* @param name the zip archive destination file name
* @return this operation instance
* @since 1.5.18
*/
public ZipOperation destinationFileName(String name) {
destinationFileName_ = name;
return this;
}
/**
* Provides regex patterns that will be found to determine which files
* will be included in the javadoc generation.
*
* @param included inclusion patterns
* @return this operation instance
* @since 1.5.18
*/
public ZipOperation included(String... included) {
included_.addAll(Arrays.stream(included).map(Pattern::compile).toList());
return this;
}
/**
* Provides patterns that will be found to determine which files
* will be included in the zip archive.
*
* @param included inclusion patterns
* @return this operation instance
* @since 1.5.18
*/
public ZipOperation included(Pattern... included) {
included_.addAll(List.of(included));
return this;
}
/**
* Provides a list of patterns that will be found to determine which files
* will be included in the zip archive.
* <p>
* A copy will be created to allow this list to be independently modifiable.
*
* @param included a list of inclusion patterns
* @return this operation instance
* @since 1.5.18
*/
public ZipOperation included(List<Pattern> included) {
included_.addAll(included);
return this;
}
/**
* Provides regex patterns that will be found to determine which files
* will be excluded from the javadoc generation.
*
* @param excluded exclusion patterns
* @return this operation instance
* @since 1.5.18
*/
public ZipOperation excluded(String... excluded) {
excluded_.addAll(Arrays.stream(excluded).map(Pattern::compile).toList());
return this;
}
/**
* Provides patterns that will be found to determine which files
* will be excluded from the zip archive.
*
* @param excluded exclusion patterns
* @return this operation instance
* @since 1.5.18
*/
public ZipOperation excluded(Pattern... excluded) {
excluded_.addAll(List.of(excluded));
return this;
}
/**
* Provides a list of patterns that will be found to determine which files
* will be excluded from the zip archive.
* <p>
* A copy will be created to allow this list to be independently modifiable.
*
* @param excluded a list of exclusion patterns
* @return this operation instance
* @since 1.5.18
*/
public ZipOperation excluded(List<Pattern> excluded) {
excluded_.addAll(excluded);
return this;
}
/**
* Retrieves the list of source directories that will be used for the
* zip archive creation.
* <p>
* This is a modifiable list that can be retrieved and changed.
*
* @return the zip archive's source directories
* @since 1.5.18
*/
public List<File> sourceDirectories() {
return sourceDirectories_;
}
/**
* Retrieves the list of source files that will be used for the
* zip archive creation.
* <p>
* This is a modifiable list that can be retrieved and changed.
*
* @return the zip archive's source files
* @since 1.5.18
*/
public List<NamedFile> sourceFiles() {
return sourceFiles_;
}
/**
* Retrieves the destination directory in which the zip archive will
* be created.
*
* @return the zip archive's destination directory
* @since 1.5.18
*/
public File destinationDirectory() {
return destinationDirectory_;
}
/**
* Retrieves the destination file name that will be used for the zip
* archive creation.
*
* @return the zip archive's destination file name
* @since 1.5.18
*/
public String destinationFileName() {
return destinationFileName_;
}
/**
* Retrieves the destination file where the zip archive will be created.
*
* @return the zip archive's destination file
* @since 1.5.18
*/
public File destinationFile() {
return new File(destinationDirectory(), destinationFileName());
}
/**
* Retrieves the list of patterns that will be evaluated to determine which files
* will be included in the zip archive.
* <p>
* This is a modifiable list that can be retrieved and changed.
*
* @return the zip's archive's inclusion patterns
* @since 1.5.18
*/
public List<Pattern> included() {
return included_;
}
/**
* Retrieves the list of patterns that will be evaluated to determine which files
* will be excluded the zip archive.
* <p>
* This is a modifiable list that can be retrieved and changed.
*
* @return the zip's archive's exclusion patterns
* @since 1.5.18
*/
public List<Pattern> excluded() {
return excluded_;
}
}

View file

@ -0,0 +1,37 @@
/*
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
* Licensed under the Apache License, Version 2.0 (the "License")
*/
package rife.bld.operations.exceptions;
import rife.tools.HttpUtils;
import java.io.File;
import java.io.Serial;
/**
* When thrown, indicates that something went wrong during signing
*
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
* @since 1.5.19
*/
public class SignException extends RuntimeException {
@Serial private static final long serialVersionUID = -7352738410475855871L;
private final File file_;
private final String reason_;
public SignException(File file, String reason) {
super("An error occurred while signing '" + file + "':\n" + reason);
file_ = file;
reason_ = reason;
}
public File getFile() {
return file_;
}
public String getReason() {
return reason_;
}
}

View file

@ -28,6 +28,7 @@ import static rife.bld.dependencies.Dependency.CLASSIFIER_SOURCES;
* @since 1.5.8
*/
public class WrapperExtensionResolver {
private final ArtifactRetriever retriever_ = ArtifactRetriever.cachingInstance();
private final File hashFile_;
private final String fingerPrintHash_;
private final File destinationDirectory_;
@ -115,7 +116,7 @@ public class WrapperExtensionResolver {
var dependencies = new DependencySet();
for (var d : dependencies_) {
if (d != null) {
dependencies.addAll(new DependencyResolver(repositories_, d).getAllDependencies(Scope.compile, Scope.runtime));
dependencies.addAll(new DependencyResolver(retriever_, repositories_, d).getAllDependencies(Scope.compile, Scope.runtime));
}
}
if (!dependencies.isEmpty()) {
@ -131,7 +132,7 @@ public class WrapperExtensionResolver {
additional_classifiers = classifiers.toArray(new String[0]);
}
dependencies.transferIntoDirectory(repositories_, destinationDirectory_, additional_classifiers);
dependencies.transferIntoDirectory(retriever_, repositories_, destinationDirectory_, additional_classifiers);
for (var dependency : dependencies) {
addTransferLocations(filenames, dependency);
@ -148,7 +149,7 @@ public class WrapperExtensionResolver {
}
private void addTransferLocations(HashSet<String> filenames, Dependency dependency) {
for (var location : new DependencyResolver(repositories_, dependency).getTransferLocations()) {
for (var location : new DependencyResolver(retriever_, repositories_, dependency).getTransferLocations()) {
filenames.add(location.substring(location.lastIndexOf("/") + 1));
}
}

View file

@ -20,7 +20,6 @@ import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import rife.tools.exceptions.FileUtilsErrorException;
public class HttpRequest implements Request {
private final HttpServletRequest request_;
@ -86,7 +85,7 @@ public class HttpRequest implements Request {
if (bodyAsBytes_ == null) {
try {
bodyAsBytes_ = FileUtils.readBytes(request_.getInputStream());
} catch (FileUtilsErrorException | IOException e) {
} catch (IOException e) {
throw new EngineException(e);
}
}

View file

@ -4,7 +4,6 @@
*/
package rife.template;
import rife.config.RifeConfig;
import rife.resources.ResourceFinderClasspath;
import rife.resources.ResourceFinderDirectories;
import rife.resources.ResourceFinderGroup;

View file

@ -32,6 +32,14 @@ public final class ArrayUtils {
// no-op
}
/**
* Determines the type of the array based on the object's class name.
*
* @param object the object to check if it is an array
* @return an ArrayType value indicating the type of the array, or NO_ARRAY if object is not an array
* @throws NullPointerException if object is null
* @since 1.0
*/
public static ArrayType getArrayType(Object object) {
var classname = object.getClass().getName();
@ -132,10 +140,25 @@ public final class ArrayUtils {
return result;
}
/**
* Creates a new string array containing formatted string values of the input object array.
*
* @param array the input object array, can be empty or {@code null}
* @return a new string array containing formatted string values of the input object array
* @since 1.0
*/
public static String[] createStringArray(Object[] array) {
return createStringArray(array, null);
}
/**
* Creates a new string array containing formatted string values of the input object array.
*
* @param array the input object array, can be empty or {@code null}
* @param constrainedProperty the optional {@link ConstrainedProperty} object containing constraints for formatting the property value
* @return a new string array containing formatted string values of the input object array
* @since 1.0
*/
public static String[] createStringArray(Object[] array, ConstrainedProperty constrainedProperty) {
if (null == array) {
return null;
@ -150,10 +173,25 @@ public final class ArrayUtils {
return new_array;
}
/**
* Creates a new string array containing formatted string values of the input boolean array.
*
* @param array the input boolean array, can be empty or {@code null}
* @return a new string array containing formatted string values of the input boolean array
* @since 1.0
*/
public static String[] createStringArray(boolean[] array) {
return createStringArray(array, null);
}
/**
* Creates a new string array containing formatted string values of the input boolean array.
*
* @param array the input boolean array, can be empty or {@code null}
* @param constrainedProperty the optional {@link ConstrainedProperty} object containing constraints for formatting the property value
* @return a new string array containing formatted string values of the input boolean array
* @since 1.0
*/
public static String[] createStringArray(boolean[] array, ConstrainedProperty constrainedProperty) {
if (null == array) {
return null;
@ -168,10 +206,25 @@ public final class ArrayUtils {
return new_array;
}
/**
* Creates a new string array containing formatted string values of the input byte array.
*
* @param array the input byte array, can be empty or {@code null}
* @return a new string array containing formatted string values of the input byte array
* @since 1.0
*/
public static String[] createStringArray(byte[] array) {
return createStringArray(array, null);
}
/**
* Creates a new string array containing formatted string values of the input byte array.
*
* @param array the input byte array, can be empty or {@code null}
* @param constrainedProperty the optional {@link ConstrainedProperty} object containing constraints for formatting the property value
* @return a new string array containing formatted string values of the input byte array
* @since 1.0
*/
public static String[] createStringArray(byte[] array, ConstrainedProperty constrainedProperty) {
if (null == array) {
return null;
@ -186,10 +239,25 @@ public final class ArrayUtils {
return new_array;
}
/**
* Creates a new string array containing formatted string values of the input char array.
*
* @param array the input char array, can be empty or {@code null}
* @return a new string array containing formatted string values of the input char array
* @since 1.0
*/
public static String[] createStringArray(char[] array) {
return createStringArray(array, null);
}
/**
* Creates a new string array containing formatted string values of the input char array.
*
* @param array the input char array, can be empty or {@code null}
* @param constrainedProperty the optional {@link ConstrainedProperty} object containing constraints for formatting the property value
* @return a new string array containing formatted string values of the input char array
* @since 1.0
*/
public static String[] createStringArray(char[] array, ConstrainedProperty constrainedProperty) {
if (null == array) {
return null;
@ -204,10 +272,25 @@ public final class ArrayUtils {
return new_array;
}
/**
* Creates a new string array containing formatted string values of the input short array.
*
* @param array the input short array, can be empty or {@code null}
* @return a new string array containing formatted string values of the input short array
* @since 1.0
*/
public static String[] createStringArray(short[] array) {
return createStringArray(array, null);
}
/**
* Creates a new string array containing formatted string values of the input short array.
*
* @param array the input short array, can be empty or {@code null}
* @param constrainedProperty the optional {@link ConstrainedProperty} object containing constraints for formatting the property value
* @return a new string array containing formatted string values of the input short array
* @since 1.0
*/
public static String[] createStringArray(short[] array, ConstrainedProperty constrainedProperty) {
if (null == array) {
return null;
@ -222,10 +305,25 @@ public final class ArrayUtils {
return new_array;
}
/**
* Creates a new string array containing formatted string values of the input int array.
*
* @param array the input int array, can be empty or {@code null}
* @return a new string array containing formatted string values of the input int array
* @since 1.0
*/
public static String[] createStringArray(int[] array) {
return createStringArray(array, null);
}
/**
* Creates a new string array containing formatted string values of the input int array.
*
* @param array the input int array, can be empty or {@code null}
* @param constrainedProperty the optional {@link ConstrainedProperty} object containing constraints for formatting the property value
* @return a new string array containing formatted string values of the input int array
* @since 1.0
*/
public static String[] createStringArray(int[] array, ConstrainedProperty constrainedProperty) {
if (null == array) {
return null;
@ -240,10 +338,25 @@ public final class ArrayUtils {
return new_array;
}
/**
* Creates a new string array containing formatted string values of the input long array.
*
* @param array the input long array, can be empty or {@code null}
* @return a new string array containing formatted string values of the input long array
* @since 1.0
*/
public static String[] createStringArray(long[] array) {
return createStringArray(array, null);
}
/**
* Creates a new string array containing formatted string values of the input long array.
*
* @param array the input long array, can be empty or {@code null}
* @param constrainedProperty the optional {@link ConstrainedProperty} object containing constraints for formatting the property value
* @return a new string array containing formatted string values of the input long array
* @since 1.0
*/
public static String[] createStringArray(long[] array, ConstrainedProperty constrainedProperty) {
if (null == array) {
return null;
@ -258,10 +371,25 @@ public final class ArrayUtils {
return new_array;
}
/**
* Creates a new string array containing formatted string values of the input float array.
*
* @param array the input float array, can be empty or {@code null}
* @return a new string array containing formatted string values of the input float array
* @since 1.0
*/
public static String[] createStringArray(float[] array) {
return createStringArray(array, null);
}
/**
* Creates a new string array containing formatted string values of the input float array.
*
* @param array the input float array, can be empty or {@code null}
* @param constrainedProperty the optional {@link ConstrainedProperty} object containing constraints for formatting the property value
* @return a new string array containing formatted string values of the input float array
* @since 1.0
*/
public static String[] createStringArray(float[] array, ConstrainedProperty constrainedProperty) {
if (null == array) {
return null;
@ -276,10 +404,25 @@ public final class ArrayUtils {
return new_array;
}
/**
* Creates a new string array containing formatted string values of the input double array.
*
* @param array the input double array, can be empty or {@code null}
* @return a new string array containing formatted string values of the input double array
* @since 1.0
*/
public static String[] createStringArray(double[] array) {
return createStringArray(array, null);
}
/**
* Creates a new string array containing formatted string values of the input double array.
*
* @param array the input double array, can be empty or {@code null}
* @param constrainedProperty the optional {@link ConstrainedProperty} object containing constraints for formatting the property value
* @return a new string array containing formatted string values of the input double array
* @since 1.0
*/
public static String[] createStringArray(double[] array, ConstrainedProperty constrainedProperty) {
if (null == array) {
return null;
@ -294,6 +437,14 @@ public final class ArrayUtils {
return new_array;
}
/**
* Creates an array of booleans from an array of objects.
*
* @param array the array to create a boolean array from
* @return a new boolean array that contains the converted values of the original array,
* or null if the original array is null
* @since 1.0
*/
public static boolean[] createBooleanArray(Object[] array) {
if (null == array) {
return null;
@ -312,6 +463,14 @@ public final class ArrayUtils {
return new_array;
}
/**
* Creates an array of bytes from an array of objects.
*
* @param array the array to create a byte array from
* @return a new byte array that contains the converted values of the original array,
* or null if the original array is null
* @since 1.0
*/
public static byte[] createByteArray(Object[] array) {
if (null == array) {
return null;
@ -334,6 +493,14 @@ public final class ArrayUtils {
return new_array;
}
/**
* Creates an array of chars from an array of objects.
*
* @param array the array to create a char array from
* @return a new char array that contains the converted values of the original array,
* or null if the original array is null
* @since 1.0
*/
public static char[] createCharArray(Object[] array) {
if (null == array) {
return null;
@ -356,6 +523,14 @@ public final class ArrayUtils {
return new_array;
}
/**
* Creates an array of shorts from an array of objects.
*
* @param array the array to create a short array from
* @return a new short array that contains the converted values of the original array,
* or null if the original array is null
* @since 1.0
*/
public static short[] createShortArray(Object[] array) {
if (null == array) {
return null;
@ -378,6 +553,14 @@ public final class ArrayUtils {
return new_array;
}
/**
* Creates an array of ints from an array of objects.
*
* @param array the array to create an int array from
* @return a new int array that contains the converted values of the original array,
* or null if the original array is null
* @since 1.0
*/
public static int[] createIntArray(Object[] array) {
if (null == array) {
return null;
@ -400,6 +583,14 @@ public final class ArrayUtils {
return new_array;
}
/**
* Creates an array of longs from an array of objects.
*
* @param array the array to create a long array from
* @return a new long array that contains the converted values of the original array,
* or null if the original array is null
* @since 1.0
*/
public static long[] createLongArray(Object[] array) {
if (null == array) {
return null;
@ -422,6 +613,14 @@ public final class ArrayUtils {
return new_array;
}
/**
* Creates an array of floats from an array of objects.
*
* @param array the array to create a float array from
* @return a new float array that contains the converted values of the original array,
* or null if the original array is null
* @since 1.0
*/
public static float[] createFloatArray(Object[] array) {
if (null == array) {
return null;
@ -444,6 +643,14 @@ public final class ArrayUtils {
return new_array;
}
/**
* Creates an array of doubles from an array of objects.
*
* @param array the array to create a double array from
* @return a new double array that contains the converted values of the original array,
* or null if the original array is null
* @since 1.0
*/
public static double[] createDoubleArray(Object[] array) {
if (null == array) {
return null;
@ -466,6 +673,14 @@ public final class ArrayUtils {
return new_array;
}
/**
* Joins two String arrays into a new array containing all elements from both arrays.
*
* @param first the first String array to join
* @param second the second String array to join
* @return a new String array with every element of both input arrays, or null if both inputs are null
* @since 1.0
*/
public static String[] join(String[] first, String[] second) {
if (null == first &&
null == second) {
@ -486,6 +701,15 @@ public final class ArrayUtils {
return new_array;
}
/**
* Joins a single String and a String array into a new array containing all elements.
*
* @param first the String array to which to append the second String
* @param second the String to append to the first array
* @return a new String array with every element of the input array and the appended String,
* or a new array containing only the second String if the input array is null
* @since 1.0
*/
public static String[] join(String[] first, String second) {
if (null == first &&
null == second) {
@ -506,6 +730,14 @@ public final class ArrayUtils {
return new_array;
}
/**
* Joins two byte arrays into a new array containing all elements from both arrays.
*
* @param first the first byte array to join
* @param second the second byte array to join
* @return a new byte array with every element of both input arrays, or null if both inputs are null
* @since 1.0
*/
public static byte[] join(byte[] first, byte[] second) {
if (null == first &&
null == second) {
@ -526,6 +758,15 @@ public final class ArrayUtils {
return new_array;
}
/**
* Joins a single byte and a byte array into a new array containing all elements.
*
* @param first the byte array to which to append the second byte
* @param second the byte to append to the first array
* @return a new byte array with every element of the input array and the appended byte,
* or a new array containing only the second byte if the input array is null
* @since 1.0
*/
public static byte[] join(byte[] first, byte second) {
if (null == first) {
return new byte[]{second};
@ -539,6 +780,14 @@ public final class ArrayUtils {
return new_array;
}
/**
* Joins two char arrays into a new array containing all elements from both arrays.
*
* @param first the first char array to join
* @param second the second char array to join
* @return a new char array with every element of both input arrays, or null if both inputs are null
* @since 1.0
*/
public static char[] join(char[] first, char[] second) {
if (null == first &&
null == second) {
@ -559,6 +808,15 @@ public final class ArrayUtils {
return new_array;
}
/**
* Joins a single char and a char array into a new array containing all elements.
*
* @param first the char array to which to append the second char
* @param second the char to append to the first array
* @return a new char array with every element of the input array and the appended char,
* or a new array containing only the second char if the input array is null
* @since 1.0
*/
public static char[] join(char[] first, char second) {
if (null == first) {
return new char[]{second};
@ -572,6 +830,14 @@ public final class ArrayUtils {
return new_array;
}
/**
* Joins two short arrays into a new array containing all elements from both arrays.
*
* @param first the first short array to join
* @param second the second short array to join
* @return a new short array with every element of both input arrays, or null if both inputs are null
* @since 1.0
*/
public static short[] join(short[] first, short[] second) {
if (null == first &&
null == second) {
@ -592,6 +858,15 @@ public final class ArrayUtils {
return new_array;
}
/**
* Joins a single short and a short array into a new array containing all elements.
*
* @param first the short array to which to append the second short
* @param second the short to append to the first array
* @return a new short array with every element of the input array and the appended short,
* or a new array containing only the second short if the input array is null
* @since 1.0
*/
public static short[] join(short[] first, short second) {
if (null == first) {
return new short[]{second};
@ -605,6 +880,14 @@ public final class ArrayUtils {
return new_array;
}
/**
* Joins two int arrays into a new array containing all elements from both arrays.
*
* @param first the first int array to join
* @param second the second int array to join
* @return a new int array with every element of both input arrays, or null if both inputs are null
* @since 1.0
*/
public static int[] join(int[] first, int[] second) {
if (null == first &&
null == second) {
@ -625,6 +908,15 @@ public final class ArrayUtils {
return new_array;
}
/**
* Joins a single int and an int array into a new array containing all elements.
*
* @param first the int array to which to append the second int
* @param second the int to append to the first array
* @return a new int array with every element of the input array and the appended int,
* or a new array containing only the second int if the input array is null
* @since 1.0
*/
public static int[] join(int[] first, int second) {
if (null == first) {
return new int[]{second};
@ -638,6 +930,14 @@ public final class ArrayUtils {
return new_array;
}
/**
* Joins two long arrays into a new array containing all elements from both arrays.
*
* @param first the first long array to join
* @param second the second long array to join
* @return a new long array with every element of both input arrays, or null if both inputs are null
* @since 1.0
*/
public static long[] join(long[] first, long[] second) {
if (null == first &&
null == second) {
@ -658,6 +958,15 @@ public final class ArrayUtils {
return new_array;
}
/**
* Joins a single long and a long array into a new array containing all elements.
*
* @param first the long array to which to append the second long
* @param second the long to append to the first array
* @return a new long array with every element of the input array and the appended long,
* or a new array containing only the second long if the input array is null
* @since 1.0
*/
public static long[] join(long[] first, long second) {
if (null == first) {
return new long[]{second};
@ -671,6 +980,14 @@ public final class ArrayUtils {
return new_array;
}
/**
* Joins two float arrays into a new array containing all elements from both arrays.
*
* @param first the first float array to join
* @param second the second float array to join
* @return a new float array with every element of both input arrays, or null if both inputs are null
* @since 1.0
*/
public static float[] join(float[] first, float[] second) {
if (null == first &&
null == second) {
@ -691,6 +1008,15 @@ public final class ArrayUtils {
return new_array;
}
/**
* Joins a single float and a float array into a new array containing all elements.
*
* @param first the float array to which to append the second float
* @param second the float to append to the first array
* @return a new float array with every element of the input array and the appended float,
* or a new array containing only the second float if the input array is null
* @since 1.0
*/
public static float[] join(float[] first, float second) {
if (null == first) {
return new float[]{second};
@ -704,6 +1030,14 @@ public final class ArrayUtils {
return new_array;
}
/**
* Joins two double arrays into a new array containing all elements from both arrays.
*
* @param first the first double array to join
* @param second the second double array to join
* @return a new double array with every element of both input arrays, or null if both inputs are null
* @since 1.0
*/
public static double[] join(double[] first, double[] second) {
if (null == first &&
null == second) {
@ -724,6 +1058,15 @@ public final class ArrayUtils {
return new_array;
}
/**
* Joins a single double and a double array into a new array containing all elements.
*
* @param first the double array to which to append the second double
* @param second the double to append to the first array
* @return a new double array with every element of the input array and the appended double,
* or a new array containing only the second double if the input array is null
* @since 1.0
*/
public static double[] join(double[] first, double second) {
if (null == first) {
return new double[]{second};
@ -737,6 +1080,14 @@ public final class ArrayUtils {
return new_array;
}
/**
* Joins two boolean arrays into a new array containing all elements from both arrays.
*
* @param first the first boolean array to join
* @param second the second boolean array to join
* @return a new boolean array with every element of both input arrays, or null if both inputs are null
* @since 1.0
*/
public static boolean[] join(boolean[] first, boolean[] second) {
if (null == first &&
null == second) {
@ -757,6 +1108,15 @@ public final class ArrayUtils {
return new_array;
}
/**
* Joins a single boolean and a boolean array into a new array containing all elements.
*
* @param first the boolean array to which to append the second boolean
* @param second the boolean to append to the first array
* @return a new boolean array with every element of the input array and the appended boolean,
* or a new array containing only the second boolean if the input array is null
* @since 1.0
*/
public static boolean[] join(boolean[] first, boolean second) {
if (null == first) {
return new boolean[]{second};

View file

@ -31,7 +31,18 @@ import java.text.ParseException;
import static rife.tools.BeanUtils.Accessors.*;
/**
* Utility class providing methods for working with Java beans.
*
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
* @since 1.0
*/
public final class BeanUtils {
/**
* Enum used to specify which accessors to consider when retrieving a bean's properties.
*
* @since 1.0
*/
public enum Accessors {
GETTERS,
SETTERS,
@ -42,6 +53,14 @@ public final class BeanUtils {
// no-op
}
/**
* Gets the BeanInfo for the specified beanClass.
*
* @param beanClass The Class to get the BeanInfo for.
* @return The BeanInfo for the specified beanClass.
* @throws BeanUtilsException If an error occurs while introspecting the bean.
* @since 1.0
*/
public static BeanInfo getBeanInfo(Class beanClass)
throws BeanUtilsException {
try {
@ -55,6 +74,17 @@ public final class BeanUtils {
return !method.getDeclaringClass().getPackageName().equals(MetaData.class.getPackageName());
}
/**
* Validates the specified property using the given parameters.
*
* @param accessor The Accessors to use when validating the property.
* @param property The PropertyDescriptor to validate.
* @param includedProperties The properties that should be included.
* @param excludedProperties The properties that should be excluded.
* @param prefix The prefix to apply to the property name.
* @return The name of the property if it's valid and should be included, null otherwise.
* @since 1.0
*/
private static String validateProperty(Accessors accessor, PropertyDescriptor property, Collection<String> includedProperties, Collection<String> excludedProperties, String prefix) {
String name = null;
@ -84,11 +114,34 @@ public final class BeanUtils {
return null;
}
/**
* Gets the names of the properties of the specified beanClass that have both read and write accessors.
*
* @param beanClass The Class to get the property names for.
* @param includedProperties The properties that should be included.
* @param excludedProperties The properties that should be excluded.
* @param prefix The prefix to apply to the property name.
* @return A set containing the names of the properties.
* @throws BeanUtilsException If an error occurs while introspecting the bean.
* @since 1.0
*/
public static Set<String> getPropertyNames(Class beanClass, String[] includedProperties, String[] excludedProperties, String prefix)
throws BeanUtilsException {
return getPropertyNames(GETTERS_SETTERS, beanClass, includedProperties, excludedProperties, prefix);
}
/**
* Gets the names of the properties of the specified beanClass that have the specified accessors.
*
* @param accessors The Accessors to use when retrieving the property names.
* @param beanClass The Class to get the property names for.
* @param includedProperties The properties that should be included.
* @param excludedProperties The properties that should be excluded.
* @param prefix The prefix to apply to the property name.
* @return A set containing the names of the properties.
* @throws BeanUtilsException If an error occurs while introspecting the bean.
* @since 1.0
*/
public static Set<String> getPropertyNames(Accessors accessors, Class beanClass, String[] includedProperties, String[] excludedProperties, String prefix)
throws BeanUtilsException {
if (null == beanClass) return Collections.emptySet();
@ -104,11 +157,36 @@ public final class BeanUtils {
return property_names;
}
/**
* Processes the properties of a given bean class with provided accessors, including and excluding properties,
* using the given prefix and calling the provided BeanPropertyProcessor with each valid property.
*
* @param beanClass The class of the bean to process.
* @param includedProperties An array of property names to include, or null if all properties should be included.
* @param excludedProperties An array of property names to exclude, or null if no properties should be excluded.
* @param prefix A string to prepend to each property name when processing.
* @param processor The BeanPropertyProcessor to call for each valid property.
* @throws BeanUtilsException If an error occurs while processing the properties, such as an invalid property name or an error invoking a property method.
* @since 1.0
*/
public static void processProperties(Class beanClass, String[] includedProperties, String[] excludedProperties, String prefix, BeanPropertyProcessor processor)
throws BeanUtilsException {
processProperties(GETTERS_SETTERS, beanClass, includedProperties, excludedProperties, prefix, processor);
}
/**
* Processes the properties of a given bean class with the provided accessors, including and excluding properties,
* using the given prefix and calling the provided BeanPropertyProcessor with each valid property.
*
* @param accessors The Accessors to use when processing properties (either GETTERS_SETTERS or FIELDS).
* @param beanClass The class of the bean to process.
* @param includedProperties An array of property names to include, or null if all properties should be included.
* @param excludedProperties An array of property names to exclude, or null if no properties should be excluded.
* @param prefix A string to prepend to each property name when processing.
* @param processor The BeanPropertyProcessor to call for each valid property.
* @throws BeanUtilsException If an error occurs while processing the properties, such as an invalid property name or an error invoking a property method.
* @since 1.0
*/
public static void processProperties(Accessors accessors, Class beanClass, String[] includedProperties, String[] excludedProperties, String prefix, BeanPropertyProcessor processor)
throws BeanUtilsException {
if (null == beanClass) return;
@ -154,11 +232,34 @@ public final class BeanUtils {
}
}
/**
* Processes the property values of a bean based on the provided parameters.
*
* @param bean the bean whose properties will be processed
* @param includedProperties an array of property names to include in the processing
* @param excludedProperties an array of property names to exclude from the processing
* @param prefix a prefix to add to all processed property names
* @param processor a processor function that will handle each property value
* @throws BeanUtilsException if an error occurs during property processing
* @since 1.0
*/
public static void processPropertyValues(final Object bean, String[] includedProperties, String[] excludedProperties, String prefix, final BeanPropertyValueProcessor processor)
throws BeanUtilsException {
processPropertyValues(GETTERS_SETTERS, bean, includedProperties, excludedProperties, prefix, processor);
}
/**
* Processes the property values of a bean based on the provided parameters, using the specified Accessors enum value.
*
* @param accessors the Accessors enum value to use for getting property values
* @param bean the bean whose properties will be processed
* @param includedProperties an array of property names to include in the processing
* @param excludedProperties an array of property names to exclude from the processing
* @param prefix a prefix to add to all processed property names
* @param processor a processor function that will handle each property value
* @throws BeanUtilsException if an error occurs during property processing
* @since 1.0
*/
public static void processPropertyValues(Accessors accessors, final Object bean, String[] includedProperties, String[] excludedProperties, String prefix, final BeanPropertyValueProcessor processor)
throws BeanUtilsException {
if (null == bean) return;
@ -187,11 +288,34 @@ public final class BeanUtils {
});
}
/**
* Counts the number of properties that match the given criteria for a specified bean class.
*
* @param beanClass the bean class to examine
* @param includedProperties an array of property names to include in the count
* @param excludedProperties an array of property names to exclude from the count
* @param prefix a prefix to add to all property names being counted
* @return the number of properties that match the given criteria
* @throws BeanUtilsException if an error occurs during property counting
* @since 1.0
*/
public static int countProperties(Class beanClass, String[] includedProperties, String[] excludedProperties, String prefix)
throws BeanUtilsException {
return countProperties(GETTERS_SETTERS, beanClass, includedProperties, excludedProperties, prefix);
}
/**
* Counts the number of properties that match the given criteria for a specified bean class, using the specified Accessors enum value.
*
* @param accessors the Accessors enum value to use for getting property values
* @param beanClass the bean class to examine
* @param includedProperties an array of property names to include in the count
* @param excludedProperties an array of property names to exclude from the count
* @param prefix a prefix to add to all property names being counted
* @return the number of properties that match the given criteria
* @throws BeanUtilsException if an error occurs during property counting
* @since 1.0
*/
public static int countProperties(Accessors accessors, Class beanClass, String[] includedProperties, String[] excludedProperties, String prefix)
throws BeanUtilsException {
if (null == beanClass) return 0;
@ -206,6 +330,16 @@ public final class BeanUtils {
return result[0];
}
/**
* Returns the value of the property with the given name from the specified bean.
* Throws an exception if the property does not exist or is not readable.
*
* @param bean The bean instance to retrieve the property value from.
* @param name The name of the property to retrieve.
* @return The value of the property.
* @throws BeanUtilsException If the bean is null, is a class and not an instance, or if the property does not exist or is not readable.
* @since 1.0
*/
public static Object getPropertyValue(Object bean, String name)
throws BeanUtilsException {
if (null == bean) throw new IllegalArgumentException("bean can't be null.");
@ -252,6 +386,16 @@ public final class BeanUtils {
throw new BeanUtilsException("The bean '" + bean_class + "' doesn't contain property '" + name + "'", bean_class);
}
/**
* Sets the value of the property with the given name in the specified bean.
* Throws an exception if the property does not exist or is not writable.
*
* @param bean The bean instance to set the property value on.
* @param name The name of the property to set.
* @param value The value to set the property to.
* @throws BeanUtilsException If the bean is null, is a class and not an instance, or if the property does not exist or is not writable.
* @since 1.0
*/
public static void setPropertyValue(Object bean, String name, Object value)
throws BeanUtilsException {
if (null == bean) throw new IllegalArgumentException("bean can't be null.");
@ -295,6 +439,16 @@ public final class BeanUtils {
throw new BeanUtilsException("The bean '" + bean_class + "' doesn't contain property '" + name + "'", bean_class);
}
/**
* Returns the class of a property of a bean, given its name.
*
* @param beanClass the class of the bean to search for the property
* @param name the name of the property to retrieve the type
* @return the class of the property
* @throws BeanUtilsException if the bean doesn't contain the specified property
* @throws IllegalArgumentException if the bean class or the name are null or empty
* @since 1.0
*/
public static Class getPropertyType(Class beanClass, String name)
throws BeanUtilsException {
if (null == beanClass) throw new IllegalArgumentException("beanClass can't be null.");
@ -326,11 +480,34 @@ public final class BeanUtils {
throw new BeanUtilsException("The bean '" + beanClass + "' doesn't contain property '" + name + "'", beanClass);
}
/**
* Returns the values of the properties of a bean as a map, given an optional prefix and inclusive/exclusive property filters.
*
* @param bean the bean to get the properties from
* @param includedProperties an array of the property names to include in the result map
* @param excludedProperties an array of the property names to exclude from the result map
* @param prefix an optional prefix to add to the property names in the result map
* @return a map containing the property values of the bean
* @throws BeanUtilsException if there was an error while retrieving the property values
* @since 1.0
*/
public static Map<String, Object> getPropertyValues(Object bean, String[] includedProperties, String[] excludedProperties, String prefix)
throws BeanUtilsException {
return getPropertyValues(GETTERS_SETTERS, bean, includedProperties, excludedProperties, prefix);
}
/**
* Returns the values of the properties of a bean as a map, given an optional prefix and inclusive/exclusive property filters and a custom set of accessors.
*
* @param accessors the Accessors object to use to retrieve the property values
* @param bean the bean to get the properties from
* @param includedProperties an array of the property names to include in the result map
* @param excludedProperties an array of the property names to exclude from the result map
* @param prefix an optional prefix to add to the property names in the result map
* @return a map containing the property values of the bean
* @throws BeanUtilsException if there was an error while retrieving the property values
* @since 1.0
*/
public static Map<String, Object> getPropertyValues(Accessors accessors, Object bean, String[] includedProperties, String[] excludedProperties, String prefix)
throws BeanUtilsException {
final var property_values = new LinkedHashMap<String, Object>();
@ -343,6 +520,14 @@ public final class BeanUtils {
return property_values;
}
/**
* Formats a property value based on the given format from a constrained property.
*
* @param propertyValue the value of the property to format
* @param constrainedProperty the constrained property that contains formatting info
* @return the formatted value of the property
* @since 1.0
*/
public static String formatPropertyValue(Object propertyValue, ConstrainedProperty constrainedProperty) {
if (propertyValue instanceof String) {
return (String) propertyValue;
@ -365,9 +550,9 @@ public final class BeanUtils {
throw new RuntimeException(e);
}
} else if (propertyValue instanceof Date ||
propertyValue instanceof Instant ||
propertyValue instanceof LocalDateTime ||
propertyValue instanceof LocalDate) {
propertyValue instanceof Instant ||
propertyValue instanceof LocalDateTime ||
propertyValue instanceof LocalDate) {
if (format == null) {
format = RifeConfig.tools().getConcisePreciseDateFormat();
}
@ -391,11 +576,36 @@ public final class BeanUtils {
return Convert.toString(propertyValue);
}
/**
* Returns a map of property names and their corresponding types for the given bean class,
* based on the included/excluded properties and prefix.
*
* @param beanClass the class for which to retrieve property types
* @param includedProperties the list of property names to include
* @param excludedProperties the list of property names to exclude
* @param prefix the prefix to use when filtering properties
* @return a map of property names and their corresponding types for the given bean class
* @throws BeanUtilsException if an error occurs during property retrieval
* @since 1.0
*/
public static Map<String, Class> getPropertyTypes(Class beanClass, String[] includedProperties, String[] excludedProperties, String prefix)
throws BeanUtilsException {
return getPropertyTypes(GETTERS_SETTERS, beanClass, includedProperties, excludedProperties, prefix);
}
/**
* Returns a map of property names and their corresponding types for the given bean class,
* based on the included/excluded properties and prefix, using the specified accessors.
*
* @param accessors the accessor type to use for property retrieval
* @param beanClass the class for which to retrieve property types
* @param includedProperties the list of property names to include
* @param excludedProperties the list of property names to exclude
* @param prefix the prefix to use when filtering properties
* @return a map of property names and their corresponding types for the given bean class
* @throws BeanUtilsException if an error occurs during property retrieval
* @since 1.0
*/
public static Map<String, Class> getPropertyTypes(Accessors accessors, Class beanClass, String[] includedProperties, String[] excludedProperties, String prefix)
throws BeanUtilsException {
if (null == beanClass) return Collections.emptyMap();
@ -541,7 +751,7 @@ public final class BeanUtils {
if (beanProperties.containsKey(name_upper)) {
if (null == emptyBean &&
(null == propertyValues ||
0 == propertyValues.length)) {
0 == propertyValues.length)) {
return;
}
@ -576,9 +786,9 @@ public final class BeanUtils {
// in case an empty template bean has been provided
if (emptyBean != null &&
(null == propertyValues ||
0 == propertyValues.length ||
null == propertyValues[0] ||
0 == propertyValues[0].length())) {
0 == propertyValues.length ||
null == propertyValues[0] ||
0 == propertyValues[0].length())) {
var read_method = property.getReadMethod();
var empty_value = read_method.invoke(emptyBean, (Object[]) null);
write_method.invoke(beanInstance, empty_value);
@ -795,11 +1005,11 @@ public final class BeanUtils {
}
write_method.invoke(beanInstance, new Object[]{parameter_values_typed});
} else if (Date.class.isAssignableFrom(component_type) ||
Instant.class.isAssignableFrom(component_type) ||
LocalDateTime.class.isAssignableFrom(component_type) ||
LocalDate.class.isAssignableFrom(component_type) ||
Time.class.isAssignableFrom(component_type) ||
LocalTime.class.isAssignableFrom(component_type)) {
Instant.class.isAssignableFrom(component_type) ||
LocalDateTime.class.isAssignableFrom(component_type) ||
LocalDate.class.isAssignableFrom(component_type) ||
Time.class.isAssignableFrom(component_type) ||
LocalTime.class.isAssignableFrom(component_type)) {
Format custom_format = null;
if (constrained_property != null &&
constrained_property.isFormatted()) {
@ -904,48 +1114,48 @@ public final class BeanUtils {
if (property_type == String.class) {
parameter_value_typed = propertyValues[0];
} else if (property_type == int.class ||
property_type == Integer.class) {
property_type == Integer.class) {
if (constrained_property != null && constrained_property.isFormatted()) {
parameter_value_typed = Convert.toInt(constrained_property.getFormat().parseObject(propertyValues[0]));
} else {
parameter_value_typed = Convert.toInt(propertyValues[0]);
}
} else if (property_type == char.class ||
property_type == Character.class) {
property_type == Character.class) {
parameter_value_typed = propertyValues[0].charAt(0);
} else if (property_type == boolean.class ||
property_type == Boolean.class) {
property_type == Boolean.class) {
parameter_value_typed = Convert.toBoolean(StringUtils.convertToBoolean(propertyValues[0]));
} else if (property_type == byte.class ||
property_type == Byte.class) {
property_type == Byte.class) {
if (constrained_property != null && constrained_property.isFormatted()) {
parameter_value_typed = Convert.toByte(constrained_property.getFormat().parseObject(propertyValues[0]));
} else {
parameter_value_typed = Convert.toByte(propertyValues[0]);
}
} else if (property_type == double.class ||
property_type == Double.class) {
property_type == Double.class) {
if (constrained_property != null && constrained_property.isFormatted()) {
parameter_value_typed = Convert.toDouble(constrained_property.getFormat().parseObject(propertyValues[0]));
} else {
parameter_value_typed = Convert.toDouble(propertyValues[0]);
}
} else if (property_type == float.class ||
property_type == Float.class) {
property_type == Float.class) {
if (constrained_property != null && constrained_property.isFormatted()) {
parameter_value_typed = Convert.toFloat(constrained_property.getFormat().parseObject(propertyValues[0]));
} else {
parameter_value_typed = Convert.toFloat(propertyValues[0]);
}
} else if (property_type == long.class ||
property_type == Long.class) {
property_type == Long.class) {
if (constrained_property != null && constrained_property.isFormatted()) {
parameter_value_typed = Convert.toLong(constrained_property.getFormat().parseObject(propertyValues[0]));
} else {
parameter_value_typed = Convert.toLong(propertyValues[0]);
}
} else if (property_type == short.class ||
property_type == Short.class) {
property_type == Short.class) {
if (constrained_property != null && constrained_property.isFormatted()) {
parameter_value_typed = Convert.toShort(constrained_property.getFormat().parseObject(propertyValues[0]));
} else {
@ -963,11 +1173,11 @@ public final class BeanUtils {
} else if (property_type == StringBuilder.class) {
parameter_value_typed = new StringBuilder(propertyValues[0]);
} else if (Date.class.isAssignableFrom(property_type) ||
Instant.class.isAssignableFrom(property_type) ||
LocalDateTime.class.isAssignableFrom(property_type) ||
LocalDate.class.isAssignableFrom(property_type) ||
Time.class.isAssignableFrom(property_type) ||
LocalTime.class.isAssignableFrom(property_type)) {
Instant.class.isAssignableFrom(property_type) ||
LocalDateTime.class.isAssignableFrom(property_type) ||
LocalDate.class.isAssignableFrom(property_type) ||
Time.class.isAssignableFrom(property_type) ||
LocalTime.class.isAssignableFrom(property_type)) {
Format custom_format = null;
if (constrained_property != null &&
constrained_property.isFormatted()) {

View file

@ -0,0 +1,27 @@
/*
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
* Licensed under the Apache License, Version 2.0 (the "License")
*/
package rife.tools;
import java.io.IOException;
/**
* Functional interface that captures an action to execute
* on a {@link DirBuilder} instance.
*
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
* @since 1.5.19
*/
@FunctionalInterface
public interface DirAction {
/**
* Executes the action on the specified {@code DirBuilder} instance.
*
* @param d The {@code DirBuilder} instance on which to execute the action.
* @throws IOException if an exception occurs while executing the action.
* @since 1.5.19
*/
void use(DirBuilder d)
throws IOException;
}

View file

@ -0,0 +1,168 @@
/*
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
* Licensed under the Apache License, Version 2.0 (the "License")
*/
package rife.tools;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.PosixFilePermission;
import java.util.Set;
import static rife.tools.FileUtils.permissionsFromMode;
/**
* Directory and file structure builder, using a fluent API and lambdas
* to convey the hierarchical structure of on the filesystem in code.
*
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
* @see DirAction
* @see FileAction
* @see FileBuilder
* @since 1.5.19
*/
public class DirBuilder {
private final Path dir;
/**
* Constructs a new {@code DirBuilder} instance with the specified directory.
*
* @param dir The directory to use for this DirBuilder.
* @since 1.5.19
*/
public DirBuilder(File dir) {
this.dir = dir.toPath();
}
/**
* Constructs a new {@code DirBuilder} instance with the specified path.
*
* @param path The path to use for this DirBuilder.
* @since 1.5.19
*/
public DirBuilder(Path path) {
this.dir = path;
}
/**
* Constructs a new {@code DirBuilder} instance with the specified path and executes an action on it.
*
* @param dir The directory to use for this {@code DirBuilder}.
* @param action The action to execute on the directory.
* @throws IOException if an error occurs while executing the action.
* @since 1.5.19
*/
public DirBuilder(File dir, DirAction action)
throws IOException {
this.dir = dir.toPath();
action.use(this);
}
/**
* Constructs a new {@code DirBuilder} instance with the specified directory and executes an action on it.
*
* @param path The path to use for this DirBuilder.
* @param action The action to execute on the directory.
* @throws IOException if an error occurs while executing the action.
* @since 1.5.19
*/
public DirBuilder(Path path, DirAction action)
throws IOException {
this.dir = path;
action.use(this);
}
/**
* Creates a new subdirectory with the specified name under the directory represented by this {@code DirBuilder}.
*
* @param dir The name of the subdirectory to create.
* @return this {@code DirBuilder} instance.
* @throws IOException if an error occurs while creating the subdirectory.
* @since 1.5.19
*/
public DirBuilder dir(String dir)
throws IOException {
Files.createDirectories(this.dir.resolve(dir));
return this;
}
/**
* Creates a new subdirectory with the specified name under the directory represented
* by this {@code DirBuilder} and executes the specified action on it.
*
* @param dir The name of the subdirectory to create.
* @param action The action to execute on the subdirectory.
* @return this {@code DirBuilder} instance.
* @throws IOException if an error occurs while creating the subdirectory or executing the action.
* @since 1.5.19
*/
public DirBuilder dir(String dir, DirAction action)
throws IOException {
var child = this.dir.resolve(dir);
Files.createDirectories(child);
new DirBuilder(child, action);
return this;
}
/**
* Specify a new file under the directory represented by this {@code DirBuilder}
* and executes the specified action on it.
*
* @param file The name of the file to create.
* @param action The action to execute on the file.
* @return this {@code DirBuilder} instance.
* @throws IOException if an error occurs while creating the file or executing the action.
* @since 1.5.19
*/
public DirBuilder file(String file, FileAction action)
throws IOException {
var child = this.dir.resolve(file);
action.use(new FileBuilder(child));
return this;
}
/**
* Deletes the directory represented by this {@code DirBuilder} and all of its contents.
*
* @return this {@code DirBuilder} instance.
* @throws IOException if an error occurs while deleting the directory.
* @since 1.5.19
*/
public DirBuilder delete()
throws IOException {
FileUtils.deleteDirectory(dir.toFile());
return this;
}
/**
* Sets the permissions for the directory represented by this {@code DirBuilder}
* using the specified Posix mode.
*
* @param mode The mode to use for setting the permissions.
* @return this {@code DirBuilder} instance.
* @throws IOException if an error occurs while setting the permissions.
* @since 1.5.19
*/
public DirBuilder perms(int mode)
throws IOException {
Files.setPosixFilePermissions(dir, permissionsFromMode(mode));
return this;
}
/**
* Sets the permissions for the directory represented by this {@code DirBuilder}
* using the specified permissions.
*
* @param permissions The permissions to use for setting the permissions.
* @return this {@code DirBuilder} instance.
* @throws IOException if an error occurs while setting the permissions.
* @since 1.5.19
*/
public DirBuilder perms(Set<PosixFilePermission> permissions)
throws IOException {
Files.setPosixFilePermissions(dir, permissions);
return this;
}
}

View file

@ -0,0 +1,27 @@
/*
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
* Licensed under the Apache License, Version 2.0 (the "License")
*/
package rife.tools;
import java.io.IOException;
/**
* Functional interface that captures an action to execute
* on a {@link FileBuilder} instance.
*
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
* @since 1.5.19
*/
@FunctionalInterface
public interface FileAction {
/**
* Executes the action on the specified {@code FileBuilder} instance.
*
* @param f The {@code FileBuilder} instance on which to execute the action.
* @throws IOException if an exception occurs while executing the action.
* @since 1.5.19
*/
void use(FileBuilder f)
throws IOException;
}

View file

@ -0,0 +1,185 @@
/*
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
* Licensed under the Apache License, Version 2.0 (the "License")
*/
package rife.tools;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.FileTime;
import java.nio.file.attribute.PosixFilePermission;
import java.util.Set;
import static rife.tools.FileUtils.permissionsFromMode;
/**
* Directory and file structure builder, using a fluent API and lambdas
* to convey the hierarchical structure of on the filesystem in code.
*
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
* @see DirAction
* @see DirBuilder
* @see FileAction
* @since 1.5.19
*/
public class FileBuilder {
private final Path file;
/**
* Constructs a new {@code FileBuilder} object with the specified file.
*
* @param file The file object to perform operations on
* @since 1.5.19
*/
public FileBuilder(File file) {
this.file = file.toPath();
}
/**
* Constructs a new {@code FileBuilder} object with the specified path.
*
* @param path The path to perform operations on
* @since 1.5.19
*/
public FileBuilder(Path path) {
this.file = path;
}
/**
* Constructs a new {@code FileBuilder} object with the specified file and performs an action on it.
*
* @param file The file object to perform operations on
* @param action The action to be performed on the file object
* @throws IOException if an error occurs while executing the action.
* @since 1.5.19
*/
public FileBuilder(File file, FileAction action)
throws IOException {
this.file = file.toPath();
action.use(this);
}
/**
* Constructs a new {@code FileBuilder} object with the specified path and performs an action on it.
*
* @param path The path to perform operations on
* @param action The action to be performed on the file object
* @throws IOException if an error occurs while executing the action.
* @since 1.5.19
*/
public FileBuilder(Path path, FileAction action)
throws IOException {
this.file = path;
action.use(this);
}
/**
* Copies the specified source file to the file of this {@code FileBuilder}.
*
* @param source The source file to be copied
* @return this {@code FileBuilder} object
* @throws IOException if an error occurs while copying the file.
* @since 1.5.19
*/
public FileBuilder copy(Path source)
throws IOException {
Files.copy(source, file);
return this;
}
/**
* Moves the specified source file to the file of this {@code FileBuilder}.
*
* @param source The source file to be moved
* @return this {@code FileBuilder} object
* @throws IOException if an error occurs while moving the file.
* @since 1.5.19
*/
public FileBuilder move(Path source)
throws IOException {
Files.move(source, file);
return this;
}
/**
* Writes the specified text to the file of this {@code FileBuilder}.
*
* @param text The text to be written to the file
* @return this {@code FileBuilder} object
* @throws IOException if an error occurs while moving the file.
* @since 1.5.19
*/
public FileBuilder write(String text)
throws IOException {
Files.writeString(file, text);
return this;
}
/**
* Touches the file of this {@code FileBuilder}.
* <p>
* If the file does not exist, it creates a new file.
* If the file exists, it updates the last access and last modification time of the file.
*
* @return this {@code FileBuilder} object
* @throws IOException if an error occurs while touching the file.
* @since 1.5.19
*/
public FileBuilder touch()
throws IOException {
if (!Files.exists(file)) {
Files.createFile(file);
} else {
var now = System.currentTimeMillis();
var time = FileTime.fromMillis(now);
Files.setAttribute(file, "lastAccessTime", time);
Files.setLastModifiedTime(file, time);
}
return this;
}
/**
* Deletes the file object of this {@code FileBuilder}.
*
* @return this {@code FileBuilder} object
* @throws IOException if an error occurs while touching the file.
* @since 1.5.19
*/
public FileBuilder delete()
throws IOException {
Files.deleteIfExists(file);
return this;
}
/**
* Sets the permissions for the file represented by this {@code FileBuilder}
* using the specified Posix mode.
*
* @param mode The mode to use for setting the permissions.
* @return this {@code FileBuilder} instance.
* @throws IOException if an error occurs while setting the permissions.
* @since 1.5.19
*/
public FileBuilder perms(int mode)
throws IOException {
Files.setPosixFilePermissions(file, permissionsFromMode(mode));
return this;
}
/**
* Sets the permissions for the file represented by this {@code FileBuilder}
* using the specified permissions.
*
* @param permissions The permissions to use for setting the permissions.
* @return this {@code FileBuilder} instance.
* @throws IOException if an error occurs while setting the permissions.
* @since 1.5.19
*/
public FileBuilder perms(Set<PosixFilePermission> permissions)
throws IOException {
Files.setPosixFilePermissions(file, permissions);
return this;
}
}

View file

@ -10,10 +10,8 @@ import java.io.*;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import java.nio.file.attribute.PosixFilePermission;
import java.util.*;
import java.util.function.Function;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@ -22,7 +20,14 @@ import java.util.zip.ZipFile;
import static java.nio.file.StandardCopyOption.COPY_ATTRIBUTES;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
import static java.nio.file.attribute.PosixFilePermission.*;
/**
* A utility class for handling files.
*
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
* @since 1.0
*/
public final class FileUtils {
public static final Pattern JAVA_FILE_PATTERN = Pattern.compile("^.*\\.java$");
public static final Pattern JAR_FILE_PATTERN = Pattern.compile("^.*\\.jar$");
@ -31,20 +36,57 @@ public final class FileUtils {
// no-op
}
public static List<String> getFileList(File file) {
return getFileList(file, null, null, true);
/**
* Returns a list of files in the given directory.
*
* @param dir The directory to search for files.
* @return A list of files in the given directory.
* @since 1.0
*/
public static List<String> getFileList(File dir) {
return getFileList(dir, null, null, true);
}
public static List<String> getFileList(File file, Pattern included, Pattern excluded) {
return getFileList(file, new Pattern[]{included}, new Pattern[]{excluded}, true);
/**
* Returns a list of files in the given directory that match the specified
* inclusion and exclusion patterns.
*
* @param dir The directory to search for files.
* @param included A pattern for files to include.
* @param excluded A pattern for files to exclude.
* @return A list of files in the given directory that match the specified inclusion and exclusion patterns.
* @since 1.0
*/
public static List<String> getFileList(File dir, Pattern included, Pattern excluded) {
return getFileList(dir, new Pattern[]{included}, new Pattern[]{excluded}, true);
}
public static List<String> getFileList(File file, List<Pattern> included, List<Pattern> excluded) {
return getFileList(file, included.toArray(new Pattern[0]), excluded.toArray(new Pattern[0]), true);
/**
* Returns a list of files in the given directory that match the specified
* inclusion and exclusion patterns.
*
* @param dir The directory to search for files.
* @param included A list of patterns for files to include.
* @param excluded A list of patterns for files to exclude.
* @return A list of files in the given directory that match the specified inclusion and exclusion patterns.
* @since 1.0
*/
public static List<String> getFileList(File dir, List<Pattern> included, List<Pattern> excluded) {
return getFileList(dir, included.toArray(new Pattern[0]), excluded.toArray(new Pattern[0]), true);
}
public static List<String> getFileList(File file, Pattern[] included, Pattern[] excluded) {
return getFileList(file, included, excluded, true);
/**
* Returns a list of files in the given directory that match the specified
* inclusion and exclusion patterns.
*
* @param dir The directory to search for files.
* @param included An array of patterns for files to include.
* @param excluded An array of patterns for files to exclude.
* @return A list of files in the given directory that match the specified inclusion and exclusion patterns.
* @since 1.0
*/
public static List<String> getFileList(File dir, Pattern[] included, Pattern[] excluded) {
return getFileList(dir, included, excluded, true);
}
private static List<String> getFileList(File file, Pattern[] included, Pattern[] excluded, boolean root) {
@ -134,6 +176,15 @@ public final class FileUtils {
return accepted;
}
/**
* Moves the source file to the target location.
*
* @param source the file to be moved.
* @param target the new location to move the file to.
* @throws FileUtilsErrorException if an error occurs while moving the file.
* @throws IllegalArgumentException if either the source or target is null.
* @since 1.0
*/
public static void moveFile(File source, File target)
throws FileUtilsErrorException {
if (null == source) throw new IllegalArgumentException("source can't be null.");
@ -146,11 +197,19 @@ public final class FileUtils {
// copy
copy(source, target);
// then delete sourcefile
// then delete source file
deleteFile(source);
}
/**
* Moves the source directory to the target location.
*
* @param source the directory to be moved.
* @param target the new location to move the directory to.
* @throws FileUtilsErrorException if an error occurs while moving the directory.
* @throws IllegalArgumentException if either the source or target is null.
* @since 1.0
*/
public static void moveDirectory(File source, File target)
throws FileUtilsErrorException {
if (null == source) throw new IllegalArgumentException("source can't be null.");
@ -181,9 +240,16 @@ public final class FileUtils {
// If we get here it means we're finished with this directory ... delete it.
deleteFile(source);
}
/**
* Deletes a directory and all its contents recursively.
*
* @param source the directory to be deleted.
* @throws FileUtilsErrorException if an error occurs while deleting the directory.
* @throws IllegalArgumentException if the source is null.
* @since 1.0
*/
public static void deleteDirectory(File source)
throws FileUtilsErrorException {
if (null == source) throw new IllegalArgumentException("source can't be null.");
@ -209,6 +275,15 @@ public final class FileUtils {
deleteFile(source);
}
/**
* Copy the contents of an InputStream to an OutputStream.
*
* @param inputStream the InputStream to copy from. Must not be null.
* @param outputStream the OutputStream to copy to. Must not be null.
* @throws FileUtilsErrorException if there is an error during the copying of streams.
* @throws IllegalArgumentException if either inputStream or outputStream is null.
* @since 1.0
*/
public static void copy(InputStream inputStream, OutputStream outputStream)
throws FileUtilsErrorException {
if (null == inputStream) throw new IllegalArgumentException("inputStream can't be null.");
@ -229,6 +304,15 @@ public final class FileUtils {
}
}
/**
* Copy the contents of an InputStream to a file.
*
* @param inputStream the InputStream to copy from; must not be null
* @param target the File to copy to; must not be null
* @throws FileUtilsErrorException if an error occurs while copying the stream to the file
* @throws IllegalArgumentException if inputStream or target is null
* @since 1.0
*/
public static void copy(InputStream inputStream, File target)
throws FileUtilsErrorException {
if (null == inputStream) throw new IllegalArgumentException("inputStream can't be null.");
@ -243,6 +327,15 @@ public final class FileUtils {
}
}
/**
* Copy the contents of a file to an OutputStream.
*
* @param source the File to copy from; must not be null
* @param outputStream the OutputStream to copy to; must not be null
* @throws FileUtilsErrorException if an error occurs while copying the file to the stream
* @throws IllegalArgumentException if source or outputStream is null
* @since 1.0
*/
public static void copy(File source, OutputStream outputStream)
throws FileUtilsErrorException {
if (null == source) throw new IllegalArgumentException("source can't be null.");
@ -257,6 +350,15 @@ public final class FileUtils {
}
}
/**
* Copy the contents of one file to another file.
*
* @param source the File to copy from; must not be null
* @param target the File to copy to; must not be null
* @throws FileUtilsErrorException if an error occurs while copying the source file to the target file
* @throws IllegalArgumentException if source or target is null
* @since 1.0
*/
public static void copy(File source, File target)
throws FileUtilsErrorException {
if (null == source) throw new IllegalArgumentException("source can't be null.");
@ -272,6 +374,15 @@ public final class FileUtils {
}
}
/**
* Copies all files and directories from the source directory to the target directory.
*
* @param sourceDir the directory to be copied from
* @param targetDir the directory to be copied to
* @throws FileUtilsErrorException if there's an error copying the files
* @throws IllegalArgumentException if either sourceDir or targetDir are null
* @since 1.0
*/
public static void copyDirectory(File sourceDir, File targetDir)
throws FileUtilsErrorException {
if (null == sourceDir) throw new IllegalArgumentException("sourceDir can't be null.");
@ -295,10 +406,18 @@ public final class FileUtils {
throw new FileUtilsErrorException("Error while copying directory '" + sourceDir.getAbsolutePath() + "' to directory '" + targetDir.getAbsolutePath() + "'.", e);
} catch (InnerClassException e) {
throw new FileUtilsErrorException(e.getMessage(), e.getCause());
}
}
/**
* Reads the complete contents of an input stream and returns it as a ByteArrayOutputStream object.
*
* @param inputStream the input stream to be read.
* @return a ByteArrayOutputStream object containing the complete contents of the specified input stream.
* @throws FileUtilsErrorException if there is an error while reading the input stream.
* @throws IllegalArgumentException if the inputStream parameter is null.
* @since 1.0
*/
public static ByteArrayOutputStream readStream(InputStream inputStream)
throws FileUtilsErrorException {
if (null == inputStream) throw new IllegalArgumentException("inputStream can't be null.");
@ -325,6 +444,15 @@ public final class FileUtils {
}
}
/**
* Reads the entire contents of an InputStream and returns it as a String, using UTF-8 encoding.
*
* @param inputStream The InputStream to read the contents from.
* @return A String containing the complete contents of the InputStream.
* @throws FileUtilsErrorException If there was an error while reading the InputStream.
* @throws IllegalArgumentException If the inputStream is null.
* @since 1.0
*/
public static String readString(InputStream inputStream)
throws FileUtilsErrorException {
if (null == inputStream) throw new IllegalArgumentException("inputStream can't be null.");
@ -332,6 +460,15 @@ public final class FileUtils {
return readStream(inputStream).toString(StandardCharsets.UTF_8);
}
/**
* Reads the entire contents of a Reader and returns it as a String.
*
* @param reader The Reader to read the contents from.
* @return A String containing the complete contents of the Reader.
* @throws FileUtilsErrorException If there was an error while reading the Reader.
* @throws IllegalArgumentException If the reader is null.
* @since 1.0
*/
public static String readString(Reader reader)
throws FileUtilsErrorException {
if (null == reader) throw new IllegalArgumentException("reader can't be null.");
@ -352,6 +489,16 @@ public final class FileUtils {
}
}
/**
* Reads the entire contents of an InputStream and returns it as a String, using the specified character encoding.
*
* @param inputStream The InputStream to read the contents from.
* @param encoding The name of the character encoding to use.
* @return A String containing the complete contents of the InputStream.
* @throws FileUtilsErrorException If there was an error while reading the InputStream.
* @throws IllegalArgumentException If the inputStream is null.
* @since 1.0
*/
public static String readString(InputStream inputStream, String encoding)
throws FileUtilsErrorException {
if (null == inputStream) throw new IllegalArgumentException("inputStream can't be null.");
@ -363,18 +510,16 @@ public final class FileUtils {
}
}
public static byte[] readBytes(InputStream inputStream)
throws FileUtilsErrorException {
if (null == inputStream) throw new IllegalArgumentException("inputStream can't be null.");
return readStream(inputStream).toByteArray();
}
public static String readString(URL source)
throws FileUtilsErrorException {
return readString(source, null);
}
/**
* Reads the content of the given URL into a string.
*
* @param source the URL to read from
* @param encoding the character encoding to use, or null to use the default encoding
* @return the content of the URL as a string
* @throws FileUtilsErrorException if an error occurs while reading the URL
* @throws IllegalArgumentException if source is null
* @since 1.0
*/
public static String readString(URL source, String encoding)
throws FileUtilsErrorException {
if (null == source) throw new IllegalArgumentException("source can't be null.");
@ -394,26 +539,30 @@ public final class FileUtils {
}
}
public static byte[] readBytes(URL source)
throws FileUtilsErrorException {
if (null == source) throw new IllegalArgumentException("source can't be null.");
try {
var connection = source.openConnection();
connection.setUseCaches(false);
try (var input_stream = connection.getInputStream()) {
return readBytes(input_stream);
}
} catch (IOException e) {
throw new FileUtilsErrorException("Error while reading url '" + source + ".", e);
}
}
/**
* Reads the content of the given file into a string using the default encoding.
*
* @param source the file to read from
* @return the content of the file as a string
* @throws FileUtilsErrorException if an error occurs while reading the file
* @throws IllegalArgumentException if source is null
* @since 1.0
*/
public static String readString(File source)
throws FileUtilsErrorException {
return readString(source, null);
}
/**
* Reads the content of the given file into a string using the specified character encoding.
*
* @param source the file to read from
* @param encoding the character encoding to use, or null to use the default encoding
* @return the content of the file as a string
* @throws FileUtilsErrorException if an error occurs while reading the file
* @throws IllegalArgumentException if source is null
* @since 1.0
*/
public static String readString(File source, String encoding)
throws FileUtilsErrorException {
if (null == source) throw new IllegalArgumentException("source can't be null.");
@ -431,6 +580,69 @@ public final class FileUtils {
}
}
/**
* Reads all characters from the {@link java.net.URL} and returns its contents as a string.
*
* @param source the URL to read from
* @return a string containing all the characters read from the URL
* @throws FileUtilsErrorException if an error occurs while reading the URL
* @throws IllegalArgumentException if source is null
* @since 1.0
*/
public static String readString(URL source)
throws FileUtilsErrorException {
return readString(source, null);
}
/**
* Reads all the bytes from the {@link java.io.InputStream}.
*
* @param inputStream the inputStream to read from
* @return a byte array containing all the bytes read from the input stream
* @throws FileUtilsErrorException if an error occurs while reading the input stream
* @throws IllegalArgumentException if inputStream is null
* @since 1.0
*/
public static byte[] readBytes(InputStream inputStream)
throws FileUtilsErrorException {
if (null == inputStream) throw new IllegalArgumentException("inputStream can't be null.");
return readStream(inputStream).toByteArray();
}
/**
* Reads all the bytes from the file denoted by the specified {@link java.io.File} object.
*
* @param source the file to read from
* @return a byte array containing all the bytes read from the file
* @throws FileUtilsErrorException if an error occurs while reading the file
* @throws IllegalArgumentException if source is null
* @since 1.0
*/
public static byte[] readBytes(URL source)
throws FileUtilsErrorException {
if (null == source) throw new IllegalArgumentException("source can't be null.");
try {
var connection = source.openConnection();
connection.setUseCaches(false);
try (var input_stream = connection.getInputStream()) {
return readBytes(input_stream);
}
} catch (IOException e) {
throw new FileUtilsErrorException("Error while reading url '" + source + ".", e);
}
}
/**
* Reads all the bytes from the {@link java.net.URL}.
*
* @param source the URL to read from
* @return a byte array containing all the bytes read from the URL
* @throws FileUtilsErrorException if an error occurs while reading the URL
* @throws IllegalArgumentException if source is null
* @since 1.0
*/
public static byte[] readBytes(File source)
throws FileUtilsErrorException {
if (null == source) throw new IllegalArgumentException("source can't be null.");
@ -444,6 +656,15 @@ public final class FileUtils {
}
}
/**
* Writes a byte array to a given file.
*
* @param content the byte array to be written
* @param destination the file to which the byte array should be written
* @throws FileUtilsErrorException if there is an error writing the byte array to the file
* @throws IllegalArgumentException if either the content or destination arguments are null
* @since 1.0
*/
public static void writeBytes(byte[] content, File destination)
throws FileUtilsErrorException {
if (null == content) throw new IllegalArgumentException("content can't be null.");
@ -459,6 +680,15 @@ public final class FileUtils {
}
}
/**
* Writes a string to a given file.
*
* @param content the string to be written
* @param destination the file to which the string should be written
* @throws FileUtilsErrorException if there is an error writing the string to the file
* @throws IllegalArgumentException if either the content or destination arguments are null
* @since 1.0
*/
public static void writeString(String content, File destination)
throws FileUtilsErrorException {
if (null == content) throw new IllegalArgumentException("content can't be null.");
@ -474,18 +704,39 @@ public final class FileUtils {
}
}
/**
* Deletes a given file.
*
* @param file The file to be deleted.
* @throws IllegalArgumentException if file is null.
* @since 1.0
*/
public static void deleteFile(File file) {
if (null == file) throw new IllegalArgumentException("file can't be null.");
file.delete();
}
/**
* Generates a unique filename.
*
* @return A unique filename string.
* @since 1.0
*/
public static String getUniqueFilename() {
var current_date = new Date();
return current_date.getTime() + "-" + (long) (1000000 * Math.random());
}
/**
* Unzips a file from the source location to a destination.
*
* @param source the file to unzip (must not be null)
* @param destination the location to unzip the file to (must not be null)
* @throws FileUtilsErrorException if an error occurs while unzipping the file or creating directories
* @since 1.0
*/
public static void unzipFile(File source, File destination)
throws FileUtilsErrorException {
if (null == source) throw new IllegalArgumentException("source can't be null.");
@ -580,27 +831,62 @@ public final class FileUtils {
}
}
/**
* Returns the base name of the specified file, without the extension.
*
* @param file The file whose base name is to be returned.
* @return The base name of the file.
* @since 1.0
*/
public static String getBaseName(File file) {
if (null == file) throw new IllegalArgumentException("file can't be null.");
return getBaseName(file.getName());
}
/**
* Returns the base name of the specified file name, without the extension.
*
* @param fileName The name of the file whose base name is to be returned.
* @return The base name of the file.
* @throws IllegalArgumentException if fileName is null.
* @since 1.0
*/
public static String getBaseName(String fileName) {
if (null == fileName) throw new IllegalArgumentException("fileName can't be null.");
String basename = null;
var basename = fileName;
var index = fileName.lastIndexOf('.');
if (index > 0 && index < fileName.length() - 1) {
if (index >= 0) {
basename = fileName.substring(0, index);
}
return basename;
}
/**
* Returns the extension of the specified {@link File}.
*
* @param file the file to get the extension from
* @return the extension of the given file or null if the file has no extension.
* @throws IllegalArgumentException if file is null
* @since 1.0
*/
public static String getExtension(File file) {
if (null == file) throw new IllegalArgumentException("file can't be null.");
return getExtension(file.getName());
}
/**
* Returns the extension of the specified file name.
*
* @param fileName the name of the file to get the extension from
* @return the extension of the given file name or null if the file name has no extension.
* @throws IllegalArgumentException if fileName is null
* @since 1.0
*/
public static String getExtension(String fileName) {
if (null == fileName) throw new IllegalArgumentException("fileName can't be null.");
@ -614,8 +900,18 @@ public final class FileUtils {
return ext;
}
/**
* Combines an arbitrary number of lists of files into a single list of absolute file paths.
*
* @param files zero or more lists of files to be combined
* @return the list of absolute file paths resulting from combining the input lists
* @since 1.5.2
*/
@SafeVarargs
public static List<String> combineToAbsolutePaths(List<File>... files) {
if (files == null) {
return Collections.emptyList();
}
var result = new ArrayList<String>();
for (var list : files) {
for (var file : list) {
@ -625,6 +921,14 @@ public final class FileUtils {
return result;
}
/**
* Generates a sorted directory listing of all files and subdirectories in the specified directory.
*
* @param directory The root directory to list.
* @return A string containing a sorted directory listing of all files and subdirectories in the specified directory.
* @throws IOException If an error occurs while listing the directory.
* @since 1.5.0
*/
public static String generateDirectoryListing(File directory)
throws IOException {
return Files.walk(Path.of(directory.getAbsolutePath()))
@ -634,31 +938,94 @@ public final class FileUtils {
.collect(Collectors.joining(System.lineSeparator()));
}
/**
* Joins a list of file paths into a single string with the file path separator.
*
* @param paths A list of file paths to join.
* @return A single string consisting of all the input file paths separated by the file path separator, or an empty string if input list is null.
* @since 1.5.2
*/
public static String joinPaths(List<String> paths) {
if (paths == null) {
return "";
}
return String.join(File.pathSeparator, paths);
}
/**
* Returns a list of Java files in the specified directory.
*
* @param directory The directory to search for Java files.
* @return A list of File objects pointing to the Java files in the directory, or an empty list if input directory is null.
* @since 1.5.10
*/
public static List<File> getJavaFileList(File directory) {
if (directory == null) {
return Collections.emptyList();
}
var dir_abs = directory.getAbsoluteFile();
return FileUtils.getFileList(dir_abs, JAVA_FILE_PATTERN, null)
.stream().map(file -> new File(dir_abs, file)).toList();
}
/**
* Transforms all files in the specified directory using the provided transformation function.
*
* @param directory The directory containing the files to be transformed.
* @param transformer The transformation function to be applied to each file.
* @throws FileUtilsErrorException If there is an error while reading or writing a file.
* @since 1.5.10
*/
public static void transformFiles(File directory, Function<String, String> transformer)
throws FileUtilsErrorException {
transformFiles(directory, null, (Pattern[]) null, transformer);
}
/**
* Transforms files in the specified directory that match the included pattern and do not match the excluded pattern
* using the provided transformation function.
*
* @param directory The directory containing the files to be transformed.
* @param included A regex pattern specifying which files to include.
* @param excluded A regex pattern specifying which files to exclude.
* @param transformer The transformation function to be applied to each file.
* @throws FileUtilsErrorException If there is an error while reading or writing a file.
* @since 1.5.10
*/
public static void transformFiles(File directory, Pattern included, Pattern excluded, Function<String, String> transformer)
throws FileUtilsErrorException {
transformFiles(directory, new Pattern[]{included}, new Pattern[]{excluded}, transformer);
}
/**
* Transforms files in the specified directory that match at least one of the included patterns and do not match any
* of the excluded patterns using the provided transformation function.
*
* @param directory The directory containing the files to be transformed.
* @param included A list of regex patterns specifying which files to include.
* @param excluded A list of regex patterns specifying which files to exclude.
* @param transformer The transformation function to be applied to each file.
* @throws FileUtilsErrorException If there is an error while reading or writing a file.
* @since 1.5.10
*/
public static void transformFiles(File directory, List<Pattern> included, List<Pattern> excluded, Function<String, String> transformer)
throws FileUtilsErrorException {
transformFiles(directory, included.toArray(new Pattern[0]), excluded.toArray(new Pattern[0]), transformer);
}
/**
* Transforms files in the specified directory that match at least one of the included patterns and do not match any
* of the excluded patterns using the provided transformation function.
*
* @param directory The directory containing the files to be transformed.
* @param included An array of regex patterns specifying which files to include.
* @param excluded An array of regex patterns specifying which files to exclude.
* @param transformer The transformation function to be applied to each file.
* @throws FileUtilsErrorException If there is an error while reading or writing a file.
* @since 1.5.10
*/
public static void transformFiles(File directory, Pattern[] included, Pattern[] excluded, Function<String, String> transformer)
throws FileUtilsErrorException {
for (var entry : FileUtils.getFileList(directory, included, excluded)) {
@ -670,4 +1037,61 @@ public final class FileUtils {
}
}
}
private static final int S_IRUSR = 0000400;
private static final int S_IWUSR = 0000200;
private static final int S_IXUSR = 0000100;
private static final int S_IRGRP = 0000040;
private static final int S_IWGRP = 0000020;
private static final int S_IXGRP = 0000010;
private static final int S_IROTH = 0000004;
private static final int S_IWOTH = 0000002;
private static final int S_IXOTH = 0000001;
/**
* Creates a new set of {@code PosixFilePermission} based on the given Posix mode.
* <p>
* Standard Posix permissions can be provided on octal numbers, for instance {@code 0755} and {@code 0644}.
*
* @param mode an integer containing permissions for the owner, group and others
* @return a Set of PosixFilePermission
* @since 1.5.19
*/
public static Set<PosixFilePermission> permissionsFromMode(int mode) {
var perms = new HashSet<PosixFilePermission>();
if ((mode & S_IRUSR) != 0) perms.add(OWNER_READ);
if ((mode & S_IWUSR) != 0) perms.add(OWNER_WRITE);
if ((mode & S_IXUSR) != 0) perms.add(OWNER_EXECUTE);
if ((mode & S_IRGRP) != 0) perms.add(GROUP_READ);
if ((mode & S_IWGRP) != 0) perms.add(GROUP_WRITE);
if ((mode & S_IXGRP) != 0) perms.add(GROUP_EXECUTE);
if ((mode & S_IROTH) != 0) perms.add(OTHERS_READ);
if ((mode & S_IWOTH) != 0) perms.add(OTHERS_WRITE);
if ((mode & S_IXOTH) != 0) perms.add(OTHERS_EXECUTE);
return perms;
}
/**
* Constructs a new {@code Path} instance using the specified file and additional path elements.
*
* @param file The file to use as the starting point for the Path.
* @param paths Additional path elements to add to the Path.
* @return A new Path instance.
* @since 1.5.19
*/
public static Path path(File file, String... paths) {
return Path.of(file.getAbsolutePath(), paths);
}
/**
* Constructs a new {@code Path} instance using the specified file and additional path elements.
*
* @param path The path to use as the starting point for the Path.
* @param paths Additional path elements to add to the Path.
* @return A new Path instance.
* @since 1.5.19
*/
public static Path path(Path path, String... paths) {
return Path.of(path.toAbsolutePath().toString(), paths);
}
}

View file

@ -4,11 +4,12 @@
*/
package rife.tools.exceptions;
import java.io.IOException;
import java.io.Serial;
public class FileUtilsErrorException extends Exception {
public class FileUtilsErrorException extends IOException {
@Serial
private static final long serialVersionUID = 5563842867757961501L;
private static final long serialVersionUID = -2727442872243338966L;
public FileUtilsErrorException(String message) {
super(message);

View file

@ -1 +1 @@
1.5.18-SNAPSHOT
1.5.19

View file

@ -23,7 +23,7 @@ import static rife.bld.dependencies.Scope.runtime;
public class TestDependencyResolver {
@Test
void testInstantiation() {
var resolver = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.uwyn.rife2", "rife2", new VersionNumber(1, 4, 0)));
var resolver = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.uwyn.rife2", "rife2", new VersionNumber(1, 4, 0)));
assertNotNull(resolver);
assertTrue(resolver.repositories().contains(MAVEN_CENTRAL));
assertTrue(resolver.repositories().contains(SONATYPE_SNAPSHOTS));
@ -32,31 +32,31 @@ public class TestDependencyResolver {
@Test
void testNotFound() {
var resolver = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.org.unknown", "voidthing"));
var resolver = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.org.unknown", "voidthing"));
assertFalse(resolver.exists());
}
@Test
void testCheckExistence() {
var resolver = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.uwyn.rife2", "rife2"));
var resolver = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.uwyn.rife2", "rife2"));
assertTrue(resolver.exists());
}
@Test
void testCheckExistenceVersion() {
var resolver = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.uwyn.rife2", "rife2", new VersionNumber(1, 4, 0)));
var resolver = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.uwyn.rife2", "rife2", new VersionNumber(1, 4, 0)));
assertTrue(resolver.exists());
}
@Test
void testCheckExistenceMissingVersion() {
var resolver = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.uwyn.rife2", "rife2", new VersionNumber(1, 3, 9)));
var resolver = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.uwyn.rife2", "rife2", new VersionNumber(1, 3, 9)));
assertFalse(resolver.exists());
}
@Test
void testListVersions() {
var resolver1 = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.uwyn.rife2", "rife2"));
var resolver1 = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.uwyn.rife2", "rife2"));
var versions1 = resolver1.listVersions();
assertNotNull(versions1);
assertFalse(versions1.isEmpty());
@ -64,7 +64,7 @@ public class TestDependencyResolver {
assertTrue(versions1.contains(new VersionNumber(1, 0, 0)));
assertTrue(versions1.contains(new VersionNumber(1, 2, 1)));
var resolver2 = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("org.eclipse.jetty", "jetty-server"));
var resolver2 = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("org.eclipse.jetty", "jetty-server"));
var versions2 = resolver2.listVersions();
assertNotNull(versions2);
assertFalse(versions2.isEmpty());
@ -75,7 +75,7 @@ public class TestDependencyResolver {
@Test
void testGetLatestVersion() {
var resolver = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.uwyn.rife2", "rife2"));
var resolver = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.uwyn.rife2", "rife2"));
var version = resolver.latestVersion();
assertNotNull(version);
assertTrue(version.compareTo(new VersionNumber(1, 4)) >= 0);
@ -83,7 +83,7 @@ public class TestDependencyResolver {
@Test
void testGetReleaseVersion() {
var resolver = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.uwyn.rife2", "rife2"));
var resolver = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.uwyn.rife2", "rife2"));
var version = resolver.releaseVersion();
assertNotNull(version);
assertTrue(version.compareTo(new VersionNumber(1, 4)) >= 0);
@ -91,7 +91,7 @@ public class TestDependencyResolver {
@Test
void testMetadata() {
var resolver = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.uwyn.rife2", "rife2", new VersionNumber(1, 4, 0)));
var resolver = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.uwyn.rife2", "rife2", new VersionNumber(1, 4, 0)));
var metadata = resolver.getMavenMetadata();
assertNotNull(metadata);
assertTrue(metadata.getLatest().compareTo(resolver.dependency().version()) > 0);
@ -100,7 +100,7 @@ public class TestDependencyResolver {
@Test
void testSnapshotMetadata() {
var resolver = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.uwyn.rife2", "rife2", new VersionNumber(1, 4, 0, "SNAPSHOT")));
var resolver = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.uwyn.rife2", "rife2", new VersionNumber(1, 4, 0, "SNAPSHOT")));
var metadata = resolver.getSnapshotMavenMetadata();
assertNotNull(metadata);
assertEquals("20230303.130437", metadata.getSnapshotTimestamp());
@ -109,7 +109,7 @@ public class TestDependencyResolver {
@Test
void testGetCompileDependenciesRIFE2() {
var resolver = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.uwyn.rife2", "rife2"));
var resolver = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.uwyn.rife2", "rife2"));
var dependencies = resolver.getDirectDependencies(compile);
assertNotNull(dependencies);
assertEquals(0, dependencies.size());
@ -117,7 +117,7 @@ public class TestDependencyResolver {
@Test
void testGetCompileDependenciesRIFE2Snapshot() {
var resolver = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.uwyn.rife2", "rife2", new VersionNumber(1, 4, 0, "SNAPSHOT")));
var resolver = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.uwyn.rife2", "rife2", new VersionNumber(1, 4, 0, "SNAPSHOT")));
var dependencies = resolver.getDirectDependencies(compile);
assertNotNull(dependencies);
assertEquals(0, dependencies.size());
@ -125,7 +125,7 @@ public class TestDependencyResolver {
@Test
void testGetCompileDependenciesJetty() {
var resolver = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("org.eclipse.jetty", "jetty-server", new VersionNumber(11, 0, 14)));
var resolver = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("org.eclipse.jetty", "jetty-server", new VersionNumber(11, 0, 14)));
var dependencies = resolver.getDirectDependencies(compile);
assertNotNull(dependencies);
assertEquals(4, dependencies.size());
@ -138,7 +138,7 @@ public class TestDependencyResolver {
@Test
void testGetCompileRuntimeDependenciesJunit() {
var resolver = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("org.junit.jupiter", "junit-jupiter", new VersionNumber(5, 9, 2)));
var resolver = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("org.junit.jupiter", "junit-jupiter", new VersionNumber(5, 9, 2)));
var dependencies_compile = resolver.getDirectDependencies(compile, runtime);
assertNotNull(dependencies_compile);
assertEquals(3, dependencies_compile.size());
@ -150,7 +150,7 @@ public class TestDependencyResolver {
@Test
void testGetCompileDependenciesSpringBoot() {
var resolver = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("org.springframework.boot", "spring-boot-starter", new VersionNumber(3, 0, 4)));
var resolver = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("org.springframework.boot", "spring-boot-starter", new VersionNumber(3, 0, 4)));
var dependencies = resolver.getDirectDependencies(compile);
assertNotNull(dependencies);
assertEquals(6, dependencies.size());
@ -165,7 +165,7 @@ public class TestDependencyResolver {
@Test
void testGetCompileDependenciesMaven() {
var resolver = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("org.apache.maven", "maven-core", new VersionNumber(3, 9, 0)));
var resolver = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("org.apache.maven", "maven-core", new VersionNumber(3, 9, 0)));
var dependencies = resolver.getDirectDependencies(compile);
assertNotNull(dependencies);
assertEquals(26, dependencies.size());
@ -200,7 +200,7 @@ public class TestDependencyResolver {
@Test
void testGetCompileDependenciesPlay() {
var resolver = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.typesafe.play", "play_2.13", new VersionNumber(2, 8, 19)));
var resolver = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.typesafe.play", "play_2.13", new VersionNumber(2, 8, 19)));
var dependencies = resolver.getDirectDependencies(compile);
assertNotNull(dependencies);
assertEquals(25, dependencies.size());
@ -234,7 +234,7 @@ public class TestDependencyResolver {
@Test
void testGetCompileDependenciesVaadin() {
var resolver = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.vaadin", "vaadin", new VersionNumber(23, 3, 7)));
var resolver = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.vaadin", "vaadin", new VersionNumber(23, 3, 7)));
var dependencies = resolver.getDirectDependencies(compile);
assertNotNull(dependencies);
assertEquals(9, dependencies.size());
@ -252,7 +252,7 @@ public class TestDependencyResolver {
@Test
void testGetCompileTransitiveDependenciesRIFE2() {
var resolver = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.uwyn.rife2", "rife2"));
var resolver = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.uwyn.rife2", "rife2"));
var dependencies = resolver.getAllDependencies(compile);
assertNotNull(dependencies);
assertEquals(1, dependencies.size());
@ -262,7 +262,7 @@ public class TestDependencyResolver {
@Test
void testGetCompileTransitiveDependenciesRIFE2Snapshot() {
var resolver = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.uwyn.rife2", "rife2", new VersionNumber(1, 4, 0, "SNAPSHOT")));
var resolver = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.uwyn.rife2", "rife2", new VersionNumber(1, 4, 0, "SNAPSHOT")));
var dependencies = resolver.getAllDependencies(compile);
assertNotNull(dependencies);
assertEquals(1, dependencies.size());
@ -272,7 +272,7 @@ public class TestDependencyResolver {
@Test
void testGetCompileTransitiveDependenciesJetty() {
var resolver = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("org.eclipse.jetty", "jetty-server", new VersionNumber(11, 0, 14)));
var resolver = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("org.eclipse.jetty", "jetty-server", new VersionNumber(11, 0, 14)));
var dependencies = resolver.getAllDependencies(compile);
assertNotNull(dependencies);
assertEquals(6, dependencies.size());
@ -287,7 +287,7 @@ public class TestDependencyResolver {
@Test
void testGetCompileTransitiveDependenciesJettyExclusion() {
var resolver = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS),
var resolver = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS),
new Dependency("org.eclipse.jetty", "jetty-server", new VersionNumber(11, 0, 14))
.exclude("org.slf4j", "slf4j-api"));
var dependencies = resolver.getAllDependencies(compile);
@ -303,7 +303,7 @@ public class TestDependencyResolver {
@Test
void testGetCompileTransitiveDependenciesJettyFullGroupExclusion() {
var resolver = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS),
var resolver = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS),
new Dependency("org.eclipse.jetty", "jetty-server", new VersionNumber(11, 0, 14))
.exclude("org.eclipse.jetty", "*"));
var dependencies = resolver.getAllDependencies(compile);
@ -317,7 +317,7 @@ public class TestDependencyResolver {
@Test
void testGetCompileTransitiveDependenciesJettyFullArtifactExclusion() {
var resolver = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS),
var resolver = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS),
new Dependency("org.eclipse.jetty", "jetty-server", new VersionNumber(11, 0, 14))
.exclude("*", "jetty-http")
.exclude("*", "slf4j-api"));
@ -333,7 +333,7 @@ public class TestDependencyResolver {
@Test
void testGetCompileTransitiveDependenciesJettyFullExclusion() {
var resolver = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS),
var resolver = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS),
new Dependency("org.eclipse.jetty", "jetty-server", new VersionNumber(11, 0, 14))
.exclude("*", "*"));
var dependencies = resolver.getAllDependencies(compile);
@ -345,8 +345,8 @@ public class TestDependencyResolver {
@Test
void testGetCompileTransitiveDependenciesJettyAndSlfj() {
var dependencies = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("org.eclipse.jetty", "jetty-server", new VersionNumber(11, 0, 14))).getAllDependencies(compile);
var dependencies2 = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("org.slf4j", "slf4j-simple", new VersionNumber(2, 0, 6))).getAllDependencies(compile, runtime);
var dependencies = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("org.eclipse.jetty", "jetty-server", new VersionNumber(11, 0, 14))).getAllDependencies(compile);
var dependencies2 = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("org.slf4j", "slf4j-simple", new VersionNumber(2, 0, 6))).getAllDependencies(compile, runtime);
assertNotNull(dependencies);
assertNotNull(dependencies2);
assertEquals(6, dependencies.size());
@ -365,7 +365,7 @@ public class TestDependencyResolver {
@Test
void testGetCompileRuntimeTransitiveDependenciesJunit() {
var resolver = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("org.junit.jupiter", "junit-jupiter", new VersionNumber(5, 9, 2)));
var resolver = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("org.junit.jupiter", "junit-jupiter", new VersionNumber(5, 9, 2)));
var dependencies_compile = resolver.getAllDependencies(compile, runtime);
assertNotNull(dependencies_compile);
assertEquals(8, dependencies_compile.size());
@ -388,7 +388,7 @@ public class TestDependencyResolver {
@Test
void testGetCompileTransitiveDependenciesSpringBoot() {
var resolver = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("org.springframework.boot", "spring-boot-starter", new VersionNumber(3, 0, 4)));
var resolver = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("org.springframework.boot", "spring-boot-starter", new VersionNumber(3, 0, 4)));
var dependencies = resolver.getAllDependencies(compile);
assertNotNull(dependencies);
assertEquals(18, dependencies.size());
@ -415,7 +415,7 @@ public class TestDependencyResolver {
@Test
void testGetCompileTransitiveDependenciesMaven() {
var resolver = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("org.apache.maven", "maven-core", new VersionNumber(3, 9, 0)));
var resolver = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("org.apache.maven", "maven-core", new VersionNumber(3, 9, 0)));
var dependencies = resolver.getAllDependencies(compile);
assertNotNull(dependencies);
assertEquals(32, dependencies.size());
@ -456,7 +456,7 @@ public class TestDependencyResolver {
@Test
void testGetCompileTransitiveDependenciesPlay() {
var resolver = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.typesafe.play", "play_2.13", new VersionNumber(2, 8, 19)));
var resolver = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.typesafe.play", "play_2.13", new VersionNumber(2, 8, 19)));
var dependencies = resolver.getAllDependencies(compile);
assertNotNull(dependencies);
assertEquals(48, dependencies.size());
@ -513,7 +513,7 @@ public class TestDependencyResolver {
@Test
void testGetCompileTransitiveDependenciesVaadin() {
var resolver = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.vaadin", "vaadin", new VersionNumber(23, 3, 7)));
var resolver = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.vaadin", "vaadin", new VersionNumber(23, 3, 7)));
var dependencies = resolver.getAllDependencies(compile);
assertNotNull(dependencies);
assertEquals(88, dependencies.size());
@ -611,10 +611,10 @@ public class TestDependencyResolver {
@Test
void testTransferDependency()
throws Exception {
var resolver = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.uwyn.rife2", "rife2"));
var resolver = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.uwyn.rife2", "rife2"));
var tmp = Files.createTempDirectory("transfers").toFile();
try {
resolver.getAllDependencies(compile).transferIntoDirectory(resolver.repositories(), tmp);
resolver.getAllDependencies(compile).transferIntoDirectory(ArtifactRetriever.instance(), resolver.repositories(), tmp);
var files = FileUtils.getFileList(tmp);
assertEquals(1, files.size());
@ -627,10 +627,10 @@ public class TestDependencyResolver {
@Test
void testTransferDependencySources()
throws Exception {
var resolver = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.uwyn.rife2", "rife2"));
var resolver = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.uwyn.rife2", "rife2"));
var tmp = Files.createTempDirectory("transfers").toFile();
try {
resolver.getAllDependencies(compile).transferIntoDirectory(resolver.repositories(), tmp, CLASSIFIER_SOURCES);
resolver.getAllDependencies(compile).transferIntoDirectory(ArtifactRetriever.instance(), resolver.repositories(), tmp, CLASSIFIER_SOURCES);
var files = FileUtils.getFileList(tmp);
assertEquals(2, files.size());
@ -643,10 +643,10 @@ public class TestDependencyResolver {
@Test
void testTransferDependencySourcesJavadoc()
throws Exception {
var resolver = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.uwyn.rife2", "rife2"));
var resolver = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.uwyn.rife2", "rife2"));
var tmp = Files.createTempDirectory("transfers").toFile();
try {
resolver.getAllDependencies(compile).transferIntoDirectory(resolver.repositories(), tmp, CLASSIFIER_SOURCES, CLASSIFIER_JAVADOC);
resolver.getAllDependencies(compile).transferIntoDirectory(ArtifactRetriever.instance(), resolver.repositories(), tmp, CLASSIFIER_SOURCES, CLASSIFIER_JAVADOC);
var files = FileUtils.getFileList(tmp);
assertEquals(3, files.size());
@ -659,10 +659,10 @@ public class TestDependencyResolver {
@Test
void testTransferDependencySnapshot()
throws Exception {
var resolver = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.uwyn.rife2", "rife2", new VersionNumber(1, 4, 0, "SNAPSHOT")));
var resolver = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.uwyn.rife2", "rife2", new VersionNumber(1, 4, 0, "SNAPSHOT")));
var tmp = Files.createTempDirectory("transfers").toFile();
try {
resolver.getAllDependencies(compile).transferIntoDirectory(resolver.repositories(), tmp);
resolver.getAllDependencies(compile).transferIntoDirectory(ArtifactRetriever.instance(), resolver.repositories(), tmp);
var files = FileUtils.getFileList(tmp);
assertEquals(1, files.size());
@ -675,10 +675,10 @@ public class TestDependencyResolver {
@Test
void testTransferDependencySnapshotSources()
throws Exception {
var resolver = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.uwyn.rife2", "rife2", new VersionNumber(1, 4, 0, "SNAPSHOT")));
var resolver = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.uwyn.rife2", "rife2", new VersionNumber(1, 4, 0, "SNAPSHOT")));
var tmp = Files.createTempDirectory("transfers").toFile();
try {
resolver.getAllDependencies(compile).transferIntoDirectory(resolver.repositories(), tmp, CLASSIFIER_SOURCES);
resolver.getAllDependencies(compile).transferIntoDirectory(ArtifactRetriever.instance(), resolver.repositories(), tmp, CLASSIFIER_SOURCES);
var files = FileUtils.getFileList(tmp);
assertEquals(2, files.size());
@ -692,10 +692,10 @@ public class TestDependencyResolver {
@Test
void testTransferDependencySnapshotSourcesJavadoc()
throws Exception {
var resolver = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.uwyn.rife2", "rife2", new VersionNumber(1, 4, 0, "SNAPSHOT")));
var resolver = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.uwyn.rife2", "rife2", new VersionNumber(1, 4, 0, "SNAPSHOT")));
var tmp = Files.createTempDirectory("transfers").toFile();
try {
resolver.getAllDependencies(compile).transferIntoDirectory(resolver.repositories(), tmp, CLASSIFIER_SOURCES, CLASSIFIER_JAVADOC);
resolver.getAllDependencies(compile).transferIntoDirectory(ArtifactRetriever.instance(), resolver.repositories(), tmp, CLASSIFIER_SOURCES, CLASSIFIER_JAVADOC);
var files = FileUtils.getFileList(tmp);
assertEquals(3, files.size());
@ -710,10 +710,10 @@ public class TestDependencyResolver {
@Test
void testTransferDependencyJetty()
throws Exception {
var resolver = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("org.eclipse.jetty", "jetty-server", new VersionNumber(11, 0, 14)));
var resolver = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("org.eclipse.jetty", "jetty-server", new VersionNumber(11, 0, 14)));
var tmp = Files.createTempDirectory("transfers").toFile();
try {
resolver.getAllDependencies(compile).transferIntoDirectory(resolver.repositories(), tmp);
resolver.getAllDependencies(compile).transferIntoDirectory(ArtifactRetriever.instance(), resolver.repositories(), tmp);
var files = FileUtils.getFileList(tmp);
assertEquals(6, files.size());
Collections.sort(files);
@ -732,10 +732,10 @@ public class TestDependencyResolver {
@Test
void testTransferDependencyJettySources()
throws Exception {
var resolver = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("org.eclipse.jetty", "jetty-server", new VersionNumber(11, 0, 14)));
var resolver = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("org.eclipse.jetty", "jetty-server", new VersionNumber(11, 0, 14)));
var tmp = Files.createTempDirectory("transfers").toFile();
try {
resolver.getAllDependencies(compile).transferIntoDirectory(resolver.repositories(), tmp, CLASSIFIER_SOURCES);
resolver.getAllDependencies(compile).transferIntoDirectory(ArtifactRetriever.instance(), resolver.repositories(), tmp, CLASSIFIER_SOURCES);
var files = FileUtils.getFileList(tmp);
assertEquals(12, files.size());
Collections.sort(files);
@ -760,10 +760,10 @@ public class TestDependencyResolver {
@Test
void testTransferDependencyJettySourcesJavadoc()
throws Exception {
var resolver = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("org.eclipse.jetty", "jetty-server", new VersionNumber(11, 0, 14)));
var resolver = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("org.eclipse.jetty", "jetty-server", new VersionNumber(11, 0, 14)));
var tmp = Files.createTempDirectory("transfers").toFile();
try {
resolver.getAllDependencies(compile).transferIntoDirectory(resolver.repositories(), tmp, CLASSIFIER_SOURCES, CLASSIFIER_JAVADOC);
resolver.getAllDependencies(compile).transferIntoDirectory(ArtifactRetriever.instance(), resolver.repositories(), tmp, CLASSIFIER_SOURCES, CLASSIFIER_JAVADOC);
var files = FileUtils.getFileList(tmp);
assertEquals(18, files.size());
Collections.sort(files);
@ -794,10 +794,10 @@ public class TestDependencyResolver {
@Test
void testTransferDependenciesJunit()
throws Exception {
var resolver = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("org.junit.jupiter", "junit-jupiter", new VersionNumber(5, 9, 2)));
var resolver = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("org.junit.jupiter", "junit-jupiter", new VersionNumber(5, 9, 2)));
var tmp = Files.createTempDirectory("transfers").toFile();
try {
resolver.getAllDependencies(compile, runtime).transferIntoDirectory(resolver.repositories(), tmp);
resolver.getAllDependencies(compile, runtime).transferIntoDirectory(ArtifactRetriever.instance(), resolver.repositories(), tmp);
var files = FileUtils.getFileList(tmp);
assertEquals(8, files.size());
@ -819,10 +819,10 @@ public class TestDependencyResolver {
@Test
void testTransferDependencySpringBoot()
throws Exception {
var resolver = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("org.springframework.boot", "spring-boot-starter", new VersionNumber(3, 0, 4)));
var resolver = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("org.springframework.boot", "spring-boot-starter", new VersionNumber(3, 0, 4)));
var tmp = Files.createTempDirectory("transfers").toFile();
try {
resolver.getAllDependencies(compile).transferIntoDirectory(resolver.repositories(), tmp);
resolver.getAllDependencies(compile).transferIntoDirectory(ArtifactRetriever.instance(), resolver.repositories(), tmp);
var files = FileUtils.getFileList(tmp);
assertEquals(18, files.size());
@ -854,10 +854,10 @@ public class TestDependencyResolver {
@Test
void testTransferDependencyMaven()
throws Exception {
var resolver = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("org.apache.maven", "maven-core", new VersionNumber(3, 9, 0)));
var resolver = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("org.apache.maven", "maven-core", new VersionNumber(3, 9, 0)));
var tmp = Files.createTempDirectory("transfers").toFile();
try {
resolver.getAllDependencies(compile).transferIntoDirectory(resolver.repositories(), tmp);
resolver.getAllDependencies(compile).transferIntoDirectory(ArtifactRetriever.instance(), resolver.repositories(), tmp);
var files = FileUtils.getFileList(tmp);
assertEquals(32, files.size());
@ -903,10 +903,10 @@ public class TestDependencyResolver {
@Test
void testTransferDependencyPlay()
throws Exception {
var resolver = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.typesafe.play", "play_2.13", new VersionNumber(2, 8, 19)));
var resolver = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.typesafe.play", "play_2.13", new VersionNumber(2, 8, 19)));
var tmp = Files.createTempDirectory("transfers").toFile();
try {
resolver.getAllDependencies(compile).transferIntoDirectory(resolver.repositories(), tmp);
resolver.getAllDependencies(compile).transferIntoDirectory(ArtifactRetriever.instance(), resolver.repositories(), tmp);
var files = FileUtils.getFileList(tmp);
assertEquals(48, files.size());
@ -968,10 +968,10 @@ public class TestDependencyResolver {
@Test
void testTransferDependencyVaadin()
throws Exception {
var resolver = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.vaadin", "vaadin", new VersionNumber(23, 3, 7)));
var resolver = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("com.vaadin", "vaadin", new VersionNumber(23, 3, 7)));
var tmp = Files.createTempDirectory("transfers").toFile();
try {
resolver.getAllDependencies(compile).transferIntoDirectory(resolver.repositories(), tmp);
resolver.getAllDependencies(compile).transferIntoDirectory(ArtifactRetriever.instance(), resolver.repositories(), tmp);
var files = FileUtils.getFileList(tmp);
assertEquals(88, files.size());
@ -1073,10 +1073,10 @@ public class TestDependencyResolver {
@Test
void testTransferCheckExisting()
throws Exception {
var resolver = new DependencyResolver(List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("org.eclipse.jetty", "jetty-server", new VersionNumber(11, 0, 14)));
var resolver = new DependencyResolver(ArtifactRetriever.instance(), List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS), new Dependency("org.eclipse.jetty", "jetty-server", new VersionNumber(11, 0, 14)));
var tmp = Files.createTempDirectory("transfers").toFile();
try {
resolver.getAllDependencies(compile).transferIntoDirectory(resolver.repositories(), tmp);
resolver.getAllDependencies(compile).transferIntoDirectory(ArtifactRetriever.instance(), resolver.repositories(), tmp);
var modification_map = new HashMap<String, Long>();
Files.walk(Path.of(tmp.getAbsolutePath()))
@ -1085,7 +1085,7 @@ public class TestDependencyResolver {
.forEach(it -> modification_map.put(it, new File(it).lastModified()));
// re-transfer and check the modification time didn't change
resolver.getAllDependencies(compile).transferIntoDirectory(resolver.repositories(), tmp);
resolver.getAllDependencies(compile).transferIntoDirectory(ArtifactRetriever.instance(), resolver.repositories(), tmp);
Files.walk(Path.of(tmp.getAbsolutePath()))
.map(path -> path.toAbsolutePath().toString())
.filter(s -> !s.equals(tmp.getAbsolutePath()))
@ -1095,7 +1095,7 @@ public class TestDependencyResolver {
var first = modification_map.keySet().stream().findFirst().get();
var first_file = new File(first);
first_file.delete();
resolver.getAllDependencies(compile).transferIntoDirectory(resolver.repositories(), tmp);
resolver.getAllDependencies(compile).transferIntoDirectory(ArtifactRetriever.instance(), resolver.repositories(), tmp);
assertNotEquals(first_file.lastModified(), modification_map.get(first));
modification_map.put(first, first_file.lastModified());
Files.walk(Path.of(tmp.getAbsolutePath()))
@ -1106,7 +1106,7 @@ public class TestDependencyResolver {
// change one file and check that this is transfered again
FileUtils.writeString("stuff", first_file);
var before_transfer_modified = first_file.lastModified();
resolver.getAllDependencies(compile).transferIntoDirectory(resolver.repositories(), tmp);
resolver.getAllDependencies(compile).transferIntoDirectory(ArtifactRetriever.instance(), resolver.repositories(), tmp);
assertNotEquals(first_file.lastModified(), before_transfer_modified);
modification_map.put(first, first_file.lastModified());
Files.walk(Path.of(tmp.getAbsolutePath()))

View file

@ -418,8 +418,6 @@ public class TestPublishOperation {
.fromProject(create_operation1.project());
jar_operation1.execute();
DependencyResolver.clearArtifactCache();
var publish_operation1 = new PublishOperation()
.fromProject(create_operation1.project())
.moment(ZonedDateTime.of(2023, 3, 29, 18, 54, 32, 909, ZoneId.of("America/New_York")))
@ -478,7 +476,6 @@ public class TestPublishOperation {
assertTrue(maven_snapshot_metadata1.getVersions().contains(create_operation1.project().version()));
// created an updated publication
DependencyResolver.clearArtifactCache();
var create_operation2 = new CreateBlankOperation() {
protected Project createProjectBlueprint() {
return new BlankProjectBlueprint(new File(workDirectory(), projectName()), packageName(), projectName(), new VersionNumber(1, 2, 3, "SNAPSHOT"));

View file

@ -1,161 +0,0 @@
/*
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
* Licensed under the Apache License, Version 2.0 (the "License")
*/
package rife.bld.operations;
import org.junit.jupiter.api.Test;
import rife.bld.NamedFile;
import rife.tools.FileUtils;
import java.io.File;
import java.nio.file.Files;
import java.util.List;
import java.util.zip.ZipFile;
import java.util.regex.Pattern;
import static org.junit.jupiter.api.Assertions.*;
public class TestZipOperation {
@Test
void testInstantiation() {
var operation = new ZipOperation();
assertTrue(operation.sourceDirectories().isEmpty());
assertTrue(operation.sourceFiles().isEmpty());
assertNull(operation.destinationDirectory());
assertNull(operation.destinationFileName());
assertTrue(operation.included().isEmpty());
assertTrue(operation.excluded().isEmpty());
}
@Test
void testPopulation() {
var source_directory1 = new File("sourceDirectory1");
var source_directory2 = new File("sourceDirectory2");
var source_file1 = new NamedFile("sourceFile1", new File("sourceFile1"));
var source_file2 = new NamedFile("sourceFile2", new File("sourceFile2"));
var destination_directory = new File("destinationDirectory");
var destination_fileName = "destinationFileName";
var included1 = Pattern.compile("included1");
var included2 = Pattern.compile("included2");
var excluded1 = Pattern.compile("excluded1");
var excluded2 = Pattern.compile("excluded2");
var operation1 = new ZipOperation()
.sourceDirectories(List.of(source_directory1, source_directory2))
.sourceFiles(List.of(source_file1, source_file2))
.destinationDirectory(destination_directory)
.destinationFileName(destination_fileName)
.included(List.of(included1, included2))
.excluded(List.of(excluded1, excluded2));
assertTrue(operation1.sourceDirectories().contains(source_directory1));
assertTrue(operation1.sourceDirectories().contains(source_directory2));
assertTrue(operation1.sourceFiles().contains(source_file1));
assertTrue(operation1.sourceFiles().contains(source_file2));
assertEquals(destination_directory, operation1.destinationDirectory());
assertEquals(destination_fileName, operation1.destinationFileName());
assertEquals(new File(destination_directory, destination_fileName), operation1.destinationFile());
assertTrue(operation1.included().contains(included1));
assertTrue(operation1.included().contains(included2));
assertTrue(operation1.excluded().contains(excluded1));
assertTrue(operation1.excluded().contains(excluded2));
var operation2 = new ZipOperation()
.destinationDirectory(destination_directory)
.destinationFileName(destination_fileName);
operation2.sourceDirectories().add(source_directory1);
operation2.sourceDirectories().add(source_directory2);
operation2.sourceFiles().add(source_file1);
operation2.sourceFiles().add(source_file2);
operation2.included().add(included1);
operation2.included().add(included2);
operation2.excluded().add(excluded1);
operation2.excluded().add(excluded2);
assertTrue(operation2.sourceDirectories().contains(source_directory1));
assertTrue(operation2.sourceDirectories().contains(source_directory2));
assertTrue(operation2.sourceFiles().contains(source_file1));
assertTrue(operation2.sourceFiles().contains(source_file2));
assertEquals(destination_directory, operation2.destinationDirectory());
assertEquals(destination_fileName, operation2.destinationFileName());
assertTrue(operation2.included().contains(included1));
assertTrue(operation2.included().contains(included2));
assertTrue(operation2.excluded().contains(excluded1));
assertTrue(operation2.excluded().contains(excluded2));
var operation3 = new ZipOperation()
.sourceDirectories(source_directory1, source_directory2)
.sourceFiles(source_file1, source_file2)
.destinationDirectory(destination_directory)
.destinationFileName(destination_fileName)
.included(included1, included2)
.excluded(excluded1, excluded2);
assertTrue(operation3.sourceDirectories().contains(source_directory1));
assertTrue(operation3.sourceDirectories().contains(source_directory2));
assertTrue(operation3.sourceFiles().contains(source_file1));
assertTrue(operation3.sourceFiles().contains(source_file2));
assertEquals(destination_directory, operation3.destinationDirectory());
assertEquals(destination_fileName, operation3.destinationFileName());
assertTrue(operation3.included().contains(included1));
assertTrue(operation3.included().contains(included2));
assertTrue(operation3.excluded().contains(excluded1));
assertTrue(operation3.excluded().contains(excluded2));
}
@Test
void testExecute()
throws Exception {
var tmp = Files.createTempDirectory("test").toFile();
try {
var source_dir = new File(tmp, "source");
var destination_dir = new File(tmp, "destination");
var destination_name = "archive.zip";
source_dir.mkdirs();
FileUtils.writeString("source1", new File(source_dir, "source1.text"));
FileUtils.writeString("source2", new File(source_dir, "source2.text"));
FileUtils.writeString("source3", new File(source_dir, "source3.text"));
FileUtils.writeString("source4", new File(source_dir, "source4.txt"));
var source5 = new File(tmp, "source5.text");
var source6 = new File(tmp, "source6.text");
FileUtils.writeString("source5", source5);
FileUtils.writeString("source6", source6);
new ZipOperation()
.sourceDirectories(List.of(source_dir))
.sourceFiles(List.of(
new NamedFile("src5.txt", source5),
new NamedFile("src6.txt", source6)))
.destinationDirectory(destination_dir)
.destinationFileName(destination_name)
.included("source.*\\.text")
.excluded("source5.*")
.execute();
var zip_archive = new File(destination_dir, destination_name);
assertTrue(zip_archive.exists());
var content = new StringBuilder();
try (var zip = new ZipFile(zip_archive)) {
var e = zip.entries();
while (e.hasMoreElements()) {
var zip_entry = e.nextElement();
content.append(zip_entry.getName());
content.append("\n");
}
}
assertEquals("""
source1.text
source2.text
source3.text
src6.txt
""", content.toString());
} finally {
FileUtils.deleteDirectory(tmp);
}
}
}

View file

@ -1400,7 +1400,8 @@ public class TestParser {
} catch (GetContentErrorException e) {
assertTrue(e.getCause() instanceof rife.resources.exceptions.ResourceFinderErrorException);
assertTrue(e.getCause().getCause() instanceof rife.tools.exceptions.FileUtilsErrorException);
assertTrue(e.getCause().getCause().getCause() instanceof java.io.UnsupportedEncodingException);
assertTrue(e.getCause().getCause().getCause() instanceof rife.tools.exceptions.FileUtilsErrorException);
assertTrue(e.getCause().getCause().getCause().getCause() instanceof java.io.UnsupportedEncodingException);
}
}
}

View file

@ -683,7 +683,7 @@ public class TestTemplateFactory {
template1_file.delete();
try {
FileUtils.copy(template1_resource.openStream(), template1_file);
} catch (FileUtilsErrorException | IOException e) {
} catch (IOException e) {
fail(ExceptionUtils.getExceptionStackTrace(e));
return;
}
@ -707,7 +707,7 @@ public class TestTemplateFactory {
var template2_resource = TemplateFactory.HTML.getParser().resolve("noblocks_in");
try {
FileUtils.copy(template2_resource.openStream(), template1_file);
} catch (FileUtilsErrorException | IOException e) {
} catch (IOException e) {
fail(ExceptionUtils.getExceptionStackTrace(e));
return;
}
@ -1135,7 +1135,7 @@ public class TestTemplateFactory {
template1_file.delete();
try {
FileUtils.copy(template1_resource.openStream(), template1_file);
} catch (FileUtilsErrorException | IOException e) {
} catch (IOException e) {
fail(ExceptionUtils.getExceptionStackTrace(e));
return;
}
@ -1159,7 +1159,7 @@ public class TestTemplateFactory {
var template2_resource = TemplateFactory.TXT.getParser().resolve("noblocks_in");
try {
FileUtils.copy(template2_resource.openStream(), template1_file);
} catch (FileUtilsErrorException | IOException e) {
} catch (IOException e) {
fail(ExceptionUtils.getExceptionStackTrace(e));
return;
}
@ -1213,7 +1213,7 @@ public class TestTemplateFactory {
try {
FileUtils.copy(template1_resource.openStream(), template1_file);
FileUtils.copy(template1_included_resource.openStream(), template1_included_file);
} catch (FileUtilsErrorException | IOException e) {
} catch (IOException e) {
fail(ExceptionUtils.getExceptionStackTrace(e));
return;
}
@ -1237,7 +1237,7 @@ public class TestTemplateFactory {
var template1_included_resource2 = TemplateFactory.HTML.getParser().resolve("noblocks_in");
try {
FileUtils.copy(template1_included_resource2.openStream(), template1_included_file);
} catch (FileUtilsErrorException | IOException e) {
} catch (IOException e) {
fail(ExceptionUtils.getExceptionStackTrace(e));
return;
}
@ -1294,7 +1294,7 @@ public class TestTemplateFactory {
try {
FileUtils.copy(template1_resource.openStream(), template1_file);
FileUtils.copy(template1_included_resource.openStream(), template1_included_file);
} catch (FileUtilsErrorException | IOException e) {
} catch (IOException e) {
fail(ExceptionUtils.getExceptionStackTrace(e));
return;
}
@ -1318,7 +1318,7 @@ public class TestTemplateFactory {
var template1_included_resource2 = TemplateFactory.TXT.getParser().resolve("noblocks_in");
try {
FileUtils.copy(template1_included_resource2.openStream(), template1_included_file);
} catch (FileUtilsErrorException | IOException e) {
} catch (IOException e) {
fail(ExceptionUtils.getExceptionStackTrace(e));
return;
}
@ -1401,7 +1401,7 @@ public class TestTemplateFactory {
var template1_included_resource2 = TemplateFactory.HTML.getParser().resolve("noblocks_in");
try {
FileUtils.copy(template1_included_resource2.openStream(), template1_included_file);
} catch (FileUtilsErrorException | IOException e) {
} catch (IOException e) {
fail(ExceptionUtils.getExceptionStackTrace(e));
return;
}

View file

@ -0,0 +1,413 @@
/*
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
* Licensed under the Apache License, Version 2.0 (the "License")
*/
package rife.tools;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import rife.bld.operations.CreateBlankOperation;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.FileTime;
import java.nio.file.attribute.PosixFilePermission;
import java.util.HashSet;
import java.util.Set;
import static org.junit.jupiter.api.Assertions.*;
import static rife.tools.FileUtils.path;
public class TestDirBuilder {
@TempDir
File tmp;
@Test
void testDirBuilderInstantiation()
throws IOException {
var builder1 = new DirBuilder(tmp);
assertNotNull(builder1);
var result1 = new StringBuilder();
var builder2 = new DirBuilder(tmp, d -> result1.append("one"));
assertNotNull(builder2);
assertEquals(result1.toString(), "one");
}
@Test
void testDirBuilderInstantiationPath()
throws IOException {
var builder1 = new DirBuilder(tmp.toPath());
assertNotNull(builder1);
var result1 = new StringBuilder();
var builder2 = new DirBuilder(tmp.toPath(), d -> result1.append("one"));
assertNotNull(builder2);
assertEquals(result1.toString(), "one");
}
@Test
void testFileBuilderInstantiation()
throws IOException {
var builder1 = new FileBuilder(tmp);
assertNotNull(builder1);
var result1 = new StringBuilder();
var builder2 = new FileBuilder(tmp, f -> result1.append("one"));
assertNotNull(builder2);
assertEquals(result1.toString(), "one");
}
@Test
void testFileBuilderInstantiationPath()
throws IOException {
var builder1 = new FileBuilder(tmp.toPath());
assertNotNull(builder1);
var result1 = new StringBuilder();
var builder2 = new FileBuilder(tmp.toPath(), f -> result1.append("one"));
assertNotNull(builder2);
assertEquals(result1.toString(), "one");
}
@Test
void testFileBuilderPathWithFile() {
var file = new File("test.txt");
var builder = new FileBuilder(file);
var expectedPath = file.getAbsoluteFile().toPath();
var actualPath = path(file, "subdir", "file.txt");
assertEquals(expectedPath.resolve("subdir/file.txt"), actualPath);
}
@Test
void testFileBuilderPathWithPath() {
var path = Path.of("test-files");
var builder = new FileBuilder(path);
var expectedPath = path.toAbsolutePath();
var actualPath = path(path, "subdir", "file.txt");
assertEquals(expectedPath.resolve("subdir/file.txt"), actualPath);
}
@Test
void testDirBuildDir()
throws IOException {
var builder = new DirBuilder(tmp);
builder.dir("subdir");
assertTrue(new File(tmp, "subdir").exists());
}
@Test
void testDirBuilderDirWithAction()
throws IOException {
var builder = new DirBuilder(tmp, d -> {
d.dir("subdir");
});
assertNotNull(builder);
assertTrue(new File(tmp, "subdir").exists());
}
@Test
void testDirFileWriteAction()
throws IOException {
var builder = new DirBuilder(tmp);
builder.dir("subdir", d -> d.file("file", f -> f.write("hello")));
assertTrue(new File(tmp, "subdir").exists());
assertTrue(new File(new File(tmp, "subdir"), "file").exists());
assertEquals("hello", FileUtils.readString(new File(new File(tmp, "subdir"), "file")));
}
@Test
void testFileWrite()
throws IOException {
var builder = new DirBuilder(tmp);
builder.file("file", f -> f.write("hello"));
assertTrue(new File(tmp, "file").exists());
assertEquals("hello", FileUtils.readString(new File(tmp, "file")));
}
@Test
void testDirDelete()
throws IOException {
var builder = new DirBuilder(tmp);
builder.dir("subdir", d -> d.file("file", f -> f.write("hello")));
assertTrue(new File(tmp, "subdir").exists());
assertTrue(new File(new File(tmp, "subdir"), "file").exists());
builder.dir("subdir", d -> d.delete());
assertFalse(new File(tmp, "subdir").exists());
assertFalse(new File(new File(tmp, "subdir"), "file").exists());
assertFalse(new File(tmp, "file").exists());
}
@Test
void testPermsMode()
throws IOException {
var dirBuilder = new DirBuilder(tmp);
// Test setting read and execute permissions
var mode = 0555;
dirBuilder.perms(mode);
Set<PosixFilePermission> expectedPermissions = new HashSet<>();
expectedPermissions.add(PosixFilePermission.OWNER_READ);
expectedPermissions.add(PosixFilePermission.GROUP_READ);
expectedPermissions.add(PosixFilePermission.OTHERS_READ);
expectedPermissions.add(PosixFilePermission.OWNER_EXECUTE);
expectedPermissions.add(PosixFilePermission.GROUP_EXECUTE);
expectedPermissions.add(PosixFilePermission.OTHERS_EXECUTE);
assertEquals(expectedPermissions, Files.getPosixFilePermissions(tmp.toPath()));
// Test setting all permissions
mode = 0777;
dirBuilder.perms(mode);
expectedPermissions = new HashSet<>();
expectedPermissions.add(PosixFilePermission.OWNER_READ);
expectedPermissions.add(PosixFilePermission.GROUP_READ);
expectedPermissions.add(PosixFilePermission.OTHERS_READ);
expectedPermissions.add(PosixFilePermission.OWNER_WRITE);
expectedPermissions.add(PosixFilePermission.GROUP_WRITE);
expectedPermissions.add(PosixFilePermission.OTHERS_WRITE);
expectedPermissions.add(PosixFilePermission.OWNER_EXECUTE);
expectedPermissions.add(PosixFilePermission.GROUP_EXECUTE);
expectedPermissions.add(PosixFilePermission.OTHERS_EXECUTE);
assertEquals(expectedPermissions, Files.getPosixFilePermissions(tmp.toPath()));
}
@Test
void testPerms()
throws IOException {
var dirBuilder = new DirBuilder(tmp);
// Test setting read and execute permissions
Set<PosixFilePermission> permissions = new HashSet<>();
permissions.add(PosixFilePermission.OWNER_READ);
permissions.add(PosixFilePermission.GROUP_READ);
permissions.add(PosixFilePermission.OTHERS_READ);
permissions.add(PosixFilePermission.OWNER_EXECUTE);
permissions.add(PosixFilePermission.GROUP_EXECUTE);
permissions.add(PosixFilePermission.OTHERS_EXECUTE);
dirBuilder.perms(permissions);
assertEquals(permissions, Files.getPosixFilePermissions(tmp.toPath()));
// Test setting all permissions
permissions = new HashSet<>();
permissions.add(PosixFilePermission.OWNER_READ);
permissions.add(PosixFilePermission.GROUP_READ);
permissions.add(PosixFilePermission.OTHERS_READ);
permissions.add(PosixFilePermission.OWNER_WRITE);
permissions.add(PosixFilePermission.GROUP_WRITE);
permissions.add(PosixFilePermission.OTHERS_WRITE);
permissions.add(PosixFilePermission.OWNER_EXECUTE);
permissions.add(PosixFilePermission.GROUP_EXECUTE);
permissions.add(PosixFilePermission.OTHERS_EXECUTE);
dirBuilder.perms(permissions);
assertEquals(permissions, Files.getPosixFilePermissions(tmp.toPath()));
}
@Test
void testFileTouch()
throws IOException {
var tempFile = File.createTempFile("test", ".txt");
var fileBuilder = new FileBuilder(tempFile);
// Test creating a new file
fileBuilder.delete().touch();
assertTrue(tempFile.exists());
// Test updating the last access and last modification time of an existing file
var now = System.currentTimeMillis();
fileBuilder.touch();
var lastAccessTime = (FileTime) Files.getAttribute(tempFile.toPath(), "lastAccessTime");
assertEquals(now, lastAccessTime.toMillis());
assertEquals(now, tempFile.lastModified());
}
@Test
void testMoveFile()
throws IOException {
var sourceFile = File.createTempFile("source", ".txt");
var targetFile = File.createTempFile("target", ".txt");
var fileBuilder = new FileBuilder(targetFile);
// Test moving a file
fileBuilder.delete().move(sourceFile.toPath());
assertFalse(sourceFile.exists());
assertTrue(targetFile.exists());
}
@Test
void testDeleteFile()
throws IOException {
var tempFile = File.createTempFile("test", ".txt");
var fileBuilder = new FileBuilder(tempFile);
// Test deleting a file
fileBuilder.delete();
assertFalse(tempFile.exists());
}
@Test
void testFilePermsMode()
throws IOException {
var tempFile = File.createTempFile("test", ".txt");
var fileBuilder = new FileBuilder(tempFile);
// Test setting read and execute permissions
var mode = 0555;
fileBuilder.perms(mode);
Set<PosixFilePermission> expectedPermissions = new HashSet<>();
expectedPermissions.add(PosixFilePermission.OWNER_READ);
expectedPermissions.add(PosixFilePermission.GROUP_READ);
expectedPermissions.add(PosixFilePermission.OTHERS_READ);
expectedPermissions.add(PosixFilePermission.OWNER_EXECUTE);
expectedPermissions.add(PosixFilePermission.GROUP_EXECUTE);
expectedPermissions.add(PosixFilePermission.OTHERS_EXECUTE);
assertEquals(expectedPermissions, Files.getPosixFilePermissions(tempFile.toPath()));
// Test setting all permissions
mode = 0777;
fileBuilder.perms(mode);
expectedPermissions = new HashSet<>();
expectedPermissions.add(PosixFilePermission.OWNER_READ);
expectedPermissions.add(PosixFilePermission.GROUP_READ);
expectedPermissions.add(PosixFilePermission.OTHERS_READ);
expectedPermissions.add(PosixFilePermission.OWNER_WRITE);
expectedPermissions.add(PosixFilePermission.GROUP_WRITE);
expectedPermissions.add(PosixFilePermission.OTHERS_WRITE);
expectedPermissions.add(PosixFilePermission.OWNER_EXECUTE);
expectedPermissions.add(PosixFilePermission.GROUP_EXECUTE);
expectedPermissions.add(PosixFilePermission.OTHERS_EXECUTE);
assertEquals(expectedPermissions, Files.getPosixFilePermissions(tempFile.toPath()));
}
@Test
void testFilePerms()
throws IOException {
var tempFile = File.createTempFile("test", ".txt");
var fileBuilder = new FileBuilder(tempFile);
// Test setting read and execute permissions
Set<PosixFilePermission> permissions = new HashSet<>();
permissions.add(PosixFilePermission.OWNER_READ);
permissions.add(PosixFilePermission.GROUP_READ);
permissions.add(PosixFilePermission.OTHERS_READ);
permissions.add(PosixFilePermission.OWNER_EXECUTE);
permissions.add(PosixFilePermission.GROUP_EXECUTE);
permissions.add(PosixFilePermission.OTHERS_EXECUTE);
fileBuilder.perms(permissions);
assertEquals(permissions, Files.getPosixFilePermissions(tempFile.toPath()));
// Test setting all permissions
permissions = new HashSet<>();
permissions.add(PosixFilePermission.OWNER_READ);
permissions.add(PosixFilePermission.GROUP_READ);
permissions.add(PosixFilePermission.OTHERS_READ);
permissions.add(PosixFilePermission.OWNER_WRITE);
permissions.add(PosixFilePermission.GROUP_WRITE);
permissions.add(PosixFilePermission.OTHERS_WRITE);
permissions.add(PosixFilePermission.OWNER_EXECUTE);
permissions.add(PosixFilePermission.GROUP_EXECUTE);
permissions.add(PosixFilePermission.OTHERS_EXECUTE);
fileBuilder.perms(permissions);
assertEquals(permissions, Files.getPosixFilePermissions(tempFile.toPath()));
}
@Test
void testFileAndDirectoryHierarchy()
throws IOException {
new DirBuilder(tmp, d -> {
d.dir("subdir1", s1 -> {
s1.file("file1.txt", f1 -> f1.write("hello world"));
s1.file("file2.txt", f2 -> f2.write("hello again"));
});
d.dir("subdir2", s2 -> {
s2.file("file3.txt", f3 -> f3.write("goodbye"));
});
});
var subdir1 = tmp.toPath().resolve("subdir1").toFile();
assertTrue(subdir1.exists());
assertTrue(subdir1.isDirectory());
var file1 = tmp.toPath().resolve("subdir1/file1.txt").toFile();
assertTrue(file1.exists());
assertTrue(file1.isFile());
var file2 = tmp.toPath().resolve("subdir1/file2.txt").toFile();
assertTrue(file2.exists());
assertTrue(file2.isFile());
var subdir2 = tmp.toPath().resolve("subdir2").toFile();
assertTrue(subdir2.exists());
assertTrue(subdir2.isDirectory());
var file3 = tmp.toPath().resolve("subdir2/file3.txt").toFile();
assertTrue(file3.exists());
assertTrue(file3.isFile());
}
@Test
void testDirectoryHierarchyCopyMove()
throws IOException {
var b = new DirBuilder(tmp, d -> {
d.dir("subdir1", s1 -> {
s1.file("file1.txt", f -> {
f.write("Hello World!");
});
s1.dir("subdir2", s2 -> {
s2.file("file2.txt", f -> {
f.write("Foo");
});
});
});
d.dir("subdir3", s3 -> {
s3.file("file3.txt", f -> f.move(path(tmp, "subdir1", "subdir2", "file2.txt")));
s3.file("file4.txt", f -> f.copy(path(tmp, "subdir1", "file1.txt")));
});
});
assertTrue(path(tmp, "subdir1", "file1.txt").toFile().exists());
assertTrue(path(tmp, "subdir3", "file4.txt").toFile().exists());
assertFalse(path(tmp, "subdir1", "subdir2", "file2.txt").toFile().exists());
assertTrue(path(tmp, "subdir3", "file3.txt").toFile().exists());
assertEquals(Files.readString(path(tmp, "subdir1", "file1.txt")), Files.readString(path(tmp, "subdir3", "file4.txt")));
assertEquals("Foo", Files.readString(path(tmp, "subdir3", "file3.txt")));
}
@Test
void testDirectoryHierarchyAgain()
throws Exception {
var operation = new CreateBlankOperation()
.workDirectory(tmp)
.packageName("tst")
.projectName("tst")
.downloadDependencies(false);
operation.execute();
new DirBuilder(tmp, t -> {
t.dir("bld", b -> {
b.dir("bin", i -> {
i.file("bld", f -> {
f.copy(path(tmp, "tst", "bld"));
f.perms(0755);
});
i.file("bld.bat", f -> {
f.copy(path(tmp, "tst", "bld.bat"));
f.perms(0755);
});
});
b.dir("lib", l -> {
l.file("bld-wrapper.jar", f -> f.move(path(tmp, "tst", "lib", "bld", "bld-wrapper.jar")));
});
});
t.dir("tst", l -> l.delete());
});
assertEquals("""
/bld
/bld/bin
/bld/bin/bld
/bld/bin/bld.bat
/bld/lib
/bld/lib/bld-wrapper.jar""", FileUtils.generateDirectoryListing(tmp));
}
}

View file

@ -1,3 +1,7 @@
/*
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
* Licensed under the Apache License, Version 2.0 (the "License")
*/
package rife.tools;
import org.junit.jupiter.api.Test;

View file

@ -0,0 +1,959 @@
/*
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
* Licensed under the Apache License, Version 2.0 (the "License")
*/
package rife.tools;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import rife.tools.exceptions.FileUtilsErrorException;
import java.io.*;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import static java.nio.file.attribute.PosixFilePermission.*;
import static org.junit.jupiter.api.Assertions.*;
import static rife.tools.FileUtils.permissionsFromMode;
public class TestFileUtils {
@TempDir
public Path tempDir;
@Test
void testMoveFile()
throws IOException {
// create source and target files
var source = new File(tempDir.toFile(), "source.txt");
var target = new File(tempDir.toFile(), "target.txt");
source.createNewFile();
// move file
FileUtils.moveFile(source, target);
// check if source and target files exist
assertFalse(source.exists());
assertTrue(target.exists());
}
@Test
void testMoveFileNullSource() {
var target = new File(tempDir.toFile(), "target.txt");
assertThrows(IllegalArgumentException.class, () -> FileUtils.moveFile(null, target));
}
@Test
void testMoveFileNullTarget() {
var source = new File(tempDir.toFile(), "source.txt");
assertThrows(IllegalArgumentException.class, () -> FileUtils.moveFile(source, null));
}
@Test
void testMoveFileMissingSource() {
var source = new File(tempDir.toFile(), "non_existing_source.txt");
var target = new File(tempDir.toFile(), "target.txt");
assertThrows(FileUtilsErrorException.class, () -> FileUtils.moveFile(source, target));
}
@Test
void testMoveDirectory()
throws IOException, FileUtilsErrorException {
// create a source directory with some files
var source_dir = new File(tempDir.toFile(), "source");
source_dir.mkdir();
var file1 = new File(source_dir, "file1.txt");
file1.createNewFile();
var sub_dir = new File(source_dir, "subdir");
sub_dir.mkdir();
var file2 = new File(sub_dir, "file2.txt");
file2.createNewFile();
// create a target directory
var targetDir = new File(tempDir.toFile(), "target");
// move the source directory to the target directory
FileUtils.moveDirectory(source_dir, targetDir);
// assert that the source directory and its contents were deleted
assertFalse(source_dir.exists());
assertFalse(file1.exists());
assertFalse(sub_dir.exists());
assertFalse(file2.exists());
// assert that the target directory and its contents were created
assertTrue(targetDir.exists());
assertTrue(new File(targetDir, "file1.txt").exists());
assertTrue(new File(targetDir, "subdir/file2.txt").exists());
}
@Test
void testMoveDirectoryNullSource() {
assertThrows(IllegalArgumentException.class, () -> FileUtils.moveDirectory(null, new File(tempDir.toFile(), "target")));
}
@Test
void testMoveDirectoryNullTarget() {
assertThrows(IllegalArgumentException.class, () -> FileUtils.moveDirectory(new File(tempDir.toFile(), "source"), null));
}
@Test
void testMoveDirectoryNonexistentSource() {
var sourceDir = new File(tempDir.toFile(), "source");
var targetDir = new File(tempDir.toFile(), "target");
assertThrows(FileUtilsErrorException.class, () -> FileUtils.moveDirectory(sourceDir, targetDir));
}
@Test
void testDeleteDirectoryNullSource() {
assertThrows(IllegalArgumentException.class, () -> FileUtils.deleteDirectory(null));
}
@Test
void testDeleteDirectoryNonExistingSource() {
assertThrows(FileUtilsErrorException.class, () -> FileUtils.deleteDirectory(new File("non_existing_directory")));
}
@Test
void testDeleteDirectory()
throws IOException {
// Create directory with files and subdirectories
var directory = tempDir.resolve("test_directory").toFile();
directory.mkdirs();
var file1 = new File(directory, "file1.txt");
file1.createNewFile();
var subdirectory = new File(directory, "subdirectory");
subdirectory.mkdir();
var file2 = new File(subdirectory, "file2.txt");
file2.createNewFile();
// Verify that directory and files exist before deleting it
assertTrue(directory.exists());
assertTrue(file1.exists());
assertTrue(subdirectory.exists());
assertTrue(file2.exists());
// Delete directory and verify that it doesn't exist anymore
FileUtils.deleteDirectory(directory);
assertFalse(directory.exists());
assertFalse(file1.exists());
assertFalse(subdirectory.exists());
assertFalse(file2.exists());
}
@Test
void testCopyStreamToFile()
throws IOException {
var input = new ByteArrayInputStream("Hello world!".getBytes());
var output_file = File.createTempFile("output", ".txt");
assertDoesNotThrow(() -> FileUtils.copy(input, output_file));
assertEquals("Hello world!", FileUtils.readString(output_file));
output_file.delete();
}
@Test
void testCopyFileToStream()
throws IOException {
var input_file = File.createTempFile("input", ".txt");
var output = new ByteArrayOutputStream();
FileUtils.writeString("Hello world!", input_file);
assertDoesNotThrow(() -> FileUtils.copy(input_file, output));
assertEquals("Hello world!", output.toString());
input_file.delete();
}
@Test
void testCopyFileToFile()
throws IOException {
var input_file = File.createTempFile("input", ".txt");
var output_file = File.createTempFile("output", ".txt");
FileUtils.writeString("Hello world!", input_file);
assertDoesNotThrow(() -> FileUtils.copy(input_file, output_file));
assertEquals("Hello world!", FileUtils.readString(output_file));
input_file.delete();
output_file.delete();
}
@Test
void testNullInputStream() {
assertThrows(IllegalArgumentException.class, () -> FileUtils.copy((InputStream) null, new ByteArrayOutputStream()));
}
@Test
void testNullOutputStream() {
assertThrows(IllegalArgumentException.class, () -> FileUtils.copy(new ByteArrayInputStream("Hello World!".getBytes()), (OutputStream) null));
}
@Test
void testNullSourceFile() {
assertThrows(IllegalArgumentException.class, () -> FileUtils.copy((File) null, new File("output.txt")));
}
@Test
void testNullTargetFile() {
assertThrows(IllegalArgumentException.class, () -> FileUtils.copy(new File("input.txt"), (File) null));
}
@Test
void testCopyDirectory()
throws Exception {
// create source and target directories with some files
var source_directory = new File(tempDir.toFile(), "source");
source_directory.mkdirs();
new File(source_directory, "dir1").mkdirs();
var target_directory = new File(tempDir.toFile(), "target");
target_directory.mkdirs();
Files.write(Paths.get(source_directory.getAbsolutePath(), "file1.txt"), "Test file 1 contents".getBytes());
Files.write(Paths.get(source_directory.getAbsolutePath(), "dir1", "file2.txt"), "Test file 2 contents".getBytes());
// call the method to copy the directory
FileUtils.copyDirectory(source_directory, target_directory);
// check that all files in the source directory are copied to target directory
assertEquals(FileUtils.generateDirectoryListing(source_directory), FileUtils.generateDirectoryListing(target_directory));
}
@Test
void testCopyDirectorySourceIsNull() {
assertThrows(IllegalArgumentException.class, () -> FileUtils.copyDirectory(null, new File("target")));
}
@Test
void testCopyDirectoryTargetIsNull() {
assertThrows(IllegalArgumentException.class, () -> FileUtils.copyDirectory(new File("source"), null));
}
@Test
void testReadStreamNull() {
assertThrows(IllegalArgumentException.class, () -> FileUtils.readStream(null));
}
@Test
void testReadStreamEmptyStream()
throws IOException {
var input = new ByteArrayInputStream(new byte[0]);
var result = FileUtils.readStream(input);
assertEquals(0, result.size());
}
@Test
void testReadStreamSmallStream()
throws IOException {
var input_bytes = new byte[]{1, 2, 3};
var input = new ByteArrayInputStream(input_bytes);
var result = FileUtils.readStream(input);
assertArrayEquals(input_bytes, result.toByteArray());
}
@Test
void testReadStreamLargeStream()
throws IOException {
var input_bytes = new byte[1024 * 1024];
for (var i = 0; i < input_bytes.length; i++) {
input_bytes[i] = (byte) (i % 256); // Fill buffer with a repeating pattern
}
var input = new ByteArrayInputStream(input_bytes);
var result = FileUtils.readStream(input);
assertArrayEquals(input_bytes, result.toByteArray());
}
private static final String TEST_STRING = "Hello, world!\n";
private static final byte[] TEST_BYTES = TEST_STRING.getBytes(StandardCharsets.UTF_8);
@Test
void testReadStringFromInputStream()
throws IOException {
InputStream input = new ByteArrayInputStream(TEST_BYTES);
var result = FileUtils.readString(input);
assertEquals(TEST_STRING, result);
}
@Test
void testReadStringFromNullInputStream() {
assertThrows(IllegalArgumentException.class, () -> FileUtils.readString((InputStream) null));
}
@Test
void testReadStringFromReader()
throws IOException {
var reader = new StringReader(TEST_STRING);
var result = FileUtils.readString(reader);
assertEquals(TEST_STRING, result);
}
@Test
void testReadStringFromNullReader() {
assertThrows(IllegalArgumentException.class, () -> FileUtils.readString((Reader) null));
}
@Test
void testReadStringFromInputStreamWithEncoding()
throws IOException {
InputStream input = new ByteArrayInputStream(TEST_BYTES);
var result = FileUtils.readString(input, StandardCharsets.UTF_8.name());
assertEquals(TEST_STRING, result);
}
@Test
void testReadStringFromInputStreamWithInvalidEncoding() {
InputStream input = new ByteArrayInputStream(TEST_BYTES);
var invalidEncoding = "invalid-encoding";
assertThrows(FileUtilsErrorException.class, () -> FileUtils.readString(input, invalidEncoding));
}
@Test
void testReadStringFromNullInputStreamWithEncoding() {
var encoding = StandardCharsets.UTF_8.name();
assertThrows(IllegalArgumentException.class, () -> FileUtils.readString((InputStream) null, encoding));
}
@Test
void testReadStringFromURLWithCharset()
throws Exception {
var url = new URL("https://rife2.com");
var actual = FileUtils.readString(url, "UTF-8");
assertTrue(Pattern.compile(".*<html[^>]*>.*</html>.*", Pattern.DOTALL).matcher(actual).matches());
}
@Test
void testReadStringFromURL()
throws Exception {
var url = new URL("https://rife2.com");
var actual = FileUtils.readString(url);
assertTrue(Pattern.compile(".*<html[^>]*>.*</html>.*", Pattern.DOTALL).matcher(actual).matches());
}
@Test
void testReadStringFromURLWithNullUrl() {
assertThrows(IllegalArgumentException.class, () -> FileUtils.readString((URL) null, "UTF-8"));
}
@Test
void testReadStringFromFileWithCharset()
throws Exception {
// Create a temporary file with some content
var tmp_file = File.createTempFile("test", ".txt");
tmp_file.deleteOnExit();
var file_writer = new FileWriter(tmp_file);
var expected = "This is a test.";
file_writer.write(expected);
file_writer.close();
// Read the string from the temporary file and compare it to the expected value
var actual = FileUtils.readString(tmp_file, "UTF-8");
assertEquals(expected, actual.trim());
}
@Test
void testReadStringFromFileWithNullFile() {
assertThrows(IllegalArgumentException.class, () -> FileUtils.readString((File) null));
}
@Test
void testReadBytesWithNullInputStream() {
assertThrows(IllegalArgumentException.class, () -> FileUtils.readBytes((InputStream) null));
}
@Test
void testReadStringWithNullFile() {
assertThrows(IllegalArgumentException.class, () -> FileUtils.readString((File) null));
}
@Test
void testReadBytesWithNullUrl() {
assertThrows(IllegalArgumentException.class, () -> FileUtils.readBytes((URL) null));
}
@Test
void testReadBytesWithInputStream()
throws Exception {
var inStream = new ByteArrayInputStream("This is a test string".getBytes());
var byteArray = FileUtils.readBytes(inStream);
assertNotNull(byteArray);
assertTrue(byteArray.length > 0);
}
@Test
void testReadBytesWithUrl()
throws Exception {
var url = new URL("https://www.google.com");
var byteArray = FileUtils.readBytes(url);
assertNotNull(byteArray);
assertTrue(byteArray.length > 0);
}
@Test
void testReadBytesWithFile()
throws Exception {
// Create a temporary file with some content
var tmp_file = File.createTempFile("test", ".txt");
tmp_file.deleteOnExit();
var file_writer = new FileWriter(tmp_file);
var expected = "This is a test.";
file_writer.write(expected);
file_writer.close();
var result = FileUtils.readBytes(tmp_file);
assertNotNull(result);
assertTrue(result.length > 0);
}
@Test
void testWriteBytesToFile()
throws Exception {
// setup
var content = "Hello World".getBytes(StandardCharsets.UTF_8);
var file = new File(tempDir.toFile(), "test.txt");
// execute
FileUtils.writeBytes(content, file);
// verify
assertTrue(file.exists());
assertEquals(content.length, file.length());
var readContent = new byte[content.length];
try (var fis = new FileInputStream(file)) {
fis.read(readContent);
}
assertArrayEquals(content, readContent);
}
@Test
void testWriteBytesContentIsNull() {
// setup
byte[] content = null;
var file = new File(tempDir.toFile(), "test.txt");
// execute & verify
var exception = assertThrows(IllegalArgumentException.class,
() -> FileUtils.writeBytes(content, file));
assertEquals("content can't be null.", exception.getMessage());
}
@Test
void testWriteBytesDestinationIsNull() {
// setup
var content = "Hello World".getBytes(StandardCharsets.UTF_8);
File file = null;
// execute & verify
var exception = assertThrows(IllegalArgumentException.class,
() -> FileUtils.writeBytes(content, file));
assertEquals("destination can't be null.", exception.getMessage());
}
@Test
void testWriteStringToFile()
throws Exception {
// setup
var content = "Hello World";
var file = new File(tempDir.toFile(), "test.txt");
// execute
FileUtils.writeString(content, file);
// verify
assertTrue(file.exists());
assertEquals(content.length(), file.length());
var readContent = new char[content.length()];
try (var fr = new FileReader(file)) {
fr.read(readContent);
}
assertEquals(content, new String(readContent));
}
@Test
void testWriteStringContentIsNull() {
// setup
String content = null;
var file = new File(tempDir.toFile(), "test.txt");
// execute & verify
var exception = assertThrows(IllegalArgumentException.class,
() -> FileUtils.writeString(content, file));
assertEquals("content can't be null.", exception.getMessage());
}
@Test
void testWriteStringDestinationIsNull() {
// setup
var content = "Hello World";
File file = null;
// execute & verify
var exception = assertThrows(IllegalArgumentException.class,
() -> FileUtils.writeString(content, file));
assertEquals("destination can't be null.", exception.getMessage());
}
@Test
void testDeleteFileNullFil() {
assertThrows(IllegalArgumentException.class, () -> FileUtils.deleteFile(null));
}
@Test
void testDeleteFile()
throws Exception {
var testFile = Files.createTempFile(tempDir, "test", ".txt").toFile();
assertTrue(testFile.exists());
FileUtils.deleteFile(testFile);
assertFalse(testFile.exists());
}
@Test
void testGetUniqueFilename() {
var filename1 = FileUtils.getUniqueFilename();
var filename2 = FileUtils.getUniqueFilename();
assertNotEquals(filename1, filename2);
}
@Test
void testUnzipFile()
throws IOException, FileUtilsErrorException {
// create temporary source zip file
var source = createTempZipFile("test.txt", "test file data");
source.deleteOnExit();
// unzip the file
FileUtils.unzipFile(source, tempDir.toFile());
// check that output file exists
var outputFile = new File(tempDir.toFile().getAbsolutePath() + File.separator + "test.txt");
assertTrue(outputFile.exists(), "Unzipped file should exist at destination.");
// clean up test files/directories
outputFile.delete();
}
@Test
void testUnzipFileNullSource() {
// test null source file argument
assertThrows(IllegalArgumentException.class, () -> {
FileUtils.unzipFile(null, new File("destination"));
});
}
@Test
void testUnzipFileNullDestination() {
// test null destination argument
assertThrows(IllegalArgumentException.class, () -> {
FileUtils.unzipFile(new File("source"), null);
});
}
@Test
void testUnzipFileBadZipFile() {
// test invalid zip file argument
assertThrows(FileUtilsErrorException.class, () -> {
FileUtils.unzipFile(new File("bad_zip_file"), new File("destination"));
});
}
@Test
void testUnzipFileBadOutputPath()
throws IOException {
// create temporary source zip file
var source = createTempZipFile("test.txt", "test file data");
source.deleteOnExit();
// create temporary directory that should not be writable
var destination = Files.createTempDirectory("test_dir").toFile();
destination.deleteOnExit();
destination.setWritable(false);
// test unzipping to invalid output path
assertThrows(FileUtilsErrorException.class, () -> {
FileUtils.unzipFile(source, destination);
});
// clean up test files/directories
destination.setWritable(true);
destination.delete();
}
private File createTempZipFile(String entryFileName, String entryFileData)
throws IOException {
var file = Files.createTempFile("test_file", ".zip").toFile();
try (var out = new ZipOutputStream(new FileOutputStream(file))) {
var entry = new ZipEntry(entryFileName);
out.putNextEntry(entry);
out.write(entryFileData.getBytes());
out.closeEntry();
}
return file;
}
@Test
void testGetBaseNameWithFile() {
var file = new File("/path/to/file.txt");
var expectedBaseName = "file";
var actualBaseName = FileUtils.getBaseName(file);
assertEquals(expectedBaseName, actualBaseName);
}
@Test
void testGetBaseNameWithString() {
var fileName = "file.txt";
var expectedBaseName = "file";
var actualBaseName = FileUtils.getBaseName(fileName);
assertEquals(expectedBaseName, actualBaseName);
}
@Test
void testGetBaseNameWithNullFile() {
assertThrows(IllegalArgumentException.class, () -> {
FileUtils.getBaseName((File) null);
});
}
@Test
void testGetBaseNameWithNullFileName() {
assertThrows(IllegalArgumentException.class, () -> {
FileUtils.getBaseName((String) null);
});
}
@Test
void testGetBaseNameWithNoExtension() {
var fileName = "file";
var expectedBaseName = "file";
var actualBaseName = FileUtils.getBaseName(fileName);
assertEquals(expectedBaseName, actualBaseName);
}
@Test
void testGetBaseNameWithLeadingDot() {
var fileName = ".file.txt";
var expectedBaseName = ".file";
var actualBaseName = FileUtils.getBaseName(fileName);
assertEquals(expectedBaseName, actualBaseName);
}
@Test
void testGetBaseNameWithTrailingDot() {
var fileName = "file.";
var expectedBaseName = "file";
var actualBaseName = FileUtils.getBaseName(fileName);
assertEquals(expectedBaseName, actualBaseName);
}
@Test
void testGetBaseNameWithMultipleDots() {
var fileName = "file.name.txt";
var expectedBaseName = "file.name";
var actualBaseName = FileUtils.getBaseName(fileName);
assertEquals(expectedBaseName, actualBaseName);
}
@Test
void testGetExtensionWithFile() {
var file = new File("test.txt");
var actual = FileUtils.getExtension(file);
var expected = "txt";
assertEquals(expected, actual);
}
@Test
void testGetExtensionWithFileName() {
var fileName = "test.txt";
var actual = FileUtils.getExtension(fileName);
var expected = "txt";
assertEquals(expected, actual);
}
@Test
void testGetExtensionWithoutExtension() {
var fileName = "test";
var actual = FileUtils.getExtension(fileName);
assertNull(actual);
}
@Test
void testGetExtensionWithEmptyString() {
var fileName = "";
var actual = FileUtils.getExtension(fileName);
assertNull(actual);
}
@Test
void testGetExtensionWithNullFile() {
assertThrows(IllegalArgumentException.class, () -> FileUtils.getExtension((File) null));
}
@Test
void testGetExtensionWithNullFileName() {
assertThrows(IllegalArgumentException.class, () -> FileUtils.getExtension((String) null));
}
@Test
public void testCombineToAbsolutePathsEmpty() {
var result = FileUtils.combineToAbsolutePaths();
assertEquals(Collections.emptyList(), result);
}
@Test
public void testCombineToAbsolutePathsNull() {
var result = FileUtils.combineToAbsolutePaths(null);
assertEquals(Collections.emptyList(), result);
}
@Test
public void testCombineToAbsolutePathsEmptyListInMiddle() {
var file1 = new File("file1.txt");
var list1 = List.of(file1);
var result = FileUtils.combineToAbsolutePaths(list1, Collections.emptyList(), list1);
assertEquals(2, result.size());
assertEquals(file1.getAbsolutePath(), result.get(0));
assertEquals(file1.getAbsolutePath(), result.get(1));
}
@Test
public void testCombineToAbsolutePathsDuplicateFiles() {
var file1 = new File("file1.txt");
var file2 = new File("file2.txt");
var list1 = List.of(file1);
var list2 = Arrays.asList(file1, file2, file2);
var result = FileUtils.combineToAbsolutePaths(list1, list2);
assertEquals(4, result.size());
assertEquals(file1.getAbsolutePath(), result.get(0));
assertEquals(file1.getAbsolutePath(), result.get(1));
assertEquals(file2.getAbsolutePath(), result.get(2));
assertEquals(file2.getAbsolutePath(), result.get(3));
}
@Test
public void testCombineToAbsolutePaths() {
// given
var file1 = new File("file1.txt");
var file2 = new File("file2.txt");
var file3 = new File("/path/to/file3.txt");
var list1 = Arrays.asList(file1, file2);
var list2 = List.of(file3);
// when
var result = FileUtils.combineToAbsolutePaths(list1, list2);
// then
assertEquals(3, result.size());
assertEquals(file1.getAbsolutePath(), result.get(0));
assertEquals(file2.getAbsolutePath(), result.get(1));
assertEquals(file3.getAbsolutePath(), result.get(2));
}
@Test
public void testGenerateDirectoryListingWithNullDirectory() {
assertThrows(NullPointerException.class, () -> {
FileUtils.generateDirectoryListing(null);
});
}
@Test
public void testGenerateDirectoryListingWithNonexistentDirectory() {
var directory = new File("nonexistent");
assertThrows(IOException.class, () -> {
FileUtils.generateDirectoryListing(directory);
});
}
@Test
public void testGenerateDirectoryListingWithEmptyDirectory()
throws IOException {
var directory = File.createTempFile("test", "");
directory.delete();
directory.mkdir();
assertEquals("", FileUtils.generateDirectoryListing(directory));
directory.delete();
}
@Test
public void testGenerateDirectoryListingWithDirectoryContainingFilesAndSubdirectories()
throws IOException {
var directory = File.createTempFile("test", "");
directory.delete();
directory.mkdir();
new File(directory, "file1.txt").createNewFile();
new File(directory, "file2.txt").createNewFile();
var subdirectory1 = new File(directory, "subdirectory1");
subdirectory1.mkdir();
new File(subdirectory1, "file3.txt").createNewFile();
var subdirectory2 = new File(directory, "subdirectory2");
subdirectory2.mkdir();
new File(subdirectory2, "file4.txt").createNewFile();
var expectedListing = "/file1.txt\n" +
"/file2.txt\n" +
"/subdirectory1\n" +
"/subdirectory1/file3.txt\n" +
"/subdirectory2\n" +
"/subdirectory2/file4.txt";
assertEquals(expectedListing, FileUtils.generateDirectoryListing(directory));
FileUtils.deleteDirectory(directory);
}
@Test
public void testJoinPathsSinglePath() {
var paths = Collections.singletonList("/path/to/file");
var expected = "/path/to/file";
var actual = FileUtils.joinPaths(paths);
assertEquals(expected, actual);
}
@Test
public void testJoinPathsMultiplePaths() {
var paths = Arrays.asList("/path/to/file1", "/path/to/file2", "/path/to/file3");
var expected = "/path/to/file1" + File.pathSeparator + "/path/to/file2" + File.pathSeparator + "/path/to/file3";
var actual = FileUtils.joinPaths(paths);
assertEquals(expected, actual);
}
@Test
public void testJoinPathsNullPaths() {
List<String> paths = null;
var expected = "";
var actual = FileUtils.joinPaths(paths);
assertEquals(expected, actual);
}
@Test
public void testGetJavaFileListSingleFile()
throws Exception {
var tempFile = new File(tempDir.toFile(), "test.java");
tempFile.createNewFile();
var expected = Collections.singletonList(tempFile);
var actual = FileUtils.getJavaFileList(tempDir.toFile());
assertIterableEquals(expected, actual);
}
@Test
public void testGetJavaFileListNestedDirectories()
throws Exception {
var nestedDir = new File(tempDir.toFile(), "nested");
var tempFile1 = new File(tempDir.toFile(), "test.java");
var tempFile2 = new File(nestedDir, "nested_test.java");
tempDir.toFile().mkdirs();
nestedDir.mkdirs();
tempFile1.createNewFile();
tempFile2.createNewFile();
var expected = Arrays.asList(tempFile1, tempFile2);
var actual = FileUtils.getJavaFileList(tempDir.toFile());
assertTrue(actual.containsAll(expected));
}
@Test
public void testGetJavaFileListNullDirectory() {
File directory = null;
List<File> expected = Collections.emptyList();
var actual = FileUtils.getJavaFileList(directory);
assertIterableEquals(expected, actual);
}
@Test
void testPermissionsFromMode() {
assertTrue(permissionsFromMode(0000).isEmpty());
assertTrue(permissionsFromMode(0001).containsAll(Set.of(OTHERS_EXECUTE)));
assertTrue(permissionsFromMode(0002).containsAll(Set.of(OTHERS_WRITE)));
assertTrue(permissionsFromMode(0004).containsAll(Set.of(OTHERS_READ)));
assertTrue(permissionsFromMode(0003).containsAll(Set.of(OTHERS_EXECUTE, OTHERS_WRITE)));
assertTrue(permissionsFromMode(0005).containsAll(Set.of(OTHERS_EXECUTE, OTHERS_READ)));
assertTrue(permissionsFromMode(0006).containsAll(Set.of(OTHERS_WRITE, OTHERS_READ)));
assertTrue(permissionsFromMode(0007).containsAll(Set.of(OTHERS_EXECUTE, OTHERS_WRITE, OTHERS_READ)));
assertTrue(permissionsFromMode(0010).containsAll(Set.of(GROUP_EXECUTE)));
assertTrue(permissionsFromMode(0020).containsAll(Set.of(GROUP_WRITE)));
assertTrue(permissionsFromMode(0040).containsAll(Set.of(GROUP_READ)));
assertTrue(permissionsFromMode(0030).containsAll(Set.of(GROUP_EXECUTE, GROUP_WRITE)));
assertTrue(permissionsFromMode(0050).containsAll(Set.of(GROUP_EXECUTE, GROUP_READ)));
assertTrue(permissionsFromMode(0060).containsAll(Set.of(GROUP_WRITE, GROUP_READ)));
assertTrue(permissionsFromMode(0070).containsAll(Set.of(GROUP_EXECUTE, GROUP_WRITE, GROUP_READ)));
assertTrue(permissionsFromMode(0100).containsAll(Set.of(OWNER_EXECUTE)));
assertTrue(permissionsFromMode(0200).containsAll(Set.of(OWNER_WRITE)));
assertTrue(permissionsFromMode(0400).containsAll(Set.of(OWNER_READ)));
assertTrue(permissionsFromMode(0300).containsAll(Set.of(OWNER_EXECUTE, OWNER_WRITE)));
assertTrue(permissionsFromMode(0500).containsAll(Set.of(OWNER_EXECUTE, OWNER_READ)));
assertTrue(permissionsFromMode(0600).containsAll(Set.of(OWNER_WRITE, OWNER_READ)));
assertTrue(permissionsFromMode(0700).containsAll(Set.of(OWNER_EXECUTE, OWNER_WRITE, OWNER_READ)));
assertTrue(permissionsFromMode(0744).containsAll(Set.of(
OWNER_EXECUTE, OWNER_WRITE, OWNER_READ,
GROUP_READ,
OTHERS_READ)));
assertTrue(permissionsFromMode(0755).containsAll(Set.of(
OWNER_EXECUTE, OWNER_WRITE, OWNER_READ,
GROUP_READ, GROUP_EXECUTE,
OTHERS_READ, OTHERS_EXECUTE)));
assertTrue(permissionsFromMode(0777).containsAll(Set.of(
OWNER_EXECUTE, OWNER_WRITE, OWNER_READ,
GROUP_EXECUTE, GROUP_WRITE, GROUP_READ,
OTHERS_EXECUTE, OTHERS_WRITE, OTHERS_READ)));
}
@Test
void testPathWithFile() {
var file = new File("file");
var path = FileUtils.path(file);
assertEquals(new File("file").getAbsolutePath(), path.toString());
}
@Test
void testPathWithFileAndPaths() {
var file = new File("file");
var path = FileUtils.path(file, "dir1", "dir2", "file2.txt");
assertEquals(new File("file/dir1/dir2/file2.txt").getAbsolutePath(), path.toString());
}
@Test
void testPathWithPath() {
var basePath = Path.of("path");
var path = FileUtils.path(basePath);
assertEquals(new File("path").getAbsolutePath(), path.toString());
}
@Test
void testPathWithPathAndPaths() {
var basePath = Path.of("path");
var path = FileUtils.path(basePath, "dir1", "dir2", "file2.txt");
assertEquals(new File("path/dir1/dir2/file2.txt").getAbsolutePath(), path.toString());
}
}

View file

@ -0,0 +1,82 @@
/*
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
* Licensed under the Apache License, Version 2.0 (the "License")
*/
package rife.tools;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import java.io.File;
import java.io.IOException;
import java.util.regex.Pattern;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class TestFileUtilsFileList {
@TempDir
File testDir;
Pattern[] included;
Pattern[] excluded;
@BeforeEach
void setUp()
throws IOException {
// create some files in the test directory
new File(testDir, "file1.txt").createNewFile();
new File(testDir, "file2.java").createNewFile();
new File(testDir, "file3.sh").createNewFile();
// set up include and exclude patterns
included = new Pattern[]{Pattern.compile("^.*\\.txt$"), Pattern.compile("^.*\\.java$")};
excluded = new Pattern[]{Pattern.compile("^file1\\.txt$")};
}
@Test
void testGetFileList() {
var file_list = FileUtils.getFileList(testDir, included, excluded);
assertEquals(1, file_list.size());
assertEquals("file2.java", file_list.get(0));
}
@Test
void testGetFileListWithNullDir() {
var file_list = FileUtils.getFileList(null, included, excluded);
assertEquals(0, file_list.size());
}
@Test
void testGetFileListWithNullIncluded() {
var file_list = FileUtils.getFileList(testDir, null, excluded);
assertEquals(2, file_list.size());
assertTrue(file_list.contains("file2.java"));
assertTrue(file_list.contains("file3.sh"));
}
@Test
void testGetFileListWithNullExcluded() {
var file_list = FileUtils.getFileList(testDir, included, null);
assertEquals(2, file_list.size());
assertTrue(file_list.contains("file1.txt"));
assertTrue(file_list.contains("file2.java"));
}
@Test
void testGetFileListWithEmptyIncluded() {
var file_list = FileUtils.getFileList(testDir, new Pattern[0], excluded);
assertEquals(2, file_list.size());
assertTrue(file_list.contains("file2.java"));
assertTrue(file_list.contains("file3.sh"));
}
@Test
void testGetFileListWithEmptyExcluded() {
var file_list = FileUtils.getFileList(testDir, included, new Pattern[0]);
assertEquals(2, file_list.size());
assertTrue(file_list.contains("file1.txt"));
assertTrue(file_list.contains("file2.java"));
}
}

View file

@ -0,0 +1,118 @@
/*
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
* Licensed under the Apache License, Version 2.0 (the "License")
*/
package rife.tools;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import rife.tools.exceptions.FileUtilsErrorException;
import java.io.File;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.regex.Pattern;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class TestFileUtilsTransform {
@TempDir
Path tempDir;
private File createFileWithContent(String fileName, String content)
throws Exception {
var file = new File(tempDir.toFile(), fileName);
FileUtils.writeString(content, file);
return file;
}
@BeforeEach
public void initFiles()
throws Exception {
createFileWithContent("file.txt", "Hello world!");
createFileWithContent("file2.txt", "Hello, world!");
createFileWithContent("file.xml", "1234");
}
@Test
public void testTransformFilesWithoutPatterns()
throws Exception {
// Given
var directory = tempDir.toFile();
Function<String, String> transformer = String::toUpperCase;
// When
FileUtils.transformFiles(directory, transformer);
// Then
assertEquals("HELLO WORLD!", FileUtils.readString(new File(directory, "file.txt")));
assertEquals("HELLO, WORLD!", FileUtils.readString(new File(directory, "file2.txt")));
assertEquals("1234", FileUtils.readString(new File(directory, "file.xml")));
}
@Test
public void testTransformFilesWithPatterns()
throws Exception {
// Given
var directory = tempDir.toFile();
var included = Pattern.compile(".*\\.txt");
var excluded = Pattern.compile(".*\\.bak");
// When
FileUtils.transformFiles(directory, included, excluded, String::toUpperCase);
// Then
assertEquals("HELLO WORLD!", FileUtils.readString(new File(directory, "file.txt")));
assertEquals("HELLO, WORLD!", FileUtils.readString(new File(directory, "file2.txt")));
assertEquals("1234", FileUtils.readString(new File(directory, "file.xml")));
}
@Test
public void testTransformFilesWithPatternLists()
throws Exception {
// Given
var directory = tempDir.toFile();
List<Pattern> includedList = new ArrayList<>();
includedList.add(Pattern.compile(".*\\.txt"));
List<Pattern> excludedList = new ArrayList<>();
excludedList.add(Pattern.compile(".*\\.bak"));
// When
FileUtils.transformFiles(directory, includedList, excludedList, String::toUpperCase);
// Then
assertEquals("HELLO WORLD!", FileUtils.readString(new File(directory, "file.txt")));
assertEquals("HELLO, WORLD!", FileUtils.readString(new File(directory, "file2.txt")));
assertEquals("1234", FileUtils.readString(new File(directory, "file.xml")));
}
@Test
public void testTransformFilesWithPatternArrays()
throws Exception {
// Given
var directory = tempDir.toFile();
var includedArray = new Pattern[]{Pattern.compile(".*\\.txt")};
var excludedArray = new Pattern[]{Pattern.compile(".*\\.bak")};
// When
FileUtils.transformFiles(directory, includedArray, excludedArray, String::toUpperCase);
// Then
assertEquals("HELLO WORLD!", FileUtils.readString(new File(directory, "file.txt")));
assertEquals("HELLO, WORLD!", FileUtils.readString(new File(directory, "file2.txt")));
assertEquals("1234", FileUtils.readString(new File(directory, "file.xml")));
}
@Test
public void testTransformFilesWithInvalidDirectory()
throws FileUtilsErrorException {
// Given
var directory = new File(tempDir.toFile(), "non-existing-directory");
// When
FileUtils.transformFiles(directory, String::toUpperCase);
}
}