Inceptum/src/main/java/io/gitlab/jfronny/inceptum/util/Utils.java

154 lines
6.0 KiB
Java

package io.gitlab.jfronny.inceptum.util;
import io.gitlab.jfronny.inceptum.Inceptum;
import java.awt.*;
import java.io.*;
import java.lang.reflect.Type;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
import java.util.Locale;
import java.util.regex.Pattern;
public class Utils {
public static final Pattern VALID_FILENAME = Pattern.compile("[a-zA-Z0-9_\\-.][a-zA-Z0-9 _\\-.]*[a-zA-Z0-9_\\-.]");
public static final String OS;
static {
String os = System.getProperty("os.name", "generic").toLowerCase(Locale.ROOT);
if ((os.contains("mac")) || (os.contains("darwin"))) {
OS = "osx";
} else if (os.contains("win")) {
OS = "windows";
} else if (os.contains("nux")) {
OS = "linux";
} else {
throw new RuntimeException("Unrecognized OS");
}
}
public static String hash(byte[] data) {
Formatter formatter = new Formatter();
try {
for (byte b : MessageDigest.getInstance("SHA-1").digest(data))
formatter.format("%02x", b);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("Could not hash using SHA1", e);
}
return formatter.toString();
}
public static byte[] downloadData(String url) throws IOException {
try (InputStream is = HttpUtils.get(url).sendInputStream()) {
return is.readAllBytes();
}
}
public static byte[] downloadData(String url, String sha1) throws IOException {
byte[] buf = downloadData(url);
if (!Utils.hash(buf).equals(sha1)) throw new IOException("Invalid hash");
return buf;
}
public static <T> T downloadObject(String url, Class<T> type) throws IOException {
return downloadObject(url, () -> HttpUtils.get(url).sendString(), type);
}
public static <T> T downloadObject(String url, String sha1, Class<T> type) throws IOException {
return downloadObject(url, () -> downloadString(url, sha1), type);
}
private static <T> T downloadObject(String url, ThrowingSupplier<String, IOException> sourceString, Class<T> type) throws IOException {
Path cache = Inceptum.CACHE_DIR.resolve(Integer.toString(url.hashCode()));
try {
String download = sourceString.get();
Files.writeString(cache, download);
return Inceptum.GSON.fromJson(download, type);
} catch (IOException e) {
if (Files.exists(cache)) {
Inceptum.LOGGER.info("Using cache for " + url, e);
try (BufferedReader br = Files.newBufferedReader(cache)) {
return Inceptum.GSON.fromJson(br, type);
} catch (IOException ioE) {
throw new IOException("Could not download object and failed loading cache", ioE);
}
} else
throw new IOException("Could not download object and no cache exists", e);
}
}
public static <T> T loadObject(Path file, Class<T> type) throws IOException {
try (BufferedReader br = Files.newBufferedReader(file)) {
return Inceptum.GSON.fromJson(br, type);
}
}
public static <T> T loadObject(Path file, Type type) throws IOException {
try (BufferedReader br = Files.newBufferedReader(file)) {
return Inceptum.GSON.fromJson(br, type);
}
}
public static <T> void writeObject(Path file, T object) throws IOException {
try (BufferedWriter bw = Files.newBufferedWriter(file, StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING)) {
Inceptum.GSON.toJson(object, bw);
}
}
public static String downloadString(String url, String sha1) throws IOException {
return new String(downloadData(url, sha1), StandardCharsets.UTF_8);
}
public static void downloadFile(String url, String sha1, Path path) throws IOException {
Files.write(path, downloadData(url, sha1));
}
public static void deleteRecursive(Path path) throws IOException {
Files.walkFileTree(path, new SimpleFileVisitor<>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
FileVisitResult fv = super.visitFile(file, attrs);
if (fv != FileVisitResult.CONTINUE) return fv;
Files.delete(file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
FileVisitResult fv = super.postVisitDirectory(dir, exc);
if (fv != FileVisitResult.CONTINUE) return fv;
Files.delete(dir);
return FileVisitResult.CONTINUE;
}
});
}
public static void openWebBrowser(URI uri) {
try {
if (OS.equals("linux") && Utils.executableInPath("xdg-open")) {
Runtime.getRuntime().exec("xdg-open " + uri);
} else if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
Desktop.getDesktop().browse(uri);
}
} catch (Exception e) {
Inceptum.LOGGER.error("Error opening web browser!", e);
}
}
public static boolean executableInPath(String executableName) {
try {
return java.util.stream.Stream
.of(System.getenv("PATH").split(java.util.regex.Pattern.quote(File.pathSeparator)))
.map(path -> path.replace("\"", "")).map(Paths::get)
.anyMatch(path -> Files.exists(path.resolve(executableName))
&& Files.isExecutable(path.resolve(executableName)));
} catch (Exception e) {
return false;
}
}
}