1package org.testng.xml.dom;
2
3import org.testng.collections.Lists;
4import org.testng.internal.collections.Pair;
5
6import java.lang.annotation.Annotation;
7import java.lang.reflect.Method;
8import java.util.Arrays;
9import java.util.List;
10
11public class Reflect {
12  public static List<Pair<Method, Wrapper>> findMethodsWithAnnotation(
13      Class<?> c, Class<? extends Annotation> ac, Object bean) {
14    List<Pair<Method, Wrapper>> result = Lists.newArrayList();
15    for (Method m : c.getMethods()) {
16      Annotation a = m.getAnnotation(ac);
17      if (a != null) {
18        result.add(Pair.of(m, new Wrapper(a, bean)));
19      }
20    }
21    return result;
22  }
23
24  public static Pair<Method, Wrapper> findSetterForTag(
25      Class<?> c, String tagName, Object bean) {
26
27    // Try to find an annotation
28    List<Class<? extends Annotation>> annotations =
29        Arrays.asList(OnElement.class, OnElementList.class, Tag.class);
30    for (Class<? extends Annotation> annotationClass : annotations) {
31      List<Pair<Method, Wrapper>> methods
32          = findMethodsWithAnnotation(c, annotationClass, bean);
33
34      for (Pair<Method, Wrapper> pair : methods) {
35        if (pair.second().getTagName().equals(tagName)) {
36          return pair;
37        }
38      }
39    }
40
41    // try fo find an adder or a setter
42    for (String prefix : new String[] { "add", "set" }) {
43      for (Method m : c.getDeclaredMethods()) {
44        String methodName = toCamelCase(tagName, prefix);
45        if (m.getName().equals(methodName)) {
46          return Pair.of(m, null);
47        }
48      }
49    }
50
51    return null;
52  }
53
54  private static String toCamelCase(String name, String prefix) {
55    return prefix + toCapitalizedCamelCase(name);
56  }
57
58  public static String toCapitalizedCamelCase(String name) {
59    StringBuilder result = new StringBuilder(name.substring(0, 1).toUpperCase());
60    for (int i = 1; i < name.length(); i++) {
61      if (name.charAt(i) == '-') {
62        result.append(Character.toUpperCase(name.charAt(i + 1)));
63        i++;
64      } else {
65        result.append(name.charAt(i));
66      }
67    }
68    return result.toString();
69  }
70
71}
72