/** * Wrap the given {@link BeanInfo} instance; copy all its existing property descriptors locally, * wrapping each in a custom {@link SimpleIndexedPropertyDescriptor indexed} or {@link * SimplePropertyDescriptor non-indexed} {@code PropertyDescriptor} variant that bypasses default * JDK weak/soft reference management; then search through its method descriptors to find any * non-void returning write methods and update or create the corresponding {@link * PropertyDescriptor} for each one found. * * @param delegate the wrapped {@code BeanInfo}, which is never modified * @throws IntrospectionException if any problems occur creating and adding new property * descriptors * @see #getPropertyDescriptors() */ public ExtendedBeanInfo(BeanInfo delegate) throws IntrospectionException { this.delegate = delegate; for (PropertyDescriptor pd : delegate.getPropertyDescriptors()) { try { this.propertyDescriptors.add( pd instanceof IndexedPropertyDescriptor ? new SimpleIndexedPropertyDescriptor((IndexedPropertyDescriptor) pd) : new SimplePropertyDescriptor(pd)); } catch (IntrospectionException ex) { // Probably simply a method that wasn't meant to follow the JavaBeans pattern... if (logger.isDebugEnabled()) { logger.debug("Ignoring invalid bean property '" + pd.getName() + "': " + ex.getMessage()); } } } MethodDescriptor[] methodDescriptors = delegate.getMethodDescriptors(); if (methodDescriptors != null) { for (Method method : findCandidateWriteMethods(methodDescriptors)) { try { handleCandidateWriteMethod(method); } catch (IntrospectionException ex) { // We're only trying to find candidates, can easily ignore extra ones here... if (logger.isDebugEnabled()) { logger.debug("Ignoring candidate write method [" + method + "]: " + ex.getMessage()); } } } } }
public ResourceInfo.MethodInfo[] getMethodDescriptors() { Set<java.lang.reflect.Method> accessors = new HashSet<java.lang.reflect.Method>(); for (PropertyDescriptor p : getPropertyDescriptors()) { accessors.add(p.getReadMethod()); accessors.add(p.getWriteMethod()); } for (MethodDescriptor o : getRemoteMethodDescriptors()) { accessors.add(o.getMethod()); } TreeSet<MethodDescriptor> methods = new TreeSet<MethodDescriptor>( new Comparator<MethodDescriptor>() { public int compare(MethodDescriptor a, MethodDescriptor b) { return a.getName().compareTo(b.getName()); } }); methods.addAll(Arrays.asList(info.getMethodDescriptors())); Iterator<MethodDescriptor> iter = methods.iterator(); while (iter.hasNext()) { MethodDescriptor m = iter.next(); if (accessors.contains(m.getMethod())) { iter.remove(); } } return MethodInfo.wrap(methods); }
public static void main(String[] args) throws IntrospectionException { BeanInfo beanInfo = Introspector.getBeanInfo(User.class); System.out.println("==>MethodDescriptor"); MethodDescriptor[] methodDescs = beanInfo.getMethodDescriptors(); for (MethodDescriptor method : methodDescs) { System.out.println(method.getName()); System.out.println(method.getDisplayName()); System.out.println(method.getShortDescription()); System.out.println(method.getValue("getName")); System.out.println("==>MethodDescriptor/ReflectionMethod"); Method reflectMethod = method.getMethod(); System.out.println(reflectMethod.getName()); System.out.println("==>MethodDescriptor/ParameterDescriptor"); ParameterDescriptor[] paramDescs = method.getParameterDescriptors(); if (paramDescs != null) { for (ParameterDescriptor paramDesc : paramDescs) { System.out.println(paramDesc.getName()); System.out.println(paramDesc.getDisplayName()); System.out.println(paramDesc.getShortDescription()); System.out.println(paramDesc.getValue("name")); } } } }
public static Method methodFor(String methodName) throws IntrospectionException { BeanInfo beanInfo = Introspector.getBeanInfo(SomeSteps.class); for (MethodDescriptor md : beanInfo.getMethodDescriptors()) { if (md.getMethod().getName().equals(methodName)) { return md.getMethod(); } } return null; }
static Method stepMethodFor(String methodName, Class<? extends Steps> stepsClass) throws IntrospectionException { BeanInfo beanInfo = Introspector.getBeanInfo(stepsClass); for (MethodDescriptor md : beanInfo.getMethodDescriptors()) { if (md.getMethod().getName().equals(methodName)) { return md.getMethod(); } } return null; }
/** * Wrap the given {@link BeanInfo} instance; copy all its existing property descriptors locally, * wrapping each in a custom {@link SimpleIndexedPropertyDescriptor indexed} or {@link * SimpleNonIndexedPropertyDescriptor non-indexed} {@code PropertyDescriptor} variant that * bypasses default JDK weak/soft reference management; then search through its method descriptors * to find any non-void returning write methods and update or create the corresponding {@link * PropertyDescriptor} for each one found. * * @param delegate the wrapped {@code BeanInfo}, which is never modified * @throws IntrospectionException if any problems occur creating and adding new property * descriptors * @see #getPropertyDescriptors() */ public ExtendedBeanInfo(BeanInfo delegate) throws IntrospectionException { this.delegate = delegate; for (PropertyDescriptor pd : delegate.getPropertyDescriptors()) { this.propertyDescriptors.add( pd instanceof IndexedPropertyDescriptor ? new SimpleIndexedPropertyDescriptor((IndexedPropertyDescriptor) pd) : new SimpleNonIndexedPropertyDescriptor(pd)); } for (Method method : findCandidateWriteMethods(delegate.getMethodDescriptors())) { handleCandidateWriteMethod(method); } }
public ResourceInfo.MethodInfo[] getRemoteMethodDescriptors() { List<MethodDescriptor> operations = new ArrayList<MethodDescriptor>(); operations.addAll(Arrays.asList(info.getMethodDescriptors())); Iterator<MethodDescriptor> iter = operations.iterator(); while (iter.hasNext()) { java.lang.reflect.Method m = iter.next().getMethod(); if (!m.isAnnotationPresent(Method.class) && !m.isAnnotationPresent(Path.class)) { iter.remove(); } } MethodInfo[] result = MethodInfo.wrap(operations); Arrays.sort( result, new Comparator<MethodInfo>() { public int compare(MethodInfo a, MethodInfo b) { return a.getRemoteName().compareTo(b.getRemoteName()); } }); return result; }
public static Method findSetter(Class<?> clazz, String name) throws IntrospectionException { BeanInfo info = Introspector.getBeanInfo(clazz); Method setter = null; for (PropertyDescriptor pd : info.getPropertyDescriptors()) { if (name.equals(pd.getName())) { setter = pd.getWriteMethod(); break; } } if (setter == null) { // sometimes this happens even when there is a setter. Don't know why. String expectedSetterName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1); for (MethodDescriptor md : info.getMethodDescriptors()) { if (md.getName().equals(expectedSetterName)) { setter = md.getMethod(); break; } } } return setter; }
@Override public MethodDescriptor[] getMethodDescriptors() { return mRootBeanInfo.getMethodDescriptors(); }
/** * Wrap the given delegate {@link BeanInfo} instance and find any non-void returning setter * methods, creating and adding a {@link PropertyDescriptor} for each. * * <p>The wrapped {@code BeanInfo} is not modified in any way by this process. * * @see #getPropertyDescriptors() * @throws IntrospectionException if any problems occur creating and adding new {@code * PropertyDescriptors} */ public ExtendedBeanInfo(BeanInfo delegate) throws IntrospectionException { this.delegate = delegate; // PropertyDescriptor instances from the delegate object are never added directly, but always // copied to the local collection of #propertyDescriptors and returned by calls to // #getPropertyDescriptors(). this algorithm iterates through all methods (method descriptors) // in the wrapped BeanInfo object, copying any existing PropertyDescriptor or creating a new // one for any non-standard setter methods found. ALL_METHODS: for (MethodDescriptor md : delegate.getMethodDescriptors()) { Method method = md.getMethod(); // bypass non-getter java.lang.Class methods for efficiency if (ReflectionUtils.isObjectMethod(method) && !method.getName().startsWith("get")) { continue ALL_METHODS; } // is the method a NON-INDEXED setter? ignore return type in order to capture non-void // signatures if (method.getName().startsWith("set") && method.getParameterTypes().length == 1) { String propertyName = propertyNameFor(method); if (propertyName.length() == 0) { continue ALL_METHODS; } for (PropertyDescriptor pd : delegate.getPropertyDescriptors()) { Method readMethod = pd.getReadMethod(); Method writeMethod = pd.getWriteMethod(); // has the setter already been found by the wrapped BeanInfo? if (writeMethod != null && writeMethod.getName().equals(method.getName())) { // yes -> copy it, including corresponding getter method (if any -- may be null) this.addOrUpdatePropertyDescriptor(propertyName, readMethod, writeMethod); continue ALL_METHODS; } // has a getter corresponding to this setter already been found by the wrapped BeanInfo? if (readMethod != null && readMethod.getName().equals(getterMethodNameFor(propertyName)) && readMethod.getReturnType().equals(method.getParameterTypes()[0])) { this.addOrUpdatePropertyDescriptor(propertyName, readMethod, method); continue ALL_METHODS; } } // the setter method was not found by the wrapped BeanInfo -> add a new PropertyDescriptor // for it // no corresponding getter was detected, so the 'read method' parameter is null. this.addOrUpdatePropertyDescriptor(propertyName, null, method); continue ALL_METHODS; } // is the method an INDEXED setter? ignore return type in order to capture non-void signatures if (method.getName().startsWith("set") && method.getParameterTypes().length == 2 && method.getParameterTypes()[0].equals(int.class)) { String propertyName = propertyNameFor(method); if (propertyName.length() == 0) { continue ALL_METHODS; } DELEGATE_PD: for (PropertyDescriptor pd : delegate.getPropertyDescriptors()) { if (!(pd instanceof IndexedPropertyDescriptor)) { continue DELEGATE_PD; } IndexedPropertyDescriptor ipd = (IndexedPropertyDescriptor) pd; Method readMethod = ipd.getReadMethod(); Method writeMethod = ipd.getWriteMethod(); Method indexedReadMethod = ipd.getIndexedReadMethod(); Method indexedWriteMethod = ipd.getIndexedWriteMethod(); // has the setter already been found by the wrapped BeanInfo? if (indexedWriteMethod != null && indexedWriteMethod.getName().equals(method.getName())) { // yes -> copy it, including corresponding getter method (if any -- may be null) this.addOrUpdatePropertyDescriptor( propertyName, readMethod, writeMethod, indexedReadMethod, indexedWriteMethod); continue ALL_METHODS; } // has a getter corresponding to this setter already been found by the wrapped BeanInfo? if (indexedReadMethod != null && indexedReadMethod.getName().equals(getterMethodNameFor(propertyName)) && indexedReadMethod.getReturnType().equals(method.getParameterTypes()[1])) { this.addOrUpdatePropertyDescriptor( propertyName, readMethod, writeMethod, indexedReadMethod, method); continue ALL_METHODS; } } // the INDEXED setter method was not found by the wrapped BeanInfo -> add a new // PropertyDescriptor // for it. no corresponding INDEXED getter was detected, so the 'indexed read method' // parameter is null. this.addOrUpdatePropertyDescriptor(propertyName, null, null, null, method); continue ALL_METHODS; } // the method is not a setter, but is it a getter? for (PropertyDescriptor pd : delegate.getPropertyDescriptors()) { // have we already copied this read method to a property descriptor locally? for (PropertyDescriptor existingPD : this.propertyDescriptors) { if (method.equals(pd.getReadMethod()) && existingPD.getName().equals(pd.getName())) { if (existingPD.getReadMethod() == null) { // no -> add it now this.addOrUpdatePropertyDescriptor(pd.getName(), method, pd.getWriteMethod()); } // yes -> do not add a duplicate continue ALL_METHODS; } } if (method == pd.getReadMethod() || (pd instanceof IndexedPropertyDescriptor && method == ((IndexedPropertyDescriptor) pd).getIndexedReadMethod())) { // yes -> copy it, including corresponding setter method (if any -- may be null) if (pd instanceof IndexedPropertyDescriptor) { this.addOrUpdatePropertyDescriptor( pd.getName(), pd.getReadMethod(), pd.getWriteMethod(), ((IndexedPropertyDescriptor) pd).getIndexedReadMethod(), ((IndexedPropertyDescriptor) pd).getIndexedWriteMethod()); } else { this.addOrUpdatePropertyDescriptor( pd.getName(), pd.getReadMethod(), pd.getWriteMethod()); } continue ALL_METHODS; } } } }
public MethodDescriptor[] getMethodDescriptors() { return delegate.getMethodDescriptors(); }
public static void main(String[] args) { try { BeanInfo b = Introspector.getBeanInfo(java.awt.Component.class); if (b.getPropertyDescriptors().length == 6 && b.getEventSetDescriptors().length == 5 && b.getMethodDescriptors().length == 128) { System.out.println("PASSED: Introspector.getBeanInfo(java.awt.Component.class)"); } else { System.out.println("FAILED: Introspector.getBeanInfo(java.awt.Component.class)"); } b = Introspector.getBeanInfo(java.util.BitSet.class); if (b.getPropertyDescriptors().length == 2 && b.getEventSetDescriptors().length == 0 && b.getMethodDescriptors().length == 17) { System.out.println("PASSED: Introspector.getBeanInfo(java.util.BitSet.class)"); } else { System.out.println("FAILED: Introspector.getBeanInfo(java.util.BitSet.class)"); } b = Introspector.getBeanInfo(java.lang.Object.class); if (b.getPropertyDescriptors().length == 1 && b.getEventSetDescriptors().length == 0 && b.getMethodDescriptors().length == 9) { System.out.println("PASSED: Introspector.getBeanInfo(java.lang.Object.class)"); } else { System.out.println("FAILED: Introspector.getBeanInfo(java.lang.Object.class)"); } b = Introspector.getBeanInfo(java.applet.Applet.class); if (b.getPropertyDescriptors().length == 24 && b.getEventSetDescriptors().length == 6 && b.getMethodDescriptors().length == 168) { System.out.println("PASSED: Introspector.getBeanInfo(java.applet.Applet.class)"); } else { System.out.println("FAILED: Introspector.getBeanInfo(java.applet.Applet.class)"); } b = Introspector.getBeanInfo(java.awt.Button.class); if (b.getPropertyDescriptors().length == 8 && b.getEventSetDescriptors().length == 6 && b.getMethodDescriptors().length == 134) { System.out.println("PASSED: Introspector.getBeanInfo(java.awt.Button.class)"); } else { System.out.println("FAILED: Introspector.getBeanInfo(java.awt.Button.class)"); } b = Introspector.getBeanInfo(java.applet.Applet.class, java.awt.Panel.class); if (b.getPropertyDescriptors().length == 8 && b.getEventSetDescriptors().length == 0 && b.getMethodDescriptors().length == 22) { System.out.println( "PASSED: Introspector.getBeanInfo(java.applet.Applet.class,java.awt.Panel.class)"); } else { System.out.println( b.getPropertyDescriptors().length + " " + b.getEventSetDescriptors().length + " " + b.getMethodDescriptors().length); System.out.println( "FAILED: Introspector.getBeanInfo(java.applet.Applet.class,java.awt.Panel.class)"); } b = Introspector.getBeanInfo(java.applet.Applet.class, java.awt.Component.class); if (b.getPropertyDescriptors().length == 18 && b.getEventSetDescriptors().length == 1 && b.getMethodDescriptors().length == 65) { System.out.println( "PASSED: Introspector.getBeanInfo(java.applet.Applet.class,java.awt.Component.class)"); } else { System.out.println( b.getPropertyDescriptors().length + " " + b.getEventSetDescriptors().length + " " + b.getMethodDescriptors().length); System.out.println( "FAILED: Introspector.getBeanInfo(java.applet.Applet.class,java.awt.Component.class)"); } b = Introspector.getBeanInfo(java.applet.Applet.class, java.lang.Object.class); if (b.getPropertyDescriptors().length == 24 && b.getEventSetDescriptors().length == 6 && b.getMethodDescriptors().length == 160) { System.out.println( "PASSED: Introspector.getBeanInfo(java.applet.Applet.class,java.lang.Object.class)"); } else { System.out.println( b.getPropertyDescriptors().length + " " + b.getEventSetDescriptors().length + " " + b.getMethodDescriptors().length); System.out.println( "FAILED: Introspector.getBeanInfo(java.applet.Applet.class,java.lang.Object.class)"); } b = Introspector.getBeanInfo(java.applet.Applet.class, null); if (b.getPropertyDescriptors().length == 24 && b.getEventSetDescriptors().length == 6 && b.getMethodDescriptors().length == 168) { System.out.println( "PASSED: Introspector.getBeanInfo(java.applet.Applet.class,java.lang.Object.class)"); } else { System.out.println( b.getPropertyDescriptors().length + " " + b.getEventSetDescriptors().length + " " + b.getMethodDescriptors().length); System.out.println("FAILED: Introspector.getBeanInfo(java.applet.Applet.class,null)"); } b = Introspector.getBeanInfo(java.applet.Applet.class); if (b.getPropertyDescriptors().length == 24 && b.getEventSetDescriptors().length == 6 && b.getMethodDescriptors().length == 168) { System.out.println("PASSED: Introspector.getBeanInfo(java.applet.Applet.class) 2nd time"); } else { System.out.println("FAILED: Introspector.getBeanInfo(java.applet.Applet.class) 2nd time"); } } catch (IntrospectionException e) { System.out.println("FAILED: IntrospectionException"); e.printStackTrace(); } }