1 package org.python.core; 3 4 import java.lang.reflect.Constructor ; 5 import java.lang.reflect.Field ; 6 import java.lang.reflect.Method ; 7 import java.lang.reflect.Modifier ; 8 9 12 13 public class PyJavaClass extends PyClass 14 { 15 public PyReflectedConstructor __init__; 16 17 public PackageManager __mgr__; 18 19 private static InternalTables tbl; 20 21 public synchronized final static InternalTables getInternalTables() { 22 if(tbl == null) 23 tbl = InternalTables.createInternalTables(); 24 return tbl; 25 } 26 27 public final boolean isLazy() { 28 return proxyClass == null; 29 } 30 31 public static final PyJavaClass lookup(String name,PackageManager mgr) { 32 if (tbl.queryCanonical(name)) { 33 Class c = mgr.findClass(null,name,"forced java class"); 34 check_lazy_allowed(c); return lookup(c); 36 } 37 PyJavaClass ret = new PyJavaClass(name, mgr); 38 tbl.putLazyCanonical(name, ret); 39 return ret; 40 } 41 42 public synchronized static final PyJavaClass lookup(Class c) { 43 if (tbl == null) { 44 tbl = InternalTables.createInternalTables(); 45 PyJavaClass jc = new PyJavaClass(true); 46 jc.init(PyJavaClass.class); 47 tbl.putCanonical(PyJavaClass.class,jc); 48 } 49 PyJavaClass ret = tbl.getCanonical(c); 50 if (ret != null) 51 return ret; 52 PyJavaClass lazy = tbl.getLazyCanonical(c.getName()); 53 if (lazy != null) { 54 initLazy(lazy); 55 if (lazy.proxyClass == c) return lazy; 56 } 57 58 Class parent = c.getDeclaringClass(); 59 if (parent == null) 60 ret = new PyJavaClass(c); 61 else 62 ret = new PyJavaInnerClass(c, lookup(parent)); 63 tbl.putCanonical(c,ret); 64 65 return ret; 66 } 67 68 private PyJavaClass(boolean fakeArg) { 69 super(true); 70 } 71 72 protected PyJavaClass(Class c) { 73 init(c); 74 } 75 76 protected PyJavaClass(String name,PackageManager mgr) { 77 __name__ = name; 78 this.__mgr__ = mgr; 79 } 80 81 protected void findModule(PyObject dict) {} 82 83 protected Class getProxyClass() { 84 initialize(); 85 return proxyClass; 86 } 87 88 private static final void check_lazy_allowed(Class c) { 92 if (PyObject.class.isAssignableFrom(c)) { throw Py.TypeError("cannot lazy load PyObject subclass"); 94 } 95 } 96 97 private static final void initLazy(PyJavaClass jc) { 98 Class c = jc.__mgr__.findClass(null,jc.__name__,"lazy java class"); 99 check_lazy_allowed(c); jc.init(c); 101 tbl.putCanonical(jc.proxyClass,jc); 102 jc.__mgr__ = null; 103 } 104 105 private boolean initialized=false; 106 107 private boolean initializing=false; 109 110 private synchronized void initialize() { 111 if (initialized || initializing) 112 return; 113 initializing = true; 114 synchronized(PyJavaClass.class) { 115 if (proxyClass == null) { 116 initLazy(this); 117 } 118 } 119 init__bases__(proxyClass); 120 init__dict__(); 121 122 if (ClassDictInit.class.isAssignableFrom(proxyClass) 123 && proxyClass != ClassDictInit.class) { 124 try { 125 Method m = proxyClass.getMethod("classDictInit", 126 new Class [] { PyObject.class }); 127 m.invoke(null, new Object [] { __dict__ }); 128 } 129 catch (Exception exc) { 130 throw Py.JavaError(exc); 133 } 134 } 135 136 if (InitModule.class.isAssignableFrom(proxyClass)) { 137 try { 138 InitModule m = (InitModule)proxyClass.newInstance(); 139 m.initModule(__dict__); 140 } 141 catch (Exception exc) { 142 throw Py.JavaError(exc); 144 } 145 } 146 147 initialized = true; 148 initializing = false; 149 } 150 151 private synchronized void init__dict__() { 152 if (__dict__ != null) 153 return; 154 PyStringMap d = new PyStringMap(); 155 __dict__ = d; 157 try { 158 Method [] methods = getAccessibleMethods(proxyClass); 159 setBeanInfoCustom(proxyClass, methods); 160 setFields(proxyClass); 161 setMethods(proxyClass, methods); 162 } catch (SecurityException se) {} 163 } 164 165 private synchronized void init__class__(Class c) { 166 180 } 181 182 private synchronized void init__bases__(Class c) { 183 if (__bases__ != null) return; 184 185 Class interfaces[] = getAccessibleInterfaces(c); 186 int nInterfaces = interfaces.length; 187 int nBases = 0; 188 int i; 189 for (i=0; i<nInterfaces; i++) { 190 Class inter = interfaces[i]; 191 if (inter == InitModule.class || inter == PyProxy.class || 192 inter == ClassDictInit.class) 193 continue; 194 nBases++; 195 } 196 197 Class superclass = c.getSuperclass(); 198 int index=0; 199 PyObject[] bases; 200 PyJavaClass tmp; 201 if (superclass == null || superclass == PyObject.class) { 202 bases = new PyObject[nBases]; 203 } else { 204 bases = new PyObject[nBases+1]; 205 tmp = PyJavaClass.lookup(superclass); 206 bases[0] = tmp; 207 tmp.initialize(); 208 index++; 209 } 210 211 for (i=0; i<nInterfaces; i++) { 212 Class inter = interfaces[i]; 213 if (inter == InitModule.class || inter == PyProxy.class || 214 inter == ClassDictInit.class) 215 continue; 216 tmp = PyJavaClass.lookup(inter); 217 tmp.initialize(); 218 bases[index++] = tmp; 219 } 220 221 __bases__ = new PyTuple(bases); 222 } 223 224 private void init(Class c) { 225 init__class__(c); 226 proxyClass = c; 227 __name__ = c.getName(); 228 } 229 230 235 private static Class [] getAccessibleInterfaces(Class c) { 236 Class [] in = c.getInterfaces(); 239 java.util.Vector v=new java.util.Vector (); 240 for (int i = 0; i < in.length; i++) { 241 if (!Modifier.isPublic(in[i].getModifiers())) 242 continue; 243 v.addElement(in[i]); 244 } 245 if (v.size() == in.length) 246 return in; 247 Class [] ret = new Class [v.size()]; 248 v.copyInto(ret); 249 return ret; 250 } 251 252 257 private static Field [] getAccessibleFields(Class c) { 258 if (!JavaAccessibility.accessIsMutable()) 259 return c.getFields(); 261 java.util.Vector fields = new java.util.Vector (); 267 while (c != null) { 268 Field [] declared = c.getDeclaredFields(); 271 for (int i=0; i < declared.length; i++) { 272 JavaAccessibility.setAccessible(declared[i], true); 275 fields.addElement(declared[i]); 276 } 277 c = c.getSuperclass(); 280 } 281 Field [] ret = new Field [fields.size()]; 283 fields.copyInto(ret); 284 return ret; 285 } 286 287 private void setFields(Class c) { 288 Field [] fields = getAccessibleFields(c); 289 for (int i=0; i<fields.length; i++) { 290 Field field = fields[i]; 291 if (field.getDeclaringClass() != c) 292 continue; 293 294 String name = getName(field.getName()); 295 boolean isstatic = Modifier.isStatic(field.getModifiers()); 296 297 if (isstatic) { 298 if (name.startsWith("__doc__") && name.length() > 7) 299 continue; 300 PyObject prop = lookup(name, false); 301 if (prop != null && prop instanceof PyBeanProperty) { 302 PyBeanProperty beanProp = ((PyBeanProperty)prop).copy(); 303 beanProp.field = field; 304 __dict__.__setitem__(name, beanProp); 305 continue; 306 } 307 } 308 __dict__.__setitem__(name, new PyReflectedField(field)); 309 } 310 } 311 312 316 317 private String getName(String name) { 318 if (name.endsWith("$")) name = name.substring(0, name.length()-1); 319 return name.intern(); 320 } 321 322 private void addMethod(Method meth) { 323 String name = getName(meth.getName()); 324 if (name == "_getPyInstance" || name == "_setPyInstance" || 325 name == "_getPySystemState" || name == "_setPySystemState") 326 { 327 return; 328 } 329 330 String classname = proxyClass.getName(); 335 if (classname.startsWith("java.awt.") && 336 classname.indexOf('.', 9) == -1) 337 { 338 if (name == "layout" || name == "insets" || 339 name == "size" || name == "minimumSize" || 340 name == "preferredSize" || name == "maximumSize" || 341 name == "bounds" || name == "enable") 342 { 343 return; 344 } 345 } 346 347 PyObject o = lookup(name, false); 350 351 PyReflectedFunction func; 354 if (o != null && o instanceof PyReflectedFunction) { 355 func = (PyReflectedFunction)o; 356 357 PyObject o1 = __dict__.__finditem__(name); 358 359 363 if (o1 != o) { 364 if (func.handles(meth)) 365 return; 366 func = func.copy(); 367 } 368 func.addMethod(meth); 369 } else { 370 func = new PyReflectedFunction(meth); 371 try { 372 Field docField = proxyClass.getField("__doc__" + name); 373 int mods = docField.getModifiers(); 374 if (docField.getType() == PyString.class && 375 Modifier.isPublic(mods) && 376 Modifier.isStatic(mods)); 377 func.__doc__ = (PyString) docField.get(null); 378 } catch (NoSuchFieldException ex) { 379 } catch (SecurityException ex) { 380 } catch (IllegalAccessException ex) {} 381 } 382 __dict__.__setitem__(name, func); 383 } 384 385 386 391 private static Method [] getAccessibleMethods(Class c) { 392 if (!JavaAccessibility.accessIsMutable()) 393 return c.getMethods(); 395 Method [] declared = c.getDeclaredMethods(); 396 for (int i=0; i < declared.length; i++) { 397 JavaAccessibility.setAccessible(declared[i], true); 400 } 401 return declared; 402 } 403 404 private boolean ignoreMethod(Method method) { 405 Class [] exceptions = method.getExceptionTypes(); 406 for (int j = 0; j < exceptions.length; j++) { 407 if (exceptions[j] == PyIgnoreMethodTag.class) { 408 return true; 409 } 410 } 411 return false; 412 } 413 414 415 private void setMethods(Class c, Method [] methods) { 416 for (int i=0; i<methods.length; i++) { 417 Method method = methods[i]; 418 Class dc = method.getDeclaringClass(); 419 if (dc != c) 420 continue; 421 int mods = dc.getModifiers(); 422 if(!(Modifier.isPublic(mods) || Modifier.isPrivate(mods) || Modifier.isProtected(mods))) { 423 continue; 425 } 426 if (ignoreMethod(method)) 427 continue; 428 addMethod(method); 429 } 430 } 431 432 433 void addProperty(String name, Class propClass, 434 Method getMethod, Method setMethod) 435 { 436 if (propClass == null) 438 return; 439 440 boolean set = true; 441 name = getName(name); 442 443 PyBeanProperty prop = new PyBeanProperty(name, propClass, getMethod, 444 setMethod); 445 446 PyObject o = lookup(name, false); 448 449 if (o != null) { 450 if (!(o instanceof PyReflectedField)) 451 return; 452 453 if (o instanceof PyBeanProperty) { 454 PyBeanProperty oldProp = (PyBeanProperty)o; 455 if (prop.myType == oldProp.myType) { 456 if ((prop.getMethod == null || oldProp.getMethod != null) 458 && 459 (prop.setMethod == null || oldProp.setMethod != null)) 460 { 461 set = false; 462 } 463 464 if (oldProp.getMethod != null) { 467 prop.getMethod = oldProp.getMethod; 468 } 469 if (oldProp.setMethod != null) { 470 prop.setMethod = oldProp.setMethod; 471 } 472 } 473 } 474 } 488 if (set) 489 __dict__.__setitem__(name, prop); 490 } 491 492 493 void addEvent(String name, Class eventClass, Method addMethod, 494 Method [] meths) 495 { 496 String eventName = eventClass.getName(); 497 498 for (int i=0; i<meths.length; i++) { 499 PyBeanEventProperty prop; 500 prop = new PyBeanEventProperty(name, eventClass, addMethod, 501 meths[i]); 502 __dict__.__setitem__(prop.__name__, prop); 503 } 504 PyBeanEvent event = new PyBeanEvent(name, eventClass, addMethod); 505 __dict__.__setitem__(event.__name__, event); 506 } 507 508 509 512 private static String decapitalize(String s) { 513 if (s.length() == 0) 515 return s; 516 char c0 = s.charAt(0); 517 if (Character.isUpperCase(c0)) { 518 if (s.length() > 1 && Character.isUpperCase(s.charAt(1))) 519 return s; 520 char[] cs = s.toCharArray(); 521 cs[0] = Character.toLowerCase(c0); 522 return new String (cs); 523 } else { 524 return s; 525 } 526 } 527 528 private void setBeanInfoCustom(Class c, Method [] meths) { 530 int i; 532 int n = meths.length; 533 for (i=0; i<n; i++) { 534 Method method = meths[i]; 535 536 if (ignoreMethod(method)) 537 continue; 538 if (method.getDeclaringClass() != c || 539 Modifier.isStatic(method.getModifiers())) 540 { 541 continue; 542 } 543 544 String name = method.getName(); 545 Method getter = null; 546 Method setter = null; 547 Class [] args = method.getParameterTypes(); 548 Class ret = method.getReturnType(); 549 Class myType=null; 550 551 String pname=""; 552 553 if (name.startsWith("get")) { 554 if (args.length != 0) 555 continue; 556 getter = method; 557 pname = decapitalize(name.substring(3)); 558 myType = ret; 559 } else { 561 if (name.startsWith("is")) { 562 if (args.length != 0 || ret != Boolean.TYPE) 563 continue; 564 getter = method; 565 pname = decapitalize(name.substring(2)); 566 myType = ret; 567 } else { 568 if (name.startsWith("set")) { 569 if (args.length != 1) 570 continue; 571 setter = method; 572 pname = decapitalize(name.substring(3)); 573 myType = args[0]; 574 } else { 576 continue; 577 } 578 } 579 } 580 581 PyObject o = __dict__.__finditem__(new PyString(pname)); 582 PyBeanProperty prop; 583 if (o == null || !(o instanceof PyBeanProperty) ) { 584 addProperty(pname, myType, getter, setter); 585 } else { 586 prop = (PyBeanProperty)o; 587 if (prop.myType != myType) { 588 if (getter != null) { 589 addProperty(pname, myType, getter, setter); 590 } 591 } else { 592 if (getter != null) prop.getMethod = getter; 594 if (setter != null && (ret == Void.TYPE || prop.setMethod==null)) 595 prop.setMethod = setter; 596 597 } 598 } 599 } 600 601 for (i=0; i<n; i++) { 602 Method method = meths[i]; 603 604 if (method.getDeclaringClass() != c || 605 Modifier.isStatic(method.getModifiers())) 606 { 607 continue; 608 } 609 610 String mname = method.getName(); 611 612 if (!(mname.startsWith("add") || mname.startsWith("set")) || 613 !mname.endsWith("Listener")) 614 { 615 continue; 616 } 617 618 Class [] args = method.getParameterTypes(); 619 Class ret = method.getReturnType(); 620 String pname=""; 621 622 if (args.length != 1 || ret != Void.TYPE) 623 continue; 624 625 Class eClass = args[0]; 626 627 if (eClass.getInterfaces().length > 0) 634 eClass.getInterfaces()[0].getClassLoader(); 635 637 if (!(java.util.EventListener .class.isAssignableFrom(eClass))) 638 continue; 639 640 String name = eClass.getName(); 641 int idot = name.lastIndexOf('.'); 642 if (idot != -1) 643 name = decapitalize(name.substring(idot+1)); 644 645 addEvent(name, eClass, method, eClass.getMethods()); 646 } 647 651 } 652 653 660 private static Constructor [] getAccessibleConstructors(Class c) { 661 if (!JavaAccessibility.accessIsMutable()) 662 return c.getConstructors(); 664 666 667 Constructor [] declared = c.getDeclaredConstructors(); 668 for (int i=0; i < declared.length; i++) { 669 JavaAccessibility.setAccessible(declared[i], true); 672 } 673 return declared; 674 } 675 676 private boolean ignoreConstructor(Constructor method) { 677 Class [] exceptions = method.getExceptionTypes(); 678 for (int j = 0; j < exceptions.length; j++) { 679 if (exceptions[j] == PyIgnoreMethodTag.class) { 680 return true; 681 } 682 } 683 return false; 684 } 685 686 private void setConstructors(Class c) { 687 if (Modifier.isInterface(c.getModifiers())) { 688 __init__ = null; 689 } else { 690 Constructor [] constructors = getAccessibleConstructors(c); 691 for (int i = 0; i < constructors.length; i++) { 692 if (ignoreConstructor(constructors[i])) { 693 continue; 694 } 695 if (__init__ == null) { 696 __init__ = new PyReflectedConstructor(constructors[i]); 697 } else { 698 __init__.addConstructor(constructors[i]); 699 } 700 } 701 if (__init__ != null) { 702 __dict__.__setitem__("__init__", __init__); 703 } 704 } 705 } 706 private boolean constructorsInitialized=false; 707 synchronized void initConstructors() { 708 if (constructorsInitialized) 709 return; 710 initialize(); 711 setConstructors(proxyClass); 712 constructorsInitialized = true; 713 } 714 715 718 private static java.util.Hashtable keywords=null; 719 private static String unmangleKeyword(String name) { 720 if (keywords == null) { 721 keywords = new java.util.Hashtable (); 722 String [] words = new String [] 723 {"or", "and", "not", "is", "in", "lambda", "if", "else", "elif", 724 "while", "for", "try", "except", "def", "class", "finally", 725 "print", 726 "pass", "break", "continue", "return", "import", "from", "del", 727 "raise", "global", "exec", "assert"}; 728 for (int i=0; i<words.length; i++) { 729 keywords.put(words[i]+"_", words[i].intern()); 730 } 731 } 732 return (String )keywords.get(name); 733 } 734 735 PyObject[] lookupGivingClass(String name, boolean stop_at_java) { 736 if (stop_at_java) 737 return new PyObject[] {null, null}; 738 if (!initialized) 739 initialize(); 740 if (name == "__init__") { 741 initConstructors(); 742 return new PyObject[] {__init__, null}; 743 } 744 745 if (Options.deprecatedKeywordMangling && name.endsWith("_")) { 748 String newName = unmangleKeyword(name); 749 if (newName != null) 750 name = newName; 751 } 752 return super.lookupGivingClass(name, stop_at_java); 753 } 754 755 public PyObject __dir__() { 756 initialize(); 757 if (__dict__ instanceof PyStringMap) { 758 return ((PyStringMap)__dict__).keys(); 759 } else { 760 return __dict__.invoke("keys"); 761 } 762 } 763 764 private PyStringMap missingAttributes = null; 765 public PyObject __findattr__(String name) { 766 if (name == "__dict__") { 767 if (__dict__ == null) 768 initialize(); 769 return __dict__; 770 } 771 if (name == "__name__") 772 return new PyString(__name__); 773 if (name == "__bases__") { 774 if (__bases__ == null) 775 initialize(); 776 return __bases__; 777 } 778 if (name == "__init__") { 779 initConstructors(); 780 if (__init__ == null) 781 return super.lookupGivingClass(name, false)[0]; 782 return __init__; 783 } 784 785 PyObject result = lookup(name, false); 786 if (result != null) 787 return result.__get__(null, null); 789 if (missingAttributes != null && 791 missingAttributes.__finditem__(name) != null) 792 { 793 return null; 794 } 795 796 result = findClassAttr(name); 798 if (result != null) 799 return result; 800 801 result = findInnerClass(name); 802 if (result != null) 803 return result; 804 805 if (missingAttributes == null) { 807 missingAttributes = new PyStringMap(); 808 } 809 missingAttributes.__setitem__(name, this); 810 return null; 811 } 812 813 private PyJavaInstance classInstance; 814 private PyObject findClassAttr(String name) { 815 if (classInstance == null) { 816 classInstance = new PyJavaInstance(proxyClass); 817 } 818 PyObject result = classInstance.__findattr__(name); 819 return result; 820 } 824 825 private PyObject findInnerClass(String name) { 826 Class p = getProxyClass(); 827 Class innerClass = Py.relFindClass(p, p.getName()+"$"+name); 828 if (innerClass == null) return null; 829 830 PyObject jinner = Py.java2py(innerClass); __dict__.__setitem__(name, jinner); 832 return jinner; 833 } 834 835 public void __setattr__(String name, PyObject value) { 836 PyObject field = lookup(name, false); 837 if (field != null) { 838 if (field.jtryset(null, value)) 839 return; 840 } 841 __dict__.__setitem__(name, value); 842 } 843 844 public void __delattr__(String name) { 845 PyObject field = lookup(name, false); 846 if (field == null) { 847 throw Py.NameError("attribute not found: "+name); 848 } 849 850 if (!field.jdontdel()) { 851 __dict__.__delitem__(name); 852 } 853 } 854 855 public PyObject __call__(PyObject[] args, String [] keywords) { 856 if (!constructorsInitialized) 857 initConstructors(); 858 859 if (PyObject.class.isAssignableFrom(proxyClass)) { 861 if (Modifier.isAbstract(proxyClass.getModifiers())) { 862 throw Py.TypeError("can't instantiate abstract class ("+ 863 __name__+")"); 864 } 865 if (__init__ == null) { 866 throw Py.TypeError("no public constructors for "+ 867 __name__); 868 } 869 return __init__.make(args,keywords); 870 } 871 872 PyInstance inst = new PyJavaInstance(this); 873 inst.__init__(args, keywords); 874 875 882 883 return inst; 884 } 885 886 public Object __tojava__(Class c) { 887 initialize(); 888 return super.__tojava__(c); 889 } 890 891 public String toString() { 892 return "<jclass "+__name__+" "+Py.idstr(this)+">"; 893 } 894 } 895 | Popular Tags |