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.
12  * This factory is kind of a lightweight Introspector as described in the Java Beans API specification.
13  * The given class is only analyzed for its public getters, setters and adders methods.
14  * Implementations of the BeanInfo interface are not taken into account for analysis.
15  * Therefore this class is only partially compatible with the Java Beans API specification.
16  *
17  *
18  * @author urechm
19  */

20 public class BeanDescriptionFactory extends ContextAwareBase {
21
22     BeanDescriptionFactory(Context context) {
23         setContext(context);
24     }
25
26     /**
27      *
28      * @param clazz to create a {@link BeanDescription} for.
29      * @return a {@link BeanDescription} for the given class.
30      */

31     public BeanDescription create(Class<?> clazz) {
32         Map<String, Method> propertyNameToGetter = new HashMap<String, Method>();
33         Map<String, Method> propertyNameToSetter = new HashMap<String, Method>();
34         Map<String, Method> propertyNameToAdder = new HashMap<String, Method>();
35         Method[] methods = clazz.getMethods();
36         for (Method method : methods) {
37             if(method.isBridge()) {
38                 // we can safely ignore bridge methods
39                 continue;
40             }
41             if (BeanUtil.isGetter(method)) {
42                 String propertyName = BeanUtil.getPropertyName(method);
43                 Method oldGetter = propertyNameToGetter.put(propertyName, method);
44                 if (oldGetter != null) {
45                     if (oldGetter.getName().startsWith(BeanUtil.PREFIX_GETTER_IS)) {
46                         propertyNameToGetter.put(propertyName, oldGetter);
47                     }
48                     String message = String.format("Class '%s' contains multiple getters for the same property '%s'.", clazz.getCanonicalName(), propertyName);
49                     addWarn(message);
50                 }
51             } else if (BeanUtil.isSetter(method)) {
52                 String propertyName = BeanUtil.getPropertyName(method);
53                 Method oldSetter = propertyNameToSetter.put(propertyName, method);
54                 if (oldSetter != null) {
55                     String message = String.format("Class '%s' contains multiple setters for the same property '%s'.", clazz.getCanonicalName(), propertyName);
56                     addWarn(message);
57                 }
58             } else if (BeanUtil.isAdder(method)) {
59                 String propertyName = BeanUtil.getPropertyName(method);
60                 Method oldAdder = propertyNameToAdder.put(propertyName, method);
61                 if (oldAdder != null) {
62                     String message = String.format("Class '%s' contains multiple adders for the same property '%s'.", clazz.getCanonicalName(), propertyName);
63                     addWarn(message);
64                 }
65             }
66         }
67         return new BeanDescription(clazz, propertyNameToGetter, propertyNameToSetter, propertyNameToAdder);
68     }
69 }
70