001// Generated by delombok at Sat Feb 25 17:58:34 UTC 2023
002package io.cui.tools.io;
003
004import static io.cui.tools.base.Preconditions.checkArgument;
005import static io.cui.tools.string.MoreStrings.isEmpty;
006import static java.util.Objects.requireNonNull;
007import java.io.BufferedInputStream;
008import java.io.IOException;
009import java.io.StringWriter;
010import java.nio.charset.Charset;
011import java.nio.charset.StandardCharsets;
012import java.nio.file.Files;
013import java.nio.file.Path;
014import java.nio.file.StandardCopyOption;
015
016/**
017 * Utility class for dealing with generic / classpath related file access.
018 *
019 * @author Oliver Wolff
020 */
021public final class FileLoaderUtility {
022    /**
023     * Returns an implementation of {@link FileLoader} matching to the given path.
024     *
025     * @param pathName must not be null or empty.
026     * @return a configured implementation of {@link FileLoader}. In case the pathName is prefixed
027     *         with {@link FileTypePrefix#CLASSPATH} it returns a {@link ClassPathLoader}. If
028     *         prefixed with
029     *         {@link FileTypePrefix#URL} it returns a {@link UrlLoader}. Otherwise, it returns a
030     *         {@link FileSystemLoader}.
031     */
032    public static FileLoader getLoaderForPath(final String pathName) {
033        if (isEmpty(pathName)) {
034            throw new IllegalArgumentException("pathName must not be null nor empty");
035        }
036        if (pathName.startsWith(FileTypePrefix.CLASSPATH.getPrefix())) {
037            return new ClassPathLoader(pathName);
038        }
039        if (pathName.startsWith(FileTypePrefix.URL.getPrefix())) {
040            return new UrlLoader(pathName);
041        }
042        return new FileSystemLoader(pathName);
043    }
044
045    // owolff: See hint Caution: Security-Impact
046    /**
047     * Helper class that copies the content of a {@link FileLoader} to the temp-folder and
048     * references it
049     * <h2>Caution: Security-Impact</h2>
050     * Creating a temp-file might introduce a security issue. Never ever use this location for
051     * sensitive information that might be of interest for an attacker
052     *
053     * @param source must not be null and represent an accessible file, saying
054     *            {@link FileLoader#isReadable()}
055     * @param markDeleteOnExit if <code>true</code> the file will be marked to delete on Exit.
056     * @return a reference on a file copied in the temp folder
057     * @throws IOException
058     */
059    @SuppressWarnings("java:S5443")
060    public static Path copyFileToTemp(final FileLoader source, final boolean markDeleteOnExit) throws IOException {
061        checkArgument(null != source, "Attribute with name source must not be null");
062        checkArgument(source.isReadable(), "Source must be readable");
063        final var target = Files.createTempFile(source.getFileName().getNamePart(), source.getFileName().getSuffix());
064        try (var inputStream = source.inputStream()) {
065            Files.copy(new BufferedInputStream(inputStream), target, StandardCopyOption.REPLACE_EXISTING);
066        }
067        if (markDeleteOnExit) {
068            target.toFile().deleteOnExit();
069        }
070        return target;
071    }
072
073    /**
074     * Convenience method for reading the content from a given {@link FileLoader} into a String
075     *
076     * @param fileLoader must not be null
077     * @param charset must not be null
078     * @return The String content of the File represented by the given {@link FileLoader}
079     * @throws IOException
080     */
081    public static String toString(final FileLoader fileLoader, final Charset charset) throws IOException {
082        requireNonNull(fileLoader);
083        final var writer = new StringWriter();
084        try (var inputStream = fileLoader.inputStream()) {
085            IOStreams.copy(inputStream, writer, charset);
086        }
087        return writer.toString();
088    }
089
090    /**
091     * Convenience method for reading the content from a given {@link FileLoader} into a String read
092     * as UTF-8 String
093     *
094     * @param fileLoader must not be null
095     * @return The String content of the File represented by the given {@link FileLoader}
096     * @throws IOException
097     */
098    public static String toString(final FileLoader fileLoader) throws IOException {
099        return toString(fileLoader, StandardCharsets.UTF_8);
100    }
101
102    /**
103     * Convenience method for reading the content from a given {@link FileLoader} into a String read
104     * as UTF-8 String
105     *
106     * @param fileLoader must not be null
107     * @return The String content of the File represented by the given {@link FileLoader}
108     * @throws IllegalArgumentException masking the actual {@link IOException}
109     * @throws NullPointerException if <code>fileLoader</code> is null
110     */
111    public static String toStringUnchecked(final FileLoader fileLoader) {
112        requireNonNull(fileLoader);
113        try {
114            return toString(fileLoader);
115        } catch (final IOException | IllegalStateException e) {
116            throw new IllegalArgumentException("Unable to read from Path " + fileLoader.getFileName(), e);
117        }
118    }
119
120    @java.lang.SuppressWarnings("all")
121    @lombok.Generated
122    private FileLoaderUtility() {
123    }
124}