KickJava   Java API By Example, From Geeks To Geeks.

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


1 // Copyright (c) Corporation for National Research Initiatives
2
package org.python.core;
3
4 class ReflectedArgs {
5     public Class JavaDoc[] args;
6     public Object JavaDoc data;
7     public Class JavaDoc declaringClass;
8     public boolean isStatic;
9     public int flags;
10
11     public static final int StandardCall=0;
12     public static final int PyArgsCall=1;
13     public static final int PyArgsKeywordsCall=2;
14
15
16     public ReflectedArgs(Object JavaDoc data, Class JavaDoc[] args,
17                          Class JavaDoc declaringClass, boolean isStatic)
18     {
19         this.data = data;
20         this.args = args;
21         this.declaringClass = declaringClass;
22         this.isStatic = isStatic;
23
24         if (args.length == 1 && args[0] == PyObject[].class) {
25             flags = PyArgsCall;
26         } else if (args.length == 2 &&
27                    args[0] == PyObject[].class &&
28                    args[1] == String JavaDoc[].class)
29         {
30             flags = PyArgsKeywordsCall;
31         } else {
32             flags = StandardCall;
33         }
34     }
35
36     public boolean matches(PyObject self, PyObject[] pyArgs,
37                             String JavaDoc[] keywords, ReflectedCallData callData)
38     {
39         if (flags != PyArgsKeywordsCall) {
40             if (keywords != null && keywords.length != 0)
41                 return false;
42         }
43
44         //if (isStatic ? self != null : self == null) return Py.NoConversion;
45
/* Ugly code to handle mismatch in static vs. instance functions... */
46         /* Will be very inefficient in cases where static and instance
47            functions both exist with same names and number of args
48         */

49         if (isStatic) {
50             if (self != null) {
51                 /*PyObject[] newArgs = new PyObject[pyArgs.length+1];
52                   System.arraycopy(pyArgs, 0, newArgs, 1, pyArgs.length);
53                   newArgs[0] = self;
54                   pyArgs = newArgs;*/

55                 self = null;
56             }
57         } else {
58             if (self == null) {
59                 if (pyArgs.length == 0)
60                     return false;
61                 self = pyArgs[0];
62                 PyObject[] newArgs = new PyObject[pyArgs.length-1];
63                 System.arraycopy(pyArgs, 1, newArgs, 0, newArgs.length);
64                 pyArgs = newArgs;
65             }
66         }
67
68         if (flags == PyArgsKeywordsCall) { // foo(PyObject[], String[])
69
callData.setLength(2);
70             callData.args[0] = pyArgs;
71             callData.args[1] = keywords;
72             callData.self = self;
73             if (self != null) {
74                 Object JavaDoc tmp = self.__tojava__(declaringClass);
75                 if (tmp != Py.NoConversion)
76                     callData.self = tmp;
77             }
78             return true;
79         } else if (flags == PyArgsCall) { // foo(PyObject[])
80
callData.setLength(1);
81             callData.args[0] = pyArgs;
82             callData.self = self;
83             if (self != null) {
84                 Object JavaDoc tmp = self.__tojava__(declaringClass);
85                 if (tmp != Py.NoConversion)
86                     callData.self = tmp;
87             }
88             return true;
89         }
90
91         int n = args.length;
92         if (pyArgs.length != n)
93             return false;
94
95         // Make error messages clearer
96
callData.errArg = -1;
97
98         if (self != null) {
99             Object JavaDoc tmp = self.__tojava__(declaringClass);
100             if (tmp == Py.NoConversion)
101                 return false;
102             callData.self = tmp;
103         } else {
104             callData.self = null;
105         }
106
107         callData.setLength(n);
108         Object JavaDoc[] javaArgs = callData.args;
109
110         for(int i=0; i<n; i++) {
111             if ((javaArgs[i] = pyArgs[i].__tojava__(args[i])) ==
112                 Py.NoConversion)
113             {
114                 // Make error messages clearer
115
if (i > callData.errArg)
116                     callData.errArg = i;
117                 return false;
118             }
119         }
120         return true;
121     }
122
123     public static int precedence(Class JavaDoc arg) {
124         if (arg == Object JavaDoc.class)
125             return 3000;
126         if (arg.isPrimitive()) {
127             if (arg == Long.TYPE) return 10;
128             if (arg == Integer.TYPE) return 11;
129             if (arg == Short.TYPE) return 12;
130             if (arg == Character.TYPE) return 13;
131             if (arg == Byte.TYPE) return 14;
132             if (arg == Double.TYPE) return 20;
133             if (arg == Float.TYPE) return 21;
134             if (arg == Boolean.TYPE) return 30;
135         }
136         // Consider Strings a primitive type
137
// This makes them higher priority than byte[]
138
if (arg == String JavaDoc.class)
139             return 40;
140
141         if (arg.isArray()) {
142             Class JavaDoc componentType = arg.getComponentType();
143             if (componentType == Object JavaDoc.class)
144                 return 2500;
145             return 100+precedence(componentType);
146         }
147         return 2000;
148     }
149
150     /* Returns 0 iff arg1 == arg2
151        Returns +/-1 iff arg1 and arg2 are unimportantly different
152        Returns +/-2 iff arg1 and arg2 are significantly different
153     */

154     public static int compare(Class JavaDoc arg1, Class JavaDoc arg2) {
155         int p1 = precedence(arg1);
156         int p2 = precedence(arg2);
157         // Special code if they are both nonprimitives
158
// Superclasses/superinterfaces are considered greater than sub's
159
if (p1 >= 2000 && p2 >= 2000) {
160             if (arg1.isAssignableFrom(arg2)) {
161                 if (arg2.isAssignableFrom(arg1)) return 0;
162                 else return +2;
163             } else {
164                 if (arg2.isAssignableFrom(arg1)) return -2;
165                 else {
166                     int cmp = arg1.getName().compareTo(arg2.getName());
167                     return cmp > 0 ? +1 : -1;
168                 }
169             }
170         } else {
171             return p1 > p2 ? +2 : (p1 == p2 ? 0 : -2);
172         }
173     }
174
175     public static final int REPLACE = 1998;
176
177     public int compareTo(ReflectedArgs other) {
178         Class JavaDoc[] oargs = other.args;
179
180         // First decision based on flags
181
if (other.flags != flags) {
182             return other.flags < flags ? -1 : +1;
183         }
184
185         // Decision based on number of args
186
int n = args.length;
187         if (n < oargs.length) return -1;
188         if (n > oargs.length) return +1;
189
190         // Decide based on static/non-static
191
if (isStatic && !other.isStatic) return +1;
192         if (!isStatic && other.isStatic) return -1;
193
194         // Compare the arg lists
195
int cmp = 0;
196         for (int i=0; i<n; i++) {
197             int tmp = compare(args[i], oargs[i]);
198             if (tmp == +2 || tmp == -2) cmp = tmp;
199             if (cmp == 0) cmp = tmp;
200         }
201
202         if (cmp != 0) return cmp > 0 ? +1 : -1;
203
204         // If arg lists are equivalent, look at declaring classes
205
boolean replace =
206             other.declaringClass.isAssignableFrom(declaringClass);
207
208         // For static methods, use the child's version
209
// For instance methods, use the parent's version
210
if (!isStatic) replace = !replace;
211
212         return replace ? REPLACE : 0;
213     }
214
215     public String JavaDoc toString() {
216         String JavaDoc s = ""+declaringClass+", "+isStatic+", "+flags+", "+data+"\n";
217         s = s+"\t(";
218         for(int j=0; j<args.length; j++) {
219             s += args[j].getName()+", ";
220         }
221         s += ")";
222         return s;
223     }
224 }
225
Popular Tags