KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > python > core > PyInstance


1 // Copyright (c) Corporation for National Research Initiatives
2
package org.python.core;
3 import java.util.Hashtable JavaDoc;
4 import java.util.StringTokenizer JavaDoc;
5 import java.io.Serializable JavaDoc;
6
7 /**
8  * A python class instance.
9  */

10
11 public class PyInstance extends PyObject
12 {
13     // xxx doc, final name
14
public transient PyClass instclass;
15     
16     // xxx
17
public PyObject fastGetClass() {
18         return instclass;
19     }
20     
21     //This field is only used by Python subclasses of Java classes
22
Object JavaDoc javaProxy;
23
24     /**
25        The namespace of this instance. Contains all instance attributes.
26     **/

27     public PyObject __dict__;
28
29     /* Override serialization behavior */
30     private void readObject(java.io.ObjectInputStream JavaDoc in)
31         throws java.io.IOException JavaDoc, ClassNotFoundException JavaDoc
32     {
33         in.defaultReadObject();
34         
35         String JavaDoc module = in.readUTF();
36         String JavaDoc name = in.readUTF();
37
38         /* Check for types and missing members here */
39         //System.out.println("module: "+module+", "+name);
40
PyObject mod = imp.importName(module.intern(), false);
41         PyClass pyc = (PyClass)mod.__getattr__(name.intern());
42
43         instclass = pyc;
44         if (javaProxy != null)
45             ((PyProxy) javaProxy)._setPySystemState(Py.getSystemState());
46     }
47
48     private void writeObject(java.io.ObjectOutputStream JavaDoc out)
49         throws java.io.IOException JavaDoc
50     {
51         //System.out.println("writing: "+getClass().getName());
52
out.defaultWriteObject();
53         PyObject name = instclass.__findattr__("__module__");
54         if (!(name instanceof PyString) || name == Py.None || name == null) {
55             throw Py.ValueError("Can't find module for class: "+
56                                 instclass.__name__);
57         }
58         out.writeUTF(name.toString());
59         name = instclass.__findattr__("__name__");
60         if (!(name instanceof PyString) || name == Py.None || name == null) {
61             throw Py.ValueError("Can't find module for class with no name");
62         }
63
64         out.writeUTF(name.toString());
65     }
66
67
68     /**
69        Returns a new
70     **/

71
72     public PyInstance(PyClass iclass, PyObject dict) {
73         instclass = iclass;
74         __dict__ = dict;
75     }
76
77     public PyInstance(PyClass iclass) {
78         this(iclass, new PyStringMap());
79     }
80
81     public PyInstance() {}
82
83     private static Hashtable JavaDoc primitiveMap;
84
85     protected void makeProxy() {
86         Class JavaDoc c = instclass.proxyClass;
87         PyProxy proxy;
88         ThreadState ts = Py.getThreadState();
89         try {
90             ts.pushInitializingProxy(this);
91             try {
92                 proxy = (PyProxy)c.newInstance();
93             } catch (java.lang.InstantiationException JavaDoc e) {
94                 Class JavaDoc sup = c.getSuperclass();
95                 String JavaDoc msg = "Default constructor failed for Java superclass";
96                 if (sup != null)
97                     msg += " " + sup.getName();
98                 throw Py.TypeError(msg);
99             } catch (NoSuchMethodError JavaDoc nsme) {
100                 throw Py.TypeError("constructor requires arguments");
101             } catch (Exception JavaDoc exc) {
102                 throw Py.JavaError(exc);
103             }
104         } finally {
105             ts.popInitializingProxy();
106         }
107
108         if (javaProxy != null && javaProxy != proxy) {
109             // The javaProxy can be initialized in Py.jfindattr()
110
throw Py.TypeError("Proxy instance already initialized");
111         }
112         PyInstance proxyInstance = proxy._getPyInstance();
113         if (proxyInstance != null && proxyInstance != this) {
114             // The proxy was initialized to another instance!!
115
throw Py.TypeError("Proxy initialization conflict");
116         }
117
118         javaProxy = proxy;
119     }
120
121     public Object JavaDoc __tojava__(Class JavaDoc c) {
122         if ((c == Object JavaDoc.class || c == Serializable JavaDoc.class) &&
123                                                     javaProxy != null) {
124             return javaProxy;
125         }
126         if (c.isInstance(this))
127             return this;
128
129         if (c.isPrimitive()) {
130             if (primitiveMap == null) {
131                 primitiveMap = new Hashtable JavaDoc();
132                 primitiveMap.put(Character.TYPE, Character JavaDoc.class);
133                 primitiveMap.put(Boolean.TYPE, Boolean JavaDoc.class);
134                 primitiveMap.put(Byte.TYPE, Byte JavaDoc.class);
135                 primitiveMap.put(Short.TYPE, Short JavaDoc.class);
136                 primitiveMap.put(Integer.TYPE, Integer JavaDoc.class);
137                 primitiveMap.put(Long.TYPE, Long JavaDoc.class);
138                 primitiveMap.put(Float.TYPE, Float JavaDoc.class);
139                 primitiveMap.put(Double.TYPE, Double JavaDoc.class);
140             }
141             Class JavaDoc tmp = (Class JavaDoc)primitiveMap.get(c);
142             if (tmp != null)
143                 c = tmp;
144         }
145
146         if (javaProxy == null && instclass.proxyClass != null) {
147             makeProxy();
148         }
149         if (c.isInstance(javaProxy))
150             return javaProxy;
151
152         if (instclass.__tojava__ != null) {
153             //try {
154
PyObject ret =
155                 instclass.__tojava__.__call__(this, PyJavaClass.lookup(c));
156
157             if (ret == Py.None)
158                 return Py.NoConversion;
159             if (ret != this)
160                 return ret.__tojava__(c);
161             /*} catch (PyException exc) {
162               System.err.println("Error in __tojava__ method");
163               Py.printException(exc);
164               }*/

165         }
166         return Py.NoConversion;
167     }
168
169     public void __init__(PyObject[] args, String JavaDoc[] keywords) {
170         // Invoke our own init function
171
PyObject init = instclass.lookup("__init__", true);
172         PyObject ret = null;
173         if (init != null) {
174             ret = init.__call__(this, args, keywords);
175         }
176         if (ret == null) {
177             if (args.length != 0) {
178                 init = instclass.lookup("__init__", false);
179                 if (init != null) {
180                     ret = init.__call__(this, args, keywords);
181                 } else {
182                     throw Py.TypeError("this constructor takes no arguments");
183                 }
184             }
185         }
186         else if (ret != Py.None) {
187             throw Py.TypeError("constructor has no return value");
188         }
189         // Now init all superclasses that haven't already been initialized
190
if (javaProxy == null && instclass.proxyClass != null) {
191             makeProxy();
192         }
193     }
194
195     public PyObject __jfindattr__(String JavaDoc name) {
196         //System.err.println("jfinding: "+name);
197
return __findattr__(name, true);
198     }
199
200     public PyObject __findattr__(String JavaDoc name) {
201         return __findattr__(name, false);
202     }
203
204     public PyObject __findattr__(String JavaDoc name, boolean stopAtJava) {
205         PyObject result = ifindlocal(name);
206         if (result != null)
207             return result;
208         // it wasn't found in the instance, try the class
209
PyObject[] result2 = instclass.lookupGivingClass(name, stopAtJava);
210         if (result2[0] != null)
211             // xxx do we need to use result2[1] (wherefound) for java cases for backw comp?
212
return result2[0].__get__(this, instclass);
213             // xxx do we need to use
214
return ifindfunction(name);
215     }
216
217     protected PyObject ifindlocal(String JavaDoc name) {
218         if (name == "__dict__") return __dict__;
219         if (name == "__class__") return instclass;
220         if (__dict__ == null) return null;
221
222         return __dict__.__finditem__(name);
223     }
224
225     protected PyObject ifindclass(String JavaDoc name, boolean stopAtJava) {
226         return instclass.lookup(name, stopAtJava);
227     }
228
229     protected PyObject ifindfunction(String JavaDoc name) {
230         PyObject getter = instclass.__getattr__;
231         if (getter == null)
232             return null;
233
234         try {
235             return getter.__call__(this, new PyString(name));
236         } catch (PyException exc) {
237             if (Py.matchException(exc, Py.AttributeError)) return null;
238             throw exc;
239         }
240     }
241
242     public PyObject invoke(String JavaDoc name) {
243         PyObject f = ifindlocal(name);
244         if (f == null) {
245             f = ifindclass(name, false);
246             if (f != null) {
247                 if (f instanceof PyFunction) {
248                     return f.__call__(this);
249                 } else {
250                     f = f.__get__(this, instclass);
251                 }
252             }
253         }
254         if (f == null) f = ifindfunction(name);
255         if (f == null) throw Py.AttributeError(name);
256         return f.__call__();
257     }
258
259     public PyObject invoke(String JavaDoc name, PyObject arg1) {
260         PyObject f = ifindlocal(name);
261         if (f == null) {
262             f = ifindclass(name, false);
263             if (f != null) {
264                 if (f instanceof PyFunction) {
265                     return f.__call__(this, arg1);
266                 } else {
267                     f = f.__get__(this, instclass);
268                 }
269             }
270         }
271         if (f == null) f = ifindfunction(name);
272         if (f == null) throw Py.AttributeError(name);
273         return f.__call__(arg1);
274     }
275
276     public PyObject invoke(String JavaDoc name, PyObject arg1, PyObject arg2) {
277         PyObject f = ifindlocal(name);
278         if (f == null) {
279             f = ifindclass(name, false);
280             if (f != null) {
281                 if (f instanceof PyFunction) {
282                     return f.__call__(this, arg1, arg2);
283                 } else {
284                     f = f.__get__(this, instclass);
285                 }
286             }
287         }
288         if (f == null) f = ifindfunction(name);
289         if (f == null) throw Py.AttributeError(name);
290         return f.__call__(arg1, arg2);
291     }
292
293
294     public void __setattr__(String JavaDoc name, PyObject value) {
295         if (name == "__class__") {
296             if (value instanceof PyClass) {
297                 instclass = (PyClass)value;
298             } else {
299                 throw Py.TypeError("__class__ must be set to a class");
300             }
301             return;
302         } else if (name == "__dict__") {
303             __dict__ = value;
304             return;
305         }
306
307         PyObject setter = instclass.__setattr__;
308         if (setter != null) {
309             setter.__call__(this, new PyString(name), value);
310         } else {
311             if (instclass.getProxyClass() != null) {
312                 PyObject field = instclass.lookup(name, false);
313                 if (field == null) {
314                     noField(name, value);
315                 } else if (!field.jtryset(this, value)) {
316                     unassignableField(name, value);
317                 }
318             } else {
319                 __dict__.__setitem__(name, value);
320             }
321         }
322     }
323
324     protected void noField(String JavaDoc name, PyObject value) {
325         __dict__.__setitem__(name, value);
326     }
327
328     protected void unassignableField(String JavaDoc name, PyObject value) {
329         __dict__.__setitem__(name, value);
330     }
331
332     public void __delattr__(String JavaDoc name) {
333         PyObject deller = instclass.__delattr__;
334         if (deller != null) {
335             deller.__call__(this, new PyString(name));
336         } else {
337             try {
338                 __dict__.__delitem__(name);
339             } catch (PyException exc) {
340                 if (Py.matchException(exc, Py.KeyError))
341                     throw Py.AttributeError("class " + instclass.__name__ +
342                                         " has no attribute '" + name + "'");
343             };
344         }
345     }
346
347     public PyObject invoke_ex(String JavaDoc name, PyObject[] args, String JavaDoc[] keywords)
348     {
349         PyObject meth = __findattr__(name);
350         if (meth == null)
351             return null;
352         return meth.__call__(args, keywords);
353     }
354
355     public PyObject invoke_ex(String JavaDoc name) {
356         PyObject meth = __findattr__(name);
357         if (meth == null)
358             return null;
359         return meth.__call__();
360     }
361     public PyObject invoke_ex(String JavaDoc name, PyObject arg1) {
362         PyObject meth = __findattr__(name);
363         if (meth == null)
364             return null;
365         return meth.__call__(arg1);
366     }
367     public PyObject invoke_ex(String JavaDoc name, PyObject arg1, PyObject arg2) {
368         PyObject meth = __findattr__(name);
369         if (meth == null)
370             return null;
371         return meth.__call__(arg1, arg2);
372     }
373
374     public PyObject __call__(PyObject args[], String JavaDoc keywords[]) {
375         ThreadState ts = Py.getThreadState();
376         if (ts.recursion_depth++ > ts.systemState.getrecursionlimit())
377             throw Py.RuntimeError("maximum __call__ recursion depth exceeded");
378         try {
379             return invoke("__call__", args, keywords);
380         } finally {
381             --ts.recursion_depth;
382         }
383     }
384
385     public PyString __repr__() {
386         PyObject ret = invoke_ex("__repr__");
387         if (ret == null) {
388             PyObject mod = instclass.__dict__.__finditem__("__module__");
389             String JavaDoc smod;
390             if (mod == Py.None) smod = "";
391             else {
392                 if (mod == null || !(mod instanceof PyString))
393                     smod = "<unknown>.";
394                 else
395                     smod = ((PyString)mod).toString()+'.';
396             }
397             return new PyString("<"+smod+instclass.__name__+
398                                 " instance "+Py.idstr(this)+">");
399         }
400
401         if (!(ret instanceof PyString))
402             throw Py.TypeError("__repr__ method must return a string");
403         return (PyString)ret;
404     }
405
406     public PyString __str__() {
407         PyObject ret = invoke_ex("__str__");
408         if (ret == null)
409             return __repr__();
410         if (!(ret instanceof PyString))
411             throw Py.TypeError("__str__ method must return a string");
412         return (PyString)ret;
413     }
414
415     public int hashCode() {
416         PyObject ret;
417         ret = invoke_ex("__hash__");
418
419         if (ret == null) {
420             if (__findattr__("__eq__") != null ||
421                 __findattr__("__cmp__") != null)
422                 throw Py.TypeError("unhashable instance");
423             return super.hashCode();
424         }
425         if (ret instanceof PyInteger) {
426             return ((PyInteger)ret).getValue();
427         }
428         throw Py.TypeError("__hash__() must return int");
429     }
430
431     // special case: does all the work
432
public int __cmp__(PyObject other) {
433         PyObject[] coerced = this._coerce(other);
434         PyObject v;
435         PyObject w;
436         PyObject ret = null;
437         if (coerced != null) {
438             v = coerced[0];
439             w = coerced[1];
440             if (!(v instanceof PyInstance) &&
441                 !(w instanceof PyInstance))
442                 return v._cmp(w);
443         } else {
444             v = this;
445             w = other;
446         }
447         if (v instanceof PyInstance) {
448             ret = ((PyInstance)v).invoke_ex("__cmp__",w);
449             if (ret != null) {
450                 if (ret instanceof PyInteger) {
451                     int result = ((PyInteger)ret).getValue();
452                     return result < 0 ? -1 : result > 0 ? 1 : 0;
453                 }
454                 throw Py.TypeError("__cmp__() must return int");
455             }
456         }
457         if (w instanceof PyInstance) {
458             ret = ((PyInstance)w).invoke_ex("__cmp__",v);
459             if (ret != null) {
460                 if (ret instanceof PyInteger) {
461                     int result = ((PyInteger)ret).getValue();
462                     return -(result < 0 ? -1 : result > 0 ? 1 : 0);
463                 }
464                 throw Py.TypeError("__cmp__() must return int");
465             }
466             
467         }
468         return -2;
469     }
470
471     private PyObject invoke_ex_richcmp(String JavaDoc name, PyObject o) {
472         PyObject ret = invoke_ex(name, o);
473         if (ret == Py.NotImplemented)
474             return null;
475         return ret;
476     }
477
478     public PyObject __lt__(PyObject o) {
479         return invoke_ex_richcmp("__lt__", o);
480     }
481
482     public PyObject __le__(PyObject o) {
483         return invoke_ex_richcmp("__le__", o);
484     }
485
486     public PyObject __gt__(PyObject o) {
487         return invoke_ex_richcmp("__gt__", o);
488     }
489
490     public PyObject __ge__(PyObject o) {
491         return invoke_ex_richcmp("__ge__", o);
492     }
493
494     public PyObject __eq__(PyObject o) {
495         return invoke_ex_richcmp("__eq__", o);
496     }
497
498     public PyObject __ne__(PyObject o) {
499         return invoke_ex_richcmp("__ne__", o);
500     }
501
502     public boolean __nonzero__() {
503         PyObject meth = null;
504         try {
505             meth = __findattr__("__nonzero__");
506         } catch (PyException exc) { }
507
508         if (meth == null) {
509             // Copied form __len__()
510
CollectionProxy proxy = getCollection();
511             if (proxy != CollectionProxy.NoProxy) {
512                 return proxy.__len__() != 0 ? true : false;
513             }
514             try {
515                 meth = __findattr__("__len__");
516             } catch (PyException exc) { }
517             if (meth == null)
518                 return true;
519         }
520
521         PyObject ret = meth.__call__();
522         return ret.__nonzero__();
523     }
524
525     private CollectionProxy collectionProxy=null;
526
527     private CollectionProxy getCollection() {
528         if (collectionProxy == null)
529             collectionProxy = CollectionProxy.findCollection(javaProxy);
530         return collectionProxy;
531     }
532
533     public int __len__() {
534         CollectionProxy proxy = getCollection();
535         if (proxy != CollectionProxy.NoProxy) {
536             return proxy.__len__();
537         }
538
539         PyObject ret = invoke("__len__");
540         if (ret instanceof PyInteger)
541             return ((PyInteger)ret).getValue();
542         throw Py.TypeError("__len__() should return an int");
543     }
544
545     public PyObject __finditem__(int key) {
546         CollectionProxy proxy = getCollection();
547         if (proxy != CollectionProxy.NoProxy) {
548             return proxy.__finditem__(key);
549         }
550         return __finditem__(new PyInteger(key));
551     }
552
553     private PyObject trySlice(PyObject key, String JavaDoc name, PyObject extraArg) {
554         if (!(key instanceof PySlice))
555             return null;
556
557         PySlice slice = (PySlice)key;
558
559         if (slice.step != Py.None && slice.step != Py.One) {
560             if (slice.step instanceof PyInteger) {
561                 if (((PyInteger)slice.step).getValue() != 1) {
562                     return null;
563                 }
564             } else {
565                 return null;
566             }
567         }
568
569         PyObject func = __findattr__(name);
570         if (func == null)
571             return null;
572
573         PyObject start = slice.start;
574         PyObject stop = slice.stop;
575
576         if (start == Py.None)
577             start = Py.Zero;
578         if (stop == Py.None)
579             stop = new PyInteger(PySystemState.maxint);
580
581         if (extraArg == null) {
582             return func.__call__(start, stop);
583         } else {
584             return func.__call__(start, stop, extraArg);
585         }
586     }
587
588     public PyObject __finditem__(PyObject key) {
589         CollectionProxy proxy = getCollection();
590         if (proxy != CollectionProxy.NoProxy) {
591             return proxy.__finditem__(key);
592         }
593
594         try {
595             PyObject ret = trySlice(key, "__getslice__", null);
596             if (ret != null)
597                 return ret;
598
599             return invoke("__getitem__", key);
600         } catch (PyException e) {
601             if (Py.matchException(e, Py.IndexError))
602                 return null;
603             throw e;
604         }
605     }
606
607     public PyObject __getitem__(PyObject key) {
608         CollectionProxy proxy = getCollection();
609         if (proxy != CollectionProxy.NoProxy) {
610             PyObject ret = proxy.__finditem__(key);
611             if (ret == null) {
612                 throw Py.KeyError(key.toString());
613             }
614             return ret;
615         }
616
617         PyObject ret = trySlice(key, "__getslice__", null);
618         if (ret != null)
619             return ret;
620
621         return invoke("__getitem__", key);
622     }
623
624     public void __setitem__(PyObject key, PyObject value) {
625         CollectionProxy proxy = getCollection();
626         if (proxy != CollectionProxy.NoProxy) {
627             proxy.__setitem__(key, value);
628             return;
629         }
630         if (trySlice(key, "__setslice__", value) != null)
631             return;
632
633         invoke("__setitem__", key, value);
634     }
635
636     public void __delitem__(PyObject key) {
637         CollectionProxy proxy = getCollection();
638         if (proxy != CollectionProxy.NoProxy) {
639             proxy.__delitem__(key);
640             return;
641         }
642         if (trySlice(key, "__delslice__", null) != null)
643             return;
644         invoke("__delitem__", key);
645     }
646
647     public PyObject __iter__() {
648         PyObject iter = getCollectionIter();
649         if (iter != null) {
650             return iter;
651         }
652         PyObject func = __findattr__("__iter__");
653         if (func != null)
654             return func.__call__();
655         func = __findattr__("__getitem__");
656         if (func == null)
657             return super.__iter__();
658         return new PySequenceIter(this);
659     }
660
661     public PyObject __iternext__() {
662         PyObject func = __findattr__("next");
663         if (func != null) {
664             try {
665                 return func.__call__();
666             } catch (PyException exc) {
667                 if (Py.matchException(exc, Py.StopIteration))
668                     return null;
669                 throw exc;
670             }
671         }
672         throw Py.TypeError("instance has no next() method");
673     }
674
675     private static CollectionIter[] iterFactories = null;
676
677     private PyObject getCollectionIter() {
678         if (iterFactories == null)
679             initializeIterators();
680         for (int i = 0; iterFactories[i] != null; i++) {
681             PyObject iter = iterFactories[i].findCollection(javaProxy);
682             if (iter != null)
683                 return iter;
684         }
685         return null;
686     }
687
688     private static synchronized void initializeIterators() {
689         if (iterFactories != null)
690             return;
691         String JavaDoc factories = "org.python.core.CollectionIter," +
692                            "org.python.core.CollectionIter2," +
693                            Py.getSystemState().registry.getProperty(
694                                 "python.collections", "");
695         int i = 0;
696         StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(factories, ",");
697         iterFactories = new CollectionIter[st.countTokens() + 1];
698         while (st.hasMoreTokens()) {
699             String JavaDoc s = st.nextToken();
700             try {
701                 Class JavaDoc factoryClass = Class.forName(s);
702                 CollectionIter factory =
703                         (CollectionIter)factoryClass.newInstance();
704                 iterFactories[i++] = factory;
705             } catch (Throwable JavaDoc t) { }
706         }
707     }
708
709     public boolean __contains__(PyObject o) {
710         PyObject func = __findattr__("__contains__");
711         if (func == null)
712            return super.__contains__(o);
713         PyObject ret = func.__call__(o);
714         return ret.__nonzero__();
715     }
716
717     //Begin the numeric methods here
718
public Object JavaDoc __coerce_ex__(PyObject o) {
719         PyObject ret = invoke_ex("__coerce__", o);
720         if (ret == null || ret == Py.None)
721             return ret;
722         if (!(ret instanceof PyTuple))
723             throw Py.TypeError("coercion should return None or 2-tuple");
724         return ((PyTuple)ret).getArray();
725     }
726
727
728     // Generated by make_binops.py
729

730     // Unary ops
731

732     /**
733      * Implements the __hex__ method by looking it up
734      * in the instance's dictionary and calling it if it is found.
735      **/

736     public PyString __hex__() {
737         PyObject ret = invoke("__hex__");
738         if (ret instanceof PyString)
739             return (PyString)ret;
740         throw Py.TypeError("__hex__() should return a string");
741     }
742
743     /**
744      * Implements the __oct__ method by looking it up
745      * in the instance's dictionary and calling it if it is found.
746      **/

747     public PyString __oct__() {
748         PyObject ret = invoke("__oct__");
749         if (ret instanceof PyString)
750             return (PyString)ret;
751         throw Py.TypeError("__oct__() should return a string");
752     }
753
754     /**
755      * Implements the __int__ method by looking it up
756      * in the instance's dictionary and calling it if it is found.
757      **/