Inceptum/src/main/java/io/gitlab/jfronny/inceptum/util/Utils.java
2021-10-31 16:59:25 +01:00

194 lines
7.7 KiB
Java

package io.gitlab.jfronny.inceptum.util;
import io.gitlab.jfronny.inceptum.Inceptum;
import io.gitlab.jfronny.inceptum.model.OSType;
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.Arrays;
import java.util.Formatter;
import java.util.function.Function;
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 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 (sha1 == null) return buf;
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(), s -> Inceptum.GSON.fromJson(s, type));
}
public static <T> T downloadObject(String url, Type type) throws IOException {
return downloadObject(url, () -> HttpUtils.get(url).sendString(), s -> Inceptum.GSON.fromJson(s, type));
}
public static <T> T downloadObject(String url, String sha1, Class<T> type) throws IOException {
return downloadObject(url, () -> downloadString(url, sha1), s -> Inceptum.GSON.fromJson(s, type));
}
private static <T> T downloadObject(String url, ThrowingSupplier<String, IOException> sourceString, Function<String, T> builder) throws IOException {
Path cache = Inceptum.CACHE_DIR.resolve(Integer.toString(url.hashCode()));
if (Files.exists(cache))
return builder.apply(Files.readString(cache));
try {
String download = sourceString.get();
Files.writeString(cache, download);
return builder.apply(download);
} catch (IOException e) {
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, Path path) throws IOException {
Files.write(path, downloadData(url));
}
public static void downloadFile(String url, String sha1, Path path) throws IOException {
Files.write(path, downloadData(url, sha1));
}
public static void clearDirectory(Path path) throws IOException {
if (!Files.exists(path)) return;
try {
Files.list(path).forEach(p -> {
if (Files.isDirectory(p)) {
try {
deleteRecursive(p);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
else {
try {
Files.delete(p);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
});
} catch (Throwable t) {
throw new IOException("Could not clear directory", t);
}
}
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 copyRecursive(Path source, Path destination) throws IOException {
copyRecursive(source, destination, StandardCopyOption.COPY_ATTRIBUTES);
}
public static void copyRecursive(Path source, Path destination, CopyOption... copyOptions) throws IOException {
if (!Files.exists(destination)) Files.createDirectories(destination);
if(Files.isDirectory(source)) {
/*Files.walk(source)
.forEach(sourcePath -> {
try {
Path destinationPath = destination.resolve(source.getFileName().toString());
Path targetPath = destinationPath.resolve(source.relativize(sourcePath).toString());
Files.copy(sourcePath, targetPath, copyOptions);
} catch (IOException e) {
Inceptum.LOGGER.error("Could not recursively copy", e);
}
});*/
Files.list(source).forEach(sourcePath -> {
try {
copyRecursive(sourcePath, destination.resolve(sourcePath.getFileName().toString()), copyOptions);
} catch (IOException e) {
Inceptum.LOGGER.error("Could not recursively copy", e);
}
});
} else if(Files.exists(source)) {
Path target = destination.resolve(source.getFileName().toString());
if (!Files.exists(target)
|| Arrays.asList(copyOptions).contains(StandardCopyOption.REPLACE_EXISTING))
Files.copy(source, target, copyOptions);
} else {
throw new FileNotFoundException(source.toAbsolutePath().toString());
}
}
public static void openWebBrowser(URI uri) {
try {
if (OSCheck.OS == OSType.LINUX && JvmUtils.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);
}
}
}