Source Code Cross Referenced for ProxyMaker.java in  » Scripting » jython » org » python » compiler » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Scripting » jython » org.python.compiler 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        // Copyright (c) Corporation for National Research Initiatives
002:        package org.python.compiler;
003:
004:        import java.util.Hashtable;
005:        import java.util.Enumeration;
006:        import java.lang.reflect.Method;
007:        import java.lang.reflect.Modifier;
008:        import java.lang.reflect.Constructor;
009:        import java.io.*;
010:        import org.python.core.Py;
011:
012:        public class ProxyMaker implements  ClassConstants {
013:            public static final int tBoolean = 0;
014:            public static final int tByte = 1;
015:            public static final int tShort = 2;
016:            public static final int tInteger = 3;
017:            public static final int tLong = 4;
018:            public static final int tFloat = 5;
019:            public static final int tDouble = 6;
020:            public static final int tCharacter = 7;
021:            public static final int tVoid = 8;
022:            public static final int tOther = 9;
023:            public static final int tNone = 10;
024:
025:            public static Hashtable types = fillTypes();
026:
027:            public static Hashtable fillTypes() {
028:                Hashtable types = new Hashtable();
029:                types.put(Boolean.TYPE, new Integer(tBoolean));
030:                types.put(Byte.TYPE, new Integer(tByte));
031:                types.put(Short.TYPE, new Integer(tShort));
032:                types.put(Integer.TYPE, new Integer(tInteger));
033:                types.put(Long.TYPE, new Integer(tLong));
034:                types.put(Float.TYPE, new Integer(tFloat));
035:                types.put(Double.TYPE, new Integer(tDouble));
036:                types.put(Character.TYPE, new Integer(tCharacter));
037:                types.put(Void.TYPE, new Integer(tVoid));
038:                return types;
039:            }
040:
041:            public static int getType(Class c) {
042:                if (c == null)
043:                    return tNone;
044:                Object i = types.get(c);
045:                if (i == null)
046:                    return tOther;
047:                else
048:                    return ((Integer) i).intValue();
049:            }
050:
051:            Class super class;
052:            Class[] interfaces;
053:            Hashtable names;
054:            Hashtable super names = new Hashtable();
055:            public ClassFile classfile;
056:            public String myClass;
057:            public boolean isAdapter = false;
058:
059:            // Ctor used by makeProxy and AdapterMaker.
060:            public ProxyMaker(String classname, Class super class) {
061:                this .myClass = "org.python.proxies." + classname;
062:                if (super class.isInterface()) {
063:                    this .super class = Object.class;
064:                    this .interfaces = new Class[] { super class };
065:                } else {
066:                    this .super class = super class;
067:                    this .interfaces = new Class[0];
068:                }
069:            }
070:
071:            // Ctor used by javamaker.
072:            public ProxyMaker(String myClass, Class super class,
073:                    Class[] interfaces) {
074:                this .myClass = myClass;
075:                if (super class == null)
076:                    super class = Object.class;
077:                this .super class = super class;
078:                if (interfaces == null)
079:                    interfaces = new Class[0];
080:                this .interfaces = interfaces;
081:            }
082:
083:            public static String mapClass(Class c) {
084:                String name = c.getName();
085:                int index = name.indexOf(".");
086:                if (index == -1)
087:                    return name;
088:
089:                StringBuffer buf = new StringBuffer(name.length());
090:                int last_index = 0;
091:                while (index != -1) {
092:                    buf.append(name.substring(last_index, index));
093:                    buf.append("/");
094:                    last_index = index + 1;
095:                    index = name.indexOf(".", last_index);
096:                }
097:                buf.append(name.substring(last_index, name.length()));
098:                return buf.toString();
099:            }
100:
101:            public static String mapType(Class type) {
102:                if (type.isArray())
103:                    return "[" + mapType(type.getComponentType());
104:
105:                switch (getType(type)) {
106:                case tByte:
107:                    return "B";
108:                case tCharacter:
109:                    return "C";
110:                case tDouble:
111:                    return "D";
112:                case tFloat:
113:                    return "F";
114:                case tInteger:
115:                    return "I";
116:                case tLong:
117:                    return "J";
118:                case tShort:
119:                    return "S";
120:                case tBoolean:
121:                    return "Z";
122:                case tVoid:
123:                    return "V";
124:                default:
125:                    return "L" + mapClass(type) + ";";
126:                }
127:            }
128:
129:            public static String makeSignature(Class[] sig, Class ret) {
130:                StringBuffer buf = new StringBuffer();
131:                buf.append("(");
132:                for (int i = 0; i < sig.length; i++) {
133:                    buf.append(mapType(sig[i]));
134:                }
135:                buf.append(")");
136:                buf.append(mapType(ret));
137:                return buf.toString();
138:            }
139:
140:            public void doConstants() throws Exception {
141:                Code code = classfile.addMethod("<clinit>", "()V",
142:                        Modifier.STATIC);
143:                code.return_();
144:            }
145:
146:            public static void doReturn(Code code, Class type) throws Exception {
147:                switch (getType(type)) {
148:                case tNone:
149:                    break;
150:                case tCharacter:
151:                case tBoolean:
152:                case tByte:
153:                case tShort:
154:                case tInteger:
155:                    code.ireturn();
156:                    break;
157:                case tLong:
158:                    code.lreturn();
159:                    break;
160:                case tFloat:
161:                    code.freturn();
162:                    break;
163:                case tDouble:
164:                    code.dreturn();
165:                    break;
166:                case tVoid:
167:                    code.return_();
168:                    break;
169:                default:
170:                    code.areturn();
171:                    break;
172:                }
173:            }
174:
175:            public static void doNullReturn(Code code, Class type)
176:                    throws Exception {
177:                switch (getType(type)) {
178:                case tNone:
179:                    break;
180:                case tCharacter:
181:                case tBoolean:
182:                case tByte:
183:                case tShort:
184:                case tInteger:
185:                    code.iconst(0);
186:                    code.ireturn();
187:                    break;
188:                case tLong:
189:                    code.ldc(code.pool.Long(0));
190:                    code.lreturn();
191:                    break;
192:                case tFloat:
193:                    code.ldc(code.pool.Float((float) 0.));
194:                    code.freturn();
195:                    break;
196:                case tDouble:
197:                    code.ldc(code.pool.Double(0.));
198:                    code.dreturn();
199:                    break;
200:                case tVoid:
201:                    code.return_();
202:                    break;
203:                default:
204:                    code.aconst_null();
205:                    code.areturn();
206:                    break;
207:                }
208:            }
209:
210:            public void callSuper(Code code, String name, String super class,
211:                    Class[] parameters, Class ret, String sig) throws Exception {
212:                code.aload(0);
213:                int local_index;
214:                int i;
215:                for (i = 0, local_index = 1; i < parameters.length; i++) {
216:                    switch (getType(parameters[i])) {
217:                    case tCharacter:
218:                    case tBoolean:
219:                    case tByte:
220:                    case tShort:
221:                    case tInteger:
222:                        code.iload(local_index);
223:                        local_index += 1;
224:                        break;
225:                    case tLong:
226:                        code.lload(local_index);
227:                        local_index += 2;
228:                        break;
229:                    case tFloat:
230:                        code.fload(local_index);
231:                        local_index += 1;
232:                        break;
233:                    case tDouble:
234:                        code.dload(local_index);
235:                        local_index += 2;
236:                        break;
237:                    default:
238:                        code.aload(local_index);
239:                        local_index += 1;
240:                        break;
241:                    }
242:                }
243:                int meth = code.pool.Methodref(super class, name, sig);
244:                code.invokespecial(meth);
245:                doReturn(code, ret);
246:            }
247:
248:            public void doJavaCall(Code code, String name, String type,
249:                    String jcallName) throws Exception {
250:                int jcall = code.pool.Methodref("org/python/core/PyObject",
251:                        jcallName, "(" + $objArr + ")" + $pyObj);
252:
253:                int py2j = code.pool.Methodref("org/python/core/Py", "py2"
254:                        + name, "(" + $pyObj + ")" + type);
255:
256:                code.invokevirtual(jcall);
257:                code.invokestatic(py2j);
258:            }
259:
260:            public void getArgs(Code code, Class[] parameters) throws Exception {
261:                if (parameters.length == 0) {
262:                    int EmptyObjects = code.pool.Fieldref("org/python/core/Py",
263:                            "EmptyObjects", $pyObjArr);
264:                    code.getstatic(EmptyObjects);
265:                } else {
266:                    code.iconst(parameters.length);
267:                    code.anewarray(code.pool.Class("java/lang/Object"));
268:                    int array = code.getLocal("[org/python/core/PyObject");
269:                    code.astore(array);
270:
271:                    int local_index;
272:                    int i;
273:                    for (i = 0, local_index = 1; i < parameters.length; i++) {
274:                        code.aload(array);
275:                        code.iconst(i);
276:
277:                        switch (getType(parameters[i])) {
278:                        case tBoolean:
279:                        case tByte:
280:                        case tShort:
281:                        case tInteger:
282:                            code.iload(local_index);
283:                            local_index += 1;
284:
285:                            int newInteger = code.pool.Methodref(
286:                                    "org/python/core/Py", "newInteger", "(I)"
287:                                            + $pyInteger);
288:                            code.invokestatic(newInteger);
289:                            break;
290:                        case tLong:
291:                            code.lload(local_index);
292:                            local_index += 2;
293:
294:                            int newInteger1 = code.pool.Methodref(
295:                                    "org/python/core/Py", "newInteger", "(J)"
296:                                            + $pyObj);
297:                            code.invokestatic(newInteger1);
298:                            break;
299:                        case tFloat:
300:                            code.fload(local_index);
301:                            local_index += 1;
302:
303:                            int newFloat = code.pool.Methodref(
304:                                    "org/python/core/Py", "newFloat", "(F)"
305:                                            + $pyFloat);
306:                            code.invokestatic(newFloat);
307:                            break;
308:                        case tDouble:
309:                            code.dload(local_index);
310:                            local_index += 2;
311:
312:                            int newFloat1 = code.pool.Methodref(
313:                                    "org/python/core/Py", "newFloat", "(D)"
314:                                            + $pyFloat);
315:                            code.invokestatic(newFloat1);
316:                            break;
317:                        case tCharacter:
318:                            code.iload(local_index);
319:                            local_index += 1;
320:                            int newString = code.pool.Methodref(
321:                                    "org/python/core/Py", "newString", "(C)"
322:                                            + $pyStr);
323:                            code.invokestatic(newString);
324:                            break;
325:                        default:
326:                            code.aload(local_index);
327:                            local_index += 1;
328:                            break;
329:                        }
330:                        code.aastore();
331:                    }
332:                    code.aload(array);
333:                }
334:            }
335:
336:            public void callMethod(Code code, String name, Class[] parameters,
337:                    Class ret, Class[] exceptions) throws Exception {
338:                Label start = null;
339:                Label end = null;
340:
341:                String jcallName = "_jcall";
342:                int instLocal = 0;
343:
344:                if (exceptions.length > 0) {
345:                    start = code.getLabel();
346:                    end = code.getLabel();
347:                    jcallName = "_jcallexc";
348:                    instLocal = code.getLocal("org/python/core/PyObject");
349:                    code.astore(instLocal);
350:                    start.setPosition();
351:                    code.aload(instLocal);
352:                }
353:
354:                getArgs(code, parameters);
355:
356:                switch (getType(ret)) {
357:                case tCharacter:
358:                    doJavaCall(code, "char", "C", jcallName);
359:                    break;
360:                case tBoolean:
361:                    doJavaCall(code, "boolean", "Z", jcallName);
362:                    break;
363:                case tByte:
364:                case tShort:
365:                case tInteger:
366:                    doJavaCall(code, "int", "I", jcallName);
367:                    break;
368:                case tLong:
369:                    doJavaCall(code, "long", "J", jcallName);
370:                    break;
371:                case tFloat:
372:                    doJavaCall(code, "float", "F", jcallName);
373:                    break;
374:                case tDouble:
375:                    doJavaCall(code, "double", "D", jcallName);
376:                    break;
377:                case tVoid:
378:                    doJavaCall(code, "void", "V", jcallName);
379:                    break;
380:                default:
381:                    int jcall = code.pool.Methodref("org/python/core/PyObject",
382:                            jcallName, "(" + $objArr + ")" + $pyObj);
383:                    code.invokevirtual(jcall);
384:                    /* catching exceptions is not vm mandatory
385:                    Label forname_start =code.getLabel();
386:                    Label forname_end = code.getLabel();
387:                    Label forname_exch_start = code.getLabel();
388:                    Label forname_exch_end = code.getLabel();
389:                    forname_start.setPosition();
390:                     */
391:                    int forname = code.pool.Methodref("java/lang/Class",
392:                            "forName", "(" + $str + ")" + $clss);
393:                    code.ldc(ret.getName());
394:                    code.invokestatic(forname);
395:                    /*
396:                    forname_end.setPosition();
397:                    code.goto_(forname_exch_end);
398:                    forname_exch_start.setPosition();
399:                    code.stack = 1;
400:                    // never reached, but this code keeps the verifier happy
401:                    code.pop();
402:                    code.aconst_null();
403:                    code.dup();
404:                    forname_exch_end.setPosition();
405:
406:                    code.addExceptionHandler(forname_start,forname_end,
407:                            forname_exch_start,
408:                            code.pool.Class("java/lang/ClassNotFoundException"));
409:                     */
410:                    int tojava = code.pool.Methodref("org/python/core/Py",
411:                            "tojava", "(" + $pyObj + $clss + ")" + $obj);
412:                    code.invokestatic(tojava);
413:                    // I guess I need this checkcast to keep the verifier happy
414:                    code.checkcast(code.pool.Class(mapClass(ret)));
415:                    break;
416:                }
417:                if (exceptions.length > 0)
418:                    end.setPosition();
419:
420:                doReturn(code, ret);
421:
422:                if (exceptions.length > 0) {
423:                    boolean throwableFound = false;
424:
425:                    Label handlerStart = null;
426:                    for (int i = 0; i < exceptions.length; i++) {
427:                        handlerStart = code.getLabel();
428:                        handlerStart.setPosition();
429:                        code.stack = 1;
430:                        int excLocal = code.getLocal("java/lang/Throwable");
431:                        code.astore(excLocal);
432:
433:                        code.aload(excLocal);
434:                        code.athrow();
435:
436:                        code.addExceptionHandler(start, end, handlerStart,
437:                                code.pool.Class(mapClass(exceptions[i])));
438:                        doNullReturn(code, ret);
439:
440:                        code.freeLocal(excLocal);
441:                        if (exceptions[i] == Throwable.class)
442:                            throwableFound = true;
443:                    }
444:
445:                    if (!throwableFound) {
446:                        // The final catch (Throwable)
447:                        handlerStart = code.getLabel();
448:                        handlerStart.setPosition();
449:                        code.stack = 1;
450:                        int excLocal = code.getLocal("java/lang/Throwable");
451:                        code.astore(excLocal);
452:                        code.aload(instLocal);
453:                        code.aload(excLocal);
454:
455:                        int jthrow = code.pool.Methodref(
456:                                "org/python/core/PyObject", "_jthrow", "("
457:                                        + $throwable + ")V");
458:                        code.invokevirtual(jthrow);
459:
460:                        code.addExceptionHandler(start, end, handlerStart,
461:                                code.pool.Class("java/lang/Throwable"));
462:                        code.freeLocal(excLocal);
463:                        doNullReturn(code, ret);
464:                    }
465:                    code.freeLocal(instLocal);
466:                }
467:            }
468:
469:            public void addMethod(Method method, int access) throws Exception {
470:                boolean isAbstract = false;
471:
472:                if (Modifier.isAbstract(access)) {
473:                    access = access & ~Modifier.ABSTRACT;
474:                    isAbstract = true;
475:                }
476:
477:                Class[] parameters = method.getParameterTypes();
478:                Class ret = method.getReturnType();
479:                String sig = makeSignature(parameters, ret);
480:
481:                String name = method.getName();
482:                //         System.out.println(name+": "+sig);
483:                names.put(name, name);
484:
485:                Code code = classfile.addMethod(name, sig, access);
486:
487:                code.aload(0);
488:                code.ldc(name);
489:
490:                if (!isAbstract) {
491:                    int tmp = code.getLocal("org/python/core/PyObject");
492:                    int jfindattr = code.pool.Methodref("org/python/core/Py",
493:                            "jfindattr", "(" + $pyProxy + $str + ")" + $pyObj);
494:                    code.invokestatic(jfindattr);
495:
496:                    code.astore(tmp);
497:                    code.aload(tmp);
498:
499:                    Label callPython = code.getLabel();
500:
501:                    code.ifnonnull(callPython);
502:
503:                    String super class = mapClass(method.getDeclaringClass());
504:
505:                    callSuper(code, name, super class, parameters, ret, sig);
506:                    callPython.setPosition();
507:                    code.aload(tmp);
508:                    callMethod(code, name, parameters, ret, method
509:                            .getExceptionTypes());
510:
511:                    addSuperMethod("super__" + name, name, super class,
512:                            parameters, ret, sig, access);
513:                } else {
514:                    if (!isAdapter) {
515:                        int jgetattr = code.pool.Methodref(
516:                                "org/python/core/Py", "jgetattr", "("
517:                                        + $pyProxy + $str + ")" + $pyObj);
518:                        code.invokestatic(jgetattr);
519:                        callMethod(code, name, parameters, ret, method
520:                                .getExceptionTypes());
521:                    } else {
522:                        int jfindattr = code.pool.Methodref(
523:                                "org/python/core/Py", "jfindattr", "("
524:                                        + $pyProxy + $str + ")" + $pyObj);
525:                        code.invokestatic(jfindattr);
526:                        code.dup();
527:                        Label returnNull = code.getLabel();
528:                        code.ifnull(returnNull);
529:                        callMethod(code, name, parameters, ret, method
530:                                .getExceptionTypes());
531:                        returnNull.setPosition();
532:                        code.pop();
533:                        doNullReturn(code, ret);
534:                    }
535:                }
536:            }
537:
538:            private String methodString(Method m) {
539:                StringBuffer buf = new StringBuffer(m.getName());
540:                buf.append(":");
541:                Class[] params = m.getParameterTypes();
542:                for (int i = 0; i < params.length; i++) {
543:                    buf.append(params[i].getName());
544:                    buf.append(",");
545:                }
546:                return buf.toString();
547:            }
548:
549:            protected void addMethods(Class c, Hashtable t) throws Exception {
550:                Method[] methods = c.getDeclaredMethods();
551:                for (int i = 0; i < methods.length; i++) {
552:                    Method method = methods[i];
553:                    String s = methodString(method);
554:                    if (t.containsKey(s))
555:                        continue;
556:                    t.put(s, s);
557:
558:                    int access = method.getModifiers();
559:                    if (Modifier.isStatic(access) || Modifier.isPrivate(access)) {
560:                        continue;
561:                    }
562:
563:                    if (Modifier.isNative(access)) {
564:                        access = access & ~Modifier.NATIVE;
565:                    }
566:
567:                    if (Modifier.isProtected(access)) {
568:                        access = (access & ~Modifier.PROTECTED)
569:                                | Modifier.PUBLIC;
570:                        if (Modifier.isFinal(access)) {
571:                            addSuperMethod(methods[i], access);
572:                            continue;
573:                        }
574:                    } else if (Modifier.isFinal(access)) {
575:                        continue;
576:                    }
577:                    addMethod(methods[i], access);
578:                }
579:
580:                Class sc = c.getSuperclass();
581:                if (sc != null)
582:                    addMethods(sc, t);
583:
584:                Class[] interfaces = c.getInterfaces();
585:                for (int j = 0; j < interfaces.length; j++) {
586:                    addMethods(interfaces[j], t);
587:                }
588:            }
589:
590:            public void addConstructor(String name, Class[] parameters,
591:                    Class ret, String sig, int access) throws Exception {
592:                Code code = classfile.addMethod("<init>", sig, access);
593:                callSuper(code, "<init>", name, parameters, Void.TYPE, sig);
594:            }
595:
596:            public void addConstructors(Class c) throws Exception {
597:                Constructor[] constructors = c.getDeclaredConstructors();
598:                String name = mapClass(c);
599:                for (int i = 0; i < constructors.length; i++) {
600:                    int access = constructors[i].getModifiers();
601:                    if (Modifier.isPrivate(access))
602:                        continue;
603:                    if (Modifier.isNative(access))
604:                        access = access & ~Modifier.NATIVE;
605:                    if (Modifier.isProtected(access))
606:                        access = access & ~Modifier.PROTECTED | Modifier.PUBLIC;
607:                    Class[] parameters = constructors[i].getParameterTypes();
608:                    String sig = makeSignature(parameters, Void.TYPE);
609:                    addConstructor(name, parameters, Void.TYPE, sig, access);
610:                }
611:            }
612:
613:            // Super methods are added for the following three reasons:
614:            //
615:            //   1) for a protected non-final method add a public method with no
616:            //   super__ prefix.  This gives needed access to this method for
617:            //   subclasses
618:            //
619:            //   2) for protected final methods, add a public method with the
620:            //   super__ prefix.  This avoids the danger of trying to override a
621:            //   final method
622:            //
623:            //   3) For any other method that is overriden, add a method with the
624:            //   super__ prefix.  This gives access to super. version or the
625:            //   method.
626:            //
627:            public void addSuperMethod(Method method, int access)
628:                    throws Exception {
629:                Class[] parameters = method.getParameterTypes();
630:                Class ret = method.getReturnType();
631:                String sig = makeSignature(parameters, ret);
632:                String super class = mapClass(method.getDeclaringClass());
633:                String super Name = method.getName();
634:                String methodName = super Name;
635:                if (Modifier.isFinal(access)) {
636:                    methodName = "super__" + super Name;
637:                    access &= ~Modifier.FINAL;
638:                }
639:                addSuperMethod(methodName, super Name, super class, parameters,
640:                        ret, sig, access);
641:            }
642:
643:            public void addSuperMethod(String methodName, String super Name,
644:                    String declClass, Class[] parameters, Class ret,
645:                    String sig, int access) throws Exception {
646:                if (methodName.startsWith("super__")) {
647:                    /* rationale: JC java-class, P proxy-class subclassing JC
648:                       in order to avoid infinite recursion P should define super__foo
649:                       only if no class between P and JC in the hierarchy defines
650:                       it yet; this means that the python class needing P is the
651:                       first that redefines the JC method foo.
652:                     */
653:                    try {
654:                        super class.getMethod(methodName, parameters);
655:                        return;
656:                    } catch (NoSuchMethodException e) {
657:                    } catch (SecurityException e) {
658:                        return;
659:                    }
660:                }
661:                super names.put(methodName, methodName);
662:                Code code = classfile.addMethod(methodName, sig, access);
663:                callSuper(code, super Name, declClass, parameters, ret, sig);
664:            }
665:
666:            public void addProxy() throws Exception {
667:                // implement PyProxy interface
668:                classfile.addField("__proxy", "Lorg/python/core/PyInstance;",
669:                        Modifier.PROTECTED);
670:                // setProxy method
671:                Code code = classfile.addMethod("_setPyInstance",
672:                        "(Lorg/python/core/PyInstance;)V", Modifier.PUBLIC);
673:
674:                int field = code.pool.Fieldref(classfile.name, "__proxy",
675:                        "Lorg/python/core/PyInstance;");
676:                code.aload(0);
677:                code.aload(1);
678:                code.putfield(field);
679:                code.return_();
680:
681:                // getProxy method
682:                code = classfile.addMethod("_getPyInstance",
683:                        "()Lorg/python/core/PyInstance;", Modifier.PUBLIC);
684:                code.aload(0);
685:                code.getfield(field);
686:                code.areturn();
687:
688:                // implement PyProxy interface
689:                classfile.addField("__systemState",
690:                        "Lorg/python/core/PySystemState;", Modifier.PROTECTED
691:                                | Modifier.TRANSIENT);
692:
693:                // setProxy method
694:                code = classfile.addMethod("_setPySystemState",
695:                        "(Lorg/python/core/PySystemState;)V", Modifier.PUBLIC);
696:
697:                field = code.pool.Fieldref(classfile.name, "__systemState",
698:                        "Lorg/python/core/PySystemState;");
699:                code.aload(0);
700:                code.aload(1);
701:                code.putfield(field);
702:                code.return_();
703:
704:                // getProxy method
705:                code = classfile.addMethod("_getPySystemState",
706:                        "()Lorg/python/core/PySystemState;", Modifier.PUBLIC);
707:                code.aload(0);
708:                code.getfield(field);
709:                code.areturn();
710:            }
711:
712:            public void addClassDictInit() throws Exception {
713:                int n = super names.size();
714:
715:                // classDictInit method
716:                classfile
717:                        .addInterface(mapClass(org.python.core.ClassDictInit.class));
718:                Code code = classfile.addMethod("classDictInit", "(" + $pyObj
719:                        + ")V", Modifier.PUBLIC | Modifier.STATIC);
720:                code.aload(0);
721:                code.ldc("__supernames__");
722:
723:                String[] names = new String[n];
724:                Enumeration e = super names.keys();
725:                for (int i = 0; e.hasMoreElements();)
726:                    names[i++] = (String) e.nextElement();
727:                CodeCompiler.makeStrings(code, names, n);
728:                int j2py = code.pool.Methodref("org/python/core/Py", "java2py",
729:                        "(" + $obj + ")" + $pyObj);
730:                code.invokestatic(j2py);
731:
732:                int setitem = code.pool.Methodref("org/python/core/PyObject",
733:                        "__setitem__", "(" + $str + $pyObj + ")V");
734:                code.invokevirtual(setitem);
735:                code.return_();
736:
737:            }
738:
739:            public void build() throws Exception {
740:                names = new Hashtable();
741:                int access = super class.getModifiers();
742:                if ((access & Modifier.FINAL) != 0) {
743:                    throw new InstantiationException(
744:                            "can't subclass final class");
745:                }
746:                access = Modifier.PUBLIC | Modifier.SYNCHRONIZED;
747:
748:                classfile = new ClassFile(myClass, mapClass(super class), access);
749:                addProxy();
750:                addConstructors(super class);
751:                classfile.addInterface("org/python/core/PyProxy");
752:
753:                Hashtable seenmethods = new Hashtable();
754:                addMethods(super class, seenmethods);
755:                for (int i = 0; i < interfaces.length; i++) {
756:                    if (interfaces[i].isAssignableFrom(super class)) {
757:                        Py.writeWarning("compiler",
758:                                "discarding redundant interface: "
759:                                        + interfaces[i].getName());
760:                        continue;
761:                    }
762:                    classfile.addInterface(mapClass(interfaces[i]));
763:                    addMethods(interfaces[i], seenmethods);
764:                }
765:                doConstants();
766:                addClassDictInit();
767:            }
768:
769:            public static String makeProxy(Class super class,
770:                    OutputStream ostream) throws Exception {
771:                ProxyMaker pm = new ProxyMaker(super class.getName(), super class);
772:                pm.build();
773:                pm.classfile.write(ostream);
774:                return pm.myClass;
775:            }
776:
777:            public static File makeFilename(String name, File dir) {
778:                int index = name.indexOf(".");
779:                if (index == -1)
780:                    return new File(dir, name + ".class");
781:
782:                return makeFilename(name.substring(index + 1, name.length()),
783:                        new File(dir, name.substring(0, index)));
784:            }
785:
786:            // This is not general enough
787:            public static OutputStream getFile(String d, String name)
788:                    throws IOException {
789:                File dir = new File(d);
790:                File file = makeFilename(name, dir);
791:                new File(file.getParent()).mkdirs();
792:                //System.out.println("proxy file: "+file);
793:                return new FileOutputStream(file);
794:            }
795:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.