1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.rat.config.parameters;
21
22 import java.lang.reflect.Field;
23 import java.lang.reflect.Method;
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.Collections;
27 import java.util.List;
28
29 import org.apache.commons.lang3.StringUtils;
30 import org.apache.rat.ConfigurationException;
31 import org.apache.rat.ImplementationException;
32 import org.apache.rat.analysis.IHeaderMatcher;
33 import org.apache.rat.license.ILicense;
34
35
36
37
38 public class DescriptionBuilder {
39
40 private DescriptionBuilder() {}
41
42
43
44
45
46
47
48 public static Description build(Object obj) {
49 if (obj instanceof ILicense) {
50 ILicense license = (ILicense)obj;
51 Class<?> clazz = obj.getClass();
52 ConfigComponent configComponent = clazz.getAnnotation(ConfigComponent.class);
53 if (configComponent == null || configComponent.type() != ComponentType.LICENSE) {
54 throw new ConfigurationException(String.format("Licenses must have License type specified in ConfigComponent annotation. Annotation missing or incorrect in %s", clazz));
55 }
56 List<Description> children = getConfigComponents(obj.getClass());
57 return new Description(ComponentType.LICENSE, license.getId(), license.getName(), false, null, children, false);
58 }
59 return buildMap(obj.getClass());
60 }
61
62 private static String fixupMethodName(Method method) {
63 String name = method.getName();
64 if (name.startsWith("get") || name.startsWith("set") || name.startsWith("add")) {
65 if (name.length() > 3) {
66 String retval = name.substring(3,4).toLowerCase();
67 if (name.length() > 4) {
68 retval+=name.substring(4);
69 }
70 return retval;
71 }
72 }
73 throw new ImplementationException(String.format("'%s' is not a recognized method name", name));
74 }
75
76
77
78
79
80 private static List<Description> getConfigComponents(Class<?> clazz) {
81 if (clazz == null || clazz == String.class || clazz == Object.class) {
82 return Collections.emptyList();
83 }
84 List<Description> result = new ArrayList<>();
85 for (Field field : clazz.getDeclaredFields()) {
86 ConfigComponent configComponent = field.getAnnotation(ConfigComponent.class);
87 if (configComponent != null) {
88 String name = StringUtils.isBlank(configComponent.name()) ? field.getName() : configComponent.name();
89 Class<?> childClazz = configComponent.parameterType() == void.class ? field.getType()
90 : configComponent.parameterType();
91 boolean isCollection = Iterable.class.isAssignableFrom(field.getType());
92
93 Description desc = new Description(configComponent.type(), name, configComponent.desc(), isCollection,
94 childClazz, getConfigComponents(childClazz), configComponent.required());
95 result.add(desc);
96 }
97 }
98 for (Method method : clazz.getDeclaredMethods()) {
99 ConfigComponent configComponent = method.getAnnotation(ConfigComponent.class);
100 if (configComponent != null) {
101 String name = StringUtils.isBlank(configComponent.name()) ? fixupMethodName(method) : configComponent.name();
102 Class<?> childClazz = configComponent.parameterType() == void.class ? method.getReturnType()
103 : configComponent.parameterType();
104 boolean isCollection = Iterable.class.isAssignableFrom(method.getReturnType());
105
106 Description desc = new Description(configComponent.type(), name, configComponent.desc(), isCollection,
107 childClazz, getConfigComponents(childClazz), configComponent.required());
108 result.add(desc);
109 }
110 }
111 result.addAll(getConfigComponents(clazz.getSuperclass()));
112 Arrays.stream(clazz.getInterfaces()).forEach(c -> result.addAll(getConfigComponents(c)));
113 return result;
114 }
115
116 private static ConfigComponent findConfigComponent(Class<?> clazz) {
117 if (clazz == null || clazz == String.class || clazz == Object.class) {
118 return null;
119 }
120 ConfigComponent configComponent = clazz.getAnnotation(ConfigComponent.class);
121 return configComponent == null ? findConfigComponent(clazz.getSuperclass()) : configComponent;
122 }
123
124
125
126
127
128 public static Description buildMap(Class<?> clazz) {
129 if (clazz == IHeaderMatcher.class) {
130 throw new ImplementationException("'clazz' parameter must not be IHeaderMatcher.class but may be a child of it");
131 }
132 ConfigComponent configComponent = findConfigComponent(clazz);
133 if (configComponent == null) {
134 return null;
135 }
136 List<Description> children = getConfigComponents(clazz);
137
138 return new Description(configComponent, false, null, children);
139 }
140 }