/* A Java-based HTTP stub server Copyright (C) 2012 Alexander Zagniotov, Isa Goksu and Eric Mrak This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package io.github.azagniotov.stubby4j.utils; import io.github.azagniotov.stubby4j.annotations.CoberturaIgnore; import java.io.BufferedInputStream; import java.io.BufferedWriter; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.Set; /** * @author Alexander Zagniotov * @since 11/8/12, 8:30 AM */ @SuppressWarnings("serial") public final class FileUtils { public static final String BR = System.lineSeparator(); private static final Set<String> ASCII_TYPES = Collections.unmodifiableSet( new HashSet<>( Arrays.asList( ".ajx", ".am", ".asa", ".asc", ".asp", ".aspx", ".awk", ".bat", ".c", ".cdf", ".cf", ".cfg", ".cfm", ".cgi", ".cnf", ".conf", ".cpp", ".css", ".csv", ".ctl", ".dat", ".dhtml", ".diz", ".file", ".forward", ".grp", ".h", ".hpp", ".hqx", ".hta", ".htaccess", ".htc", ".htm", ".html", ".htpasswd", ".htt", ".htx", ".in", ".inc", ".info", ".ini", ".ink", ".java", ".js", ".json", ".jsp", ".log", ".logfile", ".m3u", ".m4", ".m4a", ".mak", ".map", ".model", ".msg", ".nfo", ".nsi", ".info", ".old", ".pas", ".patch", ".perl", ".php", ".php2", ".php3", ".php4", ".php5", ".php6", ".phtml", ".pix", ".pl", ".pm", ".po", ".pwd", ".py", ".qmail", ".rb", ".rbl", ".rbw", ".readme", ".reg", ".rss", ".rtf", ".ruby", ".session", ".setup", ".sh", ".shtm", ".shtml", ".sql", ".ssh", ".stm", ".style", ".svg", ".tcl", ".text", ".threads", ".tmpl", ".tpl", ".txt", ".ubb", ".vbs", ".xhtml", ".xml", ".xrc", ".xsl", ".yaml", ".yml" ) ) ); private static final String LINE_SEPARATOR_UNIX = "\n"; private static final String LINE_SEPARATOR_MAC_OS_PRE_X = "\r"; private static final String LINE_SEPARATOR_WINDOWS = "\r\n"; private static final String LINE_SEPARATOR_TOKEN = "[_T_O_K_E_N_]"; private FileUtils() { } public static File uriToFile(final String dataYamlConfigParentDir, final String relativePath) throws IOException { final File contentFile = new File(dataYamlConfigParentDir, relativePath); if (!contentFile.isFile()) { throw new IOException(String.format("Could not load file from path: %s", relativePath)); } return contentFile; } public static File uriToFile(final String absolutePath) throws IOException { final File contentFile = new File(absolutePath); if (!contentFile.isFile()) { throw new IOException(String.format("Could not load file from path: %s", absolutePath)); } return contentFile; } @CoberturaIgnore public static File fileFromString(final String content) throws IOException { final File temp = File.createTempFile("tmp", ".txt"); temp.deleteOnExit(); try (final FileWriter fileWriter = new FileWriter(temp); final BufferedWriter bufferedWriter = new BufferedWriter(fileWriter)) { bufferedWriter.write(content); } return temp; } public static boolean isTemplateFile(final File file) throws IOException { return isCharacterFile(file) && StringUtils.isTokenized(characterFileToString(file)); } public static boolean isFilePathContainTemplateTokens(final File file) { return StringUtils.isTokenized(file.getAbsolutePath()); } public static byte[] fileToBytes(final File file) throws IOException { if (isCharacterFile(file)) { return characterFileToUtf8Bytes(file); } return binaryFileToBytes(file); } @CoberturaIgnore static byte[] binaryFileToBytes(final String dataYamlConfigParentDir, final String relativePath) throws IOException { final File contentFile = new File(dataYamlConfigParentDir, relativePath); if (!contentFile.isFile()) { throw new IOException(String.format("Could not load file from path: %s", relativePath)); } return Files.readAllBytes(Paths.get(contentFile.toURI())); } @CoberturaIgnore static byte[] binaryFileToBytes(final File file) throws IOException { return Files.readAllBytes(Paths.get(file.toURI())); } public static String enforceSystemLineSeparator(final String loadedContent) { if (!StringUtils.isSet(loadedContent)) { return ""; } return loadedContent .replace(LINE_SEPARATOR_WINDOWS, LINE_SEPARATOR_TOKEN) .replace(LINE_SEPARATOR_MAC_OS_PRE_X, LINE_SEPARATOR_TOKEN) .replace(LINE_SEPARATOR_UNIX, LINE_SEPARATOR_TOKEN) .replace(LINE_SEPARATOR_TOKEN, BR); } public static InputStream constructInputStream(final File file) throws IOException { return makeBuffered(Files.newInputStream(Paths.get(file.toURI()))); } public static InputStream constructInputStream(final String content) throws IOException { return makeBuffered(new ByteArrayInputStream(content.getBytes(StringUtils.charsetUTF8()))); } static InputStream makeBuffered(final InputStream inputStream) { return new BufferedInputStream(inputStream); } private static String characterFileToString(final File file) throws IOException { final String loadedContent = StringUtils.inputStreamToString(constructInputStream(file)); return enforceSystemLineSeparator(loadedContent); } private static byte[] characterFileToUtf8Bytes(final File file) throws IOException { final String loadedContent = characterFileToString(file); return StringUtils.getBytesUtf8(loadedContent); } private static boolean isCharacterFile(final File file) throws IOException { return ASCII_TYPES.contains(StringUtils.extractFilenameExtension(file.getName())); } }