1 3 package org.python.modules; 4 5 import java.lang.ref.*; 6 import java.util.*; 7 import org.python.core.*; 8 9 10 public class _weakref implements ClassDictInit { 11 static ReferenceQueue referenceQueue = new ReferenceQueue(); 12 13 static RefReaperThread reaperThread; 14 static Map objects = new HashMap(); 15 16 public static PyObject ReferenceError = null; 17 18 static { 19 reaperThread = new RefReaperThread(); 20 reaperThread.setDaemon(true); 21 reaperThread.start(); 22 } 23 24 25 public static void classDictInit(PyObject dict) 26 throws PyIgnoreMethodTag 27 { 28 ReferenceError = Py.makeClass("ReferenceError", 29 new PyObject[] { Py.RuntimeError }, 30 Py.newJavaCode(_weakref.class, "empty__init__"), 31 Py.None); 32 dict.__setitem__("ReferenceError", ReferenceError); 33 } 34 35 public static PyObject empty__init__(PyObject[] arg, String [] kws) { 37 PyObject dict = new PyStringMap(); 38 dict.__setitem__("__module__", new PyString("_weakref")); 39 return dict; 40 } 41 42 public static ReferenceType ref(PyObject object) { 43 GlobalRef gref = mkGlobal(object); 44 ReferenceType ret = (ReferenceType)gref.find(ReferenceType.class); 45 if (ret != null) { 46 return ret; 47 } 48 return new ReferenceType(mkGlobal(object), null); 49 } 50 51 public static ReferenceType ref(PyObject object, PyObject callback) { 52 return new ReferenceType(mkGlobal(object), callback); 53 } 54 55 public static ProxyType proxy(PyObject object) { 56 GlobalRef gref = mkGlobal(object); 57 ProxyType ret = (ProxyType)gref.find(ProxyType.class); 58 if (ret != null) { 59 return ret; 60 } 61 if (object.isCallable()) { 62 return new CallableProxyType(mkGlobal(object), null); 63 } else { 64 return new ProxyType(mkGlobal(object), null); 65 } 66 } 67 68 public static ProxyType proxy(PyObject object, PyObject callback) { 69 if (object.isCallable()) { 70 return new CallableProxyType(mkGlobal(object), callback); 71 } else { 72 return new ProxyType(mkGlobal(object), callback); 73 } 74 } 75 76 public static int getweakrefcount(PyObject o) { 77 GlobalRef ref = (GlobalRef) objects.get(new GlobalRef(o)); 78 if (ref == null) 79 return 0; 80 return ref.count(); 81 } 82 83 public static PyList getweakrefs(PyObject o) { 84 GlobalRef ref = (GlobalRef) objects.get(new GlobalRef(o)); 85 if (ref == null) 86 return new PyList(); 87 return ref.refs(); 88 } 89 90 private static GlobalRef mkGlobal(PyObject object) { 91 GlobalRef ref = (GlobalRef) objects.get(new GlobalRef(object)); 92 if (ref == null) { 93 ref = new GlobalRef(object, referenceQueue); 94 objects.put(ref, ref); 95 } 96 return ref; 97 } 98 99 static class RefReaperThread extends Thread { 100 RefReaperThread() { 101 super("weakref reaper"); 102 } 103 104 public void collect() throws InterruptedException { 105 GlobalRef gr = (GlobalRef) referenceQueue.remove(); 106 gr.call(); 107 objects.remove(gr); 108 gr = null; 109 } 110 111 public void run() { 112 while (true) { 113 try { 114 collect(); 115 } catch (InterruptedException exc) { } 116 } 117 } 118 } 119 120 121 public static class GlobalRef extends WeakReference { 122 private Vector references = new Vector(); 123 private int hash; 124 125 public GlobalRef(PyObject object) { 126 super(object); 127 hash = object.hashCode(); 128 } 129 130 public GlobalRef(PyObject object, ReferenceQueue queue) { 131 super(object, queue); 132 hash = object.hashCode(); 133 } 134 135 public synchronized void add(AbstractReference ref) { 136 Reference r = new WeakReference(ref); 137 references.addElement(r); 138 } 139 140 private final AbstractReference getReferenceAt(int idx) { 141 WeakReference wref = (WeakReference) references.elementAt(idx); 142 return (AbstractReference) wref.get(); 143 } 144 145 149 synchronized AbstractReference find(Class cls) { 150 for (int i = references.size() - 1; i >= 0; i--) { 151 AbstractReference r = getReferenceAt(i); 152 if (r == null) 153 references.removeElementAt(i); 154 else if (r.callback == null && r.getClass() == cls) { 155 return r; 156 } 157 } 158 return null; 159 } 160 161 164 synchronized void call() { 165 for (int i = references.size() - 1; i >= 0; i--) { 166 AbstractReference r = getReferenceAt(i); 167 if (r == null) 168 references.removeElementAt(i); 169 else 170 r.call(); 171 } 172 } 173 174 synchronized public int count() { 175 for (int i = references.size() - 1; i >= 0; i--) { 176 AbstractReference r = getReferenceAt(i); 177 if (r == null) { 178 references.removeElementAt(i); 179 } 180 } 181 return references.size(); 182 } 183 184 synchronized public PyList refs() { 185 Vector list = new Vector(); 186 for (int i = references.size() - 1; i >= 0; i--) { 187 AbstractReference r = getReferenceAt(i); 188 if (r == null) 189 references.removeElementAt(i); 190 else 191 list.addElement(r); 192 } 193 return new PyList(list); 194 } 195 196 199 public boolean equals(Object o) { 200 if (this == o) return true; 201 if (!(o instanceof GlobalRef)) return false; 202 Object t = this.get(); 203 Object u = ((GlobalRef)o).get(); 204 if ((t == null) || (u == null)) return false; 205 if (t == u) return true; 206 return t.equals(u); 207 } 208 209 212 public int hashCode() { 213 return hash; 214 } 215 } 216 217 218 public static abstract class AbstractReference extends PyObject { 219 PyObject callback; 220 protected GlobalRef gref; 221 222 public AbstractReference(GlobalRef gref, PyObject callback) { 223 this.gref = gref; 224 this.callback = callback; 225 gref.add(this); 226 } 227 228 void call() { 229 if (callback == null) 230 return; 231 try { 232 callback.__call__(this); 233 } catch (Exception exc) { 234 exc.printStackTrace(); 235 } 236 } 237 238 protected PyObject py() { 239 PyObject o = (PyObject) gref.get(); 240 if (o == null) { 241 throw new PyException(ReferenceError, 242 "weakly-referenced object no longer exists"); 243 } 244 return o; 245 } 246 247 public int hashCode() { 248 return gref.hash; 249 } 250 251 public PyObject __eq__(PyObject other) { 252 if (other.getClass() != getClass()) 253 return null; 254 PyObject pythis = (PyObject) gref.get(); 255 PyObject pyother = (PyObject) ((AbstractReference) other). 256 gref.get(); 257 if (pythis == null || pyother == null) 258 return this == other ? Py.One : Py.Zero; 259 return pythis._eq(pyother); 260 } 261 262 } 263 264 265 public static class ReferenceType extends AbstractReference { 266 ReferenceType(GlobalRef gref, PyObject callback) { 267 super(gref, callback); 268 } 269 270 public PyObject __call__() { 271 return Py.java2py(gref.get()); 272 } 273 274 public String toString() { 275 String ret = "<weakref " + 276 Py.idstr(this) +";"; 277 PyObject obj = (PyObject) gref.get(); 278 if (obj != null) 279 ret += " to " + obj.safeRepr() + ">"; 280 else 281 ret += " dead>"; 282 return ret; 283 } 284 } 285 286 public static class ProxyType extends AbstractReference { 287 ProxyType(GlobalRef ref, PyObject callback) { 288 super(ref, callback); 289 } 290 291 public PyObject __findattr__(String name) { 292 return py().__findattr__(name); 293 } 294 295 public void __setattr__(String name, PyObject value) { 296 py().__setattr__(name, value); 297 } 298 299 public void __delattr__(String name) { 300 py().__delattr__(name); 301 } 302 303 public PyString __str__() { return py().__str__(); } 304 public PyString __hex__() { return py().__hex__(); } 305 public PyString __oct__() { return py().__oct__(); } 306 public PyObject __int__() { return py().__int__(); } 307 public PyFloat __float__() { return py().__float__(); } 308 public PyLong __long__() { return py().__long__(); } 309 public PyComplex __complex__() { return py().__complex__(); } 310 public PyObject __pos__() { return py().__pos__(); } 311 public PyObject __neg__() { return py().__neg__(); } 312 public PyObject __abs__() { return py().__abs__(); } 313 public PyObject __invert__() { return py().__invert__(); } 314 315 public PyObject __add__(PyObject o) { return py().__add__(o); } 316 public PyObject __radd__(PyObject o) { return py().__radd__(o); } 317 public PyObject __iadd__(PyObject o) { return py().__iadd__(o); } 318 public PyObject __sub__(PyObject o) { return py().__sub__(o); } 319 public PyObject __rsub__(PyObject o) { return py().__rsub__(o); } 320 public PyObject __isub__(PyObject o) { return py().__isub__(o); } 321 public PyObject __mul__(PyObject o) { return py().__mul__(o); } 322 public PyObject __rmul__(PyObject o) { return py().__rmul__(o); } 323 public PyObject __imul__(PyObject o) { return py().__imul__(o); } 324 public PyObject __div__(PyObject o) { return py().__div__(o); } 325 public PyObject __rdiv__(PyObject o) { return py().__rdiv__(o); } 326 public PyObject __idiv__(PyObject o) { return py().__idiv__(o); } 327 public PyObject __mod__(PyObject o) { return py().__mod__(o); } 328 public PyObject __rmod__(PyObject o) { return py().__rmod__(o); } 329 public PyObject __imod__(PyObject o) { return py().__imod__(o); } 330 public PyObject __divmod__(PyObject o) { return py().__divmod__(o); } 331 public PyObject __rdivmod__(PyObject o) { return py().__rdivmod__(o);} 332 public PyObject __pow__(PyObject o) { return py().__pow__(o); } 333 public PyObject __rpow__(PyObject o) { return py().__rpow__(o); } 334 public PyObject __ipow__(PyObject o) { return py().__ipow__(o); } 335 public PyObject __lshift__(PyObject o) { return py().__lshift__(o); } 336 public PyObject __rlshift__(PyObject o) { return py().__rlshift__(o);} 337 public PyObject __ilshift__(PyObject o) { return py().__ilshift__(o);} 338 339 public PyObject __rshift__(PyObject o) { return py().__rshift__(o); } 340 public PyObject __rrshift__(PyObject o) { return py().__rrshift__(o);} 341 public PyObject __irshift__(PyObject o) { return py().__irshift__(o);} 342 public PyObject __and__(PyObject o) { return py().__and__(o); } 343 public PyObject __rand__(PyObject o) { return py().__rand__(o); } 344 public PyObject __iand__(PyObject o) { return py().__iand__(o); } 345 public PyObject __or__(PyObject o) { return py().__or__(o); } 346 public PyObject __ror__(PyObject o) { return py().__ror__(o); } 347 public PyObject __ior__(PyObject o) { return py().__ior__(o); } 348 public PyObject __xor__(PyObject o) { return py().__xor__(o); } 349 public PyObject __rxor__(PyObject o) { return py().__rxor__(o); } 350 public PyObject __ixor__(PyObject o) { return py().__ixor__(o); } 351 352 public String toString() { 353 String ret = "<weakref " +Py.idstr(this); 354 PyObject obj = (PyObject) gref.get(); 355 if (obj == null) 356 obj = Py.None; 357 ret += " to " + obj.safeRepr() + " "+ 358 Py.idstr(obj) + ">"; 359 return ret; 360 } 361 } 362 363 public static class CallableProxyType extends ProxyType { 364 CallableProxyType(GlobalRef ref, PyObject callback) { 365 super(ref, callback); 366 } 367 public PyObject __call__(PyObject[] args, String [] kws) { 368 return py().__call__(args, kws); 369 } 370 } 371 372 373 } 374 375 376 | Popular Tags |