Warning : session_start(): open(/var/lib/php/sessions/sess_a0a34q1o5qbvl5llf00knsmbmh, O_RDWR) failed: No space left on device (28) in /var/www/tb-usercake/models/config.php on line 51
Warning : session_start(): Failed to read session data: files (path: /var/lib/php/sessions) in /var/www/tb-usercake/models/config.php on line 51
import java.util.*;
import java.util.zip.*;
import java.util.List;
import java.util.regex.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
import java.util.concurrent.locks.*;
import java.util.function.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
import javax.swing.table.*;
import java.io.*;
import java.net.*;
import java.lang.reflect.*;
import java.lang.ref.*;
import java.lang.management.*;
import java.security.*;
import java.security.spec.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.awt.geom.*;
import javax.imageio.*;
import java.math.*;
import static x30_pkg.x30_util.DynamicObject;
import java.nio.file.Path;
import java.text.NumberFormat;
import java.text.*;
import java.awt.geom.*;
import java.nio.charset.Charset;
import java.util.TimeZone;
import java.text.SimpleDateFormat;
class main {
static class Entity extends NamedConcept {
}
abstract static class AbstractJavaObjectEntity extends Entity {
abstract A object();
public String toString() {
String s = super.toString();
Object o = object();
if (o != null)
s += " " + str_pcall(o);
return s;
}
}
static class TransientJavaObjectEntity extends AbstractJavaObjectEntity {
final public A getObject(){ return object(); }
public A object() { return object; }
transient A object;
}
static class PersistentJavaObjectEntity extends AbstractJavaObjectEntity {
final public A getObject(){ return object(); }
public A object() { return object; }
A object;
}
static class ConceptEntity extends AbstractJavaObjectEntity {
Ref concept = new Ref();
ConceptEntity(A concept) { this.concept.set(concept); }
A object() { return concept.get(); }
}
static class FieldInObjectEntity extends Entity {
static final String _fieldOrder = "objectEntity fieldName";
Ref> objectEntity = new Ref();
String fieldName;
FieldInObjectEntity(AbstractJavaObjectEntity objectEntity, String fieldName) {
this.objectEntity.set(objectEntity);
this.fieldName = fieldName;
}
Object value() { return !objectEntity.has() ? null : getOpt(objectEntity.get().object(), fieldName); }
public String toString() {
String s = super.toString() + " " + fieldName + " in " + objectEntity;
Object value = value();
if (value != null)
s += appendBracketed("value of type " + className(value));
return s;
}
}
static class DeclaredFieldEntity extends Entity {
static final String _fieldOrder = "theClass fieldName";
Class theClass;
String fieldName;
DeclaredFieldEntity(Class theClass, String fieldName) {
this.fieldName = fieldName;
this.theClass = theClass;}
Field fieldObject() { return findFieldOfClass(theClass, fieldName); }
public String toString() {
var fieldObject = fieldObject();
return super.toString() + " " + (fieldObject != null ? str(fieldObject)
: "[field not found: " + className(theClass) + "." + fieldName + "]");
}
}
static String str_pcall(Object o) {
try {
return str(o);
} catch (Throwable e) { printStackTrace(e);
return "[error in toString of " + className(o) + "]";
}
}
static Object getOpt(Object o, String field) {
return getOpt_cached(o, field);
}
static Object getOpt(String field, Object o) {
return getOpt_cached(o, field);
}
static Object getOpt_raw(Object o, String field) { try {
Field f = getOpt_findField(o.getClass(), field);
if (f == null) return null;
makeAccessible(f);
return f.get(o);
} catch (Exception __e) { throw rethrow(__e); } }
// access of static fields is not yet optimized
static Object getOpt(Class c, String field) { try {
if (c == null) return null;
Field f = getOpt_findStaticField(c, field);
if (f == null) return null;
makeAccessible(f);
return f.get(null);
} catch (Exception __e) { throw rethrow(__e); } }
static Field getOpt_findStaticField(Class> c, String field) {
Class _c = c;
do {
for (Field f : _c.getDeclaredFields())
if (f.getName().equals(field) && (f.getModifiers() & java.lang.reflect.Modifier.STATIC) != 0)
return f;
_c = _c.getSuperclass();
} while (_c != null);
return null;
}
static Value value(A a) {
return new Value (a);
}
static String appendBracketed(Object o) {
String b = strOrNull(o);
return empty(b) ? "" : "" + " (" + b + ")";
}
static String appendBracketed(String a, String b) {
return a + appendBracketed(b);
}
static String className(Object o) {
return getClassName(o);
}
static Field fieldObject(Object o, String field) {
return findField2(o, field);
}
static Field findFieldOfClass(Class c, String field) {
return c == null || field == null ? null : getOpt_getFieldMap(c).get(field);
}
static String str(Object o) {
return o == null ? "null" : o.toString();
}
static String str(char[] c) {
return new String(c);
}
static A printStackTrace(A e) {
// we go to system.out now - system.err is nonsense
if (e != null) print(getStackTrace(e));
return e;
}
static void printStackTrace() {
printStackTrace(new Throwable());
}
static void printStackTrace(String msg) {
printStackTrace(new Throwable(msg));
}
static void printStackTrace(String msg, Throwable e) {
printStackTrace(new Throwable(msg, e));
}
//static final Map> getOpt_cache = newDangerousWeakHashMap(f getOpt_special_init);
static class getOpt_Map extends WeakHashMap {
getOpt_Map() {
if (getOpt_special == null) getOpt_special = new HashMap();
clear();
}
public void clear() {
super.clear();
//print("getOpt clear");
put(Class.class, getOpt_special);
put(String.class, getOpt_special);
}
}
static final Map> getOpt_cache = _registerDangerousWeakMap(synchroMap(new getOpt_Map()));
//static final Map> getOpt_cache = _registerWeakMap(synchroMap(new getOpt_Map));
static HashMap getOpt_special; // just a marker
/*static void getOpt_special_init(Map map) {
map.put(Class.class, getOpt_special);
map.put(S.class, getOpt_special);
}*/
static Map getOpt_getFieldMap(Object o) {
Class c = _getClass(o);
HashMap map = getOpt_cache.get(c);
if (map == null)
map = getOpt_makeCache(c);
return map;
}
static Object getOpt_cached(Object o, String field) { try {
if (o == null) return null;
Map map = getOpt_getFieldMap(o);
if (map == getOpt_special) {
if (o instanceof Class)
return getOpt((Class) o, field);
/*if (o instanceof S)
ret getOpt(getBot((S) o), field);*/
if (o instanceof Map)
return ((Map) o).get(field);
}
Field f = map.get(field);
if (f != null) return f.get(o);
if (o instanceof DynamicObject)
return syncMapGet2(((DynamicObject) o).fieldValues, field);
return null;
} catch (Exception __e) { throw rethrow(__e); } }
// used internally - we are in synchronized block
static HashMap getOpt_makeCache(Class c) {
HashMap map;
if (isSubtypeOf(c, Map.class))
map = getOpt_special;
else {
map = new HashMap();
if (!reflection_classesNotToScan().contains(c.getName())) {
Class _c = c;
do {
for (Field f : _c.getDeclaredFields()) {
makeAccessible(f);
String name = f.getName();
if (!map.containsKey(name))
map.put(name, f);
}
_c = _c.getSuperclass();
} while (_c != null);
}
}
if (getOpt_cache != null) getOpt_cache.put(c, map);
return map;
}
static Field getOpt_findField(Class> c, String field) {
Class _c = c;
do {
for (Field f : _c.getDeclaredFields())
if (f.getName().equals(field))
return f;
_c = _c.getSuperclass();
} while (_c != null);
return null;
}
static Field makeAccessible(Field f) {
try {
f.setAccessible(true);
} catch (Throwable e) {
// Note: The error reporting only works with Java VM option --illegal-access=deny
vmBus_send("makeAccessible_error", e, f);
}
return f;
}
static Method makeAccessible(Method m) {
try {
m.setAccessible(true);
} catch (Throwable e) {
vmBus_send("makeAccessible_error", e, m);
}
return m;
}
static Constructor makeAccessible(Constructor c) {
try {
c.setAccessible(true);
} catch (Throwable e) {
vmBus_send("makeAccessible_error", e, c);
}
return c;
}
static RuntimeException rethrow(Throwable t) {
if (t instanceof Error)
_handleError((Error) t);
throw t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t);
}
static RuntimeException rethrow(String msg, Throwable t) {
throw new RuntimeException(msg, t);
}
static String strOrNull(Object o) {
return o == null ? null : str(o);
}
static boolean empty(Collection c) { return c == null || c.isEmpty(); }
static boolean empty(Iterable c) { return c == null || !c.iterator().hasNext(); }
static boolean empty(CharSequence s) { return s == null || s.length() == 0; }
static boolean empty(Map map) { return map == null || map.isEmpty(); }
static boolean empty(Object[] o) { return o == null || o.length == 0; }
static boolean empty(BitSet bs) { return bs == null || bs.isEmpty(); }
static boolean empty(Object o) {
if (o instanceof Collection) return empty((Collection) o);
if (o instanceof String) return empty((String) o);
if (o instanceof Map) return empty((Map) o);
if (o instanceof Object[]) return empty((Object[]) o);
if (o instanceof byte[]) return empty((byte[]) o);
if (o == null) return true;
throw fail("unknown type for 'empty': " + getType(o));
}
static boolean empty(Iterator i) { return i == null || !i.hasNext(); }
static boolean empty(double[] a) { return a == null || a.length == 0; }
static boolean empty(float[] a) { return a == null || a.length == 0; }
static boolean empty(int[] a) { return a == null || a.length == 0; }
static boolean empty(long[] a) { return a == null || a.length == 0; }
static boolean empty(byte[] a) { return a == null || a.length == 0; }
static boolean empty(short[] a) { return a == null || a.length == 0; }
static boolean empty(MultiSet ms) { return ms == null || ms.isEmpty(); }
static boolean empty(MultiMap mm) { return mm == null || mm.isEmpty(); }
static boolean empty(File f) { return getFileSize(f) == 0; }
static boolean empty(Rect r) { return !(r != null && r.w != 0 && r.h != 0); }
static boolean empty(AppendableChain c) { return c == null; }
static String getClassName(Object o) {
return o == null ? "null" : o instanceof Class ? ((Class) o).getName() : o.getClass().getName();
}
static Field findField2(Object o, String field) {
Class c = o.getClass();
HashMap map;
synchronized(getOpt_cache) {
map = getOpt_cache.get(c);
if (map == null)
map = getOpt_makeCache(c);
}
if (map == getOpt_special) {
if (o instanceof Class)
return findField2_findStaticField((Class) o, field);
}
return map.get(field);
}
static Field findField2_findStaticField(Class> c, String field) {
Class _c = c;
do {
for (Field f : _c.getDeclaredFields())
if (f.getName().equals(field) && (f.getModifiers() & java.lang.reflect.Modifier.STATIC) != 0)
return f;
_c = _c.getSuperclass();
} while (_c != null);
return null;
}
static volatile StringBuffer local_log = new StringBuffer(); // not redirected
static boolean printAlsoToSystemOut = true;
static volatile Appendable print_log = local_log; // might be redirected, e.g. to main bot
// in bytes - will cut to half that
static volatile int print_log_max = 1024*1024;
static volatile int local_log_max = 100*1024;
static boolean print_silent = false; // total mute if set
static Object print_byThread_lock = new Object();
static volatile ThreadLocal print_byThread; // special handling by thread - prefers F1
static volatile Object print_allThreads;
static volatile Object print_preprocess;
static void print() {
print("");
}
static A print(String s, A o) {
print(combinePrintParameters(s, o));
return o;
}
// slightly overblown signature to return original object...
static A print(A o) {
ping_okInCleanUp();
if (print_silent) return o;
String s = o + "\n";
print_noNewLine(s);
return o;
}
static void print_noNewLine(String s) {
try {
Object f = getThreadLocal(print_byThread_dontCreate());
if (f == null) f = print_allThreads;
if (f != null)
// We do need the general callF machinery here as print_byThread is sometimes shared between modules
if (isFalse(
f instanceof F1 ? ((F1) f).get(s) :
callF(f, s))) return;
} catch (Throwable e) {
System.out.println(getStackTrace(e));
}
print_raw(s);
}
static void print_raw(String s) {
if (print_preprocess != null) s = (String) callF(print_preprocess, s);
s = fixNewLines(s);
Appendable loc = local_log;
Appendable buf = print_log;
int loc_max = print_log_max;
if (buf != loc && buf != null) {
print_append(buf, s, print_log_max);
loc_max = local_log_max;
}
if (loc != null)
print_append(loc, s, loc_max);
if (printAlsoToSystemOut)
System.out.print(s);
vmBus_send("printed", mc(), s);
}
static void print_autoRotate() {
}
static String getStackTrace(Throwable throwable) {
lastException(throwable);
return getStackTrace_noRecord(throwable);
}
static String getStackTrace_noRecord(Throwable throwable) {
StringWriter writer = new StringWriter();
throwable.printStackTrace(new PrintWriter(writer));
return hideCredentials(writer.toString());
}
static String getStackTrace() {
return getStackTrace_noRecord(new Throwable());
}
static String getStackTrace(String msg) {
return getStackTrace_noRecord(new Throwable(msg));
}
static void clear(Collection c) {
if (c != null) c.clear();
}
static void clear(Map map) {
if (map != null) map.clear();
}
static void put(Map map, A a, B b) {
if (map != null) map.put(a, b);
}
static void put(List l, int i, A a) {
if (l != null && i >= 0 && i < l(l)) l.set(i, a);
}
static List _registerDangerousWeakMap_preList;
static A _registerDangerousWeakMap(A map) {
return _registerDangerousWeakMap(map, null);
}
static A _registerDangerousWeakMap(A map, Object init) {
callF(init, map);
if (init instanceof String) {
final String f = (String) init;
init = new VF1() { public void get(Map map) { try { callMC(f, map) ; } catch (Exception __e) { throw rethrow(__e); } }
public String toString() { return "callMC(f, map)"; }};
}
if (javax() == null) {
// We're in class init
if (_registerDangerousWeakMap_preList == null) _registerDangerousWeakMap_preList = synchroList();
_registerDangerousWeakMap_preList.add(pair(map, init));
return map;
}
call(javax(), "_registerDangerousWeakMap", map, init);
return map;
}
static void _onLoad_registerDangerousWeakMap() {
assertNotNull(javax());
if (_registerDangerousWeakMap_preList == null) return;
for (Pair p : _registerDangerousWeakMap_preList)
_registerDangerousWeakMap(p.a, p.b);
_registerDangerousWeakMap_preList = null;
}
static Map synchroMap() {
return synchroHashMap();
}
static Map synchroMap(Map map) {
return Collections.synchronizedMap(map);
}
static Class> _getClass(String name) {
try {
return Class.forName(name);
} catch (ClassNotFoundException e) {
return null; // could optimize this
}
}
static Class _getClass(Object o) {
return o == null ? null
: o instanceof Class ? (Class) o : o.getClass();
}
static Class _getClass(Object realm, String name) {
try {
return classLoaderForObject(realm).loadClass(classNameToVM(name));
} catch (ClassNotFoundException e) {
return null; // could optimize this
}
}
static B syncMapGet2(Map map, A a) {
if (map == null) return null;
synchronized(collectionMutex(map)) {
return map.get(a);
}
}
static B syncMapGet2(A a, Map map) {
return syncMapGet2(map, a);
}
static boolean isSubtypeOf(Class a, Class b) {
return a != null && b != null && b.isAssignableFrom(a); // << always hated that method, let's replace it!
}
static Set reflection_classesNotToScan_value = litset(
"jdk.internal.loader.URLClassPath"
);
static Set reflection_classesNotToScan() {
return reflection_classesNotToScan_value;
}
static void vmBus_send(String msg, Object... args) {
Object arg = vmBus_wrapArgs(args);
pcallFAll_minimalExceptionHandling(vm_busListeners_live(), msg, arg);
pcallFAll_minimalExceptionHandling(vm_busListenersByMessage_live().get(msg), msg, arg);
}
static void vmBus_send(String msg) {
vmBus_send(msg, (Object) null);
}
static void _handleError(Error e) {
call(javax(), "_handleError", e);
}
static RuntimeException fail() { throw new RuntimeException("fail"); }
static RuntimeException fail(Throwable e) { throw asRuntimeException(e); }
static RuntimeException fail(Object msg) { throw new RuntimeException(String.valueOf(msg)); }
static RuntimeException fail(Object... objects) { throw new Fail(objects); }
static RuntimeException fail(String msg) { throw new RuntimeException(msg == null ? "" : msg); }
static RuntimeException fail(String msg, Throwable innerException) { throw new RuntimeException(msg, innerException); }
static String getType(Object o) {
return getClassName(o);
}
static long getFileSize(String path) {
return path == null ? 0 : new File(path).length();
}
static long getFileSize(File f) {
return f == null ? 0 : f.length();
}
static AutoCloseable tempInterceptPrintIfNotIntercepted(F1 f) {
return print_byThread().get() == null ? tempInterceptPrint(f) : null;
}
static String combinePrintParameters(String s, Object o) {
return (endsWithLetterOrDigit(s) ? s + ": " : s) + o;
}
static void ping_okInCleanUp() {
if (ping_pauseAll || ping_anyActions)
ping_impl(true);
}
// this syntax should be removed...
static Object getThreadLocal(Object o, String name) {
ThreadLocal t = (ThreadLocal) (getOpt(o, name));
return t != null ? t.get() : null;
}
static A getThreadLocal(ThreadLocal tl) {
return tl == null ? null : tl.get();
}
static A getThreadLocal(ThreadLocal tl, A defaultValue) {
return or(getThreadLocal(tl), defaultValue);
}
static ThreadLocal print_byThread_dontCreate() {
return print_byThread;
}
static boolean isFalse(Object o) {
return eq(false, o);
}
static Map> callF_cache = newDangerousWeakHashMap();
static A callF(F0 f) {
return f == null ? null : f.get();
}
static B callF(F1 f, A a) {
return f == null ? null : f.get(a);
}
static A callF(IF0 f) {
return f == null ? null : f.get();
}
static B callF(IF1 f, A a) {
return f == null ? null : f.get(a);
}
static B callF(A a, IF1 f) {
return f == null ? null : f.get(a);
}
static C callF(IF2 f, A a, B b) {
return f == null ? null : f.get(a, b);
}
static void callF(VF1 f, A a) {
if (f != null) f.get(a);
}
static void callF(A a, IVF1 f) {
if (f != null) f.get(a);
}
static void callF(IVF1 f, A a) {
if (f != null) f.get(a);
}
static Object callF(Runnable r) { { if (r != null) r.run(); } return null; }
static Object callF(Object f, Object... args) {
return safeCallF(f, args);
}
static Object safeCallF(Object f, Object... args) {
if (f instanceof Runnable) {
((Runnable) f).run();
return null;
}
if (f == null) return null;
Class c = f.getClass();
ArrayList methods;
synchronized(callF_cache) {
methods = callF_cache.get(c);
if (methods == null)
methods = callF_makeCache(c);
}
int n = l(methods);
if (n == 0) {
if (f instanceof String)
throw fail("Legacy call: " + f);
throw fail("No get method in " + getClassName(c));
}
if (n == 1) return invokeMethod(methods.get(0), f, args);
for (int i = 0; i < n; i++) {
Method m = methods.get(i);
if (call_checkArgs(m, args, false))
return invokeMethod(m, f, args);
}
throw fail("No matching get method in " + getClassName(c));
}
// used internally
static ArrayList callF_makeCache(Class c) {
ArrayList l = new ArrayList();
Class _c = c;
do {
for (Method m : _c.getDeclaredMethods())
if (m.getName().equals("get")) {
makeAccessible(m);
l.add(m);
}
if (!l.isEmpty()) break;
_c = _c.getSuperclass();
} while (_c != null);
callF_cache.put(c, l);
return l;
}
static String fixNewLines(String s) {
int i = indexOf(s, '\r');
if (i < 0) return s;
int l = s.length();
StringBuilder out = new StringBuilder(l);
out.append(s, 0, i);
for (; i < l; i++) {
char c = s.charAt(i);
if (c != '\r')
out.append(c);
else {
out.append('\n');
if (i+1 < l && s.charAt(i+1) == '\n') ++i;
}
}
return out.toString();
}
static void print_append(Appendable buf, String s, int max) { try {
synchronized(buf) {
buf.append(s);
if (buf instanceof StringBuffer)
rotateStringBuffer(((StringBuffer) buf), max);
else if (buf instanceof StringBuilder)
rotateStringBuilder(((StringBuilder) buf), max);
}
} catch (Exception __e) { throw rethrow(__e); } }
static Class mc() {
return main.class;
}
// PersistableThrowable doesn't hold GC-disturbing class references in backtrace
static volatile PersistableThrowable lastException_lastException;
static PersistableThrowable lastException() {
return lastException_lastException;
}
static void lastException(Throwable e) {
lastException_lastException = persistableThrowable(e);
}
static String hideCredentials(URL url) { return url == null ? null : hideCredentials(str(url)); }
static String hideCredentials(String url) {
try {
if (startsWithOneOf(url, "http://", "https://") && isAGIBlueDomain(hostNameFromURL(url))) return url;
} catch (Throwable e) {
print("HideCredentials", e);
}
return url.replaceAll("([&?])(_pass|key|cookie)=[^&\\s\"]*", "$1$2=");
}
static String hideCredentials(Object o) {
return hideCredentials(str(o));
}
static int l(Object[] a) { return a == null ? 0 : a.length; }
static int l(boolean[] a) { return a == null ? 0 : a.length; }
static int l(byte[] a) { return a == null ? 0 : a.length; }
static int l(short[] a) { return a == null ? 0 : a.length; }
static int l(long[] a) { return a == null ? 0 : a.length; }
static int l(int[] a) { return a == null ? 0 : a.length; }
static int l(float[] a) { return a == null ? 0 : a.length; }
static int l(double[] a) { return a == null ? 0 : a.length; }
static int l(char[] a) { return a == null ? 0 : a.length; }
static int l(Collection c) { return c == null ? 0 : c.size(); }
static int l(Iterator i) { return iteratorCount_int_close(i); } // consumes the iterator && closes it if possible
static int l(Map m) { return m == null ? 0 : m.size(); }
static int l(CharSequence s) { return s == null ? 0 : s.length(); }
static long l(File f) { return f == null ? 0 : f.length(); }
static int l(Object o) {
return o == null ? 0
: o instanceof String ? l((String) o)
: o instanceof Map ? l((Map) o)
: o instanceof Collection ? l((Collection) o)
: o instanceof Object[] ? l((Object[]) o)
: o instanceof boolean[] ? l((boolean[]) o)
: o instanceof byte[] ? l((byte[]) o)
: o instanceof char[] ? l((char[]) o)
: o instanceof short[] ? l((short[]) o)
: o instanceof int[] ? l((int[]) o)
: o instanceof float[] ? l((float[]) o)
: o instanceof double[] ? l((double[]) o)
: o instanceof long[] ? l((long[]) o)
: (Integer) call(o, "size");
}
static int l(MultiSet ms) { return ms == null ? 0 : ms.size(); }
static int l(AppendableChain a) { return a == null ? 0 : a.size; }
static HashMap> callMC_cache = new HashMap();
static String callMC_key;
static Method callMC_value;
// varargs assignment fixer for a single string array argument
static Object callMC(String method, String[] arg) {
return callMC(method, new Object[] {arg});
}
static Object callMC(String method, Object... args) { try {
Method me;
if (callMC_cache == null) callMC_cache = new HashMap(); // initializer time workaround
synchronized(callMC_cache) {
me = method == callMC_key ? callMC_value : null;
}
if (me != null) try {
return invokeMethod(me, null, args);
} catch (IllegalArgumentException e) {
throw new RuntimeException("Can't call " + me + " with arguments " + classNames(args), e);
}
List m;
synchronized(callMC_cache) {
m = callMC_cache.get(method);
}
if (m == null) {
if (callMC_cache.isEmpty()) {
callMC_makeCache();
m = callMC_cache.get(method);
}
if (m == null) throw fail("Method named " + method + " not found in main");
}
int n = m.size();
if (n == 1) {
me = m.get(0);
synchronized(callMC_cache) {
callMC_key = method;
callMC_value = me;
}
try {
return invokeMethod(me, null, args);
} catch (IllegalArgumentException e) {
throw new RuntimeException("Can't call " + me + " with arguments " + classNames(args), e);
}
}
for (int i = 0; i < n; i++) {
me = m.get(i);
if (call_checkArgs(me, args, false))
return invokeMethod(me, null, args);
}
throw fail("No method called " + method + " with arguments (" + joinWithComma(getClasses(args)) + ") found in main");
} catch (Exception __e) { throw rethrow(__e); } }
static void callMC_makeCache() {
synchronized(callMC_cache) {
callMC_cache.clear();
Class _c = (Class) mc(), c = _c;
while (c != null) {
for (Method m : c.getDeclaredMethods())
if ((m.getModifiers() & java.lang.reflect.Modifier.STATIC) != 0) {
makeAccessible(m);
multiMapPut(callMC_cache, m.getName(), m);
}
c = c.getSuperclass();
}
}
}
static Class javax() {
return getJavaX();
}
static List synchroList() {
return synchroList(new ArrayList ());
}
static List synchroList(List l) {
return Collections.synchronizedList(l);
}
static Pair pair(A a, B b) {
return new Pair(a, b);
}
static Pair pair(A a) {
return new Pair(a, a);
}
static Object call(Object o) {
return callF(o);
}
// varargs assignment fixer for a single string array argument
static Object call(Object o, String method, String[] arg) {
return call(o, method, new Object[] {arg});
}
static Object call(Object o, String method, Object... args) {
//ret call_cached(o, method, args);
return call_withVarargs(o, method, args);
}
static A assertNotNull(A a) {
assertTrue(a != null);
return a;
}
static A assertNotNull(String msg, A a) {
assertTrue(msg, a != null);
return a;
}
static Map synchroHashMap() {
return synchronizedMap(new HashMap());
}
static ClassLoader classLoaderForObject(Object o) {
if (o instanceof ClassLoader) return ((ClassLoader) o);
if (o == null) return null;
return _getClass(o).getClassLoader();
}
// Note: This is actually broken. Inner classes must stay with a $ separator
static String classNameToVM(String name) {
return name.replace(".", "$");
}
// TODO: JDK 17!! ?? No! Yes? Yes!!
static Object collectionMutex(List l) {
return l;
}
static Object collectionMutex(Object o) {
if (o instanceof List) return o;
// TODO: actually use our own maps so we can get the mutex properly
String c = className(o);
return o;
}
static HashSet litset(A... items) {
return lithashset(items);
}
static Object vmBus_wrapArgs(Object... args) {
return empty(args) ? null
: l(args) == 1 ? args[0]
: args;
}
static void pcallFAll_minimalExceptionHandling(Collection l, Object... args) {
if (l != null) for (Object f : cloneList(l)) { ping(); pcallF_minimalExceptionHandling(f, args); }
}
static void pcallFAll_minimalExceptionHandling(Iterator it, Object... args) {
while (it.hasNext()) { ping(); pcallF_minimalExceptionHandling(it.next(), args); }
}
static Set vm_busListeners_live_cache;
static Set vm_busListeners_live() { if (vm_busListeners_live_cache == null) vm_busListeners_live_cache = vm_busListeners_live_load(); return vm_busListeners_live_cache;}
static Set vm_busListeners_live_load() {
return vm_generalIdentityHashSet("busListeners");
}
static Map vm_busListenersByMessage_live_cache;
static Map vm_busListenersByMessage_live() { if (vm_busListenersByMessage_live_cache == null) vm_busListenersByMessage_live_cache = vm_busListenersByMessage_live_load(); return vm_busListenersByMessage_live_cache;}
static Map vm_busListenersByMessage_live_load() {
return vm_generalHashMap("busListenersByMessage");
}
static RuntimeException asRuntimeException(Throwable t) {
if (t instanceof Error)
_handleError((Error) t);
return t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t);
}
static ThreadLocal print_byThread() {
synchronized(print_byThread_lock) {
if (print_byThread == null)
print_byThread = new ThreadLocal();
}
return print_byThread;
}
// f can return false to suppress regular printing
// call print_raw within f to actually print something
static AutoCloseable tempInterceptPrint(F1 f) {
return tempSetThreadLocal(print_byThread(), f);
}
static boolean endsWithLetterOrDigit(String s) {
return s != null && s.length() > 0 && Character.isLetterOrDigit(s.charAt(s.length()-1));
}
//sbool ping_actions_shareable = true;
static volatile boolean ping_pauseAll = false;
static int ping_sleep = 100; // poll pauseAll flag every 100
static volatile boolean ping_anyActions = false;
static Map ping_actions = newWeakHashMap();
static ThreadLocal ping_isCleanUpThread = new ThreadLocal();
// always returns true
static boolean ping() {
//ifdef useNewPing
newPing();
//endifdef
if (ping_pauseAll || ping_anyActions) ping_impl(true /* XXX */);
//ifndef LeanMode ping_impl(); endifndef
return true;
}
// returns true when it slept
static boolean ping_impl(boolean okInCleanUp) { try {
if (ping_pauseAll && !isAWTThread()) {
do
Thread.sleep(ping_sleep);
while (ping_pauseAll);
return true;
}
if (ping_anyActions) { // don't allow sharing ping_actions
if (!okInCleanUp && !isTrue(ping_isCleanUpThread.get()))
failIfUnlicensed();
Object action = null;
synchronized(ping_actions) {
if (!ping_actions.isEmpty()) {
action = ping_actions.get(currentThread());
if (action instanceof Runnable)
ping_actions.remove(currentThread());
if (ping_actions.isEmpty()) ping_anyActions = false;
}
}
if (action instanceof Runnable)
((Runnable) action).run();
else if (eq(action, "cancelled"))
throw fail("Thread cancelled.");
}
return false;
} catch (Exception __e) { throw rethrow(__e); } }
static A or(A a, A b) {
return a != null ? a : b;
}
static boolean eq(Object a, Object b) {
return a == b || a != null && b != null && a.equals(b);
}
// a little kludge for stuff like eq(symbol, "$X")
static boolean eq(Symbol a, String b) {
return eq(str(a), b);
}
static Map newDangerousWeakHashMap() {
return _registerDangerousWeakMap(synchroMap(new WeakHashMap()));
}
// initFunction: voidfunc(Map) - is called initially, and after clearing the map
static Map newDangerousWeakHashMap(Object initFunction) {
return _registerDangerousWeakMap(synchroMap(new WeakHashMap()), initFunction);
}
static Object invokeMethod(Method m, Object o, Object... args) { try {
try {
return m.invoke(o, args);
} catch (InvocationTargetException e) {
throw rethrow(getExceptionCause(e));
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException(e.getMessage() + " - was calling: " + m + ", args: " + joinWithSpace(classNames(args)));
}
} catch (Exception __e) { throw rethrow(__e); } }
static boolean call_checkArgs(Method m, Object[] args, boolean debug) {
Class>[] types = m.getParameterTypes();
if (types.length != args.length) {
if (debug)
print("Bad parameter length: " + args.length + " vs " + types.length);
return false;
}
for (int i = 0; i < types.length; i++) {
Object arg = args[i];
if (!(arg == null ? !types[i].isPrimitive()
: isInstanceX(types[i], arg))) {
if (debug)
print("Bad parameter " + i + ": " + arg + " vs " + types[i]);
return false;
}
}
return true;
}
static int indexOf(List l, A a, int startIndex) {
if (l == null) return -1;
int n = l(l);
for (int i = startIndex; i < n; i++)
if (eq(l.get(i), a))
return i;
return -1;
}
static int indexOf(List l, int startIndex, A a) {
return indexOf(l, a, startIndex);
}
static int indexOf(List l, A a) {
if (l == null) return -1;
return l.indexOf(a);
}
static int indexOf(String a, String b) {
return a == null || b == null ? -1 : a.indexOf(b);
}
static int indexOf(String a, String b, int i) {
return a == null || b == null ? -1 : a.indexOf(b, i);
}
static int indexOf(String a, char b) {
return a == null ? -1 : a.indexOf(b);
}
static int indexOf(String a, int i, char b) {
return indexOf(a, b, i);
}
static int indexOf(String a, char b, int i) {
return a == null ? -1 : a.indexOf(b, i);
}
static int indexOf(String a, int i, String b) {
return a == null || b == null ? -1 : a.indexOf(b, i);
}
static int indexOf(A[] x, A a) {
int n = l(x);
for (int i = 0; i < n; i++)
if (eq(x[i], a))
return i;
return -1;
}
static int indexOf(Iterable l, A a) {
if (l == null) return -1;
int i = 0;
for (A x : l) {
if (eq(x, a))
return i;
i++;
}
return -1;
}
static void rotateStringBuffer(StringBuffer buf, int max) { try {
if (buf == null) return;
synchronized(buf) {
if (buf.length() <= max) return;
try {
int newLength = max/2;
int ofs = buf.length()-newLength;
String newString = buf.substring(ofs);
buf.setLength(0);
buf.append("[...] ").append(newString);
} catch (Exception e) {
buf.setLength(0);
}
buf.trimToSize();
}
} catch (Exception __e) { throw rethrow(__e); } }
static void rotateStringBuilder(StringBuilder buf, int max) { try {
if (buf == null) return;
synchronized(buf) {
if (buf.length() <= max) return;
try {
int newLength = max/2;
int ofs = buf.length()-newLength;
String newString = buf.substring(ofs);
buf.setLength(0);
buf.append("[...] ").append(newString);
} catch (Exception e) {
buf.setLength(0);
}
buf.trimToSize();
}
} catch (Exception __e) { throw rethrow(__e); } }
static PersistableThrowable persistableThrowable(Throwable e) {
return e == null ? null : new PersistableThrowable(e);
}
static boolean startsWithOneOf(String s, String... l) {
for (String x : l) if (startsWith(s, x)) return true; return false;
}
static boolean startsWithOneOf(String s, Matches m, String... l) {
for (String x : l) if (startsWith(s, x, m)) return true; return false;
}
static boolean isAGIBlueDomain(String domain) {
return domainIsUnder(domain, theAGIBlueDomain());
}
static String hostNameFromURL(String url) { try {
return empty(url) ? null : new URL(url).getHost();
} catch (Exception __e) { throw rethrow(__e); } }
static int iteratorCount_int_close(Iterator i) { try {
int n = 0;
if (i != null) while (i.hasNext()) { i.next(); ++n; }
if (i instanceof AutoCloseable) ((AutoCloseable) i).close();
return n;
} catch (Exception __e) { throw rethrow(__e); } }
static List classNames(Collection l) {
return getClassNames(l);
}
static List classNames(Object[] l) {
return getClassNames(Arrays.asList(l));
}
static String joinWithComma(Collection c) {
return join(", ", c);
}
static String joinWithComma(Object... c) {
return join(", ", c);
}
static String joinWithComma(String... c) {
return join(", ", c);
}
static String joinWithComma(Pair p) {
return p == null ? "" : joinWithComma(str(p.a), str(p.b));
}
static List getClasses(Object[] array) {
List l = emptyList(l(array));
for (Object o : array) l.add(_getClass(o));
return l;
}
static void multiMapPut(Map > map, A a, B b) {
List l = map.get(a);
if (l == null)
map.put(a, l = new ArrayList());
l.add(b);
}
static void multiMapPut(MultiMap mm, A key, B value) {
if (mm != null && key != null && value != null) mm.put(key, value);
}
static Class __javax;
static Class getJavaX() { try {
return __javax;
} catch (Exception __e) { throw rethrow(__e); } }
static void __setJavaX(Class j) {
__javax = j;
_onJavaXSet();
}
static Object call_withVarargs(Object o, String method, Object... args) { try {
if (o == null) return null;
if (o instanceof Class) {
Class c = (Class) o;
_MethodCache cache = callOpt_getCache(c);
Method me = cache.findStaticMethod(method, args);
if (me != null)
return invokeMethod(me, null, args);
// try varargs
List methods = cache.cache.get(method);
if (methods != null) methodSearch: for (Method m : methods) {
{ if (!(m.isVarArgs())) continue; }
{ if (!(isStaticMethod(m))) continue; }
Object[] newArgs = massageArgsForVarArgsCall(m, args);
if (newArgs != null)
return invokeMethod(m, null, newArgs);
}
throw fail("Method " + c.getName() + "." + method + "(" + joinWithComma(classNames(args)) + ") not found");
} else {
Class c = o.getClass();
_MethodCache cache = callOpt_getCache(c);
Method me = cache.findMethod(method, args);
if (me != null)
return invokeMethod(me, o, args);
// try varargs
List methods = cache.cache.get(method);
if (methods != null) methodSearch: for (Method m : methods) {
{ if (!(m.isVarArgs())) continue; }
Object[] newArgs = massageArgsForVarArgsCall(m, args);
if (newArgs != null)
return invokeMethod(m, o, newArgs);
}
throw fail("Method " + c.getName() + "." + method + "(" + joinWithComma(classNames(args)) + ") not found");
}
} catch (Exception __e) { throw rethrow(__e); } }
static void assertTrue(Object o) {
if (!(eq(o, true) /*|| isTrue(pcallF(o))*/))
throw fail(str(o));
}
static boolean assertTrue(String msg, boolean b) {
if (!b)
throw fail(msg);
return b;
}
static boolean assertTrue(boolean b) {
if (!b)
throw fail("oops");
return b;
}
static Map synchronizedMap() {
return synchroMap();
}
static Map synchronizedMap(Map map) {
return synchroMap(map);
}
static HashSet lithashset(A... items) {
HashSet set = new HashSet();
for (A a : items) set.add(a);
return set;
}
static ArrayList cloneList(Iterable l) {
return l instanceof Collection ? cloneList((Collection) l) : asList(l);
}
static ArrayList cloneList(Collection l) {
if (l == null) return new ArrayList();
synchronized(collectionMutex(l)) {
return new ArrayList (l);
}
}
static Object pcallF_minimalExceptionHandling(Object f, Object... args) {
try {
return callFunction(f, args);
} catch (Throwable e) {
System.out.println(getStackTrace(e));
_storeException(e);
}
return null;
}
static Set vm_generalIdentityHashSet(Object name) {
synchronized(vm_generalMap()) {
Set set = (Set) (vm_generalMap_get(name));
if (set == null)
vm_generalMap_put(name, set = syncIdentityHashSet());
return set;
}
}
static Map vm_generalHashMap(Object name) {
synchronized(vm_generalMap()) {
Map m = (Map) (vm_generalMap_get(name));
if (m == null)
vm_generalMap_put(name, m = syncHashMap());
return m;
}
}
static AutoCloseable tempSetThreadLocal(final ThreadLocal tl, A a) {
if (tl == null) return null;
final A prev = setThreadLocal(tl, a);
return new AutoCloseable() { public String toString() { return "tl.set(prev);"; } public void close() throws Exception { tl.set(prev); }};
}
static Map newWeakHashMap() {
return _registerWeakMap(synchroMap(new WeakHashMap()));
}
static void newPing() {
var tl = newPing_actionTL();
Runnable action = tl == null ? null : tl.get();
{ if (action != null) action.run(); }
}
// TODO: test if android complains about this
static boolean isAWTThread() {
if (isAndroid()) return false;
if (isHeadless()) return false;
return isAWTThread_awt();
}
static boolean isAWTThread_awt() {
return SwingUtilities.isEventDispatchThread();
}
static boolean isTrue(Object o) {
if (o instanceof Boolean)
return ((Boolean) o).booleanValue();
if (o == null) return false;
if (o instanceof ThreadLocal) // TODO: remove this
return isTrue(((ThreadLocal) o).get());
throw fail(getClassName(o));
}
static boolean isTrue(Boolean b) {
return b != null && b.booleanValue();
}
static void failIfUnlicensed() {
assertTrue("license off", licensed());
}
static Thread currentThread() {
return Thread.currentThread();
}
static Throwable getExceptionCause(Throwable e) {
Throwable c = e.getCause();
return c != null ? c : e;
}
static String joinWithSpace(Iterable c) {
return join(" ", c);
}
static String joinWithSpace(String... c) {
return join(" ", c);
}
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;
if (type == double.class) return arg instanceof Double;
return type.isInstance(arg);
}
static boolean startsWith(String a, String b) {
return a != null && a.startsWith(unnull(b));
}
static boolean startsWith(String a, char c) {
return nemptyString(a) && a.charAt(0) == c;
}
static boolean startsWith(String a, String b, Matches m) {
if (!startsWith(a, b)) return false;
if (m != null) m.m = new String[] {substring(a, strL(b))};
return true;
}
static boolean startsWith(List a, List b) {
if (a == null || listL(b) > listL(a)) return false;
for (int i = 0; i < listL(b); i++)
if (neq(a.get(i), b.get(i)))
return false;
return true;
}
static boolean domainIsUnder(String domain, String mainDomain) {
return eqic(domain, mainDomain) || ewic(domain, "." + mainDomain);
}
static String theAGIBlueDomain() {
return "agi.blue";
}
static List getClassNames(Collection l) {
List out = new ArrayList();
if (l != null) for (Object o : l)
out.add(o == null ? null : getClassName(o));
return out;
}
public static String join(String glue, Iterable strings) {
if (strings == null) return "";
if (strings instanceof Collection) {
if (((Collection) strings).size() == 1) return str(first((Collection) strings));
}
StringBuilder buf = new StringBuilder();
Iterator i = strings.iterator();
if (i.hasNext()) {
buf.append(i.next());
while (i.hasNext())
buf.append(glue).append(i.next());
}
return buf.toString();
}
public static String join(String glue, String... strings) {
return join(glue, Arrays.asList(strings));
}
public static String join(String glue, Object... strings) {
return join(glue, Arrays.asList(strings));
}
static String join(Iterable strings) {
return join("", strings);
}
static String join(Iterable strings, String glue) {
return join(glue, strings);
}
public static String join(String[] strings) {
return join("", strings);
}
static String join(String glue, Pair p) {
return p == null ? "" : str(p.a) + glue + str(p.b);
}
static ArrayList emptyList() {
return new ArrayList();
//ret Collections.emptyList();
}
static ArrayList emptyList(int capacity) {
return new ArrayList(max(0, capacity));
}
// Try to match capacity
static ArrayList emptyList(Iterable l) {
return l instanceof Collection ? emptyList(((Collection) l).size()) : emptyList();
}
static ArrayList emptyList(Object[] l) {
return emptyList(l(l));
}
// get correct type at once
static ArrayList emptyList(Class c) {
return new ArrayList();
}
static void _onJavaXSet() {}
static final Map callOpt_cache = newDangerousWeakHashMap();
static Object callOpt_cached(Object o, String methodName, Object... args) { try {
if (o == null) return null;
if (o instanceof Class) {
Class c = (Class) o;
_MethodCache cache = callOpt_getCache(c);
// TODO: (super-rare) case where method exists static and non-static
// with different args
Method me = cache.findMethod(methodName, args);
if (me == null || (me.getModifiers() & Modifier.STATIC) == 0) return null;
return invokeMethod(me, null, args);
} else {
Class c = o.getClass();
_MethodCache cache = callOpt_getCache(c);
Method me = cache.findMethod(methodName, args);
if (me == null) return null;
return invokeMethod(me, o, args);
}
} catch (Exception __e) { throw rethrow(__e); } }
// no longer synchronizes! (see #1102990)
static _MethodCache callOpt_getCache(Class c) {
_MethodCache cache = callOpt_cache.get(c);
if (cache == null)
callOpt_cache.put(c, cache = new _MethodCache(c));
return cache;
}
static boolean isStaticMethod(Method m) {
return methodIsStatic(m);
}
static Object[] massageArgsForVarArgsCall(Method m, Object[] args) {
Class>[] types = m.getParameterTypes();
int n = types.length-1, nArgs = args.length;
if (nArgs < n) return null;
for (int i = 0; i < n; i++)
if (!argumentCompatibleWithType(args[i], types[i]))
return null;
Class varArgType = types[n].getComponentType();
for (int i = n; i < nArgs; i++)
if (!argumentCompatibleWithType(args[i], varArgType))
return null;
Object[] newArgs = new Object[n+1];
arraycopy(args, 0, newArgs, 0, n);
Object[] varArgs = arrayOfType(varArgType, nArgs-n);
arraycopy(args, n, varArgs, 0, nArgs-n);
newArgs[n] = varArgs;
return newArgs;
}
// unclear semantics as to whether return null on null
static ArrayList asList(A[] a) {
return a == null ? new ArrayList () : new ArrayList (Arrays.asList(a));
}
static ArrayList asList(int[] a) {
if (a == null) return null;
ArrayList l = emptyList(a.length);
for (int i : a) l.add(i);
return l;
}
static ArrayList asList(long[] a) {
if (a == null) return null;
ArrayList l = emptyList(a.length);
for (long i : a) l.add(i);
return l;
}
static ArrayList asList(float[] a) {
if (a == null) return null;
ArrayList l = emptyList(a.length);
for (float i : a) l.add(i);
return l;
}
static ArrayList asList(double[] a) {
if (a == null) return null;
ArrayList l = emptyList(a.length);
for (double i : a) l.add(i);
return l;
}
static ArrayList asList(short[] a) {
if (a == null) return null;
ArrayList l = emptyList(a.length);
for (short i : a) l.add(i);
return l;
}
static ArrayList asList(Iterator it) {
ArrayList l = new ArrayList();
if (it != null)
while (it.hasNext())
l.add(it.next());
return l;
}
// disambiguation
static ArrayList asList(IterableIterator s) {
return asList((Iterator) s);
}
static ArrayList asList(Iterable s) {
if (s instanceof ArrayList) return (ArrayList) s;
ArrayList l = new ArrayList();
if (s != null)
for (A a : s)
l.add(a);
return l;
}
static ArrayList asList(Producer p) {
ArrayList l = new ArrayList();
A a;
if (p != null) while ((a = p.next()) != null)
l.add(a);
return l;
}
static ArrayList asList(Enumeration e) {
ArrayList l = new ArrayList();
if (e != null)
while (e.hasMoreElements())
l.add(e.nextElement());
return l;
}
static List asList(Pair p) {
return p == null ? null : ll(p.a, p.b);
}
static Object callFunction(Object f, Object... args) {
return callF(f, args);
}
static Throwable _storeException_value;
static void _storeException(Throwable e) {
_storeException_value = e;
}
static Map vm_generalMap_map;
static Map vm_generalMap() {
if (vm_generalMap_map == null)
vm_generalMap_map = (Map) get(javax(), "generalMap");
return vm_generalMap_map;
}
static Object vm_generalMap_get(Object key) {
return vm_generalMap().get(key);
}
static Object vm_generalMap_put(Object key, Object value) {
return mapPutOrRemove(vm_generalMap(), key, value);
}
static Set syncIdentityHashSet() {
return (Set) synchronizedSet(identityHashSet());
}
static Map syncHashMap() {
return synchroHashMap();
}
static A setThreadLocal(ThreadLocal tl, A value) {
if (tl == null) return null;
A old = tl.get();
tl.set(value);
return old;
}
static List _registerWeakMap_preList;
static A _registerWeakMap(A map) {
if (javax() == null) {
// We're in class init
if (_registerWeakMap_preList == null) _registerWeakMap_preList = synchroList();
_registerWeakMap_preList.add(map);
return map;
}
try {
call(javax(), "_registerWeakMap", map);
} catch (Throwable e) {
printException(e);
print("Upgrade JavaX!!");
}
return map;
}
static void _onLoad_registerWeakMap() {
assertNotNull(javax());
if (_registerWeakMap_preList == null) return;
for (Object o : _registerWeakMap_preList)
_registerWeakMap(o);
_registerWeakMap_preList = null;
}
static x30_pkg.x30_util.BetterThreadLocal newPing_actionTL;
static x30_pkg.x30_util.BetterThreadLocal newPing_actionTL() {
if (newPing_actionTL == null)
newPing_actionTL = vm_generalMap_getOrCreate("newPing_actionTL",
() -> {
Runnable value = (Runnable) (callF_gen(vm_generalMap_get("newPing_valueForNewThread")));
var tl = new x30_pkg.x30_util.BetterThreadLocal();
tl.set(value);
return tl;
});
return newPing_actionTL;
}
static int isAndroid_flag;
static boolean isAndroid() {
if (isAndroid_flag == 0)
isAndroid_flag = System.getProperty("java.vendor").toLowerCase().indexOf("android") >= 0 ? 1 : -1;
return isAndroid_flag > 0;
}
static Boolean isHeadless_cache;
static boolean isHeadless() {
if (isHeadless_cache != null) return isHeadless_cache;
if (isAndroid()) return isHeadless_cache = true;
if (GraphicsEnvironment.isHeadless()) return isHeadless_cache = true;
// Also check if AWT actually works.
// If DISPLAY variable is set but no X server up, this will notice.
try {
SwingUtilities.isEventDispatchThread();
return isHeadless_cache = false;
} catch (Throwable e) { return isHeadless_cache = true; }
}
static volatile boolean licensed_yes = true;
static boolean licensed() {
if (!licensed_yes) return false;
ping_okInCleanUp();
return true;
}
static void licensed_off() {
licensed_yes = false;
}
static String unnull(String s) {
return s == null ? "" : s;
}
static Collection unnull(Collection l) {
return l == null ? emptyList() : l;
}
static List unnull(List l) { return l == null ? emptyList() : l; }
static int[] unnull(int[] l) { return l == null ? emptyIntArray() : l; }
static char[] unnull(char[] l) { return l == null ? emptyCharArray() : l; }
static double[] unnull(double[] l) { return l == null ? emptyDoubleArray() : l; }
static Map unnull(Map l) {
return l == null ? emptyMap() : l;
}
static Iterable unnull(Iterable i) {
return i == null ? emptyList() : i;
}
static A[] unnull(A[] a) {
return a == null ? (A[]) emptyObjectArray() : a;
}
static BitSet unnull(BitSet b) {
return b == null ? new BitSet() : b;
}
static Pt unnull(Pt p) {
return p == null ? new Pt() : p;
}
//ifclass Symbol
static Symbol unnull(Symbol s) {
return s == null ? emptySymbol() : s;
}
//endif
static Pair unnull(Pair p) {
return p != null ? p : new Pair(null, null);
}
static int unnull(Integer i) { return i == null ? 0 : i; }
static long unnull(Long l) { return l == null ? 0L : l; }
static double unnull(Double l) { return l == null ? 0.0 : l; }
static boolean nemptyString(String s) {
return s != null && s.length() > 0;
}
static String substring(String s, int x) {
return substring(s, x, strL(s));
}
static String substring(String s, int x, int y) {
if (s == null) return null;
if (x < 0) x = 0;
int n = s.length();
if (y < x) y = x;
if (y > n) y = n;
if (x >= y) return "";
return s.substring(x, y);
}
// convenience method for quickly dropping a prefix
static String substring(String s, CharSequence l) {
return substring(s, lCharSequence(l));
}
static int strL(String s) {
return s == null ? 0 : s.length();
}
static int listL(Collection l) {
return l == null ? 0 : l.size();
}
static boolean neq(Object a, Object b) {
return !eq(a, b);
}
static boolean eqic(String a, String b) {
if ((a == null) != (b == null)) return false;
if (a == null) return true;
return a.equalsIgnoreCase(b);
}
static boolean eqic(Symbol a, Symbol b) {
return eq(a, b);
}
static boolean eqic(Symbol a, String b) {
return eqic(asString(a), b);
}
static boolean eqic(char a, char b) {
if (a == b) return true;
char u1 = Character.toUpperCase(a);
char u2 = Character.toUpperCase(b);
if (u1 == u2) return true;
return Character.toLowerCase(u1) == Character.toLowerCase(u2);
}
static boolean ewic(String a, String b) {
return endsWithIgnoreCase(a, b);
}
static boolean ewic(String a, String b, Matches m) {
return endsWithIgnoreCase(a, b, m);
}
static Object first(Object list) {
return first((Iterable) list);
}
static A first(List list) {
return empty(list) ? null : list.get(0);
}
static A first(A[] bla) {
return bla == null || bla.length == 0 ? null : bla[0];
}
static Pair first(Map map) {
return mapEntryToPair(first(entrySet(map)));
}
static Pair first(MultiMap mm) {
if (mm == null) return null;
var e = first(mm.data.entrySet());
if (e == null) return null;
return pair(e.getKey(), first(e.getValue()));
}
static A first(IterableIterator i) {
return first((Iterator ) i);
}
static A first(Iterator i) {
return i == null || !i.hasNext() ? null : i.next();
}
static A first(Iterable i) {
if (i == null) return null;
Iterator it = i.iterator();
return it.hasNext() ? it.next() : null;
}
static Character first(String s) { return empty(s) ? null : s.charAt(0); }
static Character first(CharSequence s) { return empty(s) ? null : s.charAt(0); }
static A first(Pair p) {
return p == null ? null : p.a;
}
static A first(T3 t) {
return t == null ? null : t.a;
}
static Byte first(byte[] l) {
return empty(l) ? null : l[0];
}
static A first(A[] l, IF1 pred) {
return firstThat(l, pred);
}
static A first(Iterable l, IF1 pred) {
return firstThat(l, pred);
}
static A first(IF1 pred, Iterable l) {
return firstThat(pred, l);
}
static A first(AppendableChain a) {
return a == null ? null : a.element;
}
static int max(int a, int b) { return Math.max(a, b); }
static int max(int a, int b, int c) { return max(max(a, b), c); }
static long max(int a, long b) { return Math.max((long) a, b); }
static long max(long a, long b) { return Math.max(a, b); }
static double max(int a, double b) { return Math.max((double) a, b); }
static float max(float a, float b) { return Math.max(a, b); }
static double max(double a, double b) { return Math.max(a, b); }
static int max(Collection c) {
int x = Integer.MIN_VALUE;
for (int i : c) x = max(x, i);
return x;
}
static double max(double[] c) {
if (c.length == 0) return Double.MIN_VALUE;
double x = c[0];
for (int i = 1; i < c.length; i++) x = Math.max(x, c[i]);
return x;
}
static float max(float[] c) {
if (c.length == 0) return Float.MAX_VALUE;
float x = c[0];
for (int i = 1; i < c.length; i++) x = Math.max(x, c[i]);
return x;
}
static byte max(byte[] c) {
byte x = -128;
for (byte d : c) if (d > x) x = d;
return x;
}
static short max(short[] c) {
short x = -0x8000;
for (short d : c) if (d > x) x = d;
return x;
}
static int max(int[] c) {
int x = Integer.MIN_VALUE;
for (int d : c) if (d > x) x = d;
return x;
}
static > A max(A a, A b) {
return cmp(a, b) >= 0 ? a : b;
}
static boolean methodIsStatic(Method m) {
return (m.getModifiers() & Modifier.STATIC) != 0;
}
static boolean argumentCompatibleWithType(Object arg, Class type) {
return arg == null ? !type.isPrimitive() : isInstanceX(type, arg);
}
static void arraycopy(Object[] a, Object[] b) {
if (a != null && b != null)
arraycopy(a, 0, b, 0, Math.min(a.length, b.length));
}
static void arraycopy(Object src, int srcPos, int destPos, int n) { arraycopy(src, srcPos, src, destPos, n); }
static void arraycopy(Object src, int srcPos, Object dest, int destPos, int n) {
if (n != 0)
System.arraycopy(src, srcPos, dest, destPos, n);
}
static A[] arrayOfType(Class type, int n) {
return makeArray(type, n);
}
static A[] arrayOfType(int n, Class type) {
return arrayOfType(type, n);
}
static List ll(A... a) {
ArrayList l = new ArrayList(a.length);
if (a != null) for (A x : a) l.add(x);
return l;
}
// get purpose 1: access a list/array/map (safer version of x.get(y))
static A get(List l, int idx) {
return l != null && idx >= 0 && idx < l(l) ? l.get(idx) : null;
}
// seems to conflict with other signatures
/*static B get(Map map, A key) {
ret map != null ? map.get(key) : null;
}*/
static A get(A[] l, int idx) {
return idx >= 0 && idx < l(l) ? l[idx] : null;
}
// default to false
static boolean get(boolean[] l, int idx) {
return idx >= 0 && idx < l(l) ? l[idx] : false;
}
// get purpose 2: access a field by reflection or a map
static Object get(Object o, String field) {
try {
if (o == null) return null;
if (o instanceof Class) return get((Class) o, field);
if (o instanceof Map)
return ((Map) o).get(field);
Field f = getOpt_findField(o.getClass(), field);
if (f != null) {
makeAccessible(f);
return f.get(o);
}
if (o instanceof DynamicObject)
return getOptDynOnly(((DynamicObject) o), field);
} catch (Exception e) {
throw asRuntimeException(e);
}
throw new RuntimeException("Field '" + field + "' not found in " + o.getClass().getName());
}
static Object get_raw(String field, Object o) {
return get_raw(o, field);
}
static Object get_raw(Object o, String field) { try {
if (o == null) return null;
Field f = get_findField(o.getClass(), field);
makeAccessible(f);
return f.get(o);
} catch (Exception __e) { throw rethrow(__e); } }
static Object get(Class c, String field) {
try {
Field f = get_findStaticField(c, field);
makeAccessible(f);
return f.get(null);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
static Field get_findStaticField(Class> c, String field) {
Class _c = c;
do {
for (Field f : _c.getDeclaredFields())
if (f.getName().equals(field) && (f.getModifiers() & java.lang.reflect.Modifier.STATIC) != 0)
return f;
_c = _c.getSuperclass();
} while (_c != null);
throw new RuntimeException("Static field '" + field + "' not found in " + c.getName());
}
static Field get_findField(Class> c, String field) {
Class _c = c;
do {
for (Field f : _c.getDeclaredFields())
if (f.getName().equals(field))
return f;
_c = _c.getSuperclass();
} while (_c != null);
throw new RuntimeException("Field '" + field + "' not found in " + c.getName());
}
static Object get(String field, Object o) {
return get(o, field);
}
static boolean get(BitSet bs, int idx) {
return bs != null && bs.get(idx);
}
static B mapPutOrRemove(Map map, A key, B value) {
if (map != null && key != null)
if (value != null) return map.put(key, value);
else return map.remove(key);
return null;
}
static Set synchronizedSet() {
return synchroHashSet();
}
static Set synchronizedSet(Set set) {
return Collections.synchronizedSet(set);
}
static Set identityHashSet() {
return Collections.newSetFromMap(new IdentityHashMap());
}
static A printException(A e) {
printStackTrace(e);
return e;
}
static A vm_generalMap_getOrCreate(Object key, F0 create) {
return vm_generalMap_getOrCreate(key, f0ToIF0(create));
}
static A vm_generalMap_getOrCreate(Object key, IF0 create) {
Map generalMap = vm_generalMap();
if (generalMap == null) return null; // must be x30 init
synchronized(generalMap) { // should switch to locks here
A a = (A) (vm_generalMap_get(key));
if (a == null)
vm_generalMap_put(key, a = create == null ? null : create.get());
return a;
}
}
static A callF_gen(F0 f) {
return f == null ? null : f.get();
}
static B callF_gen(F1 f, A a) {
return f == null ? null : f.get(a);
}
static A callF_gen(IF0 f) {
return f == null ? null : f.get();
}
static B callF_gen(IF1 f, A a) {
return f == null ? null : f.get(a);
}
static B callF_gen(A a, IF1 f) {
return f == null ? null : f.get(a);
}
static C callF_gen(IF2 f, A a, B b) {
return f == null ? null : f.get(a, b);
}
static void callF_gen(VF1 f, A a) {
{ if (f != null) f.get(a); }
}
static void callF_gen(A a, IVF1 f) {
{ if (f != null) f.get(a); }
}
static void callF_gen(IVF1 f, A a) {
{ if (f != null) f.get(a); }
}
static Object callF_gen(Runnable r) { { if (r != null) r.run(); } return null; }
static Object callF_gen(Object f, Object... args) {
return callF(f, args);
}
static int[] emptyIntArray_a = new int[0];
static int[] emptyIntArray() { return emptyIntArray_a; }
static char[] emptyCharArray = new char[0];
static char[] emptyCharArray() { return emptyCharArray; }
static double[] emptyDoubleArray = new double[0];
static double[] emptyDoubleArray() { return emptyDoubleArray; }
static Map emptyMap() {
return new HashMap();
}
static Object[] emptyObjectArray_a = new Object[0];
static Object[] emptyObjectArray() { return emptyObjectArray_a; }
static Symbol emptySymbol_value;
static Symbol emptySymbol() {
if (emptySymbol_value == null) emptySymbol_value = symbol("");
return emptySymbol_value;
}
static int lCharSequence(CharSequence s) {
return s == null ? 0 : s.length();
}
static String asString(Object o) {
return o == null ? null : o.toString();
}
static boolean endsWithIgnoreCase(String a, String b) {
int la = l(a), lb = l(b);
return la >= lb && regionMatchesIC(a, la-lb, b, 0, lb);
}
static boolean endsWithIgnoreCase(String a, String b, Matches m) {
if (!endsWithIgnoreCase(a, b)) return false;
if (m != null)
m.m = new String[] { substring(a, 0, l(a)-l(b)) };
return true;
}
static Pair mapEntryToPair(Map.Entry e) {
return e == null ? null : pair(e.getKey(), e.getValue());
}
static Set> entrySet(Map map) {
return _entrySet(map);
}
static A firstThat(Iterable l, IF1 pred) {
for (A a : unnullForIteration(l))
if (pred.get(a))
return a;
return null;
}
static A firstThat(A[] l, IF1 pred) {
for (A a : unnullForIteration(l))
if (pred.get(a))
return a;
return null;
}
static A firstThat(IF1 pred, Iterable l) {
return firstThat(l, pred);
}
static A firstThat(IF1 pred, A[] l) {
return firstThat(l, pred);
}
static int cmp(Number a, Number b) {
return a == null ? b == null ? 0 : -1 : cmp(a.doubleValue(), b.doubleValue());
}
static int cmp(double a, double b) {
return a < b ? -1 : a == b ? 0 : 1;
}
static int cmp(int a, int b) {
return a < b ? -1 : a == b ? 0 : 1;
}
static int cmp(long a, long b) {
return a < b ? -1 : a == b ? 0 : 1;
}
static int cmp(Object a, Object b) {
if (a == null) return b == null ? 0 : -1;
if (b == null) return 1;
return ((Comparable) a).compareTo(b);
}
static A[] makeArray(Class type, int n) {
return (A[]) Array.newInstance(type, n);
}
static Object getOptDynOnly(DynamicObject o, String field) {
if (o == null || o.fieldValues == null) return null;
return o.fieldValues.get(field);
}
static Set synchroHashSet() {
return synchronizedSet(new HashSet ());
}
static IF0 f0ToIF0(F0 f) {
return f == null ? null : () -> f.get();
}
static WeakHasherMap symbol_map = new WeakHasherMap(new Hasher() {
public int hashCode(Symbol symbol) { return symbol.text.hashCode(); }
public boolean equals(Symbol a, Symbol b) {
if (a == null) return b == null;
return b != null && eq(a.text, b.text);
}
});
static Symbol symbol(String s) {
if (s == null) return null;
synchronized(symbol_map) {
// TODO: avoid object creation by passing the string to findKey
Symbol symbol = new Symbol(s, true);
Symbol existingSymbol = symbol_map.findKey(symbol);
if (existingSymbol == null)
symbol_map.put(existingSymbol = symbol, true);
return existingSymbol;
}
}
static Symbol symbol(CharSequence s) {
if (s == null) return null;
if (s instanceof Symbol) return (Symbol) s;
if (s instanceof String) return symbol((String) s);
return symbol(str(s));
}
static Symbol symbol(Object o) {
return symbol((CharSequence) o);
}
static boolean regionMatchesIC(String a, int offsetA, String b, int offsetB, int len) {
return a != null && a.regionMatches(true, offsetA, b, offsetB, len);
}
static Set> _entrySet(Map map) {
return map == null ? Collections.EMPTY_SET : map.entrySet();
}
static String unnullForIteration(String s) {
return s == null ? "" : s;
}
static Collection unnullForIteration(Collection l) {
return l == null ? immutableEmptyList() : l;
}
static List unnullForIteration(List l) { return l == null ? immutableEmptyList() : l; }
static int[] unnullForIteration(int[] l) { return l == null ? emptyIntArray() : l; }
static char[] unnullForIteration(char[] l) { return l == null ? emptyCharArray() : l; }
static double[] unnullForIteration(double[] l) { return l == null ? emptyDoubleArray() : l; }
static short[] unnullForIteration(short[] l) { return l == null ? emptyShortArray() : l; }
static Map unnullForIteration(Map l) {
return l == null ? immutableEmptyMap() : l;
}
static Iterable unnullForIteration(Iterable i) {
return i == null ? immutableEmptyList() : i;
}
static A[] unnullForIteration(A[] a) {
return a == null ? (A[]) emptyObjectArray() : a;
}
static BitSet unnullForIteration(BitSet b) {
return b == null ? new BitSet() : b;
}
static Pt unnullForIteration(Pt p) {
return p == null ? new Pt() : p;
}
//ifclass Symbol
static Symbol unnullForIteration(Symbol s) {
return s == null ? emptySymbol() : s;
}
//endif
static Pair unnullForIteration(Pair p) {
return p != null ? p : new Pair(null, null);
}
static long unnullForIteration(Long l) { return l == null ? 0L : l; }
static List immutableEmptyList() {
return Collections.emptyList();
}
static short[] emptyShortArray = new short[0];
static short[] emptyShortArray() { return emptyShortArray; }
static Map immutableEmptyMap() {
return Collections.emptyMap();
}
// A database system for only slightly modified Java objects.
// Recent changes:
// -minimal crash recovery disabled for now (could reenable)
// -idCounter.structure file no longer used
// -allDynamic/safeLoad disabled, it doesn't really make any sense
// -conceptsFile can be in any directory now
// Functions that should always be there for child processes:
static int concepts_internStringsLongerThan = 10;
static ThreadLocal concepts_unlisted = new ThreadLocal();
// BREAKING CHANGE 2021/6/7 set to true
static boolean concepts_unlistedByDefault = true; // true = we can create instances of concepts with "new" without registering them automatically
interface IConceptIndex {
void update(Concept c); // also for adding
void remove(Concept c);
}
interface IFieldIndex {
Collection getAll(Val val);
List allValues(); // returns a cloned list
MultiSet allValues_multiSet();
IterableIterator objectIterator();
}
// Approach to persisting the Concepts object itself (in normal
// DB operation, this is not done): For simplification, speed and
// compactness, we make almost all the fields transient and store only // the concepts and the idCounter. To unstructure the Concepts object,
// use unstructureConcepts() or postUnstructureConcepts(), then
// re-set up any indices, listeners etc.
// base class indicating nothing
static class ConceptsChange {}
// change of a single concept
static class ConceptCreate extends ConceptsChange implements IFieldsToList{
Concept c;
ConceptCreate() {}
ConceptCreate(Concept c) {
this.c = c;}
public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + c + ")"; }
public boolean equals(Object o) {
if (!(o instanceof ConceptCreate)) return false;
ConceptCreate __3 = (ConceptCreate) o;
return eq(c, __3.c);
}
public int hashCode() {
int h = -1751266972;
h = boostHashCombine(h, _hashCode(c));
return h;
}
public Object[] _fieldsToList() { return new Object[] {c}; }
}
// change of a single concept
static class ConceptChange extends ConceptsChange implements IFieldsToList{
Concept c;
ConceptChange() {}
ConceptChange(Concept c) {
this.c = c;}
public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + c + ")"; }
public boolean equals(Object o) {
if (!(o instanceof ConceptChange)) return false;
ConceptChange __4 = (ConceptChange) o;
return eq(c, __4.c);
}
public int hashCode() {
int h = -1760609256;
h = boostHashCombine(h, _hashCode(c));
return h;
}
public Object[] _fieldsToList() { return new Object[] {c}; }
}
// removal of a single concept
// c.id is going to become 0 at some point, so we pass the
// id separately
static class ConceptDelete extends ConceptsChange implements IFieldsToList{
static final String _fieldOrder = "id c";
long id;
Concept c;
ConceptDelete() {}
ConceptDelete(long id, Concept c) {
this.c = c;
this.id = id;}
public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + id + ", " + c + ")"; }
public boolean equals(Object o) {
if (!(o instanceof ConceptDelete)) return false;
ConceptDelete __5 = (ConceptDelete) o;
return id == __5.id && eq(c, __5.c);
}
public int hashCode() {
int h = -1734431213;
h = boostHashCombine(h, _hashCode(id));
h = boostHashCombine(h, _hashCode(c));
return h;
}
public Object[] _fieldsToList() { return new Object[] {id, c}; }
}
// unknown change anywhere in concepts; consider it all dirty
// (this one should not be used except for batch jobs)
static class FullChange extends ConceptsChange implements IFieldsToList{
FullChange() {}
public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + ")"; }
public boolean equals(Object o) {
return o instanceof FullChange;
}
public int hashCode() {
int h = 733452095;
return h;
}
public Object[] _fieldsToList() { return null; }
}
static class Concepts implements AutoCloseable {
SortedMap concepts = synchroTreeMap();
long idCounter;
transient HashMap perClassData;
transient Map miscMap; // don't use directly, call miscMap... methods to access
// set to "-" for non-persistent (possibly not implemented)
// also, can include a case ID ("#123/1")
// TODO: phase out (we have conceptsFile field now)
transient String programID;
transient File conceptsFile;
transient Concepts parent; // new mechanism
transient volatile long changes, changesWritten, lastChange;
transient volatile java.util.Timer autoSaver;
transient volatile boolean dontSave = false;
transient volatile boolean savingConcepts, noXFullGrab;
transient boolean vmBusSend = true;
transient boolean initialSave = false; // set to false to avoid initial useless saving
transient int autoSaveInterval = -1000; // 1 second + wait logic
transient boolean useGZIP = true, quietSave;
transient ReentrantLock lock = new ReentrantLock(true);
transient ReentrantLock saverLock = new ReentrantLock(true);
transient long lastSaveTook = -1, lastSaveWas, loadTook, uncompressedSize;
transient float maxAutoSavePercentage = 10;
transient List conceptIndices;
transient Map, Map> fieldIndices;
transient Map, Map> ciFieldIndices;
//transient L saveActions = synchroList();
transient List preSave;
transient Object classFinder = _defaultClassFinder();
transient List onAllChanged = synchroList(); // list of runnables
transient Set onChange = new HashSet();
transient Object saveWrapper; // VF1, to profile saving
transient boolean modifyOnCreate = false; // set _modified == created initially
transient boolean modifyOnBackRef = false; // set modified if back refs change
transient boolean useFileLock = true; // instead of locking by bot
// OLD - not done anymore. transient bool collectForwardRefs
transient FileBasedLock fileLock;
transient boolean storeBaseClassesInStructure = false; // helps with schema evolution when concept subclasses disappear
transient boolean useBackRefsForSearches = false; // assume backRefs are sane in order to speed up searches
transient boolean defunct = false;
transient int newBackupEveryXMinutes = 60;
// add more fields for Concepts here
Concepts() {}
Concepts(String programID) {
this.programID = programID;}
Concepts(File conceptsFile) {
this.conceptsFile = conceptsFile;}
synchronized long internalID() {
do {
++idCounter;
} while (hasConcept(idCounter));
return idCounter;
}
synchronized HashMap perClassData() {
if (perClassData == null) perClassData = new HashMap();
return perClassData;
}
void initProgramID() {
if (programID == null)
programID = getDBProgramID();
}
Concepts load() {
initProgramID();
// try custom grabber
Object dbGrabber = miscMapGet("dbGrabber");
if (dbGrabber != null && !isFalse(callF(dbGrabber)))
return this;
try {
if (tryToGrab()) return this;
} catch (Throwable e) {
if (!exceptionMessageContains(e, "no xfullgrab"))
printShortException(e);
print("xfullgrab failed - loading DB of " + programID + " from disk");
}
return loadFromDisk();
}
Concepts loadFromDisk() {
if (nempty(concepts)) clearConcepts();
// minimal crash recovery (disabled for now)
//restoreLatestBackupIfConceptsFileEmpty(programID, doIt := true);
long time = now();
Map _concepts = (Map) (unstructureGZFile(conceptsFile(), toIF1(classFinder)));
putAll(concepts, _concepts);
assignConceptsToUs();
loadTook = now()-time;
done("Loaded " + n2(l(concepts), "concept"), time);
calcIdCounter();
return this;
}
Concepts loadConcepts() { return load(); }
boolean tryToGrab() {
if (sameSnippetID(programID, getDBProgramID())) return false;
RemoteDB db = connectToDBOpt(programID); try {
if (db != null) {
loadGrab(db.fullgrab());
return true;
}
return false;
} finally { _close(db); }}
Concepts loadGrab(String grab) {
clearConcepts();
DynamicObject_loading.set(true);
try {
Map map = (Map) unstructure(grab, false, classFinder);
concepts.putAll(map);
assignConceptsToUs();
for (long l : map.keySet())
idCounter = max(idCounter, l);
} finally {
DynamicObject_loading.set(null);
}
//XXX allChanged(); // Nobody is listening at this point anyway
return this;
}
void assignConceptsToUs() {
// fix unstructure bugs
for (Pair p: mapToPairs((Map) (Map) concepts))
if (!(p.b instanceof Concept)) {
print("DROPPING non-existant concept " + p.a + ": " + dynShortName(p.b));
concepts.remove(p.a);
}
for (Concept c : values(concepts)) c._concepts = this;
for (Concept c : values(concepts))
c._doneLoading2(); // doneLoading2 is called on all concepts after all concepts are loaded
}
String progID() {
return programID == null ? getDBProgramID() : programID;
}
Concept getConcept(String id) {
return empty(id) ? null : getConcept(parseLong(id));
}
Concept getConcept(long id) {
return (Concept) concepts.get((long) id);
}
Concept getConcept(RC ref) {
return ref == null ? null : getConcept(ref.longID());
}
boolean hasConcept(long id) {
return concepts.containsKey((long) id);
}
void deleteConcept(long id) {
Concept c = getConcept(id);
if (c == null)
print("Concept " + id + " not found");
else
c.delete();
}
void calcIdCounter() {
Long lastID = lastKey(concepts);
idCounter = lastID == null ? 1 : lastID+1;
}
File conceptsDir() { return dirOfFile(conceptsFile()); }
File conceptsFile() {
if (conceptsFile != null) return conceptsFile;
return getProgramFile(programID, useGZIP ? "concepts.structure.gz" : "concepts.structure");
}
// used for locking when useFileLock is activated
File lockFile() {
return newFile(conceptsDir(), "concepts.lock");
}
FileBasedLock fileLock() {
if (fileLock == null)
fileLock = new FileBasedLock(lockFile());
return fileLock;
}
void saveConceptsIfDirty() { saveConcepts(); }
void save() { saveConcepts(); }
void saveConcepts() {
vmBus_send("saveConceptsCalled", Concepts.this);
if (dontSave) return;
initProgramID();
saverLock.lock();
savingConcepts = true;
long start = now(), time;
try {
String s = null;
//synchronized(main.class) {
long _changes = changes;
if (_changes == changesWritten) return;
File f = conceptsFile();
lock.lock();
long fullTime = now();
try {
if (useGZIP) {
vmBus_send("callingSaveWrapper", Concepts.this, saveWrapper);
callRunnableWithWrapper(saveWrapper, new Runnable() { public void run() { try {
vmBus_send("callingPreSave", Concepts.this, preSave);
callFAll(preSave);
vmBus_send("writingFile", Concepts.this, f);
uncompressedSize = saveGZStructureToFile(f, cloneMap(concepts), makeStructureData());
vmBus_send("gzFileSaved", Concepts.this, f, uncompressedSize);
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "vmBus_send callingPreSave(Concepts.this, preSave);\r\n callFAll(preS..."; }});
newFile(conceptsDir(), "concepts.structure").delete();
} else
s = fullStructure();
} finally {
lock.unlock();
}
/*while (nempty(saveActions))
pcallF(popFirst(saveActions));*/
changesWritten = _changes; // only update when structure didn't fail
if (!useGZIP) {
time = now()-start;
if (!quietSave)
print("Saving " + toM(l(s)) + "M chars (" /*+ changesWritten + ", "*/ + time + " ms)");
start = now();
saveTextFile(f, javaTokWordWrap(s));
newFile(conceptsDir(), "concepts.structure.gz").delete();
}
File conceptsFile = conceptsFile();
File backupFile = newFile(conceptsDir(), "backups/" + fileName(conceptsFile) + ".backup" + ymd() + "-" + formatInt(hours(), 2)
+ (newBackupEveryXMinutes >= 60 ? "" : formatInt(roundDownTo_rev(minutes(), newBackupEveryXMinutes), 2)));
// TODO: get rid of this
copyFile(f, backupFile);
time = now()-start;
if (!quietSave)
print("Saved " + toK(f.length()) + " K, " + n(concepts, "concepts") + " (" + time + " ms)");
lastSaveWas = fullTime;
lastSaveTook = now()-fullTime;
} finally {
savingConcepts = false;
saverLock.unlock();
}
}
void _autoSaveConcepts() {
if (autoSaveInterval < 0 && maxAutoSavePercentage != 0) {
long pivotTime = Math.round(lastSaveWas+lastSaveTook*100.0/maxAutoSavePercentage);
if (now() < pivotTime) {
//print("Skipping auto-save (last save took " + lastSaveTook + ")");
return;
}
}
try {
saveConcepts();
} catch (Throwable e) {
print("Concept save failed, will try again");
printStackTrace(e);
}
}
String fullStructure() {
return structure(cloneMap(concepts), makeStructureData());
}
transient IF0 makeStructureData;
structure_Data makeStructureData() { return makeStructureData != null ? makeStructureData.get() : makeStructureData_base(); }
final structure_Data makeStructureData_fallback(IF0 _f) { return _f != null ? _f.get() : makeStructureData_base(); }
structure_Data makeStructureData_base() {
return finishStructureData(new structure_Data());
}
structure_Data finishStructureData(structure_Data data) {
if (storeBaseClassesInStructure)
data.storeBaseClasses = true;
return data;
}
void clearConcepts() {
for (Concept c : allConcepts()) c.delete();
//concepts.clear();
//allChanged();
}
void fireLegacyChangeEvent() {
synchronized(this) { ++changes; lastChange = sysNow(); }
if (vmBusSend) vmBus_send("conceptsChanged", this);
pcallFAll(onAllChanged);
}
// auto-save every second if dirty
synchronized void autoSaveConcepts() {
if (autoSaver == null) {
if (isTransient()) throw fail("Can't persist transient database");
autoSaver = doEvery_daemon("Concepts Saver for " + conceptsDir(),
abs(autoSaveInterval), new Runnable() { public void run() { try { _autoSaveConcepts() ;
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "_autoSaveConcepts()"; }});
// print("Installed auto-saver (" + autoSaveInterval + " ms, " + progID() + ")");
}
}
public void close() { cleanMeUp(); }
void cleanMeUp() {
try {
defunct = true;
boolean shouldSave = autoSaver != null;
if (autoSaver != null) {
autoSaver.cancel();
autoSaver = null;
}
while (savingConcepts) sleepInCleanUp(10);
if (shouldSave)
saveConceptsIfDirty();
} catch (Throwable __e) { printStackTrace(__e); }
{ cleanUp(fileLock); fileLock = null; }
}
Map getIDsAndNames() {
Map map = new HashMap();
Map cloned = cloneMap(concepts);
for (long id : keys(cloned))
map.put(id, cloned.get(id).className);
return map;
}
void deleteConcepts(List l) {
ping();
if (l != null) for (Object o : cloneList(l))
if (o instanceof Long) {
Concept c = concepts.get(o);
if (c != null) c.delete();
} else if (o instanceof Concept)
((Concept) o).delete();
else
warn("Can't delete " + getClassName(o));
}
A conceptOfType(Class type) {
IConceptCounter counter = conceptCounterForClass(type);
if (counter != null) return (A) first(counter.allConcepts());
return firstOfType(allConcepts(), type);
}
List conceptsOfType(Class type) {
List l = conceptsOfType_noParent(type);
if (parent == null) return l;
return concatLists_conservative(l, parent.conceptsOfType(type));
}
List conceptsOfType_noParent(Class type) {
ping();
IConceptCounter counter = conceptCounterForClass(type);
if (counter != null) return (List ) cloneList(counter.allConcepts());
return filterByType(allConcepts(), type);
}
List listConcepts(Class type) {
return conceptsOfType(type);
}
List list(Class type) {
return conceptsOfType(type);
}
List list_noParent(Class type) {
return conceptsOfType_noParent(type);
}
// TODO: would be better to make this Cl (indices may return sets)
List list(String type) {
return conceptsOfType(type);
}
List conceptsOfType(String type) {
return filterByDynamicType(allConcepts(), "main$" + type);
}
boolean hasConceptOfType(Class extends Concept> type) {
return hasType(allConcepts(), type);
}
void persistConcepts() {
loadConcepts();
autoSaveConcepts();
}
// We love synonyms
void conceptPersistence() { persistConcepts(); }
Concepts persist() { persistConcepts(); return this; }
void persist(Integer interval) {
if (interval != null) autoSaveInterval = interval;
persist();
}
// Runs r if there is no concept of that type
A ensureHas(Class c, Runnable r) {
A a = conceptOfType(c);
if (a == null) {
r.run();
a = conceptOfType(c);
if (a == null)
throw fail("Concept not made by " + r + ": " + shortClassName(c));
}
return a;
}
// Ensures that every concept of type c1 is ref'd by a concept of
// type c2.
// Type of func: voidfunc(concept)
void ensureHas(Class extends Concept> c1, Class extends Concept> c2, Object func) {
for (Concept a : conceptsOfType(c1)) {
Concept b = findBackRef(a, c2);
if (b == null) {
callF(func, a);
b = findBackRef(a, c2);
if (b == null)
throw fail("Concept not made by " + func + ": " + shortClassName(c2));
}
}
}
// Type of func: voidfunc(concept)
void forEvery(Class extends Concept> type, Object func) {
for (Concept c : conceptsOfType(type))
callF(func, c);
}
int deleteAll(Class extends Concept> type) {
List l = (List) conceptsOfType(type);
for (Concept c : l) c.delete();
return l(l);
}
// always returns a new list (callers depend on this)
Collection allConcepts() {
synchronized(concepts) {
return new ArrayList(values(concepts));
}
}
IConceptCounter conceptCounterForClass(Class extends Concept> c) {
for (IFieldIndex idx : values(mapGet(fieldIndices, c)))
if (idx instanceof IConceptCounter) return ((IConceptCounter) idx);
for (IFieldIndex idx : values(mapGet(ciFieldIndices, c)))
if (idx instanceof IConceptCounter) return ((IConceptCounter) idx);
return null;
}
int countConcepts(Class c, Object... params) {
int n = countConcepts_noParent(c, params);
if (parent == null) return n;
return n+parent.countConcepts(c, params);
}
int countConcepts_noParent(Class c, Object... params) {
ping();
if (empty(params)) {
IConceptCounter counter = conceptCounterForClass(c);
if (counter != null) return counter.countConcepts();
return l(list_noParent(c));
}
int n = 0;
for (A x : list_noParent(c)) if (checkConceptFields(x, params)) ++n;
return n;
}
int countConcepts(String c, Object... params) {
ping();
if (empty(params)) return l(list(c));
int n = 0;
for (Concept x : list(c)) if (checkConceptFields(x, params)) ++n;
return n;
}
int countConcepts() {
return l(concepts);
}
synchronized List clonedConceptIndices() {
return cloneList(conceptIndices);
}
synchronized void addConceptIndex(IConceptIndex index) {
if (conceptIndices == null)
conceptIndices = new ArrayList();
conceptIndices.add(index);
}
synchronized void removeConceptIndex(IConceptIndex index) {
if (conceptIndices == null) return;
conceptIndices.remove(index);
if (empty(conceptIndices)) conceptIndices = null;
}
synchronized void addFieldIndex(Class extends Concept> c, String field, IFieldIndex index) {
if (fieldIndices == null)
fieldIndices = new HashMap();
Map map = fieldIndices.get(c);
if (map == null)
fieldIndices.put(c, map = new HashMap());
map.put(field, index);
}
synchronized void removeFieldIndex(Class extends Concept> c, String field, IFieldIndex index) {
Map map = mapGet(fieldIndices, c);
mapRemove(map, field);
}
synchronized IFieldIndex getFieldIndex(Class extends Concept> c, String field) {
if (fieldIndices == null) return null;
Map map = fieldIndices.get(c);
return map == null ? null : map.get(field);
}
synchronized IFieldIndex getAnyIndexForClass(Class extends Concept> c) {
return firstValue(fieldIndices == null ? null : fieldIndices.get(c));
}
synchronized void addCIFieldIndex(Class extends Concept> c, String field, IFieldIndex index) {
if (ciFieldIndices == null)
ciFieldIndices = new HashMap();
Map map = ciFieldIndices.get(c);
if (map == null)
ciFieldIndices.put(c, map = new HashMap());
map.put(field, index);
}
synchronized void removeCIFieldIndex(Class extends Concept> c, String field) {
Map map = mapGet(ciFieldIndices, c);
mapRemove(map, field);
}
synchronized IFieldIndex getCIFieldIndex(Class extends Concept> c, String field) {
if (ciFieldIndices == null) return null;
Map map = ciFieldIndices.get(c);
return map == null ? null : map.get(field);
}
// inter-process methods
RC xnew(String name, Object... values) {
return new RC(cnew(name, values));
}
void xset(long id, String field, Object value) {
xset(new RC(id), field, value);
}
void xset(RC c, String field, Object value) {
if (value instanceof RC)
value = getConcept((RC) value);
cset(getConcept(c), field, value);
}
Object xget(long id, String field) {
return xget(new RC(id), field);
}
Object xget(RC c, String field) {
return xgetPost(cget(getConcept(c), field));
}
Object xgetPost(Object o) {
o = deref(o);
if (o instanceof Concept)
return new RC((Concept) o);
return o;
}
void xdelete(long id) {
xdelete(new RC(id));
}
void xdelete(RC c) {
getConcept(c).delete();
}
void xdelete(List l) {
for (RC c : l)
xdelete(c);
}
List xlist() {
return map("toPassRef", allConcepts());
}
List xlist(String className) {
return map("toPassRef", conceptsOfType(className));
}
boolean isTransient() { return eq(programID, "-"); }
String xfullgrab() {
if (noXFullGrab) throw fail("no xfullgrab (DB too large)");
Lock __1 = lock(); lock(__1); try {
if (changes == changesWritten && !isTransient())
return loadConceptsStructure(programID);
return fullStructure();
} finally { unlock(__1); } }
/* dev.
Either xfullgrabGZipped() {
lock lock();
if (changes == changesWritten && !isTransient())
ret loadConceptsStructure(programID);
ret fullStructure();
}*/
void xshutdown() {
// Killing whole VM if someone wants this DB to shut down
cleanKillVM();
}
long xchangeCount() { return changes; }
int xcount() { return countConcepts(); }
void register(Concept c) {
ping();
if (c._concepts == this) return;
if (c._concepts != null) throw fail("Can't re-register");
c.id = internalID();
c.created = now();
if (modifyOnCreate) c._setModified(c.created);
register_phase2(c);
vmBus_send("conceptCreated", c);
fireChange(new ConceptCreate(c));
}
// also called by replaceConceptAndUpdateRefs
void register_phase2(Concept c) {
c._concepts = this;
concepts.put((long) c.id, c);
for (Concept.Ref r : c._refs())
r.index();
c.change();
c._onRegistered();
}
void registerKeepingID(Concept c) {
if (c._concepts == this) return;
if (c._concepts != null) throw fail("Can't re-register");
c._concepts = this;
concepts.put((long) c.id, c);
c.change();
}
void conceptChanged(Concept c) {
fireChange(new ConceptChange(c));
if (conceptIndices != null)
for (IConceptIndex index : clonedConceptIndices())
index.update(c);
}
boolean hasUnsavedData() {
return changes != changesWritten || savingConcepts;
}
synchronized Object miscMapGet(Object key) {
return mapGet(miscMap, key);
}
synchronized Object miscMapPut(Object key, Object value) {
if (miscMap == null) miscMap = new HashMap();
return miscMap.put(key, value);
}
synchronized void miscMapRemove(Object key) {
mapRemove(miscMap, key);
}
// Note: auto-typing can fool you, make sure create returns
// a wide enough type
synchronized A miscMapGetOrCreate(Object key, IF0 create) {
if (containsKey(miscMap, key)) return (A) miscMap.get(key);
A value = create.get();
miscMapPut(key, value);
return value;
}
void setParent(Concepts parent) {
this.parent = parent;
}
void fireChange(ConceptsChange change) {
if (change == null) return;
pcallFAll(onChange, change);
fireLegacyChangeEvent();
}
final void onChange(IVF1 l){ addChangeListener(l); }
void addChangeListener(IVF1 l) {
syncAdd(onChange, l);
}
void removeChangeListener(IVF1 l) {
syncRemove(onChange, l);
}
void addPreSave(Runnable r) {
preSave = syncAddOrCreate(preSave, r);
}
public String toString() {
return nConcepts(concepts) + " (" + conceptsDir() + ", hash: " + identityHashCode(this) + ")";
}
} // end of Concepts
// TODO: Move everyone over to this so we can have concepts that
// don't subclass Concept. It's hard though because of Concept.Ref
interface IConcept {
public long _conceptID();
public Concepts concepts();
}
static class Concept extends DynamicObject implements IConcept {
transient Concepts _concepts; // Where we belong
long id;
long created, _modified;
List[ backRefs;
// used only internally (cnew)
Concept(String className) {
super(className);
_created();
}
Concept() {
if (!_loading()) {
//className = shortClassName(this); // XXX - necessary?
//print("New concept of type " + className);
_created();
}
}
Concept(boolean unlisted) {
if (!unlisted) _created();
}
boolean includeZeroIDInToString() { return false; }
public String toString() {
String s = shortDynamicClassName(this);
long id = this.id;
if (id != 0 || includeZeroIDInToString())
s += " " + id;
return s;
}
static boolean loading() { return _loading(); }
static boolean _loading() { return dynamicObjectIsLoading(); }
void _created() {
if (!concepts_unlistedByDefault && !eq(concepts_unlisted.get(), true))
db_mainConcepts().register(this);
}
// base class + required interface. experimental
class TypedRef] extends Ref {
TypedRef() {}
//Class aType;
Class bType;
TypedRef(Class bType) {
this.bType = bType;}
TypedRef(Class bType, B value) {
this.bType = bType; set((A) value); }
TypedRef(B value) { set((A) value); }
public boolean set(A a) {
return super.set(checkValue(a));
}
void check() { checkValue(get()); }
C checkValue(C a) {
if (bType != null && a != null)
assertIsInstance(a, bType);
return a;
}
B b() { return (B) value; }
}
class Ref implements IRef {
A value;
Ref() {
if (!dynamicObjectIsLoading())
registerRef();
}
void registerRef() {
vmBus_send("registeringConceptRef", this);
}
Ref(A value) {
this.value = value;
registerRef();
index();
}
// get owning concept (source)
Concept concept() {
return Concept.this;
}
// get target
public A get() { return value; }
public boolean has() { return value != null; }
boolean set(A a) {
if (a == value) return false;
unindex();
value = a;
index();
change();
return true;
}
void setIfEmpty(A a) {
if (!has()) set(a);
}
public void set(Ref ref) { set(ref.get()); }
public void clear() { set((A) null); }
boolean validRef() {
return value != null && _concepts != null && _concepts == value._concepts;
}
// TODO: sync all the indexing and unindexing!?
void index() {
if (validRef()) {
value._addBackRef(this);
change();
}
}
Ref unindex() {
if (validRef()) {
value._removeBackRef(this);
change();
}
return this;
}
void unindexAndDrop() {
unindex();
_removeRef(this);
}
void change() {
Concept.this.change();
}
public String toString() { return
str(value); }
}
class RefL extends AbstractList {
List[> l = new ArrayList();
RefL() {}
RefL(List] l) { replaceWithList(l); }
public void clear() {
while (!isEmpty()) removeLast(this);
}
public void replaceWithList(List l) {
clear();
for (A a : unnullForIteration(l)) add(a);
}
public A set(int i, A o) {
Ref ref = syncGet(l, i);
A prev = ref.get();
ref.set(o);
return prev;
}
public void add(int i, A o) {
syncAdd(l, i, new Ref(o));
}
public A get(int i) {
return syncGet(l, i).get();
}
public A remove(int i) {
return syncRemove(l, i).get();
}
public int size() {
return syncL(l);
}
public boolean contains(Object o) {
if (o instanceof Concept)
for (Ref r : l) if (eq(r.get(), o)) return true;
return super.contains(o);
}
}
void delete() {
//name = "[defunct " + name + "]";
//defunct = true;
//energy = 0;
// clean refs
for (Ref r : unnullForIteration(_refs()))
r.unindex();
// set back refs to null
for (Ref r : cloneList(backRefs))
r.set((Concept) null);
backRefs = null;
var _concepts = this._concepts;
if (_concepts != null) {
_concepts.concepts.remove(id);
_concepts.fireChange(new ConceptDelete(id, this));
if (_concepts.conceptIndices != null)
for (IConceptIndex index : _concepts.conceptIndices)
index.remove(this);
this._concepts = null;
}
id = 0;
}
BaseXRef export() {
return new BaseXRef(_concepts.progID(), id);
}
// notice system of a change in this object
final void _change(){ change(); }
void change() {
_setModified(now());
_change_withoutUpdatingModifiedField();
}
void _setModified(long modified) {
_modified = modified;
}
final void _change_withoutUpdatingModifiedField() {
_onChange();
if (_concepts != null) _concepts.conceptChanged(this);
}
// overridable
void _onChange() {}
String _programID() {
return _concepts == null ? getDBProgramID() : _concepts.progID();
}
// overridable
void _addBackRef(Concept.Ref ref) {
backRefs = addDyn_quickSync(backRefs, ref);
_backRefsModified();
}
void _backRefsModified() {
if (_concepts != null && _concepts.modifyOnBackRef) change();
}
void _removeBackRef(Concept.Ref ref) {
backRefs = removeDyn_quickSync(backRefs, ref);
_backRefsModified();
}
void _removeRef(Concept.Ref ref) {
}
int _backRefCount() { return syncL(backRefs); }
// convenience methods
final void setField(String field, Object value){ _setField(field, value); }
void _setField(String field, Object value) {
cset(this, field, value);
}
boolean setField_trueIfChanged(String field, Object value) {
return cset(this, field, value) != 0;
}
A setFieldAndReturn(String field, A value) {
setField(field, value);
return value;
}
final void setFields(Object... values){ _setFields(values); }
void _setFields(Object... values) {
cset(this, values);
}
public Concepts concepts() { return _concepts; }
boolean isDeleted() { return id == 0; }
void _doneLoading2() {
Map map = _fieldMigrations();
if (map != null) for (Map.Entry extends String, ? extends FieldMigration> __0 : _entrySet( map))
{ String oldField = __0.getKey(); FieldMigration m = __0.getValue(); crenameField_noOverwrite(this, oldField, m.newField); }
}
static class FieldMigration implements IFieldsToList{
String newField;
FieldMigration() {}
FieldMigration(String newField) {
this.newField = newField;}
public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + newField + ")"; }
public boolean equals(Object o) {
if (!(o instanceof FieldMigration)) return false;
FieldMigration __6 = (FieldMigration) o;
return eq(newField, __6.newField);
}
public int hashCode() {
int h = 558692372;
h = boostHashCombine(h, _hashCode(newField));
return h;
}
public Object[] _fieldsToList() { return new Object[] {newField}; }
}
// value is
Map _fieldMigrations() { return null; }
// new wrapper to get a copy of the refs list
// so we can eventually drop the refs field
Collection[ _refs() {
return scanConceptForRefs(this);
}
Concepts _concepts() { return _concepts; }
boolean _conceptsDefunct() { return _concepts != null && _concepts.defunct; }
boolean _conceptsDefunctOrUnregistered() { return _concepts == null || _concepts.defunct; }
// allow refs to do magic stuff?
void _onRegistered() {
/*for (Ref ref : _refs())
refs._onRegistered();*/
}
] boolean addAndChange(Collection cl, A a) {
if (cl == null || !cl.add(a)) return false;
change();
return true;
}
void clearAndChange(Collection cl) {
if (cl == null) return;
cl.clear();
change();
}
File conceptsDir() {
var concepts = concepts();
return concepts == null ? null : concepts.conceptsDir();
}
File fileInConceptsDir(String name) {
var dir = conceptsDir();
return dir == null ? null : newFile(dir, name);
}
public long _conceptID() { return id; }
} // end of Concept
// remote reference (for inter-process communication or
// external databases). Formerly "PassRef".
// prepared for string ids if we do them later
static class RC {
transient Object owner;
String id;
RC() {} // make serialisation happy
RC(long id) { this.id = str(id); }
RC(Object owner, long id) { this.id = str(id); this.owner = owner; }
RC(Concept c) { this(c.id); }
long longID() { return parseLong(id); }
public String toString() {
return id;
}
transient RemoteDB db;
String getString(String field) { return db.xS(this, field); }
Object get(String field) { return db.xget(this, field); }
void set(String field, Object value) { db.xset(this, field, value); }
} // end of RC
// Reference to a concept in another program
static class BaseXRef {
String programID;
long id;
BaseXRef() {}
BaseXRef(String programID, long id) {
this.id = id;
this.programID = programID;}
public boolean equals(Object o) {
if (!(o instanceof BaseXRef)) return false;
BaseXRef r = (BaseXRef) o;
return eq(programID, r.programID) && eq(id, r.id);
}
public int hashCode() {
return programID.hashCode() + (int) id;
}
}
// BaseXRef as a concept
static class XRef extends Concept {
BaseXRef ref;
XRef() {}
XRef(BaseXRef ref) {
this.ref = ref; _doneLoading2(); }
// after we have been added to concepts
void _doneLoading2() {
getIndex().put(ref, this);
}
HashMap getIndex() {
return getXRefIndex(_concepts);
}
}
static synchronized HashMap getXRefIndex(Concepts concepts) {
HashMap cache = (HashMap) concepts.perClassData().get(XRef.class);
if (cache == null)
concepts.perClassData.put(XRef.class, cache = new HashMap());
return cache;
}
// uses mainConcepts
static XRef lookupOrCreateXRef(BaseXRef ref) {
XRef xref = getXRefIndex(db_mainConcepts()).get(ref);
if (xref == null)
xref = new XRef(ref);
return xref;
}
// define standard concept functions to use main concepts
// Now in db_mainConcepts()
/*static void cleanMeUp_concepts() {
if (db_mainConcepts() != null) db_mainConcepts().cleanMeUp();
// mainConcepts = null; // TODO
}*/
static void loadAndAutoSaveConcepts() {
db_mainConcepts().persist();
}
static void loadAndAutoSaveConcepts(int interval) {
db_mainConcepts().persist(interval);
}
static RC toPassRef(Concept c) {
return new RC(c);
}
// so we can instantiate the program to run as a bare DB bot
static void concepts_setUnlistedByDefault(boolean b) {
concepts_unlistedByDefault = b;
}
// immutable, has strong refs
// Do not run in a synchronized block - it goes wrong in the presence
// of elaborate classloaders (like in Gazelle BEA)
// see #1102990 and #1102991
final static class _MethodCache {
final Class c;
final HashMap> cache = new HashMap();
_MethodCache(Class c) {
this.c = c; _init(); }
void _init() {
Class _c = c;
Module myModule = getClass().getModule();
boolean anyHiddenClasses = false;
while (_c != null) {
boolean exported = classIsExportedTo(_c, myModule);
if (!exported)
anyHiddenClasses = true;
else
for (Method m : _c.getDeclaredMethods())
if ((anyHiddenClasses || !isAbstract(m))
&& !reflection_isForbiddenMethod(m))
multiMapPut(cache, m.getName(), makeAccessible(m));
_c = _c.getSuperclass();
}
// add default methods - this might lead to a duplication
// because the overridden method is also added, but it's not
// a problem except for minimal performance loss.
// If any classes in the hierarchy were inaccessible, we add
// all interface methods (see test_callForbiddenMethodByReflection for a test)
for (Class intf : allInterfacesImplementedBy(c))
for (Method m : intf.getDeclaredMethods())
if ((anyHiddenClasses || m.isDefault()) && !reflection_isForbiddenMethod(m))
multiMapPut(cache, m.getName(), makeAccessible(m));
}
// Returns only matching methods
Method findMethod(String method, Object[] args) { try {
List m = cache.get(method);
if (m == null) return null;
int n = m.size();
for (int i = 0; i < n; i++) {
Method me = m.get(i);
if (call_checkArgs(me, args, false))
return me;
}
return null;
} catch (Exception __e) { throw rethrow(__e); } }
Method findStaticMethod(String method, Object[] args) { try {
List m = cache.get(method);
if (m == null) return null;
int n = m.size();
for (int i = 0; i < n; i++) {
Method me = m.get(i);
if (isStaticMethod(me) && call_checkArgs(me, args, false))
return me;
}
return null;
} catch (Exception __e) { throw rethrow(__e); } }
}
static abstract class VF1 implements IVF1 {
public abstract void get(A a);
}
static class Matches {
String[] m;
Matches() {}
Matches(String... m) {
this.m = m;}
String get(int i) { return i < m.length ? m[i] : null; }
String unq(int i) { return unquote(get(i)); }
String tlc(int i) { return unq(i).toLowerCase(); }
boolean bool(int i) { return "true".equals(unq(i)); }
String rest() { return m[m.length-1]; } // for matchStart
int psi(int i) { return Integer.parseInt(unq(i)); }
public String toString() { return "Matches(" + joinWithComma(quoteAll(asList(m))) + ")"; }
public int hashCode() { return _hashCode(toList(m)); }
public boolean equals(Object o) { return o instanceof Matches && arraysEqual(m, ((Matches) o).m); }
}
static class NamedConcept extends Concept {
String name;
public String toString() {
String s = super.toString();
if (nempty(name))
s += " " + quote(name);
return s;
}
}
// for the version with MasterSymbol (used WAY back in "Smart Bot"!) see #1010608
static class Symbol implements CharSequence {
String text;
Symbol() {}
Symbol(String text, boolean dummy) {
this.text = text;} // weird signature to prevent accidental calling
public int hashCode() { return _hashCode(text); }
public String toString() { return text; }
public boolean equals(Object o) {
return this == o;
}
// implementation of CharSequence methods
public int length() { return text.length(); }
public char charAt(int index) { return text.charAt(index); }
public CharSequence subSequence(int start, int end) {
return text.substring(start, end);
}
}
static abstract class F0 {
abstract A get();
}
static abstract class F1 {
abstract B get(A a);
}
// you still need to implement hasNext() and next()
static abstract class IterableIterator implements Iterator , Iterable {
public Iterator iterator() {
return this;
}
public void remove() {
unsupportedOperation();
}
}
static class MultiMap {
Map > data = new HashMap >();
int fullSize;
MultiMap() {}
MultiMap(boolean useTreeMap) { if (useTreeMap) data = new TreeMap(); }
MultiMap(MultiMap map) { putAll(map); }
MultiMap(Map > data) {
this.data = data;}
void put(A key, B value) { synchronized(data) {
List list = data.get(key);
if (list == null)
data.put(key, list = _makeEmptyList());
list.add(value);
++fullSize;
}}
void add(A key, B value) { put(key, value); }
void addAll(A key, Collection values) { putAll(key, values); }
void addAllIfNotThere(A key, Collection values) { synchronized(data) {
for (B value : values)
setPut(key, value);
}}
void setPut(A key, B value) { synchronized(data) {
if (!containsPair(key, value))
put(key, value);
}}
boolean containsPair(A key, B value) { synchronized(data) {
return get(key).contains(value);
}}
void putAll(Collection keys, B value) { synchronized(data) {
for (A key : unnullForIteration(keys))
put(key, value);
}}
void putAll(A key, Collection values) { synchronized(data) {
if (nempty(values)) getActual(key).addAll(values);
}}
void putAll(Iterable> pairs) { synchronized(data) {
for (Pair p : unnullForIteration(pairs))
put(p.a, p.b);
}}
void removeAll(A key, Collection values) { synchronized(data) {
for (B value : values)
remove(key, value);
}}
List get(A key) { synchronized(data) {
List list = data.get(key);
return list == null ? Collections. emptyList() : list;
}}
List getOpt(A key) { synchronized(data) {
return data.get(key);
}}
List getAndClear(A key) { synchronized(data) {
List l = cloneList(data.get(key));
remove(key);
return l;
}}
// returns actual mutable live list
// creates the list if not there
List getActual(A key) { synchronized(data) {
List list = data.get(key);
if (list == null)
data.put(key, list = _makeEmptyList());
return list;
}}
void clean(A key) { synchronized(data) {
List list = data.get(key);
if (list != null && list.isEmpty()) {
fullSize -= l(list);
data.remove(key);
}
}}
Set keySet() { synchronized(data) {
return data.keySet();
}}
Set keys() { synchronized(data) {
return data.keySet();
}}
void remove(A key) { synchronized(data) {
fullSize -= l(this.getOpt(key));
data.remove(key);
}}
final void remove(Pair p){ removePair(p); }
void removePair(Pair p) {
if (p != null) remove(p.a, p.b);
}
void remove(A key, B value) { synchronized(data) {
List list = data.get(key);
if (list != null) {
if (list.remove(value))
fullSize--;
if (list.isEmpty())
data.remove(key);
}
}}
void clear() { synchronized(data) {
data.clear();
}}
boolean containsKey(A key) { synchronized(data) {
return data.containsKey(key);
}}
B getFirst(A key) { synchronized(data) {
List list = get(key);
return list.isEmpty() ? null : list.get(0);
}}
void addAll(MultiMap map) { putAll(map); }
void putAll(MultiMap map) { synchronized(data) {
for (A key : map.keySet())
putAll(key, map.get(key));
}}
void putAll(Map map) { synchronized(data) {
if (map != null) for (Map.Entry e : map.entrySet())
put(e.getKey(), e.getValue());
}}
final int keyCount(){ return keysSize(); }
int keysSize() { synchronized(data) { return l(data); }}
// full size - note: expensive operation
final int fullSize(){ return size(); }
int size() { synchronized(data) {
return fullSize;
}}
// expensive operation
List reverseGet(B b) { synchronized(data) {
List l = new ArrayList();
for (A key : data.keySet())
if (data.get(key).contains(b))
l.add(key);
return l;
}}
Map > asMap() { synchronized(data) {
return cloneMap(data);
}}
boolean isEmpty() { synchronized(data) { return data.isEmpty(); }}
// override in subclasses
List _makeEmptyList() {
return new ArrayList();
}
// returns live lists
Collection> allLists() {
synchronized(data) {
return new ArrayList(data.values());
}
}
Collection> values() { return allLists(); }
List allValues() {
return concatLists(data.values());
}
Object mutex() { return data; }
public String toString() { return "mm" + str(data); }
}
public static interface IF0 {
A get();
}
static interface Hasher {
int hashCode(A a);
boolean equals(A a, A b);
}
static interface IF1 {
B get(A a);
}
static class Value implements IF0 , IFieldsToList{
A value;
Value() {}
Value(A value) {
this.value = value;}
public boolean equals(Object o) {
if (!(o instanceof Value)) return false;
Value __1 = (Value) o;
return eq(value, __1.value);
}
public int hashCode() {
int h = 82420049;
h = boostHashCombine(h, _hashCode(value));
return h;
}
public Object[] _fieldsToList() { return new Object[] {value}; }
public A get() { return value; }
public String toString() { return str(get()); }
}
/*
* @(#)WeakHashMap.java 1.5 98/09/30
*
* Copyright 1998 by Sun Microsystems, Inc.,
* 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
* All rights reserved.
*
* This software is the confidential and proprietary information
* of Sun Microsystems, Inc. ("Confidential Information"). You
* shall not disclose such Confidential Information and shall use
* it only in accordance with the terms of the license agreement
* you entered into with Sun.
*/
// From https://github.com/mernst/plume-lib/blob/df0bfafc3c16848d88f4ea0ef3c8bf3367ae085e/java/src/plume/WeakHasherMap.java
static final class WeakHasherMap extends AbstractMap implements Map {
private Hasher hasher = null;
/*@Pure*/
private boolean keyEquals(Object k1, Object k2) {
return (hasher==null ? k1.equals(k2)
: hasher.equals(k1, k2));
}
/*@Pure*/
private int keyHashCode(Object k1) {
return (hasher==null ? k1.hashCode()
: hasher.hashCode(k1));
}
// The WeakKey class can't be static because it depends on the hasher.
// That in turn means that its methods can't be static.
// However, I need to be able to call the methods such as create() that
// were static in the original version of this code.
// This finesses that.
private /*@Nullable*/ WeakKey WeakKeyCreate(K k) {
if (k == null) return null;
else return new WeakKey(k);
}
private /*@Nullable*/ WeakKey WeakKeyCreate(K k, ReferenceQueue super K> q) {
if (k == null) return null;
else return new WeakKey(k, q);
}
// Cannot be a static class: uses keyHashCode() and keyEquals()
private final class WeakKey extends WeakReference {
private int hash; /* Hashcode of key, stored here since the key
may be tossed by the GC */
private WeakKey(K k) {
super(k);
hash = keyHashCode(k);
}
private /*@Nullable*/ WeakKey create(K k) {
if (k == null) return null;
else return new WeakKey(k);
}
private WeakKey(K k, ReferenceQueue super K> q) {
super(k, q);
hash = keyHashCode(k);
}
private /*@Nullable*/ WeakKey create(K k, ReferenceQueue super K> q) {
if (k == null) return null;
else return new WeakKey(k, q);
}
/* A WeakKey is equal to another WeakKey iff they both refer to objects
that are, in turn, equal according to their own equals methods */
/*@Pure*/
@Override
public boolean equals(/*@Nullable*/ Object o) {
if (o == null) return false; // never happens
if (this == o) return true;
// This test is illegal because WeakKey is a generic type,
// so use the getClass hack below instead.
// if (!(o instanceof WeakKey)) return false;
if (!(o.getClass().equals(WeakKey.class))) return false;
Object t = this.get();
@SuppressWarnings("unchecked")
Object u = ((WeakKey)o).get();
if ((t == null) || (u == null)) return false;
if (t == u) return true;
return keyEquals(t, u);
}
/*@Pure*/
@Override
public int hashCode() {
return hash;
}
}
/* Hash table mapping WeakKeys to values */
private HashMap hash;
/* Reference queue for cleared WeakKeys */
private ReferenceQueue super K> queue = new ReferenceQueue();
/* Remove all invalidated entries from the map, that is, remove all entries
whose keys have been discarded. This method should be invoked once by
each public mutator in this class. We don't invoke this method in
public accessors because that can lead to surprising
ConcurrentModificationExceptions. */
@SuppressWarnings("unchecked")
private void processQueue() {
WeakKey wk;
while ((wk = (WeakKey)queue.poll()) != null) { // unchecked cast
hash.remove(wk);
}
}
/* -- Constructors -- */
/**
* Constructs a new, empty WeakHashMap with the given
* initial capacity and the given load factor.
*
* @param initialCapacity the initial capacity of the
* WeakHashMap
*
* @param loadFactor the load factor of the WeakHashMap
*
* @throws IllegalArgumentException If the initial capacity is less than
* zero, or if the load factor is
* nonpositive
*/
public WeakHasherMap(int initialCapacity, float loadFactor) {
hash = new HashMap(initialCapacity, loadFactor);
}
/**
* Constructs a new, empty WeakHashMap with the given
* initial capacity and the default load factor, which is
* 0.75.
*
* @param initialCapacity the initial capacity of the
* WeakHashMap
*
* @throws IllegalArgumentException If the initial capacity is less than
* zero
*/
public WeakHasherMap(int initialCapacity) {
hash = new HashMap(initialCapacity);
}
/**
* Constructs a new, empty WeakHashMap with the default
* capacity and the default load factor, which is 0.75.
*/
public WeakHasherMap() {
hash = new HashMap();
}
/**
* Constructs a new, empty WeakHashMap with the default
* capacity and the default load factor, which is 0.75.
* The WeakHashMap uses the specified hasher for hashing
* keys and comparing them for equality.
* @param h the Hasher to use when hashing values for this map
*/
public WeakHasherMap(Hasher h) {
hash = new HashMap();
hasher = h;
}
/* -- Simple queries -- */
/**
* Returns the number of key-value mappings in this map.
* Note: In contrast to most implementations of the
* Map interface, the time required by this operation is
* linear in the size of the map.
*/
/*@Pure*/
@Override
public int size() {
return entrySet().size();
}
/**
* Returns true if this map contains no key-value mappings.
*/
/*@Pure*/
@Override
public boolean isEmpty() {
return entrySet().isEmpty();
}
/**
* Returns true if this map contains a mapping for the
* specified key.
*
* @param key the key whose presence in this map is to be tested
*/
/*@Pure*/
@Override
public boolean containsKey(Object key) {
@SuppressWarnings("unchecked")
K kkey = (K) key;
return hash.containsKey(WeakKeyCreate(kkey));
}
/* -- Lookup and modification operations -- */
/**
* Returns the value to which this map maps the specified key.
* If this map does not contain a value for this key, then return
* null.
*
* @param key the key whose associated value, if any, is to be returned
*/
/*@Pure*/
@Override
public /*@Nullable*/ V get(Object key) { // type of argument is Object, not K
@SuppressWarnings("unchecked")
K kkey = (K) key;
return hash.get(WeakKeyCreate(kkey));
}
/**
* Updates this map so that the given key maps to the given
* value. If the map previously contained a mapping for
* key then that mapping is replaced and the previous value is
* returned.
*
* @param key the key that is to be mapped to the given
* value
* @param value the value to which the given key is to be
* mapped
*
* @return the previous value to which this key was mapped, or
* null if if there was no mapping for the key
*/
@Override
public V put(K key, V value) {
processQueue();
return hash.put(WeakKeyCreate(key, queue), value);
}
/**
* Removes the mapping for the given key from this map, if
* present.
*
* @param key the key whose mapping is to be removed
*
* @return the value to which this key was mapped, or null if
* there was no mapping for the key
*/
@Override
public V remove(Object key) { // type of argument is Object, not K
processQueue();
@SuppressWarnings("unchecked")
K kkey = (K) key;
return hash.remove(WeakKeyCreate(kkey));
}
/**
* Removes all mappings from this map.
*/
@Override
public void clear() {
processQueue();
hash.clear();
}
/* -- Views -- */
/* Internal class for entries */
// This can't be static, again because of dependence on hasher.
@SuppressWarnings("TypeParameterShadowing")
private final class Entry implements Map.Entry {
private Map.Entry ent;
private K key; /* Strong reference to key, so that the GC
will leave it alone as long as this Entry
exists */
Entry(Map.Entry ent, K key) {
this.ent = ent;
this.key = key;
}
/*@Pure*/
@Override
public K getKey() {
return key;
}
/*@Pure*/
@Override
public V getValue() {
return ent.getValue();
}
@Override
public V setValue(V value) {
return ent.setValue(value);
}
/*@Pure*/
private boolean keyvalEquals(K o1, K o2) {
return (o1 == null) ? (o2 == null) : keyEquals(o1, o2);
}
/*@Pure*/
private boolean valEquals(V o1, V o2) {
return (o1 == null) ? (o2 == null) : o1.equals(o2);
}
/*@Pure*/
@SuppressWarnings("NonOverridingEquals")
public boolean equals(Map.Entry e /* Object o*/) {
// if (! (o instanceof Map.Entry)) return false;
// Map.Entry e = (Map.Entry)o;
return (keyvalEquals(key, e.getKey())
&& valEquals(getValue(), e.getValue()));
}
/*@Pure*/
@Override
public int hashCode() {
V v;
return (((key == null) ? 0 : keyHashCode(key))
^ (((v = getValue()) == null) ? 0 : v.hashCode()));
}
}
/* Internal class for entry sets */
private final class EntrySet extends AbstractSet> {
Set> hashEntrySet = hash.entrySet();
@Override
public Iterator> iterator() {
return new Iterator>() {
Iterator> hashIterator = hashEntrySet.iterator();
Map.Entry next = null;
@Override
public boolean hasNext() {
while (hashIterator.hasNext()) {
Map.Entry ent = hashIterator.next();
WeakKey wk = ent.getKey();
K k = null;
if ((wk != null) && ((k = wk.get()) == null)) {
/* Weak key has been cleared by GC */
continue;
}
next = new Entry(ent, k);
return true;
}
return false;
}
@Override
public Map.Entry next() {
if ((next == null) && !hasNext())
throw new NoSuchElementException();
Map.Entry e = next;
next = null;
return e;
}
@Override
public void remove() {
hashIterator.remove();
}
};
}
/*@Pure*/
@Override
public boolean isEmpty() {
return !(iterator().hasNext());
}
/*@Pure*/
@Override
public int size() {
int j = 0;
for (Iterator> i = iterator(); i.hasNext(); i.next()) j++;
return j;
}
@Override
public boolean remove(Object o) {
processQueue();
if (!(o instanceof Map.Entry,?>)) return false;
@SuppressWarnings("unchecked")
Map.Entry e = (Map.Entry)o; // unchecked cast
Object ev = e.getValue();
WeakKey wk = WeakKeyCreate(e.getKey());
Object hv = hash.get(wk);
if ((hv == null)
? ((ev == null) && hash.containsKey(wk)) : hv.equals(ev)) {
hash.remove(wk);
return true;
}
return false;
}
/*@Pure*/
@Override
public int hashCode() {
int h = 0;
for (Iterator> i = hashEntrySet.iterator(); i.hasNext(); ) {
Map.Entry ent = i.next();
WeakKey wk = ent.getKey();
Object v;
if (wk == null) continue;
h += (wk.hashCode()
^ (((v = ent.getValue()) == null) ? 0 : v.hashCode()));
}
return h;
}
}
private /*@Nullable*/ Set> entrySet = null;
/**
* Returns a Set view of the mappings in this map.
*/
/*@SideEffectFree*/
@Override
public Set> entrySet() {
if (entrySet == null) entrySet = new EntrySet();
return entrySet;
}
// find matching key
K findKey(Object key) {
processQueue();
K kkey = (K) key;
// TODO: use replacement for HashMap to avoid reflection
WeakKey wkey = WeakKeyCreate(kkey);
WeakKey found = hashMap_findKey(hash, wkey);
return found == null ? null : found.get();
}
}
static class PersistableThrowable extends DynamicObject {
String className;
String msg;
String stacktrace;
PersistableThrowable() {}
PersistableThrowable(Throwable e) {
if (e == null)
className = "Crazy Null Error";
else {
className = getClassName(e).replace('/', '.');
msg = e.getMessage();
stacktrace = getStackTrace_noRecord(e);
}
}
public String toString() {
return nempty(msg) ? className + ": " + msg : className;
}
}
static interface IVF1 {
void get(A a);
}
static class Fail extends RuntimeException implements IFieldsToList{
Object[] objects;
Fail() {}
Fail(Object... objects) {
this.objects = objects;}public Object[] _fieldsToList() { return new Object[] {objects}; }
Fail(Throwable cause, Object... objects) {
super(cause);
this.objects = objects;
}
public String toString() { return joinNemptiesWithColon("Fail", commaCombine(getCause(), objects)); }
}
static class Pair implements Comparable> {
A a;
B b;
Pair() {}
Pair(A a, B b) {
this.b = b;
this.a = a;}
public int hashCode() {
return hashCodeFor(a) + 2*hashCodeFor(b);
}
public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof Pair)) return false;
Pair t = (Pair) o;
return eq(a, t.a) && eq(b, t.b);
}
public String toString() {
return "<" + a + ", " + b + ">";
}
public int compareTo(Pair p) {
if (p == null) return 1;
int i = ((Comparable ) a).compareTo(p.a);
if (i != 0) return i;
return ((Comparable) b).compareTo(p.b);
}
}
static interface IFieldsToList {
Object[] _fieldsToList();
}
// the lockFile must be a file separate from any data files.
// It is created & deleted by this class, and will always have
// size 0.
static class FileBasedLock implements AutoCloseable {
File lockFile;
double timeout = 60.0; // in seconds. refresh happens twice as often
boolean verbose = false;
boolean haveLock = false;
java.util.Timer touchTimer;
FileBasedLock() {}
FileBasedLock(File lockFile) {
this.lockFile = lockFile;}
FileBasedLock(File lockFile, double timeout) {
this.timeout = timeout;
this.lockFile = lockFile;}
// returns true iff lock was acquired (or kept)
synchronized boolean tryToLock() {
if (haveLock) return true;
if (fileExists(lockFile)) {
double age = fileAgeInSeconds(lockFile);
double remaining = timeout-age;
print("Lock file age: " + lockFile + ": " + iround(age) + " s"
+ (remaining <= 0 ? " - old, deleting" : "- please start again in " + nSeconds(iceil(remaining))));
if (remaining <= 0) {
print("Deleting old lock file (program crashed?): " + lockFile + " (age: " + iround(age) + " seconds)");
deleteFile(lockFile);
}
}
try {
mkdirsForFile(lockFile);
java.nio.file.Files.createFile(toPath(lockFile));
acquired();
return true;
} catch (Throwable e) {
printExceptionShort("Can't lock", e);
return false;
}
}
private void acquired() {
haveLock = true;
startTouchTimer();
}
void forceLock() { try {
print("Force-locking " + lockFile);
touchFile(lockFile); // make or touch file
acquired();
} catch (Exception __e) { throw rethrow(__e); } }
String lockError() {
return "Couldn't aquire lock file: " + lockFile;
}
void lockOrFail() {
if (!tryToLock())
throw fail(lockError());
}
synchronized void startTouchTimer() {
if (touchTimer != null) return;
double interval = timeout/2;
touchTimer = doEvery(interval, new Runnable() { public void run() { try { doTouch();
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "doTouch();"; }});
if (verbose) print("Touch timer started for " + lockFile + " (" + interval + "s)");
}
synchronized void doTouch() { try {
if (haveLock) {
if (verbose) print("Touching lock file: " + lockFile);
touchExistingFile(lockFile);
}
} catch (Throwable __e) { printStackTrace(__e); }}
public synchronized void close() { try {
{ cleanUp(touchTimer); touchTimer = null; }
if (haveLock) {
haveLock = false;
if (verbose) print("Deleting lock file: " + lockFile);
deleteFile(lockFile);
}
} catch (Throwable __e) { printStackTrace(__e); }}
synchronized void _simulateCrash() {
{ cleanUp(touchTimer); touchTimer = null; }
}
void deleteOnExit() {
if (haveLock)
lockFile.deleteOnExit();
}
}
// could almost add IVar here - but void set() and bool set() are incompatible in some places
static interface IRef extends IF0 {
// called by the referencee to atomically replace itself
// Passing oldValue to avoid race conditions
public default void replaceValue(A oldValue, A newValue) {}
}
static interface IConceptCounter {
Class extends Concept> conceptClass();
int countConcepts();
Collection allConcepts();
}
// uses HashMap by default
static class MultiSet implements IMultiSet {
Map map = new HashMap();
int size; // now maintaining a size counter
MultiSet(boolean useTreeMap) {
if (useTreeMap) map = new TreeMap();
}
MultiSet(TreeMap map) {
this.map = map;}
MultiSet() {}
MultiSet(Iterable c) { addAll(c); }
MultiSet(MultiSet ms) { synchronized(ms) {
for (A a : ms.keySet()) add(a, ms.get(a));
}}
// returns new count
public synchronized int add(A key) { return add(key, 1); }
synchronized void addAll(Iterable c) {
if (c != null) for (A a : c) add(a);
}
synchronized void addAll(MultiSet ms) {
for (A a : ms.keySet()) add(a, ms.get(a));
}
synchronized int add(A key, int count) {
if (count <= 0) return 0; // don't calculate return value in this case
size += count;
Integer i = map.get(key);
map.put(key, i != null ? (count += i) : count);
return count;
}
synchronized void put(A key, int count) {
int oldCount = get(key);
if (count == oldCount) return;
size += count-oldCount;
if (count != 0)
map.put(key, count);
else
map.remove(key);
}
public synchronized int get(A key) {
Integer i = map.get(key);
return i != null ? i : 0;
}
synchronized boolean contains(A key) {
return map.containsKey(key);
}
synchronized void remove(A key) {
Integer i = map.get(key);
if (i != null) {
--size;
if (i > 1)
map.put(key, i - 1);
else
map.remove(key);
}
}
synchronized List topTen() { return getTopTen(); }
synchronized List getTopTen() { return getTopTen(10); }
synchronized List getTopTen(int maxSize) {
List list = getSortedListDescending();
return list.size() > maxSize ? list.subList(0, maxSize) : list;
}
synchronized List highestFirst() {
return getSortedListDescending();
}
synchronized List lowestFirst() {
return reversedList(getSortedListDescending());
}
synchronized 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;
}
synchronized int getNumberOfUniqueElements() {
return map.size();
}
synchronized int uniqueSize() {
return map.size();
}
synchronized Set asSet() {
return map.keySet();
}
synchronized NavigableSet navigableSet() {
return navigableKeys((NavigableMap) map);
}
synchronized Set keySet() {
return map.keySet();
}
synchronized 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;
}
synchronized void removeAll(A key) {
size -= get(key);
map.remove(key);
}
synchronized int size() {
return size;
}
synchronized MultiSet mergeWith(MultiSet set) {
MultiSet result = new MultiSet ();
for (A a : set.asSet()) {
result.add(a, set.get(a));
}
return result;
}
synchronized boolean isEmpty() {
return map.isEmpty();
}
synchronized public String toString() { // hmm. sync this?
return str(map);
}
synchronized void clear() {
map.clear();
size = 0;
}
final Map toMap(){ return asMap(); }
synchronized Map asMap() {
return cloneMap(map);
}
}
static class RemoteDB implements AutoCloseable {
DialogIO db;
String name;
// s = bot name or snippet ID
RemoteDB(String s) {
this(s, false);
}
RemoteDB(String s, boolean autoStart) {
name = s;
if (isSnippetID(s)) name = dbBotName(s);
db = findBot(name);
if (db == null)
if (autoStart) {
nohupJavax(fsI(s));
waitForBotStartUp(name);
assertNotNull("Weird problem", db = findBot(s));
} else
throw fail("DB " + s + " not running");
}
boolean functional() { return db != null; } // now always true
List list() { return adopt((List) rpc(db, "xlist")); }
List list(String className) { return adopt((List) rpc(db, "xlist", className)); }
List xlist() { return list(); }
List xlist(String className) { return list(className); }
// adopt is an internal method
List adopt(List l) {
if (l != null) for (RC rc : l) adopt(rc);
return l;
}
RC adopt(RC rc) { if (rc != null) rc.db = this; return rc; }
Object adopt(Object o) {
if (o instanceof RC) return adopt((RC) o);
return o;
}
String xclass(RC o) {
return (String) rpc(db, "xclass", o);
}
Object xget(RC o, String field) {
return adopt(rpc(db, "xget", o, field));
}
String xS(RC o, String field) {
return (String) xget(o, field);
}
RC xgetref(RC o, String field) {
return adopt((RC) xget(o, field));
}
void xset(RC o, String field, Object value) {
rpc(db, "xset", o, field, value);
}
RC uniq(String className) {
RC ref = first(list(className));
if (ref == null)
ref = xnew(className);
return ref;
}
RC xuniq(String className) { return uniq(className); }
RC xnew(String className, Object... values) {
return adopt((RC) rpc(db, "xnew", className, values));
}
void xdelete(RC o) {
rpc(db, "xdelete", o);
}
void xdelete(List l) {
rpc(db, "xdelete", l);
}
public void close() {
_close(db);
}
String fullgrab() { return (String) rpc(db, "xfullgrab"); }
String xfullgrab() { return fullgrab(); }
void xshutdown() { rpc(db, "xshutdown"); }
long xchangeCount() { return (long) rpc(db, "xchangeCount"); }
int xcount() { return (int) rpc(db, "xcount"); }
void reconnect() {
close();
db = findBot(name);
}
RC rc(long id) { return new RC(this, id); }
}
static interface IMultiSet {
// returns new count
int add(A key);
/*void addAll(Iterable c) {
if (c != null) for (A a : c) add(a);
}
void addAll(MultiSet ms) {
for (A a : ms.keySet()) add(a, ms.get(a));
}*/
//int add(A key, int count);
//void put(A key, int count);
int get(A key);
//bool contains(A key);
//void remove(A key);
/*List topTen();
synchronized List getTopTen() { ret getTopTen(10); }
synchronized List getTopTen(int maxSize) {
List list = getSortedListDescending();
return list.size() > maxSize ? list.subList(0, maxSize) : list;
}
synchronized L highestFirst() {
ret getSortedListDescending();
}
synchronized L lowestFirst() {
ret reversedList(getSortedListDescending());
}
synchronized L 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));
}
});
ret list;
}
synchronized int getNumberOfUniqueElements() {
return map.size();
}
synchronized int uniqueSize() {
ret map.size();
}
synchronized Set asSet() {
return map.keySet();
}
synchronized NavigableSet navigableSet() {
return navigableKeys((NavigableMap) map);
}
synchronized Set keySet() {
return map.keySet();
}
synchronized 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;
}
synchronized void removeAll(A key) {
size -= get(key);
map.remove(key);
}
synchronized int size() {
ret size;
}
synchronized MultiSet mergeWith(MultiSet set) {
MultiSet result = new MultiSet ();
for (A a : set.asSet()) {
result.add(a, set.get(a));
}
return result;
}
synchronized boolean isEmpty() {
return map.isEmpty();
}
synchronized public String toString() { // hmm. sync this?
return str(map);
}
synchronized void clear() {
map.clear();
size = 0;
}
synchronized Map asMap() {
ret cloneMap(map);
}*/
}
static abstract class DialogIO implements AutoCloseable {
String line;
boolean eos, loud, noClose;
Lock lock = lock();
abstract String readLineImpl();
abstract boolean isStillConnected();
abstract void sendLine(String line);
abstract boolean isLocalConnection();
abstract Socket getSocket();
int getPort() { Socket s = getSocket(); return s == null ? 0 : s.getPort(); }
boolean helloRead = false;
int shortenOutputTo = 500;
String readLineNoBlock() {
String l = line;
line = null;
return l;
}
boolean waitForLine() { try {
ping();
if (line != null) return true;
//print("Readline");
line = readLineImpl();
//print("Readline done: " + line);
if (line == null) eos = true;
return line != null;
} catch (Exception __e) { throw rethrow(__e); } }
String readLine() {
waitForLine();
helloRead = true;
return readLineNoBlock();
}
String ask(String s, Object... args) {
if (loud) return askLoudly(s, 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("> " + shorten(s, shortenOutputTo));
sendLine(s);
String answer = readLine();
print("< " + shorten(answer, shortenOutputTo));
return answer;
}
void pushback(String l) {
if (line != null)
throw fail();
line = l;
helloRead = false;
}
}
static abstract class DialogHandler {
abstract void run(DialogIO io);
}
static Lock dbLock() {
return db_mainConcepts().lock;
}
static Lock dbLock(Concepts cc) {
return cc == null ? null : cc.lock;
}
static Lock dbLock(Concept c) {
return dbLock(c == null ? null : c._concepts);
}
static boolean bareDBMode_on = false;
static void bareDBMode() {
bareDBMode(null); // default autoSaveInterval
}
static void bareDBMode(Integer autoSaveInterval) {
bareDBMode_on = true;
conceptsAndBot(autoSaveInterval);
}
static ThreadLocal DynamicObject_loading = or((ThreadLocal) get(getClass("x30_pkg.x30_util"), "DynamicObject_loading"), new ThreadLocal());
static ThreadLocal dynamicObjectIsLoading_threadLocal() {
return DynamicObject_loading;
}
static List getAll(Map map, Collection l) {
return lookupAllOpt(map, l);
}
static List getAll(Collection l, Map map) {
return lookupAllOpt(map, l);
}
static > List getAll(Iterable l) {
return getVars(l);
}
static String shortClassName_dropNumberPrefix(Object o) {
return dropNumberPrefix(shortClassName(o));
}
static int boostHashCombine(int a, int b) {
return a ^ (b + 0x9e3779b9 + (a << 6) + (a >> 2));
}
static int _hashCode(Object a) {
return a == null ? 0 : a.hashCode();
}
static NavigableMap synchroTreeMap() {
return synchroNavigableMap(new TreeMap());
}
static Object _defaultClassFinder_value = defaultDefaultClassFinder();
static Object _defaultClassFinder() {
return _defaultClassFinder_value;
}
static boolean hasConcept(Class extends Concept> c, Object... params) {
return findConceptWhere(c, params) != null;
}
static String getDBProgramID_id;
static String getDBProgramID() {
return nempty(getDBProgramID_id) ? getDBProgramID_id : programIDWithCase();
}
static Object load(String varName) {
readLocally(varName);
return get(mc(), varName);
}
static Object load(String progID, String varName) {
readLocally(progID, varName);
return get(mc(), varName);
}
static boolean exceptionMessageContains(Throwable e, String s) {
return cic(getInnerMessage(e), s);
}
static void printShortException(Throwable e) {
print(exceptionToStringShort(e));
}
static void printShortException(String s, Throwable e) {
print(s, exceptionToStringShort(e));
}
static boolean nempty(Collection c) {
return !empty(c);
}
static boolean nempty(CharSequence s) {
return !empty(s);
}
static boolean nempty(Object[] o) { return !empty(o); }
static boolean nempty(byte[] o) { return !empty(o); }
static boolean nempty(int[] o) { return !empty(o); }
static boolean nempty(BitSet bs) { return !empty(bs); }
static boolean nempty(Map m) {
return !empty(m);
}
static boolean nempty(Iterator i) {
return i != null && i.hasNext();
}
static boolean nempty(MultiMap mm) { return mm != null && !mm.isEmpty(); }
static boolean nempty(Object o) { return !empty(o); }
static boolean nempty(Rect r) { return r != null && r.w != 0 && r.h != 0; }
static boolean nempty(MultiSet ms) { return ms != null && !ms.isEmpty(); }
static void clearConcepts() {
db_mainConcepts().clearConcepts();
}
static void clearConcepts(Concepts concepts) {
concepts.clearConcepts();
}
static long now_virtualTime;
static long now() {
return now_virtualTime != 0 ? now_virtualTime : System.currentTimeMillis();
}
static Object unstructureGZFile(File f) { return unstructureGZFile(f, null); }
static Object unstructureGZFile(File f, IF1 classFinder) { try {
if (!fileExists(f)) return null;
BufferedReader reader = utf8BufferedReader(gzInputStream(f));
return unstructure_tok(javaTokC_noMLS_onReader(reader), false, classFinder);
} catch (Exception __e) { throw rethrow(__e); } }
static File conceptsFile(String progID) {
return getProgramFile(progID, conceptsFileName());
}
static File conceptsFile() {
return conceptsFile(dbProgramID());
}
static IF1 toIF1(final Object f) {
if (f == null) return null;
if (f instanceof IF1) return (IF1) f;
if (isString(f)) {
throw fail("callF_legacy");
}
return new IF1() {
public Object get(Object a) { return callF(f, a); }
};
}
static Map putAll(Map a, Map extends A,? extends B> b) {
if (a != null && b != null) a.putAll(b);
return a;
}
static MultiMap putAll(MultiMap a, Map extends A,? extends B> b) {
if (a != null) a.putAll((Map) b);
return a;
}
static Map putAll(Map a, Object... b) {
if (a != null)
litmap_impl(a, b);
return a;
}
static int done_minPrint = 10;
static long done(long startTime, String desc) {
long time = now()-startTime;
if (time >= done_minPrint)
print(desc + " [" + time + " ms]");
return time;
}
static long done(String desc, long startTime) {
return done(startTime, desc);
}
static long done(long startTime) {
return done(startTime, "");
}
static String n2(long l) { return formatWithThousands(l); }
static String n2(AtomicLong l) { return n2(l.get()); }
static String n2(Collection l) { return n2(l(l)); }
static String n2(Map map) { return n2(l(map)); }
static String n2(double l, String singular) {
return empty(singular) ? str(l) : n2(l, singular, singular + "s");
}
static String n2(double l, String singular, String plural) {
if (fraction(l) == 0)
return n2((long) l, singular, plural);
else
return l + " " + plural;
}
static String n2(long l, String singular, String plural) {
return n_fancy2(l, singular, plural);
}
static String n2(long l, String singular) {
return empty(singular) ? n2(l) : n_fancy2(l, singular, singular + "s");
}
static String n2(Collection l, String singular) {
return n2(l(l), singular);
}
static String n2(Collection l, String singular, String plural) {
return n_fancy2(l, singular, plural);
}
static String n2(Map m, String singular, String plural) {
return n_fancy2(m, singular, plural);
}
static String n2(Map m, String singular) {
return n2(l(m), singular);
}
static String n2(long[] a, String singular) { return n2(l(a), singular); }
static String n2(Object[] a, String singular) { return n2(l(a), singular); }
static String n2(Object[] a, String singular, String plural) { return n_fancy2(a, singular, plural); }
static String n2(MultiSet ms, String singular, String plural) {
return n_fancy2(ms, singular, plural);
}
static boolean sameSnippetID(String a, String b) {
if (!isSnippetID(a) || !isSnippetID(b)) return false;
return parseSnippetID(a) == parseSnippetID(b);
}
static RemoteDB connectToDBOpt(String dbNameOrID) { try {
return new RemoteDB(dbNameOrID);
} catch (Throwable __e) { return null; } }
static void _close(AutoCloseable c) {
if (c != null) try {
c.close();
} catch (Throwable e) {
// Some classes stupidly throw an exception on double-closing
if (c instanceof javax.imageio.stream.ImageOutputStream)
return;
else throw rethrow(e);
}
}
// TODO: cyclic structures involving certain lists & sets
static Object unstructure(String text) {
return unstructure(text, false);
}
static Object unstructure(String text, boolean allDynamic) {
return unstructure(text, allDynamic, null);
}
static Object unstructure(String text, IF1 classFinder) {
return unstructure(text, false, classFinder);
}
static int structure_internStringsLongerThan = 50;
static int unstructure_unquoteBufSize = 100;
static int unstructure_tokrefs; // stats
abstract static class unstructure_Receiver {
abstract void set(Object o);
}
// classFinder: func(name) -> class (optional)
static Object unstructure(String text, boolean allDynamic,
Object classFinder) {
if (text == null) return null;
return unstructure_tok(javaTokC_noMLS_iterator(text), allDynamic, classFinder);
}
static Object unstructure_reader(BufferedReader reader) {
return unstructure_tok(javaTokC_noMLS_onReader(reader), false, null);
}
static Object unstructure_tok(final Producer tok, final boolean allDynamic, final Object _classFinder) {
final boolean debug = unstructure_debug;
final class X {
int i = -1;
final Object classFinder = _classFinder != null ? _classFinder : _defaultClassFinder();
String mcDollar = actualMCDollar();
// use Eclipse primitive collection if possible (smaller & hopefully faster?)
HashMap refs = new HashMap();
HashMap tokrefs = new HashMap();
HashSet concepts = new HashSet();
HashMap classesMap = new HashMap();
List stack = new ArrayList();
Map baseClassMap = new HashMap();
HashMap innerClassConstructors = new HashMap();
String curT;
char[] unquoteBuf = new char[unstructure_unquoteBufSize];
X() {
try {
Class mc = (Class) (callF(_classFinder, ""));
if (mc != null) mcDollar = mc.getName() + "$";
} catch (Throwable __e) { printStackTrace(__e); }
}
Class findAClass(String fullClassName) { try {
return classFinder != null ? (Class) callF(classFinder, fullClassName) : findClass_fullName(fullClassName);
} catch (Throwable __e) { return null; } }
String unquote(String s) {
return unquoteUsingCharArray(s, unquoteBuf);
}
// look at current token
String t() {
return curT;
}
// get current token, move to next
String tpp() {
String t = curT;
consume();
return t;
}
void parse(final unstructure_Receiver out) {
String t = t();
int refID;
if (structure_isMarker(t, 0, l(t))) {
refID = parseInt(t.substring(1));
consume();
} else refID = -1;
// if (debug) print("parse: " + quote(t));
final int tokIndex = i;
parse_inner(refID, tokIndex, new unstructure_Receiver() {
void set(Object o) {
if (refID >= 0)
refs.put(refID, o);
if (o != null)
tokrefs.put(tokIndex, o);
out.set(o);
}
});
}
void parse_inner(int refID, int tokIndex, unstructure_Receiver out) {
String t = t();
// if (debug) print("parse_inner: " + quote(t));
String cname = t;
Class c = classesMap.get(cname);
if (c == null) {
if (t.startsWith("\"")) {
String s = internIfLongerThan(unquote(tpp()), structure_internStringsLongerThan);
out.set(s); return;
}
if (t.startsWith("'")) {
out.set(unquoteCharacter(tpp())); return;
}
if (t.equals("bigint")) {
out.set(parseBigInt()); return;
}
if (t.equals("d")) {
out.set(parseDouble()); return;
}
if (t.equals("fl")) {
out.set(parseFloat()); return;
}
if (t.equals("sh")) {
consume();
t = tpp();
if (t.equals("-")) {
t = tpp();
out.set((short) (-parseInt(t))); return;
}
out.set((short) parseInt(t)); return;
}
if (t.equals("-")) {
consume();
t = tpp();
out.set(isLongConstant(t) ? (Object) (-parseLong(t)) : (Object) (-parseInt(t))); return;
}
if (isInteger(t) || isLongConstant(t)) {
consume();
//if (debug) print("isLongConstant " + quote(t) + " => " + isLongConstant(t));
if (isLongConstant(t)) {
out.set(parseLong(t)); return;
}
long l = parseLong(t);
boolean isInt = l == (int) l;
out.set(isInt ? (Object) Integer.valueOf((int) l) : (Object) Long.valueOf(l)); return;
}
if (t.equals("false") || t.equals("f")) {
consume(); out.set(false); return;
}
if (t.equals("true") || t.equals("t")) {
consume(); out.set(true); return;
}
if (t.equals("-")) {
consume();
t = tpp();
out.set(isLongConstant(t) ? (Object) (-parseLong(t)) : (Object) (-parseInt(t))); return;
}
if (isInteger(t) || isLongConstant(t)) {
consume();
//if (debug) print("isLongConstant " + quote(t) + " => " + isLongConstant(t));
if (isLongConstant(t)) {
out.set(parseLong(t)); return;
}
long l = parseLong(t);
boolean isInt = l == (int) l;
out.set(isInt ? (Object) Integer.valueOf((int) l) : (Object) Long.valueOf(l)); return;
}
if (t.equals("File")) {
consume();
File f = new File(unquote(tpp()));
out.set(f); return;
}
if (t.startsWith("r") && isInteger(t.substring(1))) {
consume();
int ref = Integer.parseInt(t.substring(1));
Object o = refs.get(ref);
if (o == null)
warn("unsatisfied back reference " + ref);
out.set(o); return;
}
if (t.startsWith("t") && isInteger(t.substring(1))) {
consume();
int ref = Integer.parseInt(t.substring(1));
Object o = tokrefs.get(ref);
if (o == null)
warn("unsatisfied token reference " + ref + " at " + tokIndex);
out.set(o); return;
}
if (t.equals("hashset")) { parseHashSet(out); return; }
if (t.equals("lhs")) { parseLinkedHashSet(out); return; }
if (t.equals("treeset")) { parseTreeSet(out); return; }
if (t.equals("ciset")) { parseCISet(out); return; }
if (eqOneOf(t, "hashmap", "hm")) {
consume();
parseMap(new HashMap(), out);
return;
}
if (t.equals("lhm")) {
consume();
parseMap(new LinkedHashMap(), out);
return;
}
if (t.equals("tm")) {
consume();
parseMap(new TreeMap(), out);
return;
}
if (t.equals("cimap")) {
consume();
parseMap(ciMap(), out);
return;
}
if (t.equals("ll")) {
consume();
LinkedList l = new LinkedList();
if (refID >= 0) refs.put(refID, l);
{ parseList(l, out); return; }
}
if (t.equals("syncLL")) { // legacy
consume();
{ parseList(synchroLinkedList(), out); return; }
}
if (t.equals("sync")) {
consume();
{ parse(new unstructure_Receiver() {
void set(Object value) {
if (value instanceof Map) {
// Java 7
if (value instanceof NavigableMap)
{ out.set(synchroNavigableMap((NavigableMap) value)); return; }
if (value instanceof SortedMap)
{ out.set(synchroSortedMap((SortedMap) value)); return; }
{ out.set(synchroMap((Map) value)); return; }
} else
{ out.set(synchroList((List) value)); return; }
}
}); return; }
}
if (t.equals("{")) {
parseMap(out); return;
}
if (t.equals("[")) {
ArrayList l = new ArrayList();
if (refID >= 0) refs.put(refID, l);
this.parseList(l, out); return;
}
if (t.equals("bitset")) {
parseBitSet(out); return;
}
if (t.equals("array") || t.equals("intarray") || t.equals("dblarray")) {
parseArray(out); return;
}
if (t.equals("ba")) {
consume();
String hex = unquote(tpp());
out.set(hexToBytes(hex)); return;
}
if (t.equals("boolarray")) {
consume();
int n = parseInt(tpp());
String hex = unquote(tpp());
out.set(boolArrayFromBytes(hexToBytes(hex), n)); return;
}
if (t.equals("class")) {
out.set(parseClass()); return;
}
if (t.equals("l")) {
parseLisp(out); return;
}
if (t.equals("null")) {
consume(); out.set(null); return;
}
if (eq(t, "c")) {
consume();
t = t();
assertTrue(isJavaIdentifier(t));
concepts.add(t);
}
// custom deserialization (new static method method)
if (eq(t, "cu")) {
consume();
t = tpp();
assertTrue(isJavaIdentifier(t));
String fullClassName = mcDollar + t;
Class _c = findAClass(fullClassName);
if (_c == null) throw fail("Class not found: " + fullClassName);
parse(new unstructure_Receiver() {
void set(Object value) {
out.set(call(_c, "_deserialize", value));
}
});
return;
}
}
if (eq(t, "j")) {
consume();
out.set(parseJava()); return;
}
if (eq(t, "bc")) {
consume();
String c1 = tpp();
String c2 = tpp();
baseClassMap.put(c1, c2);
{ parse_inner(refID, i, out); return; }
}
// add more tokens here
// Now we want to find our target class c
// Have we failed to look up the class before?
//bool seenBefore = classesMap.containsKey(cname);
// If we have seen the class before, we skip all of this
// and simply leave c as null
// TODO - how do we fill className?
//if (!seenBefore) {
if (c == null && !isJavaIdentifier(t))
throw new RuntimeException("Unknown token " + (i+1) + ": " + quote(t));
// any other class name (or package name)
consume();
String className, fullClassName;
// Is it a package name?
if (eq(t(), ".")) {
consume();
className = fullClassName = t + "." + assertIdentifier(tpp());
} else {
className = t;
fullClassName = mcDollar + t;
}
if (c == null && !allDynamic) {
// First, find class
c = findAClass(fullClassName);
classesMap.put(className, c);
}
// check for existing base class
if (c == null && !allDynamic) {
Set seen = new HashSet();
String parent = className;
while (true) {
String baseName = baseClassMap.get(parent);
if (baseName == null)
break;
if (!seen.add(baseName))
throw fail("Cyclic superclass info: " + baseName);
c = findAClass(mcDollar + baseName);
if (c == null)
print("Base class " + baseName + " of " + parent + " doesn't exist either");
else if (isAbstract(c))
print("Can't instantiate abstract base class: " + c);
else {
printVars_str("Reverting to base class", "className", className, "baseName", baseName, "c", c);
classesMap.put(className, c);
break;
}
parent = baseName;
}
}
//}
// Check if it has an outer reference
boolean hasBracket = eq(t(), "(");
if (hasBracket) consume();
boolean hasOuter = hasBracket && startsWith(t(), "this$");
DynamicObject dO = null;
Object o = null;
final String thingName = t;
if (c != null) {
if (hasOuter) try {
Constructor ctor = innerClassConstructors.get(c);
if (ctor == null)
innerClassConstructors.put(c, ctor = nuStubInnerObject_findConstructor(c, classFinder));
o = ctor.newInstance(new Object[] {null});
} catch (Exception e) {
print("Error deserializing " + c + ": " + e);
o = nuEmptyObject(c);
} else
o = nuEmptyObject(c);
if (o instanceof DynamicObject) dO = (DynamicObject) o;
} else {
if (concepts.contains(t) && (c = findAClass(mcDollar + "Concept")) != null)
o = dO = (DynamicObject) nuEmptyObject(c);
else
dO = new DynamicObject();
dO.className = className;
}
// Save in references list early because contents of object
// might link back to main object
if (refID >= 0)
refs.put(refID, o != null ? o : dO);
tokrefs.put(tokIndex, o != null ? o : dO);
// NOW parse the fields!
HashMap fields = new HashMap(); // no longer preserving order (why did we do this?)
Object _o = o;
DynamicObject _dO = dO;
if (hasBracket) {
stack.add(new Runnable() { public void run() { try {
if (eq(t(), ",")) consume();
if (eq(t(), ")")) {
consume(")");
objRead(_o, _dO, fields, hasOuter);
out.set(_o != null ? _o : _dO);
} else {
final String key = unquote(tpp());
String t = tpp();
if (!eq(t, "="))
throw fail("= expected, got " + t + " after " + quote(key) + " in object " + thingName /*+ " " + sfu(fields)*/);
stack.add(this);
parse(new unstructure_Receiver() {
void set(Object value) {
fields.put(key, value);
/*ifdef unstructure_debug
print("Got field value " + value + ", next token: " + t());
endifdef*/
//if (eq(t(), ",")) consume();
}
});
}
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ifdef unstructure_debug\r\n print(\"in object values, token: \" + t())..."; }});
} else {
objRead(o, dO, fields, hasOuter);
out.set(o != null ? o : dO);
}
}
void objRead(Object o, DynamicObject dO, Map fields, boolean hasOuter) {
// translate between diferent compilers (this$0 vs this$1)
Object outer = fields.get("this$0");
if (outer != null) fields.put("this$1", outer);
else {
outer = fields.get("this$1");
if (outer != null) fields.put("this$0", outer);
}
if (o != null) {
if (dO != null) {
setOptAllDyn_pcall(dO, fields);
} else {
setOptAll_pcall(o, fields);
}
if (hasOuter)
fixOuterRefs(o);
} else for (Map.Entry e : fields.entrySet())
setDynObjectValue(dO, intern(e.getKey()), e.getValue());
if (o != null)
pcallOpt_noArgs(o, "_doneLoading");
}
void parseSet(final Set set, final unstructure_Receiver out) {
this.parseList(new ArrayList(), new unstructure_Receiver() {
void set(Object o) {
set.addAll((List) o);
out.set(set);
}
});
}
void parseLisp(final unstructure_Receiver out) {
throw fail("class Lisp not included");
}
void parseBitSet(final unstructure_Receiver out) {
consume("bitset");
consume("{");
final BitSet bs = new BitSet();
stack.add(new Runnable() { public void run() { try {
if (eq(t(), "}")) {
consume("}");
out.set(bs);
} else {
stack.add(this);
parse(new unstructure_Receiver() {
void set(Object o) {
bs.set((Integer) o);
if (eq(t(), ",")) consume();
}
});
}
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (eq(t(), \"}\")) {\r\n consume(\"}\");\r\n out.set(bs);\r\n ..."; }});
}
void parseList(final List list, final unstructure_Receiver out) {
tokrefs.put(i, list);
consume("[");
stack.add(new Runnable() { public void run() { try {
if (eq(t(), "]")) {
consume();
out.set(list);
} else {
stack.add(this);
parse(new unstructure_Receiver() {
void set(Object o) {
//if (debug) print("List element type: " + getClassName(o));
list.add(o);
if (eq(t(), ",")) consume();
}
});
}
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (eq(t(), \"]\")) {\r\n consume();\r\n ifdef unstructure_debug\r..."; }});
}
void parseArray(unstructure_Receiver out) {
String _type = tpp();
int dims;
if (eq(t(), "S")) { // string array
_type = "S";
consume();
}
if (eq(t(), "/")) { // multi-dimensional array
consume();
dims = parseInt(tpp());
} else
dims = 1;
consume("{");
List list = new ArrayList();
String type = _type;
stack.add(new Runnable() { public void run() { try {
if (eq(t(), "}")) {
consume("}");
if (dims > 1) {
Class atype;
if (type.equals("intarray")) atype = int.class;
else if (type.equals("S")) atype = String.class;
else throw todo("multi-dimensional arrays of other types");
out.set(list.toArray((Object[]) newMultiDimensionalOuterArray(atype, dims, l(list))));
} else
out.set(
type.equals("intarray") ? toIntArray(list)
: type.equals("dblarray") ? toDoubleArray(list)
: type.equals("S") ? toStringArray(list)
: list.toArray());
} else {
stack.add(this);
parse(new unstructure_Receiver() {
void set(Object o) {
list.add(o);
if (eq(t(), ",")) consume();
}
});
}
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (eq(t(), \"}\")) {\r\n consume(\"}\");\r\n if (dims > 1) {\r\n ..."; }});
}
Object parseClass() {
consume("class");
consume("(");
String name = unquote(tpp());
consume(")");
Class c = allDynamic ? null : findAClass(name);
if (c != null) return c;
DynamicObject dO = new DynamicObject();
dO.className = "java.lang.Class";
name = dropPrefix(mcDollar, name);
dO.fieldValues.put("name", name);
return dO;
}
Object parseBigInt() {
consume("bigint");
consume("(");
String val = tpp();
if (eq(val, "-"))
val = "-" + tpp();
consume(")");
return new BigInteger(val);
}
Object parseDouble() {
consume("d");
consume("(");
String val = unquote(tpp());
consume(")");
return Double.parseDouble(val);
}
Object parseFloat() {
consume("fl");
String val;
if (eq(t(), "(")) {
consume("(");
val = unquote(tpp());
consume(")");
} else {
val = unquote(tpp());
}
return Float.parseFloat(val);
}
void parseHashSet(unstructure_Receiver out) {
consume("hashset");
parseSet(new HashSet(), out);
}
void parseLinkedHashSet(unstructure_Receiver out) {
consume("lhs");
parseSet(new LinkedHashSet(), out);
}
void parseTreeSet(unstructure_Receiver out) {
consume("treeset");
parseSet(new TreeSet(), out);
}
void parseCISet(unstructure_Receiver out) {
consume("ciset");
parseSet(ciSet(), out);
}
void parseMap(unstructure_Receiver out) {
parseMap(new TreeMap(), out);
}
Object parseJava() {
String j = unquote(tpp());
Matches m = new Matches();
if (jmatch("java.awt.Color[r=*,g=*,b=*]", j, m))
return nuObject("java.awt.Color", parseInt(m.unq(0)), parseInt(m.unq(1)), parseInt(m.unq(2)));
else {
warn("Unknown Java object: " + j);
return null;
}
}
void parseMap(final Map map, final unstructure_Receiver out) {
consume("{");
stack.add(new Runnable() {
boolean v = false;
Object key;
public void run() {
if (v) {
v = false;
stack.add(this);
if (!eq(tpp(), "="))
throw fail("= expected, got " + t() + " in map of size " + l(map));
parse(new unstructure_Receiver() {
void set(Object value) {
map.put(key, value);
if (eq(t(), ",")) consume();
}
});
} else {
if (eq(t(), "}")) {
consume("}");
out.set(map);
} else {
v = true;
stack.add(this);
parse(new unstructure_Receiver() {
void set(Object o) {
key = o;
}
});
}
} // if v else
} // run()
});
}
/*void parseSub(unstructure_Receiver out) {
int n = l(stack);
parse(out);
while (l(stack) > n)
stack
}*/
void consume() { curT = tok.next(); ++i; }
void consume(String s) {
if (!eq(t(), s)) {
/*S prevToken = i-1 >= 0 ? tok.get(i-1) : "";
S nextTokens = join(tok.subList(i, Math.min(i+2, tok.size())));
fail(quote(s) + " expected: " + prevToken + " " + nextTokens + " (" + i + "/" + tok.size() + ")");*/
throw fail(quote(s) + " expected, got " + quote(t()));
}
consume();
}
// outer wrapper function getting first token and unwinding the stack
void parse_initial(unstructure_Receiver out) {
consume(); // get first token
parse(out);
while (nempty(stack))
popLast(stack).run();
}
}
ThreadLocal tlLoading = dynamicObjectIsLoading_threadLocal();
Boolean b = tlLoading.get();
tlLoading.set(true);
try {
final Var v = new Var();
X x = new X();
x.parse_initial(new unstructure_Receiver() {
void set(Object o) { v.set(o); }
});
unstructure_tokrefs = x.tokrefs.size();
return v.get();
} finally {
tlLoading.set(b);
}
}
static boolean unstructure_debug = false;
static List> mapToPairs(Map map) {
List