KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > python > modules > _weakref


1 // Copyright 2001 Finn Bock
2

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     /** <i>Internal use only. Do not call this method explicit.</i> */
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     // An empty __init__ method
36
public static PyObject empty__init__(PyObject[] arg, String JavaDoc[] 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 JavaDoc {
100         RefReaperThread() {
101             super("weakref reaper");
102         }
103
104         public void collect() throws InterruptedException JavaDoc {
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 JavaDoc 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         /**
146          * Search for a reusable refrence. To be reused, it must be of the
147          * same class and it must not have a callback.
148          */

149         synchronized AbstractReference find(Class JavaDoc 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         /**
162          * Call each of the registered references.
163          */

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         /**
197          * Allow GlobalRef's to be used as hashtable keys.
198          */

199         public boolean equals(Object JavaDoc o) {
200             if (this == o) return true;
201             if (!(o instanceof GlobalRef)) return false;
202             Object JavaDoc t = this.get();
203             Object JavaDoc 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         /**
210          * Allow GlobalRef's to be used as hashtable keys.
211          */

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 JavaDoc 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 JavaDoc toString() {
275             String JavaDoc 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 JavaDoc name) {
292             return py().__findattr__(name);
293         }
294
295         public void __setattr__(String JavaDoc name, PyObject value) {
296             py().__setattr__(name, value);
297         }
298
299         public void __delattr__(String JavaDoc 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 JavaDoc toString() {
353             String JavaDoc 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 JavaDoc[] kws) {
368             return py().__call__(args, kws);
369         }
370     }
371
372
373 }
374
375
376
Popular Tags