View Javadoc
1   package ch.qos.logback.core.joran.util.beans;
2   
3   import java.lang.reflect.Method;
4   import java.util.HashMap;
5   import java.util.Map;
6   
7   import ch.qos.logback.core.Context;
8   import ch.qos.logback.core.spi.ContextAwareBase;
9   
10  /**
11   * Encapsulates creation of {@link BeanDescription} instances. This factory is
12   * kind of a lightweight Introspector as described in the Java Beans API
13   * specification. The given class is only analyzed for its public getters,
14   * setters and adders methods. Implementations of the BeanInfo interface are not
15   * taken into account for analysis. Therefore this class is only partially
16   * compatible with the Java Beans API specification.
17   *
18   *
19   * @author urechm
20   */
21  public class BeanDescriptionFactory extends ContextAwareBase {
22  
23      BeanDescriptionFactory(Context context) {
24          setContext(context);
25      }
26  
27      /**
28       *
29       * @param clazz to create a {@link BeanDescription} for.
30       * @return a {@link BeanDescription} for the given class.
31       */
32      public BeanDescription create(Class<?> clazz) {
33          Map<String, Method> propertyNameToGetter = new HashMap<String, Method>();
34          Map<String, Method> propertyNameToSetter = new HashMap<String, Method>();
35          Map<String, Method> propertyNameToAdder = new HashMap<String, Method>();
36          Method[] methods = clazz.getMethods();
37          for (Method method : methods) {
38              if (method.isBridge()) {
39                  // we can safely ignore bridge methods
40                  continue;
41              }
42              if (BeanUtil.isGetter(method)) {
43                  String propertyName = BeanUtil.getPropertyName(method);
44                  Method oldGetter = propertyNameToGetter.put(propertyName, method);
45                  if (oldGetter != null) {
46                      if (oldGetter.getName().startsWith(BeanUtil.PREFIX_GETTER_IS)) {
47                          propertyNameToGetter.put(propertyName, oldGetter);
48                      }
49                      String message = String.format("Class '%s' contains multiple getters for the same property '%s'.",
50                              clazz.getCanonicalName(), propertyName);
51                      addWarn(message);
52                  }
53              } else if (BeanUtil.isSetter(method)) {
54                  String propertyName = BeanUtil.getPropertyName(method);
55                  Method oldSetter = propertyNameToSetter.put(propertyName, method);
56                  if (oldSetter != null) {
57                      String message = String.format("Class '%s' contains multiple setters for the same property '%s'.",
58                              clazz.getCanonicalName(), propertyName);
59                      addWarn(message);
60                  }
61              } else if (BeanUtil.isAdder(method)) {
62                  String propertyName = BeanUtil.getPropertyName(method);
63                  Method oldAdder = propertyNameToAdder.put(propertyName, method);
64                  if (oldAdder != null) {
65                      String message = String.format("Class '%s' contains multiple adders for the same property '%s'.",
66                              clazz.getCanonicalName(), propertyName);
67                      addWarn(message);
68                  }
69              }
70          }
71          return new BeanDescription(clazz, propertyNameToGetter, propertyNameToSetter, propertyNameToAdder);
72      }
73  }