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 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 javax.imageio.*;
import java.math.*;
/*
* #!
* Ontopia Engine
* #-
* Copyright (C) 2001 - 2013 The Ontopia Project
* #-
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* !#
*/
// modified by Stefan Reich
// Implements the Set interface more compactly than
// java.util.HashSet by using a closed hashtable.
import static x30_pkg.x30_util.DynamicObject;
class main {
static class CompactHashSet extends java.util.AbstractSet {
protected final static int INITIAL_SIZE = 0;
protected final static int FIRST_INCREMENT = 3; // 2 or 3 are useful
public final static double LOAD_FACTOR = 0.75;
protected final static Object nullObject = new Object();
protected final static Object deletedObject = new Object();
protected int elements;
protected int freecells;
protected A[] objects;
protected int modCount;
CompactHashSet() {
this(INITIAL_SIZE);
}
CompactHashSet(int size) {
objects = (A[]) (size == 0 ? emptyObjectArray() : new Object[size]);
elements = 0;
freecells = objects.length;
modCount = 0;
}
CompactHashSet(Collection c) {
this(c.size());
addAll(c);
}
@Override
public Iterator iterator() {
return new CompactHashIterator();
}
@Override
public int size() {
return elements;
}
@Override
public boolean isEmpty() {
return elements == 0;
}
@Override
public boolean contains(Object o) {
return find(o) != null;
}
synchronized A find(Object o) {
if (objects.length == 0) return null;
if (o == null) o = nullObject;
int hash = o.hashCode();
int index = (hash & 0x7FFFFFFF) % objects.length;
int offset = 1;
// search for the object (continue while !null and !this object)
while(objects[index] != null &&
!(objects[index].hashCode() == hash &&
objects[index].equals(o))) {
index = ((index + offset) & 0x7FFFFFFF) % objects.length;
offset = offset*2 + 1;
if (offset == -1)
offset = 2;
}
return objects[index];
}
boolean removeIfSame(Object o) {
A value = find(o);
if (value == o) {
remove(value);
return true;
}
return false;
}
@Override
synchronized public boolean add(Object o) {
if (objects.length == 0) rehash(FIRST_INCREMENT);
if (o == null) o = nullObject;
int hash = o.hashCode();
int index = (hash & 0x7FFFFFFF) % objects.length;
int offset = 1;
int deletedix = -1;
// search for the object (continue while !null and !this object)
while(objects[index] != null &&
!(objects[index].hashCode() == hash &&
objects[index].equals(o))) {
// if there's a deleted object here we can put this object here,
// provided it's not in here somewhere else already
if (objects[index] == deletedObject)
deletedix = index;
index = ((index + offset) & 0x7FFFFFFF) % objects.length;
offset = offset*2 + 1;
if (offset == -1)
offset = 2;
}
if (objects[index] == null) { // wasn't present already
if (deletedix != -1) // reusing a deleted cell
index = deletedix;
else
freecells--;
modCount++;
elements++;
// here we face a problem regarding generics:
// add(A o) is not possible because of the null Object. We cant do 'new A()' or '(A) new Object()'
// so adding an empty object is a problem here
// If (! o instanceof A) : This will cause a class cast exception
// If (o instanceof A) : This will work fine
objects[index] = (A) o;
// do we need to rehash?
if (1 - (freecells / (double) objects.length) > LOAD_FACTOR)
rehash();
return true;
} else // was there already
return false;
}
@Override
synchronized public boolean remove(Object o) {
if (objects.length == 0) return false;
if (o == null) o = nullObject;
int hash = o.hashCode();
int index = (hash & 0x7FFFFFFF) % objects.length;
int offset = 1;
// search for the object (continue while !null and !this object)
while(objects[index] != null &&
!(objects[index].hashCode() == hash &&
objects[index].equals(o))) {
index = ((index + offset) & 0x7FFFFFFF) % objects.length;
offset = offset*2 + 1;
if (offset == -1)
offset = 2;
}
// we found the right position, now do the removal
if (objects[index] != null) {
// we found the object
// same problem here as with add
objects[index] = (A) deletedObject;
modCount++;
elements--;
return true;
} else
// we did not find the object
return false;
}
@Override
synchronized public void clear() {
elements = 0;
for (int ix = 0; ix < objects.length; ix++)
objects[ix] = null;
freecells = objects.length;
modCount++;
}
@Override
synchronized public Object[] toArray() {
Object[] result = new Object[elements];
Object[] objects = this.objects;
int pos = 0;
for (int i = 0; i < objects.length; i++)
if (objects[i] != null && objects[i] != deletedObject) {
if (objects[i] == nullObject)
result[pos++] = null;
else
result[pos++] = objects[i];
}
// unchecked because it should only contain A
return result;
}
// not sure if this needs to have generics
@Override
synchronized public T[] toArray(T[] a) {
int size = elements;
if (a.length < size)
a = (T[])java.lang.reflect.Array.newInstance(
a.getClass().getComponentType(), size);
A[] objects = this.objects;
int pos = 0;
for (int i = 0; i < objects.length; i++)
if (objects[i] != null && objects[i] != deletedObject) {
if (objects[i] == nullObject)
a[pos++] = null;
else
a[pos++] = (T) objects[i];
}
return a;
}
protected void rehash() {
int garbagecells = objects.length - (elements + freecells);
if (garbagecells / (double) objects.length > 0.05)
// rehash with same size
rehash(objects.length);
else
// rehash with increased capacity
rehash(objects.length*2 + 1);
}
protected void rehash(int newCapacity) {
int oldCapacity = objects.length;
@SuppressWarnings("unchecked")
A[] newObjects = (A[]) new Object[newCapacity];
for (int ix = 0; ix < oldCapacity; ix++) {
Object o = objects[ix];
if (o == null || o == deletedObject)
continue;
int hash = o.hashCode();
int index = (hash & 0x7FFFFFFF) % newCapacity;
int offset = 1;
// search for the object
while(newObjects[index] != null) { // no need to test for duplicates
index = ((index + offset) & 0x7FFFFFFF) % newCapacity;
offset = offset*2 + 1;
if (offset == -1)
offset = 2;
}
newObjects[index] = (A) o;
}
objects = newObjects;
freecells = objects.length - elements;
}
private class CompactHashIterator implements Iterator {
private int index;
private int lastReturned = -1;
private int expectedModCount;
@SuppressWarnings("empty-statement")
public CompactHashIterator() {
synchronized(CompactHashSet.this) {
for (index = 0; index < objects.length &&
(objects[index] == null ||
objects[index] == deletedObject); index++)
;
expectedModCount = modCount;
}
}
@Override
public boolean hasNext() {
synchronized(CompactHashSet.this) {
return index < objects.length;
}
}
@SuppressWarnings("empty-statement")
@Override
public T next() {
synchronized(CompactHashSet.this) {
/*if (modCount != expectedModCount)
throw new ConcurrentModificationException();*/
int length = objects.length;
if (index >= length) {
lastReturned = -2;
throw new NoSuchElementException();
}
lastReturned = index;
for (index += 1; index < length &&
(objects[index] == null ||
objects[index] == deletedObject); index++)
;
if (objects[lastReturned] == nullObject)
return null;
else
return (T) objects[lastReturned];
}
}
@Override
public void remove() {
synchronized(CompactHashSet.this) {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
if (lastReturned == -1 || lastReturned == -2)
throw new IllegalStateException();
// delete object
if (objects[lastReturned] != null && objects[lastReturned] != deletedObject) {
objects[lastReturned] = (A) deletedObject;
elements--;
modCount++;
expectedModCount = modCount; // this is expected; we made the change
}
}
}
}
synchronized int capacity() { return objects.length; }
// returns true if there was a shrink
synchronized boolean shrinkToFactor(double factor) {
if (factor > LOAD_FACTOR)
throw fail("Shrink factor must be equal to or smaller than load factor: " + factor + " / " + LOAD_FACTOR);
int newCapacity = max(INITIAL_SIZE, iround(size()/factor));
if (newCapacity >= capacity()) return false;
rehash(newCapacity);
return true;
}
}
static Object[] emptyObjectArray_a = new Object[0];
static Object[] emptyObjectArray() { return emptyObjectArray_a; }
static void addAll(Collection c, Iterable b) {
if (c != null && b != null) for (A a : b) c.add(a);
}
static boolean addAll(Collection c, Collection b) {
return c != null && b != null && c.addAll(b);
}
static boolean addAll(Collection c, B... b) {
return c != null && b != null && c.addAll(Arrays.asList(b));
}
static Map addAll(Map a, Map extends A,? extends B> b) {
if (a != null) a.putAll(b);
return a;
}
static Iterator iterator(Iterable c) {
return c == null ? emptyIterator() : c.iterator();
}
static String find(String pattern, String text) {
Matcher matcher = Pattern.compile(pattern).matcher(text);
if (matcher.find())
return matcher.group(1);
return null;
}
static A find(Collection c, Object... data) {
for (A x : c)
if (checkFields(x, data))
return x;
return null;
}
static void remove(List l, int i) {
if (l != null && i >= 0 && i < l(l))
l.remove(i);
}
static void remove(Collection l, A a) {
if (l != null) l.remove(a);
}
static B remove(Map map, Object a) {
return map == null ? null : map.remove(a);
}
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 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 int iround(double d) {
return (int) Math.round(d);
}
static int iround(Number n) {
return iround(toDouble(n));
}
static Iterator emptyIterator() {
return Collections.emptyIterator();
}
static boolean checkFields(Object x, Object... data) {
for (int i = 0; i < l(data); i += 2)
if (neq(getOpt(x, (String) data[i]), data[i+1]))
return false;
return true;
}
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 RuntimeException asRuntimeException(Throwable t) {
if (t instanceof Error)
_handleError((Error) t);
return t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t);
}
static double toDouble(Object o) {
if (o instanceof Number)
return ((Number) o).doubleValue();
if (o instanceof BigInteger)
return ((BigInteger) o).doubleValue();
if (o instanceof String)
return parseDouble((String) o);
if (o == null) return 0.0;
throw fail(o);
}
static boolean neq(Object a, Object b) {
return !eq(a, b);
}
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 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 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 void _handleError(Error e) {
call(javax(), "_handleError", e);
}
static double parseDouble(String s) {
return empty(s) ? 0.0 : Double.parseDouble(s);
}
static boolean eq(Object a, Object b) {
return a == b || a != null && b != null && a.equals(b);
}
//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 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 void callF(VF1 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) {
if (f instanceof String)
return callMCWithVarArgs((String) f, args); // possible SLOWDOWN over callMC
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) {
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 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 Class javax() {
return getJavaX();
}
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(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(File f) { return getFileSize(f) == 0; }
static String str(Object o) {
return o == null ? "null" : o.toString();
}
static String str(char[] c) {
return new String(c);
}
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