Resources.java
/**
* Copyright (C) 2022 Christopher J. Stehno
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.cjstehno.testthings;
import io.github.cjstehno.testthings.serdes.JacksonJsonSerdes;
import io.github.cjstehno.testthings.serdes.SerdesProvider;
import lombok.NoArgsConstructor;
import lombok.val;
import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Map;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.nio.file.StandardOpenOption.CREATE_NEW;
import static java.nio.file.StandardOpenOption.WRITE;
import static lombok.AccessLevel.PRIVATE;
/**
* Some useful utilities for working with classpath resources.
*
* @see io.github.cjstehno.testthings.junit.ResourcesExtension
*/
@NoArgsConstructor(access = PRIVATE)
public final class Resources {
/**
* Loads the specified resource path as a String with the specified charset.
*
* @param path the classpath resource path
* @param charset the charset to be used
* @return the string version of the resource
*/
public static String resourceToString(final String path, final Charset charset) {
return new String(resourceToBytes(path), charset);
}
/**
* Loads the specified resource path as a UTF-8 string.
*
* @param path the classpath resource path
* @return the string version of the resource
*/
public static String resourceToString(final String path) {
return resourceToString(path, UTF_8);
}
/**
* Loads the specified classpath resource as a byte array.
*
* @param path the resource path
* @return a byte array containing the resource data
*/
public static byte[] resourceToBytes(final String path) {
try (val rs = resourceStream(path)) {
return rs.readAllBytes();
} catch (IOException ioe) {
throw new RuntimeException(ioe);
}
}
/**
* Loads the specified classpath resource as an InputStream.
*
* @param path the resource path
* @return an InputStream containing the resource data
*/
public static InputStream resourceStream(final String path) {
return Resources.class.getResourceAsStream(path);
}
/**
* Loads the specified classpath resource as a {@link Reader}, specifically a {@link BufferedReader}.
*
* @param path the resource path
* @return a Reader containing the resource data
*/
public static Reader resourceReader(final String path) {
return new BufferedReader(new InputStreamReader(resourceStream(path)));
}
/**
* Retrieves the URL for the specified resource.
*
* @param path the resource path
* @return the resource URL
*/
public static URL resourceUrl(final String path) {
return Resources.class.getResource(path);
}
/**
* Retrieves the {@link Path} reference to the classpath resource.
*
* @param path the resource path
* @return the Path reference to the classpath resource
*/
public static Path resourcePath(final String path) {
return Path.of(resourceUri(path));
}
/**
* Retrieves the {@link File} reference to the classpath resource.
*
* @param path the resource path
* @return the File reference to the classpath resource
*/
public static File resourceFile(final String path) {
return new File(resourceUri(path));
}
/**
* Loads the resource at the specified path as bytes and then deserializes it to the specified object type.
*
* @param provider the serdes provider
* @param path the resource path
* @param <T> the type of the deserialized object
* @param type the object type
* @return the deserialized object loaded from the resource path
*/
public static <T> T resourceDeserialized(final SerdesProvider provider, final String path, final Class<? extends T> type) {
try {
return provider.deserialize(resourceToBytes(path), type);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* Loads the resource at the specified path as bytes and then deserializes as JSON it to the specified object type.
*
* @param path the resource path
* @param type the object type
* @param <T> the type of the deserialized object
* @return the deserialized object from the resource path content
*/
public static <T> T resourceDeserialized(final String path, final Class<? extends T> type) {
return resourceDeserialized(new JacksonJsonSerdes(), path, type);
}
/**
* Retrieves the URI for the specified resource.
*
* @param path the resource path
* @return the resource URI
*/
public static URI resourceUri(final String path) {
try {
return resourceUrl(path).toURI();
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}
/**
* Copies the classpath resource at the specified path to the provided destination path.
*
* @param resourcePath the classpath resource path
* @param path the destination path
*/
public static void copyResourceTo(final String resourcePath, final Path path) {
try {
Files.write(path, resourceToBytes(resourcePath), WRITE, CREATE_NEW);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* Copies the classpath resource at the specified path to the provided destination file.
*
* @param resourcePath the classpath resource path
* @param file the destination file
*/
public static void copyResourceTo(final String resourcePath, final File file) {
copyResourceTo(resourcePath, file.toPath());
}
/**
* Loads the content at the specified classpath location as a string template. The replacement values are surrounded
* by curly braces, as <code>{tag}</code>. The provided map defines the replacement values.
*
* @param path the resource path
* @param replacements the replacement values
* @return the template with all defined values replaced
*/
public static String template(final String path, final Map<String, Object> replacements) {
var temp = resourceToString(path);
for (val entry : replacements.entrySet()) {
temp = temp.replaceAll("\\{%s\\}".formatted(entry.getKey()), entry.getValue().toString());
}
return temp;
}
}