home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1998 January / PCO0198.ISO / browser / net_linx / jae40.jar / java / beans / Introspector.class (.txt) < prev    next >
Encoding:
Java Class File  |  1997-11-03  |  9.5 KB  |  555 lines

  1. package java.beans;
  2.  
  3. import java.lang.reflect.Method;
  4. import java.lang.reflect.Modifier;
  5. import java.util.Enumeration;
  6. import java.util.Hashtable;
  7.  
  8. public class Introspector {
  9.    private BeanInfo informant;
  10.    private boolean propertyChangeSource = false;
  11.    private Class beanClass;
  12.    private BeanInfo superBeanInfo;
  13.    private BeanInfo[] additionalBeanInfo;
  14.    private static Hashtable cache = new Hashtable();
  15.    private static Class eventListenerType = getClassForName("java.util.EventListener.class");
  16.    private String defaultEventName;
  17.    private String defaultPropertyName;
  18.    private int defaultEventIndex = -1;
  19.    private int defaultPropertyIndex = -1;
  20.    private Hashtable methods = new Hashtable();
  21.    private Hashtable properties = new Hashtable();
  22.    private Hashtable events = new Hashtable();
  23.    private static String[] searchPath = new String[]{"sun.beans.infos"};
  24.  
  25.    public static BeanInfo getBeanInfo(Class var0) throws IntrospectionException {
  26.       BeanInfo var1 = (BeanInfo)cache.get(var0);
  27.       if (var1 == null) {
  28.          var1 = (new Introspector(var0, (Class)null)).getBeanInfo();
  29.          cache.put(var0, var1);
  30.       }
  31.  
  32.       return var1;
  33.    }
  34.  
  35.    public static BeanInfo getBeanInfo(Class var0, Class var1) throws IntrospectionException {
  36.       return (new Introspector(var0, var1)).getBeanInfo();
  37.    }
  38.  
  39.    public static String decapitalize(String var0) {
  40.       if (var0 != null && var0.length() != 0) {
  41.          if (var0.length() > 1 && Character.isUpperCase(var0.charAt(1)) && Character.isUpperCase(var0.charAt(0))) {
  42.             return var0;
  43.          } else {
  44.             char[] var1 = var0.toCharArray();
  45.             var1[0] = Character.toLowerCase(var1[0]);
  46.             return new String(var1);
  47.          }
  48.       } else {
  49.          return var0;
  50.       }
  51.    }
  52.  
  53.    public static String[] getBeanInfoSearchPath() {
  54.       return searchPath;
  55.    }
  56.  
  57.    public static void setBeanInfoSearchPath(String[] var0) {
  58.       searchPath = var0;
  59.    }
  60.  
  61.    private Introspector(Class var1, Class var2) throws IntrospectionException {
  62.       this.beanClass = var1;
  63.       if (var2 != null) {
  64.          boolean var3 = false;
  65.  
  66.          for(Class var4 = var1.getSuperclass(); var4 != null; var4 = var4.getSuperclass()) {
  67.             if (var4 == var2) {
  68.                var3 = true;
  69.             }
  70.          }
  71.  
  72.          if (!var3) {
  73.             throw new IntrospectionException(var2.getName() + " not superclass of " + var1.getName());
  74.          }
  75.       }
  76.  
  77.       this.informant = this.findInformant(var1);
  78.       if (var1.getSuperclass() != var2) {
  79.          if (var2 == null) {
  80.             this.superBeanInfo = getBeanInfo(var1.getSuperclass());
  81.          } else {
  82.             this.superBeanInfo = getBeanInfo(var1.getSuperclass(), var2);
  83.          }
  84.       }
  85.  
  86.       if (this.informant != null) {
  87.          this.additionalBeanInfo = this.informant.getAdditionalBeanInfo();
  88.       }
  89.  
  90.       if (this.additionalBeanInfo == null) {
  91.          this.additionalBeanInfo = new BeanInfo[0];
  92.       }
  93.  
  94.    }
  95.  
  96.    private BeanInfo getBeanInfo() throws IntrospectionException {
  97.       BeanDescriptor var1 = this.getTargetBeanDescriptor();
  98.       EventSetDescriptor[] var2 = this.getTargetEventInfo();
  99.       int var3 = this.getTargetDefaultEventIndex();
  100.       PropertyDescriptor[] var4 = this.getTargetPropertyInfo();
  101.       int var5 = this.getTargetDefaultPropertyIndex();
  102.       MethodDescriptor[] var6 = this.getTargetMethodInfo();
  103.       return new GenericBeanInfo(var1, var2, var3, var4, var5, var6, this.informant);
  104.    }
  105.  
  106.    private BeanInfo findInformant(Class var1) {
  107.       String var2 = var1.getName() + "BeanInfo";
  108.  
  109.       try {
  110.          ClassLoader var8 = var1.getClassLoader();
  111.          Object var9 = null;
  112.          Class var10;
  113.          if (var8 == null) {
  114.             var10 = Class.forName(var2);
  115.          } else {
  116.             var10 = var8.loadClass(var2);
  117.          }
  118.  
  119.          return (BeanInfo)var10.newInstance();
  120.       } catch (Exception var7) {
  121.          while(var2.indexOf(46) > 0) {
  122.             var2 = var2.substring(var2.indexOf(46) + 1);
  123.          }
  124.  
  125.          for(int var3 = 0; var3 < searchPath.length; ++var3) {
  126.             try {
  127.                String var4 = searchPath[var3] + "." + var2;
  128.                Class var5 = Class.forName(var4);
  129.                return (BeanInfo)var5.newInstance();
  130.             }
  131.          }
  132.  
  133.          return null;
  134.       }
  135.    }
  136.  
  137.    private PropertyDescriptor[] getTargetPropertyInfo() throws IntrospectionException {
  138.       PropertyDescriptor[] var1 = null;
  139.       if (this.informant != null) {
  140.          var1 = this.informant.getPropertyDescriptors();
  141.          int var2 = this.informant.getDefaultPropertyIndex();
  142.          if (var2 >= 0 && var2 < var1.length) {
  143.             this.defaultPropertyName = var1[var2].getName();
  144.          }
  145.       }
  146.  
  147.       if (var1 == null && this.superBeanInfo != null) {
  148.          PropertyDescriptor[] var10 = this.superBeanInfo.getPropertyDescriptors();
  149.  
  150.          for(int var3 = 0; var3 < var10.length; ++var3) {
  151.             this.addProperty(var10[var3]);
  152.          }
  153.  
  154.          int var4 = this.superBeanInfo.getDefaultPropertyIndex();
  155.          if (var4 >= 0 && var4 < var10.length) {
  156.             this.defaultPropertyName = var10[var4].getName();
  157.          }
  158.       }
  159.  
  160.       for(int var11 = 0; var11 < this.additionalBeanInfo.length; ++var11) {
  161.          PropertyDescriptor[] var12 = this.additionalBeanInfo[var11].getPropertyDescriptors();
  162.          if (var12 != null) {
  163.             for(int var16 = 0; var16 < var12.length; ++var16) {
  164.                this.addProperty(var12[var16]);
  165.             }
  166.          }
  167.       }
  168.  
  169.       if (var1 != null) {
  170.          for(int var13 = 0; var13 < var1.length; ++var13) {
  171.             this.addProperty(var1[var13]);
  172.          }
  173.       } else {
  174.          Method[] var14 = this.beanClass.getDeclaredMethods();
  175.  
  176.          for(int var17 = 0; var17 < var14.length; ++var17) {
  177.             Method var5 = var14[var17];
  178.             if (Modifier.isPublic(var5.getModifiers())) {
  179.                String var6 = var5.getName();
  180.                Class[] var7 = var5.getParameterTypes();
  181.                Class var8 = var5.getReturnType();
  182.                Object var9 = null;
  183.                if (var6.startsWith("get") && var7.length == 0) {
  184.                   var9 = new PropertyDescriptor(decapitalize(var6.substring(3)), var5, (Method)null);
  185.                } else if (var6.startsWith("get") && var7.length == 1 && var7[0] == Integer.TYPE) {
  186.                   var9 = new IndexedPropertyDescriptor(decapitalize(var6.substring(3)), (Method)null, (Method)null, var5, (Method)null);
  187.                } else if (var6.startsWith("set") && var7.length == 1 && var8 == Void.TYPE) {
  188.                   var9 = new PropertyDescriptor(decapitalize(var6.substring(3)), (Method)null, var5);
  189.                   if (this.throwsException(var5, getClassForName("PropertyVetoException.class"))) {
  190.                      ((PropertyDescriptor)var9).setConstrained(true);
  191.                   }
  192.                } else if (var6.startsWith("set") && var7.length == 2 && var7[0] == Integer.TYPE) {
  193.                   var9 = new IndexedPropertyDescriptor(decapitalize(var6.substring(3)), (Method)null, (Method)null, (Method)null, var5);
  194.                   if (this.throwsException(var5, getClassForName("PropertyVetoException.class"))) {
  195.                      ((PropertyDescriptor)var9).setConstrained(true);
  196.                   }
  197.                } else if (var6.startsWith("is") && var7.length == 0 && var8 == Boolean.TYPE) {
  198.                   var9 = new PropertyDescriptor(decapitalize(var6.substring(2)), var5, (Method)null);
  199.                }
  200.  
  201.                if (var9 != null) {
  202.                   if (this.propertyChangeSource) {
  203.                      ((PropertyDescriptor)var9).setBound(true);
  204.                   }
  205.  
  206.                   this.addProperty((PropertyDescriptor)var9);
  207.                }
  208.             }
  209.          }
  210.       }
  211.  
  212.       PropertyDescriptor[] var15 = new PropertyDescriptor[this.properties.size()];
  213.       Enumeration var18 = this.properties.elements();
  214.  
  215.       for(int var19 = 0; var19 < var15.length; ++var19) {
  216.          var15[var19] = (PropertyDescriptor)var18.nextElement();
  217.          if (this.defaultPropertyName != null && this.defaultPropertyName.equals(var15[var19].getName())) {
  218.             this.defaultPropertyIndex = var19;
  219.          }
  220.       }
  221.  
  222.       return var15;
  223.    }
  224.  
  225.    void addProperty(PropertyDescriptor var1) {
  226.       String var2 = ((FeatureDescriptor)var1).getName();
  227.       PropertyDescriptor var3 = (PropertyDescriptor)this.properties.get(var2);
  228.       if (var3 == null) {
  229.          this.properties.put(var2, var1);
  230.       } else {
  231.          Class var4 = var3.getPropertyType();
  232.          Class var5 = var1.getPropertyType();
  233.          if (var4 != null && var5 != null && var4 != var5) {
  234.             this.properties.put(var2, var1);
  235.          } else {
  236.             Object var6;
  237.             if (!(var3 instanceof IndexedPropertyDescriptor) && !(var1 instanceof IndexedPropertyDescriptor)) {
  238.                var6 = new PropertyDescriptor(var3, var1);
  239.             } else {
  240.                var6 = new IndexedPropertyDescriptor(var3, var1);
  241.             }
  242.  
  243.             this.properties.put(var2, var6);
  244.          }
  245.       }
  246.    }
  247.  
  248.    private EventSetDescriptor[] getTargetEventInfo() throws IntrospectionException {
  249.       EventSetDescriptor[] var1 = null;
  250.       if (this.informant != null) {
  251.          var1 = this.informant.getEventSetDescriptors();
  252.          int var2 = this.informant.getDefaultEventIndex();
  253.          if (var2 >= 0 && var2 < var1.length) {
  254.             this.defaultEventName = var1[var2].getName();
  255.          }
  256.       }
  257.  
  258.       if (var1 == null && this.superBeanInfo != null) {
  259.          EventSetDescriptor[] var21 = this.superBeanInfo.getEventSetDescriptors();
  260.  
  261.          for(int var3 = 0; var3 < var21.length; ++var3) {
  262.             this.addEvent(var21[var3]);
  263.          }
  264.  
  265.          int var4 = this.superBeanInfo.getDefaultEventIndex();
  266.          if (var4 >= 0 && var4 < var21.length) {
  267.             this.defaultEventName = var21[var4].getName();
  268.          }
  269.       }
  270.  
  271.       for(int var22 = 0; var22 < this.additionalBeanInfo.length; ++var22) {
  272.          EventSetDescriptor[] var23 = this.additionalBeanInfo[var22].getEventSetDescriptors();
  273.          if (var23 != null) {
  274.             for(int var27 = 0; var27 < var23.length; ++var27) {
  275.                this.addEvent(var23[var27]);
  276.             }
  277.          }
  278.       }
  279.  
  280.       if (var1 != null) {
  281.          for(int var24 = 0; var24 < var1.length; ++var24) {
  282.             this.addEvent(var1[var24]);
  283.          }
  284.       } else {
  285.          Method[] var25 = this.beanClass.getDeclaredMethods();
  286.          Hashtable var28 = new Hashtable();
  287.          Hashtable var5 = new Hashtable();
  288.  
  289.          for(int var6 = 0; var6 < var25.length; ++var6) {
  290.             Method var7 = var25[var6];
  291.             if (Modifier.isPublic(var7.getModifiers())) {
  292.                String var8 = var7.getName();
  293.                Class[] var9 = var7.getParameterTypes();
  294.                Class var10 = var7.getReturnType();
  295.                if (var8.startsWith("add") && var9.length == 1 && var10 == Void.TYPE) {
  296.                   String var35 = var8.substring(3) + ":" + var9[0];
  297.                   var28.put(var35, var7);
  298.                } else if (var8.startsWith("remove") && var9.length == 1 && var10 == Void.TYPE) {
  299.                   String var11 = var8.substring(6) + ":" + var9[0];
  300.                   var5.put(var11, var7);
  301.                }
  302.             }
  303.          }
  304.  
  305.          Enumeration var31 = var28.keys();
  306.          this.beanClass.getName();
  307.  
  308.          while(var31.hasMoreElements()) {
  309.             String var32 = (String)var31.nextElement();
  310.             if (var5.get(var32) != null && var32.indexOf("Listener:") > 0) {
  311.                String var33 = var32.substring(0, var32.indexOf(58));
  312.                String var34 = decapitalize(var33.substring(0, var33.length() - 8));
  313.                Method var36 = (Method)var28.get(var32);
  314.                Method var12 = (Method)var5.get(var32);
  315.                Class var13 = var36.getParameterTypes()[0];
  316.                if (isSubclass(var13, eventListenerType)) {
  317.                   Method[] var14 = var13.getMethods();
  318.                   int var15 = 0;
  319.  
  320.                   for(int var16 = 0; var16 < var14.length; ++var16) {
  321.                      if (this.isEventHandler(var14[var16])) {
  322.                         ++var15;
  323.                      } else {
  324.                         var14[var16] = null;
  325.                      }
  326.                   }
  327.  
  328.                   Method[] var17 = new Method[var15];
  329.                   int var18 = 0;
  330.  
  331.                   for(int var19 = 0; var19 < var14.length; ++var19) {
  332.                      if (var14[var19] != null) {
  333.                         var17[var18++] = var14[var19];
  334.                      }
  335.                   }
  336.  
  337.                   EventSetDescriptor var20 = new EventSetDescriptor(var34, var13, var17, var36, var12);
  338.                   if (this.throwsException(var36, getClassForName("java.util.TooManyListenersException.class"))) {
  339.                      var20.setUnicast(true);
  340.                   }
  341.  
  342.                   this.addEvent(var20);
  343.                }
  344.             }
  345.          }
  346.       }
  347.  
  348.       EventSetDescriptor[] var26 = new EventSetDescriptor[this.events.size()];
  349.       Enumeration var29 = this.events.elements();
  350.  
  351.       for(int var30 = 0; var30 < var26.length; ++var30) {
  352.          var26[var30] = (EventSetDescriptor)var29.nextElement();
  353.          if (this.defaultEventName != null && this.defaultEventName.equals(var26[var30].getName())) {
  354.             this.defaultEventIndex = var30;
  355.          }
  356.       }
  357.  
  358.       return var26;
  359.    }
  360.  
  361.    void addEvent(EventSetDescriptor var1) {
  362.       String var2 = ((FeatureDescriptor)var1).getName();
  363.       if (var2.equals("propertyChange")) {
  364.          this.propertyChangeSource = true;
  365.       }
  366.  
  367.       EventSetDescriptor var3 = (EventSetDescriptor)this.events.get(var2);
  368.       if (var3 == null) {
  369.          this.events.put(var2, var1);
  370.       } else {
  371.          EventSetDescriptor var4 = new EventSetDescriptor(var3, var1);
  372.          this.events.put(var2, var4);
  373.       }
  374.    }
  375.  
  376.    private MethodDescriptor[] getTargetMethodInfo() throws IntrospectionException {
  377.       MethodDescriptor[] var1 = null;
  378.       if (this.informant != null) {
  379.          var1 = this.informant.getMethodDescriptors();
  380.       }
  381.  
  382.       if (var1 == null && this.superBeanInfo != null) {
  383.          MethodDescriptor[] var2 = this.superBeanInfo.getMethodDescriptors();
  384.  
  385.          for(int var3 = 0; var3 < var2.length; ++var3) {
  386.             this.addMethod(var2[var3]);
  387.          }
  388.       }
  389.  
  390.       for(int var7 = 0; var7 < this.additionalBeanInfo.length; ++var7) {
  391.          MethodDescriptor[] var8 = this.additionalBeanInfo[var7].getMethodDescriptors();
  392.          if (var8 != null) {
  393.             for(int var4 = 0; var4 < var8.length; ++var4) {
  394.                this.addMethod(var8[var4]);
  395.             }
  396.          }
  397.       }
  398.  
  399.       if (var1 != null) {
  400.          for(int var9 = 0; var9 < var1.length; ++var9) {
  401.             this.addMethod(var1[var9]);
  402.          }
  403.       } else {
  404.          Method[] var10 = this.beanClass.getDeclaredMethods();
  405.  
  406.          for(int var12 = 0; var12 < var10.length; ++var12) {
  407.             Method var5 = var10[var12];
  408.             if (Modifier.isPublic(var5.getModifiers())) {
  409.                MethodDescriptor var6 = new MethodDescriptor(var5);
  410.                this.addMethod(var6);
  411.             }
  412.          }
  413.       }
  414.  
  415.       MethodDescriptor[] var11 = new MethodDescriptor[this.methods.size()];
  416.       Enumeration var13 = this.methods.elements();
  417.  
  418.       for(int var14 = 0; var14 < var11.length; ++var14) {
  419.          var11[var14] = (MethodDescriptor)var13.nextElement();
  420.       }
  421.  
  422.       return var11;
  423.    }
  424.  
  425.    private void addMethod(MethodDescriptor var1) {
  426.       Method var2 = var1.getMethod();
  427.       StringBuffer var3 = new StringBuffer();
  428.       var3.append(var2.getName());
  429.       Class[] var4 = var2.getParameterTypes();
  430.  
  431.       for(int var5 = 0; var5 < var4.length; ++var5) {
  432.          var3.append(":");
  433.          var3.append(var4[var5].getName());
  434.       }
  435.  
  436.       String var6 = var3.toString();
  437.       MethodDescriptor var7 = (MethodDescriptor)this.methods.get(var6);
  438.       if (var7 == null) {
  439.          this.methods.put(var6, var1);
  440.       } else {
  441.          MethodDescriptor var8 = new MethodDescriptor(var7, var1);
  442.          this.methods.put(var6, var8);
  443.       }
  444.    }
  445.  
  446.    private int getTargetDefaultEventIndex() {
  447.       return this.defaultEventIndex;
  448.    }
  449.  
  450.    private int getTargetDefaultPropertyIndex() {
  451.       return this.defaultPropertyIndex;
  452.    }
  453.  
  454.    private BeanDescriptor getTargetBeanDescriptor() throws IntrospectionException {
  455.       if (this.informant != null) {
  456.          BeanDescriptor var1 = this.informant.getBeanDescriptor();
  457.          if (var1 != null) {
  458.             return var1;
  459.          }
  460.       }
  461.  
  462.       return new BeanDescriptor(this.beanClass);
  463.    }
  464.  
  465.    private boolean isEventHandler(Method var1) throws IntrospectionException {
  466.       try {
  467.          Class[] var2 = var1.getParameterTypes();
  468.          if (var2.length != 1) {
  469.             return false;
  470.          } else {
  471.             String var3 = String.valueOf(var2[0]);
  472.             return var3.indexOf("Event") >= 0;
  473.          }
  474.       } catch (Exception var4) {
  475.          throw new IntrospectionException("Unexpected reflection exception: " + var4);
  476.       }
  477.    }
  478.  
  479.    static Method findMethod(Class var0, String var1, int var2) throws IntrospectionException {
  480.       if (var1 == null) {
  481.          return null;
  482.       } else {
  483.          Method[] var3 = var0.getMethods();
  484.  
  485.          for(int var4 = 0; var4 < var3.length; ++var4) {
  486.             Method var5 = var3[var4];
  487.             if (var5.getName().equals(var1) && var5.getParameterTypes().length == var2) {
  488.                return var5;
  489.             }
  490.          }
  491.  
  492.          return findDirectMethod(var0, var1, var2);
  493.       }
  494.    }
  495.  
  496.    static Method findDirectMethod(Class var0, String var1, int var2) throws IntrospectionException {
  497.       Method[] var3 = var0.getDeclaredMethods();
  498.  
  499.       for(int var4 = 0; var4 < var3.length; ++var4) {
  500.          Method var5 = var3[var4];
  501.          if (var5.getName().equals(var1) && Modifier.isPublic(var5.getModifiers()) && var5.getParameterTypes().length == var2) {
  502.             return var5;
  503.          }
  504.       }
  505.  
  506.       throw new IntrospectionException("No direct method \"" + var1 + "\" with " + var2 + " arg");
  507.    }
  508.  
  509.    static boolean isSubclass(Class var0, Class var1) {
  510.       if (var0 == var1) {
  511.          return true;
  512.       } else if (var0 != null && var1 != null) {
  513.          for(Class var2 = var0; var2 != null; var2 = var2.getSuperclass()) {
  514.             if (var2 == var1) {
  515.                return true;
  516.             }
  517.  
  518.             if (var1.isInterface()) {
  519.                Class[] var3 = var2.getInterfaces();
  520.  
  521.                for(int var4 = 0; var4 < var3.length; ++var4) {
  522.                   if (var3[var4] == var1) {
  523.                      return true;
  524.                   }
  525.                }
  526.             }
  527.          }
  528.  
  529.          return false;
  530.       } else {
  531.          return false;
  532.       }
  533.    }
  534.  
  535.    private boolean throwsException(Method var1, Class var2) {
  536.       Class[] var3 = var1.getExceptionTypes();
  537.  
  538.       for(int var4 = 0; var4 < var3.length; ++var4) {
  539.          if (var3[var4] == var2) {
  540.             return true;
  541.          }
  542.       }
  543.  
  544.       return false;
  545.    }
  546.  
  547.    public static Class getClassForName(String var0) {
  548.       try {
  549.          return Class.forName(var0);
  550.       } catch (ClassNotFoundException var1) {
  551.          return null;
  552.       }
  553.    }
  554. }
  555.