KickJava   Java API By Example, From Geeks To Geeks.

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


1 // Copyright (c) Corporation for National Research Initiatives
2
package org.python.core;
3
4 import java.lang.reflect.Constructor JavaDoc;
5 import java.lang.reflect.Modifier JavaDoc;
6 import java.lang.reflect.InvocationTargetException JavaDoc;
7 import java.lang.InstantiationException JavaDoc;
8
9
10 public class PyReflectedConstructor extends PyReflectedFunction
11 {
12     
13     public PyReflectedConstructor(String JavaDoc name) {
14         super(name);
15         __name__ = name;
16         argslist = new ReflectedArgs[1];
17         nargs = 0;
18     }
19
20     public PyReflectedConstructor(Constructor JavaDoc c) {
21         this(c.getDeclaringClass().getName());
22         addConstructor(c);
23     }
24
25     private ReflectedArgs makeArgs(Constructor JavaDoc m) {
26         return new ReflectedArgs(m, m.getParameterTypes(),
27                                  m.getDeclaringClass(), true);
28     }
29
30     public void addConstructor(Constructor JavaDoc m) {
31         int mods = m.getModifiers();
32         // Only add public methods unless we're overriding
33
if (!Modifier.isPublic(mods) && !JavaAccessibility.accessIsMutable())
34             return;
35         addArgs(makeArgs(m));
36     }
37
38     // xxx temporary solution, type ctr will go through __new__ ...
39
PyObject make(PyObject[] args,String JavaDoc[] keywords) {
40         ReflectedArgs[] argsl = argslist;
41                 
42         ReflectedCallData callData = new ReflectedCallData();
43         Object JavaDoc method=null;
44         boolean consumes_keywords = false;
45         int n = nargs;
46         int nkeywords = keywords.length;
47         PyObject[] allArgs = null;
48         
49         // Check for a matching constructor to call
50
if (n > 0) { // PyArgsKeywordsCall signature, if present, is the first
51
if (argsl[0].matches(null, args, keywords, callData)) {
52                 method = argsl[0].data;
53                 consumes_keywords = argsl[0].flags == ReflectedArgs.PyArgsKeywordsCall;
54             } else {
55                 allArgs = args;
56                 int i = 1;
57                 if (nkeywords > 0) {
58                     args = new PyObject[allArgs.length-nkeywords];
59                     System.arraycopy(allArgs, 0, args, 0, args.length);
60                     i = 0;
61                 }
62                 for (; i < n; i++) {
63                     ReflectedArgs rargs = argsl[i];
64                         if (rargs
65                             .matches(null, args, Py.NoKeywords, callData)) {
66                         method = rargs.data; break; }
67                 }
68             }
69         }
70
71         // Throw an error if no valid set of arguments
72
if (method == null) {
73             throwError(callData.errArg, args.length, true /*xxx?*/,false);
74         }
75
76         // Do the actual constructor call
77
PyObject obj = null;
78         Constructor JavaDoc ctor = (Constructor JavaDoc)method;
79         try {
80             obj = (PyObject)ctor.newInstance(callData.getArgsArray());
81         }
82         catch (Throwable JavaDoc t) {
83             throw Py.JavaError(t);
84         }
85         
86         if (!consumes_keywords) {
87             int offset = args.length;
88             for (int i=0; i<nkeywords; i++) {
89                 obj.__setattr__(keywords[i], allArgs[i+offset]);
90             }
91         }
92     
93         return obj;
94     }
95
96     public PyObject __call__(PyObject self, PyObject[] args,
97                              String JavaDoc[] keywords)
98     {
99         ReflectedArgs[] argsl = argslist;
100
101         if (self == null || !(self instanceof PyInstance)) {
102             throw Py.TypeError("invalid self argument to constructor");
103         }
104
105         PyInstance iself = (PyInstance)self;
106         Class JavaDoc javaClass = iself.instclass.proxyClass;
107         //Class[] javaClasses = iself.__class__.proxyClasses;
108
//int myIndex = -1;
109
boolean proxyConstructor=false;
110         Class JavaDoc declaringClass = argsl[0].declaringClass;
111
112         // If this is the constructor for a proxy class or not...
113
if (PyProxy.class.isAssignableFrom(declaringClass)) {
114 // if (self instanceof PyJavaInstance) {
115
// throw Py.TypeError(
116
// "invalid self argument to proxy constructor");
117
// }
118
}
119         else {
120             if (!(iself instanceof PyJavaInstance)) {
121                 // Get proxy constructor and call it
122
if (declaringClass.isAssignableFrom(javaClass)) {
123                     proxyConstructor = true;
124                 } else {
125                     throw Py.TypeError("invalid self argument");
126                 }
127
128                 PyJavaClass jc = PyJavaClass.lookup(javaClass); // xxx
129
jc.initConstructors();
130                 return jc.__init__.__call__(iself, args, keywords);
131             }
132         }
133
134
135         if (declaringClass.isAssignableFrom(javaClass)) {
136             proxyConstructor = true;
137         } else {
138             throw Py.TypeError("self invalid - must implement: "+
139                                declaringClass.getName());
140         }
141
142         if (iself.javaProxy != null) {
143             Class JavaDoc sup = iself.instclass.proxyClass;
144             if (PyProxy.class.isAssignableFrom(sup))
145                 sup = sup.getSuperclass();
146             throw Py.TypeError("instance already instantiated for "+
147                                sup.getName());
148         }
149
150         ReflectedCallData callData = new ReflectedCallData();
151         Object JavaDoc method=null;
152
153         // Remove keyword args
154
int nkeywords = keywords.length;
155         PyObject[] allArgs = args;
156         if (nkeywords > 0) {
157             args = new PyObject[allArgs.length-nkeywords];
158             System.arraycopy(allArgs, 0, args, 0, args.length);
159         }
160
161         // Check for a matching constructor to call
162
int n = nargs;
163         for (int i=0; i<n; i++) {
164             ReflectedArgs rargs = argsl[i];
165             if (rargs.matches(null, args, Py.NoKeywords, callData)) {
166                 method = rargs.data;
167                 break;
168             }
169         }
170
171         // Throw an error if no valid set of arguments
172
if (method == null) {
173             throwError(callData.errArg, args.length, self != null, false);
174         }
175
176         // Do the actual constructor call
177
Object JavaDoc jself = null;
178         ThreadState ts = Py.getThreadState();
179         try {
180             ts.pushInitializingProxy(iself);
181             Constructor JavaDoc ctor = (Constructor JavaDoc)method;
182             try {
183                 jself = ctor.newInstance(callData.getArgsArray());
184             }
185             catch (InvocationTargetException JavaDoc e) {
186                 if (e.getTargetException() instanceof InstantiationException JavaDoc){
187                     Class JavaDoc sup = iself.instclass.proxyClass.getSuperclass();
188                     String JavaDoc msg = "Constructor failed for Java superclass";
189                     if (sup != null)
190                         msg += " " + sup.getName();
191                     throw Py.TypeError(msg);
192                 }
193                 else throw Py.JavaError(e);
194             }
195             catch (Throwable JavaDoc t) {
196                 throw Py.JavaError(t);
197             }
198         }
199         finally {
200             ts.popInitializingProxy();
201         }
202
203         iself.javaProxy = jself;
204
205         // Do setattr's for keyword args
206
int offset = args.length;
207         for (int i=0; i<nkeywords; i++) {
208             iself.__setattr__(keywords[i], allArgs[i+offset]);
209         }
210         return Py.None;
211     }
212
213     public PyObject __call__(PyObject[] args, String JavaDoc[] keywords) {
214         if (args.length < 1) {
215             throw Py.TypeError("constructor requires self argument");
216         }
217         PyObject[] newArgs = new PyObject[args.length-1];
218         System.arraycopy(args, 1, newArgs, 0, newArgs.length);
219
220         return __call__(args[0], newArgs, keywords);
221     }
222
223     public String JavaDoc toString() {
224         //printArgs();
225
return "<java constructor "+__name__+" "+Py.idstr(this)+">";
226     }
227 }
228
Popular Tags