package javarepl; import com.googlecode.totallylazy.Pair; import com.googlecode.totallylazy.Sequence; import com.googlecode.totallylazy.Sequences; import com.googlecode.totallylazy.functions.Function1; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Type; import java.net.ServerSocket; import java.net.URI; import java.net.URL; import java.util.function.Consumer; import java.util.jar.JarFile; import java.util.jar.JarInputStream; import java.util.jar.Manifest; import java.util.zip.ZipEntry; import static com.googlecode.totallylazy.Files.*; import static com.googlecode.totallylazy.Randoms.takeFromValues; import static com.googlecode.totallylazy.Sequences.*; import static com.googlecode.totallylazy.Strings.replace; import static com.googlecode.totallylazy.io.URLs.url; import static com.googlecode.totallylazy.predicates.Predicates.is; import static com.googlecode.totallylazy.predicates.Predicates.where; import static java.lang.String.format; import static java.lang.reflect.Modifier.isPublic; import static java.net.URLDecoder.decode; public class Utils { public static Boolean javaVersionAtLeast(String version) { return (System.getProperty("java.version").compareTo(version) >= 0); } public static String randomIdentifier(String prefix) { return prefix + "$" + takeFromValues(characters("abcdefghijklmnopqrstuvwxyz1234567890")).take(20).toString(""); } public static Type extractType(Type type) { if (type instanceof Class<?>) { Class<?> clazz = (Class<?>) type; if (clazz.isAnonymousClass() || clazz.isSynthetic() || clazz.isMemberClass()) { if (clazz.getGenericSuperclass().equals(Object.class)) { return extractType(sequence(clazz.getGenericInterfaces()) .headOption() .getOrElse(Object.class)); } else { return extractType(clazz.getGenericSuperclass()); } } if (!isPublic(clazz.getModifiers())) return extractType(clazz.getGenericSuperclass()); return clazz; } return type; } public static Throwable unwrapException(Throwable e) { if (e instanceof InvocationTargetException) return unwrapException(((InvocationTargetException) e).getTargetException()); return e; } public static URL resolveURL(String path) { try { return url(path); } catch (Exception e) { return url("file:" + path); } } public static boolean isWebUrl(URL classpathUrl) { return sequence("http", "https").contains(classpathUrl.getProtocol()); } public static String applicationVersion() { try { File path = new File(decode(Main.class.getProtectionDomain().getCodeSource().getLocation().getPath(), "ISO-8859-1")); if (!path.isDirectory()) { JarInputStream jarStream = new JarInputStream(new FileInputStream(path)); Manifest manifest = jarStream.getManifest(); return manifest.getMainAttributes().getValue("Implementation-Version"); } } catch (Exception e) { // ignore } return "[unknown]"; } public static <T> Sequence<Sequence<T>> permutations(Sequence<T> items) { return powerSetPermutations(items).filter(where(Sequence::size, is(items.size()))); } public static <T> Sequence<Sequence<T>> powerSetPermutations(Sequence<T> items) { return cartesianProductPower(items, items.size()).append(Sequences.<T>empty()); } private static <T> Sequence<Sequence<T>> cartesianProductPower(Sequence<T> items, int times) { if (times == 0) return items.cartesianProduct().map(Pair.functions.values()).unsafeCast(); return cartesianProductPower(items, times - 1) .cartesianProduct(items) .map(pair -> pair.first().append(pair.second()).unique()) .unique(); } public static Function1<Class<?>, String> canonicalName() { return Class::getCanonicalName; } public static String listValues(String name, Sequence<?> list) { return format(name + ":\n %s\n", list.toString("\n").replaceAll("\n", "\n ")); } public static int randomServerPort() { try { ServerSocket serverSocket = new ServerSocket(0); Integer serverPort = serverSocket.getLocalPort(); serverSocket.close(); return serverPort; } catch (Exception e) { throw new RuntimeException(e); } } public static File randomOutputDirectory() { File file = temporaryDirectory("JavaREPL/" + randomFilename()); file.deleteOnExit(); return file; } public static JarFile jarFile(URI path) { try { return new JarFile(new File(path)); } catch (IOException e) { throw new RuntimeException("Couldn't create jar file for path " + path, e); } } public static Function1<URL, String> urlAsFilePath() { return url -> new File(url.getFile()).getPath(); } public static Sequence<String> entries(File file) { if (file.isDirectory()) { return recursiveFiles(file) .map(path().then(replace(file.getPath() + File.separator, ""))); } else { try { return memorise(new JarFile(new File(file.toURI())).entries()) .map(ZipEntry::getName); } catch (Exception e) { System.err.println("Couldn't load entries from jar " + file.toURI() + ". " + e.getLocalizedMessage()); return empty(); } } } public static Consumer<Throwable> throwException() { return throwable -> { throw new RuntimeException(throwable); }; } }