import javax.imageio.*; import java.awt.image.*; import java.awt.event.*; import java.awt.*; import java.security.NoSuchAlgorithmException; import java.security.MessageDigest; import java.lang.management.*; import java.lang.reflect.*; import java.net.*; import java.io.*; import javax.swing.text.*; import javax.swing.event.*; import javax.swing.*; import java.util.concurrent.atomic.*; import java.util.concurrent.*; import java.util.regex.*; import java.util.List; import java.util.zip.*; import java.util.*; // Talk Bot just LOVES to communicate. // v2 can... store stuff. public class main { static String computerID = getMyComputerID(); static String i; static Object object; public static void main(String[] args) throws Exception { i = "A Talk Bot On Computer " + computerID + "."; makeAndroid(i); } static synchronized String answer(String s) { if (match3("who are you?", s)) return i; if (match3("what is the object?", s)) return structure(object); if (match3("suck the chat", s)) { List lines = getChatHistory(); setObject(lines); return "ok - I'm having " + lines.size() + " line(s)."; } return "hm."; } static void setObject(Object o) { object = o; saveLocally("object"); } static List getChatHistory() { List lines = new ArrayList(); while (true) { String line = suckFromChat(); if (line == null) return lines; lines.add(line); if (line.length() == 0) break; } return lines; } static String getMyComputerID() { try { return computerID(); } catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }} static class Matches { String[] m; } static boolean match3(String pat, String s) { return match3(pat, s, null); } static boolean match3(String pat, String s, Matches matches) { List tokpat = parse3(pat), toks = parse3(s); String[] m = match2(tokpat, toks); //print(structure(tokpat) + " on " + structure(toks) + " => " + structure(m)); if (m == null) return false; else { if (matches != null) matches.m = m; return true; } } static List parse3(String s) { return dropPunctuation(javaTokPlusPeriod(s)); } static abstract class DialogIO { abstract boolean isStillConnected(); abstract String readLineNoBlock(); abstract boolean waitForLine(); abstract void sendLine(String line); abstract boolean isLocalConnection(); abstract Socket getSocket(); } static abstract class DialogHandler { abstract void run(DialogIO io); } // Dialog classes static class Android { int port; DialogHandler handler; } static int makeAndroid(final String greeting) { return makeAndroid(greeting, new StringFunc() { public String get(String s) { try { return (String) call(getMainClass(), "answer", s) ; } catch (Exception _e) { throw _e instanceof RuntimeException ? (RuntimeException) _e : new RuntimeException(_e); } } }); } static int makeAndroidNoConsole(final String greeting, final StringFunc f) { return makeAndroid(greeting, f, false, false); } static int makeAndroidNoConsoleDaemon(final String greeting, final StringFunc f) { return makeAndroid(greeting, f, false, true); } static int makeAndroid(final String greeting, final StringFunc f) { return makeAndroid(greeting, f, true, false); } static int makeAndroid(final String greeting, final StringFunc f, boolean console, boolean daemon) { print(greeting); final Android a = new Android(); a.handler = makeAndroid_makeDialogHandler(greeting, f); a.port = daemon ? startDialogServerOnPortAboveDaemon(5000, a.handler) : startDialogServerOnPortAbove(5000, a.handler); if (console) { print("You may also type on this console."); Thread _t_0 = new Thread() { public void run() { try { String line; while ((line = readLine()) != null) { if ("bye".equals(line)) print("> bye stranger"); else makeAndroid_getAnswer(line, f); // prints answer on console too } } catch (Exception _e) { throw _e instanceof RuntimeException ? (RuntimeException) _e : new RuntimeException(_e); } } }; _t_0.start(); } record(a); return a.port; } static DialogHandler makeAndroid_makeDialogHandler(final String greeting, final StringFunc f) { return new DialogHandler() { public void run(final DialogIO io) { if (!(publicCommOn() || io.isLocalConnection())) { io.sendLine("Sorry, not allowed"); return; } String dialogID = randomID(8); io.sendLine(greeting + " / Your ID: " + dialogID); while (io.isStillConnected()) { if (io.waitForLine()) { final String line = io.readLineNoBlock(); String s = dialogID + " at " + now() + ": " + quote(line); print(s); if ("bye".equals(line)) { io.sendLine("bye stranger"); return; } String answer = makeAndroid_getAnswer(line, f); io.sendLine(answer == null ? "null" : answer); //appendToLog(logFile, s); } } }}; } static String makeAndroid_getAnswer(String line, StringFunc f) { String answer; try { answer = makeAndroid_fallback(line, f.get(line)); } catch (Throwable e) { e = getInnerException(e); e.printStackTrace(); answer = e.toString(); } print("> " + answer); return answer; } static String makeAndroid_fallback(String s, String answer) { if (answer == null) answer = (String) call(getJavaX(), "answer", s); // fall back to VM android if (answer == null) answer = "?"; if (answer.indexOf('\n') >= 0 || answer.indexOf('\r') >= 0) answer = quote(answer); return answer; } static String programID; static synchronized void saveLocally(String variableName) { File textFile = new File(programDir(programID), variableName + ".text"); File structureFile = new File(programDir(programID), variableName + ".structure"); Object x = get(main.class, variableName); if (x == null) { textFile.delete(); structureFile.delete(); } else if (x instanceof String) { structureFile.delete(); saveTextFile(textFile, (String) x); } else { textFile.delete(); saveTextFile(structureFile, structure(x)); } } static String _computerID; public static String computerID() throws IOException { if (_computerID == null) { File file = new File(userHome(), ".tinybrain/computer-id"); _computerID = loadTextFile(file.getPath(), null); if (_computerID == null) { _computerID = makeRandomID(12); saveTextFile(file.getPath(), _computerID); } } return _computerID; } static String structure(Object o) { return structure(o, 0); } static String structure(Object o, int stringSizeLimit) { if (o == null) return "null"; String name = o.getClass().getName(); StringBuilder buf = new StringBuilder(); if (o instanceof Collection) { for (Object x : (Collection) o) { if (buf.length() != 0) buf.append(", "); buf.append(structure(x, stringSizeLimit)); } return "[" + buf + "]"; } if (o instanceof Map) { for (Object e : ((Map) o).entrySet()) { if (buf.length() != 0) buf.append(", "); buf.append(structure(((Map.Entry) e).getKey(), stringSizeLimit)); buf.append("="); buf.append(structure(((Map.Entry) e).getValue(), stringSizeLimit)); } return "{" + buf + "}"; } if (o.getClass().isArray()) { int n = Array.getLength(o); for (int i = 0; i < n; i++) { if (buf.length() != 0) buf.append(", "); buf.append(structure(Array.get(o, i), stringSizeLimit)); } return "{" + buf + "}"; } if (o instanceof String) return quote(stringSizeLimit != 0 ? shorten((String) o, stringSizeLimit) : (String) o); // Need more cases? This should cover all library classes... if (name.startsWith("java.") || name.startsWith("javax.")) return String.valueOf(o); String shortName = o.getClass().getName().replaceAll("^main\\$", ""); // TODO: go to superclasses too Field[] fields = o.getClass().getDeclaredFields(); int numFields = 0; String fieldName = ""; for (Field field : fields) { if ((field.getModifiers() & Modifier.STATIC) != 0) continue; Object value; try { value = field.get(o); } catch (Exception e) { value = "?"; } fieldName = field.getName(); // put special cases here... if (value != null) { if (buf.length() != 0) buf.append(", "); buf.append(fieldName + "=" + structure(value, stringSizeLimit)); } ++numFields; } String b = buf.toString(); if (numFields == 1) b = b.replaceAll("^" + fieldName + "=", ""); // drop field name if only one String s = shortName; if (buf.length() != 0) s += "(" + b + ")"; return s; } static Class getMainClass() { try { return Class.forName("main"); } catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }} static Throwable getInnerException(Throwable e) { while (e.getCause() != null) e = e.getCause(); return e; } static boolean publicCommOn() { return "1".equals(loadTextFile(new File(userHome(), ".javax/public-communication"))); } static List record_list = synchroList(); static void record(Object o) { record_list.add(o); } static AtomicInteger dialogServer_clients = new AtomicInteger(); static int startDialogServerOnPortAbove(int port, DialogHandler handler) { while (!startDialogServerIfPortAvailable(port, handler)) ++port; return port; } static int startDialogServerOnPortAboveDaemon(int port, DialogHandler handler) { while (!startDialogServerIfPortAvailable(port, handler, true)) ++port; return port; } static void startDialogServer(int port, DialogHandler handler) { if (!startDialogServerIfPortAvailable(port, handler)) fail("Can't start dialog server on port " + port); } static boolean startDialogServerIfPortAvailable(int port, final DialogHandler handler) { return startDialogServerIfPortAvailable(port, handler, false); } static boolean startDialogServerIfPortAvailable(int port, final DialogHandler handler, boolean daemon) { ServerSocket serverSocket = null; try { serverSocket = new ServerSocket(port); } catch (IOException e) { // probably the port number is used - let's assume there already is a chat server. return false; } final ServerSocket _serverSocket = serverSocket; Thread thread = new Thread() { public void run() { try { while (true) { try { final Socket s = _serverSocket.accept(); print("connect - clients: " + dialogServer_clients.incrementAndGet()); Thread _t_1 = new Thread() { public void run() { try { try { final Writer w = new OutputStreamWriter(s.getOutputStream(), "UTF-8"); final BufferedReader in = new BufferedReader( new InputStreamReader(s.getInputStream(), "UTF-8")); DialogIO io = new DialogIO() { String line; boolean buff; Socket getSocket() { return s; } // local means localhost - todo: test boolean isLocalConnection() { return s.getInetAddress().isLoopbackAddress(); } boolean isStillConnected() { return !(buff || s.isClosed()); } String readLineNoBlock() { String l = line; line = null; return l; } boolean waitForLine() { try { if (line != null) return true; //print("Readline"); line = in.readLine(); //print("Readline done: " + line); if (line == null) buff = true; return line != null; } catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }} void sendLine(String line) { try { w.write(line + "\n"); w.flush(); } catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }} }; try { handler.run(io); } finally { s.close(); } } finally { print("client disconnect - " + dialogServer_clients.decrementAndGet() + " remaining"); } } catch (Exception _e) { throw _e instanceof RuntimeException ? (RuntimeException) _e : new RuntimeException(_e); } } }; _t_1.start(); } catch (SocketTimeoutException e) { } } } catch (IOException e) { throw new RuntimeException(e); } }}; if (daemon) thread.setDaemon(true); thread.start(); print("Dialog server on port " + port + " started."); return true; } static BufferedReader readLine_reader; static String readLine() { try { if (readLine_reader == null) readLine_reader = new BufferedReader(new InputStreamReader(System.in, "UTF-8")); String s = readLine_reader.readLine(); if (s != null) print(s); return s; } catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }} static File programDir() { return programDir(getProgramID()); } static File programDir(String snippetID) { return new File(userHome(), "JavaX-Data/" + formatSnippetID(snippetID)); } static int suckFromChat_chatPort = 9751; static Socket suckFromChat_socket; static BufferedReader suckFromChat_in, suckFromChatNoHistory_in; static boolean suckFromChat_present; static String suckFromChatNoHistory() { try { if (suckFromChatNoHistory_in == null) { startChatServerIfNotUp(); waitForChatServer(); final Socket s = new Socket("localhost", suckFromChat_chatPort+2); print("connected to chat"); suckFromChatNoHistory_in = new BufferedReader( new InputStreamReader(s.getInputStream(), "UTF-8")); } return suckFromChatNoHistory_in.readLine(); } catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }} static String suckFromChat() { try { if (suckFromChat_in == null) { startChatServerIfNotUp(); waitForChatServer(); suckFromChat_socket = new Socket("localhost", suckFromChat_chatPort+1); print("connected to chat"); //reportToChat("Hey ho I'm sucking!"); suckFromChat_in = new BufferedReader( new InputStreamReader(suckFromChat_socket.getInputStream(), "UTF-8")); } String line = suckFromChat_in.readLine(); if (line != null && line.length() == 0) suckFromChat_present = true; // We have reached the present :) return line; } catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }} static void suckFromChat_close() { try { if (suckFromChat_socket != null) { suckFromChat_socket.close(); suckFromChat_socket = null; } } catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }} static Class __javax; static Class getJavaX() { return __javax; } static String randomID(int length) { return makeRandomID(length); } static List dropPunctuation(List tok) { tok = new ArrayList(tok); for (int i = 1; i < tok.size(); i += 2) { String t = tok.get(i); if (t.length() == 1 && !Character.isLetter(t.charAt(0)) && !Character.isDigit(t.charAt(0)) && !t.equals("*")) { tok.set(i-1, tok.get(i-1) + tok.get(i+1)); tok.remove(i); tok.remove(i); i -= 2; } } return tok; } // match2 matches multiple "*" (matches a single token) wildcards and zero or one "..." wildcards (matches multiple tokens) static String[] match2(List pat, List tok) { // standard case (no ...) int i = pat.indexOf("..."); if (i < 0) return match2_match(pat, tok); pat = new ArrayList(pat); // We're modifying it, so copy first pat.set(i, "*"); int expand = 0; while (pat.size() < tok.size()) { ++expand; pat.add(i, "*"); pat.add(i+1, ""); // doesn't matter } return match2_match(pat, tok); } static String[] match2_match(List pat, List tok) { List result = new ArrayList(); if (pat.size() != tok.size()) { /*if (debug) print("Size mismatch: " + structure(pat) + " vs " + structure(tok));*/ return null; } for (int i = 1; i < pat.size(); i += 2) { String p = pat.get(i), t = tok.get(i); /*if (debug) print("Checking " + p + " against " + t);*/ if ("*".equals(p)) result.add(t); else if (!p.equalsIgnoreCase(t)) return null; } return result.toArray(new String[result.size()]); } static long now_virtualTime; static long now() { return now_virtualTime != 0 ? now_virtualTime : System.currentTimeMillis(); } // javaTok extended with "..." token. static List javaTokPlusPeriod(String s) { List tok = new ArrayList(); int l = s.length(); int i = 0; while (i < l) { int j = i; char c; String cc; // scan for whitespace while (j < l) { c = s.charAt(j); cc = s.substring(j, Math.min(j+2, l)); if (c == ' ' || c == '\t' || c == '\r' || c == '\n') ++j; else if (cc.equals("/*")) { do ++j; while (j < l && !s.substring(j, Math.min(j+2, l)).equals("*/")); j = Math.min(j+2, l); } else if (cc.equals("//")) { do ++j; while (j < l && "\r\n".indexOf(s.charAt(j)) < 0); } else break; } tok.add(s.substring(i, j)); i = j; if (i >= l) break; c = s.charAt(i); // cc is not needed in rest of loop body cc = s.substring(i, Math.min(i+2, l)); // scan for non-whitespace if (c == '\'' || c == '"') { char opener = c; ++j; while (j < l) { if (s.charAt(j) == opener) { ++j; break; } else if (s.charAt(j) == '\\' && j+1 < l) j += 2; else ++j; } } else if (Character.isJavaIdentifierStart(c)) do ++j; while (j < l && Character.isJavaIdentifierPart(s.charAt(j))); else if (Character.isDigit(c)) do ++j; while (j < l && Character.isDigit(s.charAt(j))); else if (cc.equals("[[")) { do ++j; while (j+1 < l && !s.substring(j, j+2).equals("]]")); j = Math.min(j+2, l); } else if (s.substring(j, Math.min(j+3, l)).equals("...")) j += 3; else ++j; tok.add(s.substring(i, j)); i = j; } if ((tok.size() % 2) == 0) tok.add(""); return tok; } static void print() { System.out.println(); } static void print(Object o) { System.out.println(o); } static void print(long i) { System.out.println(i); } /** writes safely (to temp file, then rename) */ public static void saveTextFile(String fileName, String contents) throws IOException { File file = new File(fileName); File parentFile = file.getParentFile(); if (parentFile != null) parentFile.mkdirs(); String tempFileName = fileName + "_temp"; if (contents != null) { FileOutputStream fileOutputStream = new FileOutputStream(tempFileName); OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream, "UTF-8"); PrintWriter printWriter = new PrintWriter(outputStreamWriter); printWriter.print(contents); printWriter.close(); } if (file.exists() && !file.delete()) throw new IOException("Can't delete " + fileName); if (contents != null) if (!new File(tempFileName).renameTo(file)) throw new IOException("Can't rename " + tempFileName + " to " + fileName); } public static void saveTextFile(File fileName, String contents) { try { saveTextFile(fileName.getPath(), contents); } catch (IOException e) { throw new RuntimeException(e); } } public static String loadTextFile(String fileName) { try { return loadTextFile(fileName, null); } catch (IOException e) { throw new RuntimeException(e); } } public static String loadTextFile(String fileName, String defaultContents) throws IOException { if (!new File(fileName).exists()) return defaultContents; FileInputStream fileInputStream = new FileInputStream(fileName); InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, "UTF-8"); return loadTextFile(inputStreamReader); } public static String loadTextFile(File fileName) { try { return loadTextFile(fileName, null); } catch (IOException e) { throw new RuntimeException(e); } } public static String loadTextFile(File fileName, String defaultContents) throws IOException { try { return loadTextFile(fileName.getPath(), defaultContents); } catch (IOException e) { throw new RuntimeException(e); } } public static String loadTextFile(Reader reader) throws IOException { StringBuilder builder = new StringBuilder(); try { char[] buffer = new char[1024]; int n; while (-1 != (n = reader.read(buffer))) builder.append(buffer, 0, n); } finally { reader.close(); } return builder.toString(); } public static String quote(String s) { if (s == null) return "null"; return "\"" + s.replace("\\", "\\\\").replace("\"", "\\\"").replace("\r", "\\r").replace("\n", "\\n") + "\""; } static Object call(Object o, String method, Object... args) { try { if (o instanceof Class) { Method m = call_findStaticMethod((Class) o, method, args, false); m.setAccessible(true); return m.invoke(null, args); } else { Method m = call_findMethod(o, method, args, false); m.setAccessible(true); return m.invoke(o, args); } } catch (Exception e) { throw new RuntimeException(e); } } static Method call_findStaticMethod(Class c, String method, Object[] args, boolean debug) { Class _c = c; while (c != null) { for (Method m : c.getDeclaredMethods()) { if (debug) System.out.println("Checking method " + m.getName() + " with " + m.getParameterTypes().length + " parameters");; if (!m.getName().equals(method)) { if (debug) System.out.println("Method name mismatch: " + method); continue; } if ((m.getModifiers() & Modifier.STATIC) == 0 || !call_checkArgs(m, args, debug)) continue; return m; } c = c.getSuperclass(); } throw new RuntimeException("Method '" + method + "' (static) with " + args.length + " parameter(s) not found in " + _c.getName()); } static Method call_findMethod(Object o, String method, Object[] args, boolean debug) { Class c = o.getClass(); while (c != null) { for (Method m : c.getDeclaredMethods()) { if (debug) System.out.println("Checking method " + m.getName() + " with " + m.getParameterTypes().length + " parameters");; if (m.getName().equals(method) && call_checkArgs(m, args, debug)) return m; } c = c.getSuperclass(); } throw new RuntimeException("Method '" + method + "' (non-static) with " + args.length + " parameter(s) not found in " + o.getClass().getName()); } private static boolean call_checkArgs(Method m, Object[] args, boolean debug) { Class[] types = m.getParameterTypes(); if (types.length != args.length) { if (debug) System.out.println("Bad parameter length: " + args.length + " vs " + types.length); return false; } for (int i = 0; i < types.length; i++) if (!(args[i] == null || isInstanceX(types[i], args[i]))) { if (debug) System.out.println("Bad parameter " + i + ": " + args[i] + " vs " + types[i]); return false; } return true; } static String _userHome; static String userHome() { if (_userHome == null) { if (isAndroid()) _userHome = "/storage/sdcard0/"; else _userHome = System.getProperty("user.home"); //System.out.println("userHome: " + _userHome); } return _userHome; } static String makeRandomID(int length) { Random random = new Random(); char[] id = new char[length]; for (int i = 0; i< id.length; i++) id[i] = (char) ((int) 'a' + random.nextInt(26)); return new String(id); } static Object get(Object o, String field) { if (o instanceof Class) return get((Class) o, field); try { Field f = get_findField(o.getClass(), field); f.setAccessible(true); return f.get(o); } catch (Exception e) { throw new RuntimeException(e); } } static Object get(Class c, String field) { try { Field f = get_findStaticField(c, field); f.setAccessible(true); return f.get(null); } catch (Exception e) { throw new RuntimeException(e); } } static Field get_findStaticField(Class c, String field) { for (Field f : c.getDeclaredFields()) if (f.getName().equals(field) && (f.getModifiers() & Modifier.STATIC) != 0) return f; throw new RuntimeException("Static field '" + field + "' not found in " + c.getName()); } static Field get_findField(Class c, String field) { for (Field f : c.getDeclaredFields()) if (f.getName().equals(field)) return f; throw new RuntimeException("Field '" + field + "' not found in " + c.getName()); } static String shorten(String s, int max) { return s.length() <= max ? s : s.substring(0, Math.min(s.length(), max)) + "..."; } static String getProgramID() { return programID; } static List synchroList() { return Collections.synchronizedList(new ArrayList()); } static List synchroList(List l) { return Collections.synchronizedList(l); } // extended over Class.isInstance() to handle primitive types static boolean isInstanceX(Class type, Object arg) { if (type == boolean.class) return arg instanceof Boolean; if (type == int.class) return arg instanceof Integer; if (type == long.class) return arg instanceof Long; if (type == float.class) return arg instanceof Float; if (type == short.class) return arg instanceof Short; if (type == char.class) return arg instanceof Character; if (type == byte.class) return arg instanceof Byte; return type.isInstance(arg); } static void waitForChatServer() { if (!portIsBound(9751)) { System.out.print("Waiting for chat server... "); do { sleep(1000); } while (!portIsBound(9751)); print("OK."); } } static void startChatServerIfNotUp() { if (portIsBound(9751)) { //print("Chat seems to be up."); } else { nohupJavax("1000867"); print("Chat server should be coming up any minute now."); } } static boolean isAndroid() { return System.getProperty("java.vendor").toLowerCase().indexOf("android") >= 0; } static RuntimeException fail() { throw new RuntimeException("fail"); } static RuntimeException fail(String msg) { throw new RuntimeException(msg); } static String formatSnippetID(String id) { return "#" + parseSnippetID(id); } static String formatSnippetID(long id) { return "#" + id; } static boolean portIsBound(int port) { try { ServerSocket s = new ServerSocket(port); s.close(); return false; } catch (IOException e) { return true; } } static void nohupJavax(String javaxargs) { try { int x = latestInstalledJavaX(); File xfile = new File(userHome(), ".javax/x" + Math.max(x, 26) + ".jar"); if (!xfile.isFile()) { String url = "http://tinybrain.de/x26.jar"; byte[] data = loadBinaryPage(url); if (data.length < 1000000) fail("Could not load " + url); saveBinaryFile(xfile.getPath(), data); } String jarPath = xfile.getPath(); nohup("java -jar " + (isWindows() ? winQuote(jarPath) : bashQuote(jarPath)) + " " + javaxargs); } catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }} static void sleep(long ms) { try { Thread.sleep(ms); } catch (Exception e) { throw new RuntimeException(e); } } static void sleep() { try { synchronized(main.class) { main.class.wait(); } } catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }} public static long parseSnippetID(String snippetID) { return Long.parseLong(shortenSnippetID(snippetID)); } static int latestInstalledJavaX() { File[] files = new File(userHome(), ".javax").listFiles(); int v = 0; if (files != null) for (File f : files) { Matcher m = Pattern.compile("x(\\d\\d\\d?)\\.jar").matcher(f.getName()); if (m.matches()) v = Math.max(v, Integer.parseInt(m.group(1))); } return v; } /** possibly improvable */ public static String bashQuote(String text) { if (text == null) return null; return "\"" + text .replace("\\", "\\\\") .replace("\"", "\\\"") .replace("\n", "\\n") .replace("\r", "\\r") + "\""; } /** possibly improvable */ public static String winQuote(String text) { if (text == null) return null; return "\"" + text .replace("\\", "\\\\") .replace("\"", "\\\"") .replace("\n", "\\n") .replace("\r", "\\r") + "\""; } public static boolean isWindows() { return System.getProperty("os.name").contains("Windows"); } public static File nohup(String cmd) throws IOException { File outFile = File.createTempFile("nohup_" + nohup_sanitize(cmd), ".out"); nohup(cmd, outFile, false); return outFile; } static String nohup_sanitize(String s) { return s.replaceAll("[^a-zA-Z0-9\\-_]", ""); } /** outFile takes stdout and stderr. */ public static void nohup(String cmd, File outFile, boolean append) throws IOException { String command = nohup_makeNohupCommand(cmd, outFile, append); File scriptFile = File.createTempFile("_realnohup", isWindows() ? ".bat" : ""); System.out.println("[Nohup] " + command); try { //System.out.println("[RealNohup] Script file: " + scriptFile.getPath()); saveTextFile(scriptFile.getPath(), command); String[] command2; if (isWindows()) command2 = new String[] {"cmd", "/c", "start", "/b", scriptFile.getPath() }; else command2 = new String[] {"/bin/bash", scriptFile.getPath() }; Process process = Runtime.getRuntime().exec(command2); try { process.waitFor(); } catch (InterruptedException e) { throw new RuntimeException(e); } int value = process.exitValue(); //System.out.println("exit value: " + value); } finally { if (!isWindows()) scriptFile.delete(); } } public static String nohup_makeNohupCommand(String cmd, File outFile, boolean append) { mkdirsForFile(outFile); String command; if (isWindows()) command = cmd + (append ? " >>" : " >") + winQuote(outFile.getPath()) + " 2>&1"; else command = "nohup " + cmd + (append ? " >>" : " >") + bashQuote(outFile.getPath()) + " 2>&1 &"; return command; } static byte[] loadBinaryPage(String url) throws IOException { return loadBinaryPage(new URL(url).openConnection()); } public static byte[] loadBinaryPage(URLConnection con) throws IOException { //setHeaders(con); ByteArrayOutputStream buf = new ByteArrayOutputStream(); InputStream inputStream = con.getInputStream(); int n = 0; while (true) { int ch = inputStream.read(); if (ch < 0) break; buf.write(ch); if (++n % 100000 == 0) System.err.println(" " + n + " bytes loaded."); } inputStream.close(); return buf.toByteArray(); } /** writes safely (to temp file, then rename) */ public static void saveBinaryFile(String fileName, byte[] contents) throws IOException { File file = new File(fileName); File parentFile = file.getParentFile(); if (parentFile != null) parentFile.mkdirs(); String tempFileName = fileName + "_temp"; FileOutputStream fileOutputStream = new FileOutputStream(tempFileName); fileOutputStream.write(contents); fileOutputStream.close(); if (file.exists() && !file.delete()) throw new IOException("Can't delete " + fileName); if (!new File(tempFileName).renameTo(file)) throw new IOException("Can't rename " + tempFileName + " to " + fileName); } static void saveBinaryFile(File fileName, byte[] contents) { try { saveBinaryFile(fileName.getPath(), contents); } catch (IOException e) { throw new RuntimeException(e); } } static String shortenSnippetID(String snippetID) { if (snippetID.startsWith("#")) snippetID = snippetID.substring(1); String httpBlaBla = "http://tinybrain.de/"; if (snippetID.startsWith(httpBlaBla)) snippetID = snippetID.substring(httpBlaBla.length()); return snippetID; } public static void mkdirsForFile(File file) { File dir = file.getParentFile(); if (dir != null) // is null if file is in current dir dir.mkdirs(); } static Object process(String processorID, Object in) { return process(processorID, in, "in"); } static Object process(String processorID, Object in, String outVar) { try { Class processor = hotwire(processorID); set(processor, "in", in); call(processor, "main", new Object[] {new String[0]}); return get(processor, outVar); } catch (Exception e) { throw new RuntimeException("Error in #" + parseSnippetID(processorID), e); } } // compile JavaX source, load classes & return main class // src can be a snippet ID or actual source code static Class hotwire(String src) { try { Class j = getJavaX(); List libraries = new ArrayList(); File srcDir = (File) call(j, "transpileMain", src, libraries); if (srcDir == null) fail("transpileMain returned null (src=" + quote(src) + ")"); Object androidContext = get(j, "androidContext"); if (androidContext != null) return (Class) call(j, "loadx2android", srcDir, src); File classesDir = (File) call(j, "TempDirMaker_make"); String javacOutput = (String) call(j, "compileJava", srcDir, libraries, classesDir); System.out.println(javacOutput); URL[] urls = new URL[libraries.size()+1]; urls[0] = classesDir.toURI().toURL(); for (int i = 0; i < libraries.size(); i++) urls[i+1] = libraries.get(i).toURI().toURL(); // make class loader URLClassLoader classLoader = new URLClassLoader(urls); // load & return main class Class theClass = classLoader.loadClass("main"); call(j, "setVars", theClass, isSnippetID(src) ? src: null); return theClass; } catch (Exception e) { throw e instanceof RuntimeException ? (RuntimeException) e : new RuntimeException(e); } } static void set(Object o, String field, Object value) { if (o instanceof Class) set((Class) o, field, value); else try { Field f = set_findField(o.getClass(), field); f.setAccessible(true); f.set(o, value); } catch (Exception e) { throw new RuntimeException(e); } } static void set(Class c, String field, Object value) { try { Field f = set_findStaticField(c, field); f.setAccessible(true); f.set(null, value); } catch (Exception e) { throw new RuntimeException(e); } } static Field set_findField(Class c, String field) { for (Field f : c.getDeclaredFields()) if (f.getName().equals(field)) return f; throw new RuntimeException("Field '" + field + "' not found in " + c.getName()); } static Field set_findStaticField(Class c, String field) { for (Field f : c.getDeclaredFields()) if (f.getName().equals(field) && (f.getModifiers() & Modifier.STATIC) != 0) return f; throw new RuntimeException("Static field '" + field + "' not found in " + c.getName()); } public static boolean isSnippetID(String s) { try { parseSnippetID(s); return true; } catch (RuntimeException e) { return false; } } } interface StringFunc { String get(String s); }