import javax.imageio.*;
import java.awt.image.*;
import java.awt.event.*;
import java.awt.*;
import java.security.spec.*;
import java.security.*;
import java.lang.management.*;
import java.lang.ref.*;
import java.lang.reflect.*;
import java.net.*;
import java.io.*;
import javax.swing.table.*;
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.*;
public class main {
// Now uses TreeMap for nicer sorting (i.e., A must be a orderable type)
static class MultiSet {
Map map = new TreeMap();
public MultiSet() {
}
public MultiSet(A key) {
add(key);
}
public void add(A key) {
add(key, 1);
}
public void add(A key, int count) {
if (map.containsKey(key))
map.put(key, map.get(key)+count);
else
map.put(key, count);
}
public int get(A key) {
return map.containsKey(key) ? map.get(key) : 0;
}
public void remove(A key) {
Integer i = map.get(key);
if (i != null && i > 1)
map.put(key, i - 1);
else
map.remove(key);
}
public List getTopTen(int maxSize) {
List list = getSortedListDescending();
return list.size() > maxSize ? list.subList(0, maxSize) : list;
}
public List getSortedListDescending() {
List list = new ArrayList(map.keySet());
Collections.sort(list, new Comparator() {
public int compare(A a, A b) {
return map.get(b).compareTo(map.get(a));
}
});
return list;
}
public int getNumberOfUniqueElements() {
return map.size();
}
public Set asSet() {
return map.keySet();
}
public A getMostPopularEntry() {
int max = 0;
A a = null;
for (Map.Entry entry : map.entrySet()) {
if (entry.getValue() > max) {
max = entry.getValue();
a = entry.getKey();
}
}
return a;
}
public void removeAll(A key) {
map.remove(key);
}
/*public A getRandomEntry(Randomizer rand) {
int total = size(), n = rand.getRandomNumber(total);
for (Map.Entry entry : map.entrySet()) {
n -= entry.getValue();
if (n < 0)
return entry.getKey();
}
throw new RuntimeException("huch");
}*/
public int size() {
int size = 0;
for (int i : map.values())
size += i;
return size;
}
public MultiSet mergeWith(MultiSet set) {
MultiSet result = new MultiSet();
for (A a : set.asSet()) {
result.add(a, set.get(a));
}
return result;
}
public boolean isEmpty() {
return map.isEmpty();
}
public String toString() {
return structure(this);
}
}
static MultiSet hitsByIP = new MultiSet();
public static void main(String[] args) throws Exception {
readLocally("hitsByIP");
makeBot("Hit Log.");
}
static synchronized String answer(String s) {
Matches m = new Matches();
if (match3("note! a hit from ip *", s, m)) {
hitsByIP.add(m.unq(0));
saveLocally("hitsByIP");
return "OK, noted.";
}
if (match3("get hits from ip *", s, m))
return "" + hitsByIP.get(m.unq(0));
return null;
}
static int makeBot(String greeting) {
return makeAndroid3(greeting).port;
}
static void makeBot(Android3 a) {
makeAndroid3(a);
}
static int max(int a, int b) {
return Math.max(a, b);
}
static class Matches {
String[] m;
String get(int i) { return m[i]; }
String unq(int i) { return unquote(m[i]); }
String fsi(int i) { return formatSnippetID(unq(i)); }
boolean bool(int i) { return "true".equals(unq(i)); }
String rest() { return m[m.length-1]; } // for matchStart
}
// class Matches
static boolean match3(String pat, String s) {
return match3(pat, s, null);
}
static boolean match3(String pat, String s, Matches matches) {
if (s == null) return false;
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;
}
}
//1001045 // double var remover
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));
}
}
// read a string variable from standard storage
// does not overwrite variable contents if there is no file
static synchronized void readLocally(String varNames) {
for (String variableName : codeTokensOnly(javaTok(varNames))) {
File textFile = new File(programDir(programID()), variableName + ".text");
File structureFile = new File(programDir(programID()), variableName + ".structure");
String value = loadTextFile(textFile);
if (value != null)
set(main.class, variableName, value);
else {
value = loadTextFile(structureFile);
if (value != null)
readLocally_set(main.class, variableName, unstructure(value));
}
}
}
static void readLocally_set(Class c, String varName, Object value) {
Object oldValue = get(c, varName);
if (oldValue instanceof List && !(oldValue instanceof ArrayList) && value != null) {
// Assume it's a synchroList.
value = synchroList((List) value);
}
set(c, varName, value);
}
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());
}
static Object get(Object o, String field) {
if (o instanceof Class) return get((Class) o, field);
if (o.getClass().getName().equals("main$DynamicObject"))
return call(get_raw(o, "fieldValues"), "get", field);
return get_raw(o, field);
}
static Object get_raw(Object o, String 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 structure(Object o) {
return structure(o, 0);
}
// leave to false, unless unstructure() breaks
static boolean structure_allowShortening = false;
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) { // TODO: store the type (e.g. HashSet/TreeSet)
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 "array{" + buf + "}";
}
if (o instanceof String)
return quote(stringSizeLimit != 0 ? shorten((String) o, stringSizeLimit) : (String) o);
if (o instanceof Class)
return "class(" + quote(((Class) o).getName()) + ")";
if (o instanceof Throwable)
return "exception(" + quote(((Throwable) o).getMessage()) + ")";
// 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\\$", "");
int numFields = 0;
String fieldName = "";
if (shortName.equals("DynamicObject")) {
shortName = (String) get(o, "className");
Map fieldValues = (Map) get(o, "fieldValues");
for (String _fieldName : fieldValues.keySet()) {
fieldName = _fieldName;
Object value = fieldValues.get(fieldName);
if (value != null) {
if (buf.length() != 0) buf.append(", ");
buf.append(fieldName + "=" + structure(value, stringSizeLimit));
}
++numFields;
}
} else {
// regular class
// TODO: go to superclasses too
Field[] fields = o.getClass().getDeclaredFields();
for (Field field : fields) {
if ((field.getModifiers() & Modifier.STATIC) != 0)
continue;
Object value;
try {
field.setAccessible(true);
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 && structure_allowShortening)
b = b.replaceAll("^" + fieldName + "=", ""); // drop field name if only one
String s = shortName;
if (buf.length() != 0)
s += "(" + b + ")";
return s;
}
static Class include(String progID) {
Class c = hotwire(progID);
setOpt(c, "programID", getProgramID());
return c;
}
static String programID() {
return getProgramID();
}
static abstract class DialogIO {
abstract boolean isStillConnected();
abstract String readLineNoBlock();
abstract boolean waitForLine();
abstract void sendLine(String line);
abstract boolean isLocalConnection();
abstract Socket getSocket();
abstract void close();
int getPort() { return getSocket().getPort(); }
boolean helloRead;
String readLine() {
waitForLine();
helloRead = true;
return readLineNoBlock();
}
String ask(String s, Object... args) {
if (!helloRead) readLine();
if (args.length != 0) s = format3(s, args);
sendLine(s);
return readLine();
}
String askLoudly(String s, Object... args) {
if (!helloRead) readLine();
if (args.length != 0) s = format3(s, args);
print("> " + s);
sendLine(s);
String answer = readLine();
print("< " + answer);
return answer;
}
}
static abstract class DialogHandler {
abstract void run(DialogIO io);
} // Dialog classes
static class Android3 {
String greeting;
boolean publicOverride; // optionally set this in client
int startPort = 5000; // optionally set this in client
Responder responder;
boolean console = true;
boolean daemon = false;
boolean incomingSilent = false;
boolean useMultiPort = true;
// set by system
int port;
long vport;
DialogHandler handler;
ServerSocket server;
Android3(String greeting) {
this.greeting = greeting;}
Android3() {}
synchronized void dispose() {
if (server == null) return;
try {
server.close();
} catch (IOException e) {
print("[internal] " + e);
}
server = null;
}
}
static abstract class Responder {
abstract String answer(String s, List history);
}
static Android3 makeAndroid3(final String greeting) {
return makeAndroid3(new Android3(greeting));
}
static Android3 makeAndroid3(final String greeting, Responder responder) {
Android3 android = new Android3(greeting);
android.responder = responder;
return makeAndroid3(android);
}
static Android3 makeAndroid3(final Android3 a) {
if (a.responder == null)
a.responder = new Responder() {
String answer(String s, List history) {
return callStaticAnswerMethod(s, history);
}
};
if (a.useMultiPort) {
a.vport = addToMultiPort(a.greeting, a.responder);
return a;
}
print(a.greeting);
a.handler = makeAndroid3_makeDialogHandler(a);
a.port = a.daemon
? startDialogServerOnPortAboveDaemon(a.startPort, a.handler)
: startDialogServerOnPortAbove(a.startPort, a.handler);
a.server = startDialogServer_serverSocket;
if (a.console && makeAndroid3_consoleInUse()) a.console = false;
if (a.console) {
// Console handling stuff
print("You may also type on this console.");
Thread _t_0 = new Thread() {
public void run() {
try {
List history = new ArrayList();
String line;
while ((line = readLine()) != null) {
if ("bye".equals(line)) {
print("> bye stranger");
history = new ArrayList();
} else {
history.add(line);
history.add(makeAndroid3_getAnswer(line, history, a)); // prints answer on console too
}
}
} catch (Exception _e) {
throw _e instanceof RuntimeException ? (RuntimeException) _e : new RuntimeException(_e); } }
};
_t_0.start();
}
record(a);
return a;
}
static DialogHandler makeAndroid3_makeDialogHandler(final Android3 a) {
return new DialogHandler() {
public void run(final DialogIO io) {
if (!a.publicOverride && !(publicCommOn() || io.isLocalConnection())) {
io.sendLine("Sorry, not allowed");
return;
}
String dialogID = randomID(8);
io.sendLine(a.greeting + " / Your ID: " + dialogID);
List history = new ArrayList();
while (io.isStillConnected()) {
if (io.waitForLine()) {
final String line = io.readLineNoBlock();
String s = dialogID + " at " + now() + ": " + quote(line);
if (!a.incomingSilent)
print(s);
if ("bye".equals(line)) {
io.sendLine("bye stranger");
return;
}
Matches m = new Matches();
history.add(line);
String answer;
if (match3("this is a continuation of talk *", s, m)
|| match3("hello bot! this is a continuation of talk *", s, m)) {
dialogID = unquote(m.m[0]);
answer = "ok";
} else
answer = makeAndroid3_getAnswer(line, history, a);
history.add(answer);
io.sendLine(answer);
//appendToLog(logFile, s);
}
}
}};
}
static String makeAndroid3_getAnswer(String line, List history, Android3 a) {
String answer;
try {
answer = makeAndroid3_fallback(line, history, a.responder.answer(line, history));
} catch (Throwable e) {
e = getInnerException(e);
e.printStackTrace();
answer = e.toString();
}
if (!a.incomingSilent)
print("> " + shorten(answer, 500));
return answer;
}
static String makeAndroid3_fallback(String s, List history, String answer) {
// Now we only do the safe thing instead of VM inspection - give out our process ID
if (answer == null && match3("what is your pid", s))
return getPID();
if (answer == null && match3("what is your program id", s)) // should be fairly safe, right?
return getProgramID();
if (match3("get injection id", s))
return getInjectionID();
if (answer == null) answer = "?";
if (answer.indexOf('\n') >= 0 || answer.indexOf('\r') >= 0)
answer = quote(answer);
return answer;
}
static boolean makeAndroid3_consoleInUse() {
for (Object o : record_list)
if (o instanceof Android3 && ((Android3) o).console)
return true;
return false;
}
static String quote(String s) {
if (s == null) return "null";
return "\"" + s.replace("\\", "\\\\").replace("\"", "\\\"").replace("\r", "\\r").replace("\n", "\\n") + "\"";
}
static String quote(long l) {
return quote("" + l);
}
static List codeTokensOnly(List tok) {
List l = new ArrayList();
for (int i = 1; i < tok.size(); i += 2)
l.add(tok.get(i));
return l;
}
static List parse3(String s) {
return dropPunctuation(javaTokPlusPeriod(s));
}
static List synchroList() {
return Collections.synchronizedList(new ArrayList());
}
static List synchroList(List l) {
return Collections.synchronizedList(l);
}
static class DynamicObject {
String className;
Map fieldValues = new TreeMap();
}
static Object unstructure(String text) {
return unstructure(text, false);
}
// actually it's now almost the same as jsonDecode :)
static Object unstructure(String text, final boolean allDynamic) {
final List tok = javaTok(text);
class X {
int i = 1;
Object parse() {
String t = tok.get(i);
if (t.startsWith("\"")) {
String s = unquote(tok.get(i));
i += 2;
return s;
}
if (t.equals("{"))
return parseMap();
if (t.equals("["))
return parseList();
if (t.equals("array"))
return parseArray();
if (t.equals("class"))
return parseClass();
if (t.equals("null")) {
i += 2; return null;
}
if (t.equals("false")) {
i += 2; return false;
}
if (t.equals("true")) {
i += 2; return true;
}
if (isInteger(t)) {
i += 2;
long l = Long.parseLong(t);
if (l == (int) l)
return (int) l;
return l;
}
if (isJavaIdentifier(t)) {
Class c = allDynamic ? null : findClass(t);
DynamicObject dO = null;
Object o = null;
if (c != null)
o = nuObject(c);
else {
dO = new DynamicObject();
dO.className = t;
}
i += 2;
if (i < tok.size() && tok.get(i).equals("(")) {
consume("(");
while (!tok.get(i).equals(")")) {
// It's like parsing a map.
//Object key = parse();
//if (tok.get(i).equals(")"))
// key = onlyField();
String key = unquote(tok.get(i));
i += 2;
consume("=");
Object value = parse();
if (o != null)
set(o, key, value);
else
dO.fieldValues.put(key, value);
if (tok.get(i).equals(",")) i += 2;
}
consume(")");
}
return o != null ? o : dO;
}
throw new RuntimeException("Unknown token " + (i+1) + ": " + t);
}
Object parseList() {
consume("[");
List list = new ArrayList();
while (!tok.get(i).equals("]")) {
list.add(parse());
if (tok.get(i).equals(",")) i += 2;
}
consume("]");
return list;
}
Object parseArray() {
consume("array");
consume("{");
List list = new ArrayList();
while (!tok.get(i).equals("}")) {
list.add(parse());
if (tok.get(i).equals(",")) i += 2;
}
consume("}");
return list.toArray();
}
Object parseClass() {
consume("class");
consume("(");
String name = tok.get(i);
i += 2;
consume(")");
Class c = allDynamic ? null : findClass(name);
if (c != null) return c;
DynamicObject dO = new DynamicObject();
dO.className = "java.lang.Class";
dO.fieldValues.put("name", name);
return dO;
}
Object parseMap() {
consume("{");
Map map = new TreeMap();
while (!tok.get(i).equals("}")) {
Object key = unstructure(tok.get(i));
i += 2;
consume("=");
Object value = parse();
map.put(key, value);
if (tok.get(i).equals(",")) i += 2;
}
consume("}");
return map;
}
void consume(String s) {
if (!tok.get(i).equals(s)) {
String prevToken = i-2 >= 0 ? tok.get(i-2) : "";
String nextTokens = join(tok.subList(i, Math.min(i+4, tok.size())));
fail(quote(s) + " expected: " + prevToken + " " + nextTokens + " (" + i + "/" + tok.size() + ")");
}
i += 2;
}
}
return new X().parse();
}
static File programDir() {
return programDir(getProgramID());
}
static File programDir(String snippetID) {
return new File(userHome(), "JavaX-Data/" + formatSnippetID(snippetID));
}
// 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, "*");
while (pat.size() < tok.size()) {
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()]);
}
// replacement for class JavaTok
// maybe incomplete, might want to add floating point numbers
// todo also: extended multi-line strings
static List javaTok(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
++j;
tok.add(s.substring(i, j));
i = j;
}
if ((tok.size() % 2) == 0) tok.add("");
return tok;
}
static List javaTok(List tok) {
return javaTok(join(tok));
}
/** 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();
}
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 e instanceof RuntimeException ? (RuntimeException) e : 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 shorten(String s, int max) {
return s.length() <= max ? s : s.substring(0, Math.min(s.length(), max)) + "...";
}
static String callStaticAnswerMethod(String s, List history) {
String answer = (String) callOpt(getMainClass(), "answer", s, history);
if (answer == null)
answer = (String) callOpt(getMainClass(), "answer", s);
return answer;
}
static String getInjectionID() {
return (String) call(getJavaX(), "getInjectionID", getMainClass());
}
static Object addToMultiPort_responder;
static long addToMultiPort(final String botName) {
return addToMultiPort(botName, new Object() {
public String answer(String s, List history) {
String answer = (String) ( callOpt(getMainClass(), "answer", s, history));
if (answer != null) return answer;
answer = (String) callOpt(getMainClass(), "answer", s);
if (answer != null) return answer;
if (match3("get injection id", s))
return getInjectionID();
return null;
}
});
}
static long addToMultiPort(final String botName, final Object responder) {
print(botName);
addToMultiPort_responder = responder;
startMultiPort();
List ports = getMultiPorts();
if (ports.isEmpty())
fail("No multiports!");
if (ports.size() > 1)
print("Multiple multi-ports. Using last one.");
Object port = last(ports);
return (Long) call(port, "addResponder", botName, new Object() {
public String answer(String s, List history) {
if (match3("get injection id", s))
return getInjectionID();
if (match3("your name", s))
return botName;
return (String) call(responder, "answer", s, history);
}
});
}
static int l(Object[] array) {
return array == null ? 0 : array.length;
}
static int l(List list) {
return list == null ? 0 : list.size();
}
static int l(String s) {
return s == null ? 0 : s.length();
}
static Throwable getInnerException(Throwable e) {
while (e.getCause() != null)
e = e.getCause();
return e;
}
static boolean isJavaIdentifier(String s) {
if (s.length() == 0 || !Character.isJavaIdentifierStart(s.charAt(0)))
return false;
for (int i = 1; i < s.length(); i++)
if (!Character.isJavaIdentifierPart(s.charAt(i)))
return false;
return true;
}
// currently finds only inner classes of class "main"
// returns null on not found
// this is the simple version that is not case-tolerant
static Class findClass(String name) {
try {
return Class.forName("main$" + name);
} catch (ClassNotFoundException e) {
return null;
}
}
static Object nuObject(Class c, Object... args) { try {
Constructor m = nuObject_findConstructor(c, args);
m.setAccessible(true);
return m.newInstance(args);
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
static Constructor nuObject_findConstructor(Class c, Object... args) {
for (Constructor m : c.getDeclaredConstructors()) {
if (!nuObject_checkArgs(m.getParameterTypes(), args, false))
continue;
return m;
}
throw new RuntimeException("Constructor with " + args.length + " matching parameter(s) not found in " + c.getName());
}
static boolean nuObject_checkArgs(Class[] types, Object[] args, boolean debug) {
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 boolean publicCommOn() {
return "1".equals(loadTextFile(new File(userHome(), ".javax/public-communication")));
}
static List