1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.util;
35
36 import static java.beans.Introspector.decapitalize;
37
38 import info.magnolia.annotation.deprecation.MgnlDeprecated;
39 import info.magnolia.jcr.node2bean.PropertyTypeDescriptor;
40 import info.magnolia.jcr.node2bean.TypeMapping;
41
42 import java.lang.reflect.AnnotatedElement;
43 import java.lang.reflect.Method;
44 import java.util.Collection;
45 import java.util.List;
46 import java.util.Optional;
47
48 import org.apache.commons.lang3.ClassUtils;
49 import org.apache.commons.lang3.StringUtils;
50
51 import com.google.common.collect.ImmutableSet;
52 import com.google.common.collect.Lists;
53
54
55
56
57 public final class DeprecationUtil {
58
59 private DeprecationUtil() {
60 }
61
62
63
64
65 public static boolean isDeprecated(AnnotatedElement element) {
66 return element.isAnnotationPresent(Deprecated.class);
67 }
68
69
70
71
72
73
74
75
76
77 public static Optional<Class<?>> findFirstEncounteredDeprecatedSuperType(Class<?> clazz) {
78 Optional<Class<?>> deprecatedFirstSuperInterface = ClassUtils.getAllInterfaces(clazz).stream()
79 .filter(DeprecationUtil::isDeprecated)
80 .findFirst();
81
82 if (deprecatedFirstSuperInterface.isPresent()) {
83 return deprecatedFirstSuperInterface;
84 }
85
86 return ClassUtils.getAllSuperclasses(clazz).stream()
87 .filter(DeprecationUtil::isDeprecated)
88 .findFirst();
89 }
90
91
92
93
94
95
96
97
98
99
100 public static Collection<Method> getDeprecatedReadMethods(TypeMapping mapping, Class<?> parentClass, String sourcePropertyName) {
101 List<Method> deprecatedMethods = Lists.newArrayList();
102
103 Collection<Class<?>> classes = DeprecationUtil.getInheritanceTree(parentClass);
104 for (Class<?> clazz : classes) {
105
106 PropertyTypeDescriptor propertyTypeDescriptor = mapping.getPropertyTypeDescriptor(clazz, sourcePropertyName);
107 if (propertyTypeDescriptor.getType() != null) {
108
109
110 Method readMethod = propertyTypeDescriptor.getReadMethod();
111 if (readMethod != null && DeprecationUtil.isDeprecated(readMethod)) {
112 deprecatedMethods.add(readMethod);
113 }
114 }
115 }
116
117 return deprecatedMethods;
118 }
119
120
121
122
123 private static Collection<Class<?>> getInheritanceTree(Class<?> clazz) {
124 List<Class<?>> allSuperInterfaces = ClassUtils.getAllInterfaces(clazz);
125 List<Class<?>> allSuperclasses = ClassUtils.getAllSuperclasses(clazz);
126
127 return ImmutableSet.<Class<?>>builder()
128 .add(clazz)
129 .addAll(allSuperInterfaces)
130 .addAll(allSuperclasses)
131 .build();
132 }
133
134
135
136
137 public static String getDeprecationMessage(Class<?> deprecatedClass) {
138 StringBuilder deprecationWarning = new StringBuilder();
139 deprecationWarning.append(String.format("Configuration was evaluated to a deprecated type: [%s]",
140 deprecatedClass.getCanonicalName().replaceAll("\\$\\$.*$", "")));
141
142 appendDeprecationInformation(deprecatedClass, deprecationWarning);
143 return deprecationWarning.toString();
144 }
145
146
147
148
149 public static String getDeprecationMessage(Class<?> actualClass, Class<?> deprecatedParentClass) {
150 StringBuilder deprecationWarning = new StringBuilder();
151 deprecationWarning.append(String.format("Configuration was evaluated to a deprecated type: [%s] due to deprecated parent type: [%s]",
152 actualClass.getCanonicalName().replaceAll("\\$\\$.*$", ""), deprecatedParentClass.getCanonicalName().replaceAll("\\$\\$.*$", "")));
153
154 appendDeprecationInformation(deprecatedParentClass, deprecationWarning);
155 return deprecationWarning.toString();
156 }
157
158
159
160
161 public static String getDeprecationMessage(Method deprecatedMethod) {
162 StringBuilder deprecationWarning = new StringBuilder();
163 deprecationWarning.append(String.format("Configuration relies on a property: [%s] which is deprecated",
164 decapitalize(deprecatedMethod.getName().replaceAll("^(get|is)", ""))));
165
166 appendDeprecationInformation(deprecatedMethod, deprecationWarning);
167 return deprecationWarning.toString();
168 }
169
170
171
172
173 public static String getDeprecationMessage(String deprecatedType, String deprecatedTypeName ,String since, String description) {
174 StringBuilder deprecationMessage = new StringBuilder("Deprecated " + deprecatedType + " definition '" + deprecatedTypeName + "' is used.");
175 deprecationMessage.append("\n").append("Deprecated since: ").append(since);
176
177 if (StringUtils.isNotBlank(description)) {
178 deprecationMessage.append("\n").append("Description: ").append(description);
179 }
180
181 return deprecationMessage.toString();
182 }
183
184
185
186
187 private static void appendDeprecationInformation(AnnotatedElement deprecatedClass, StringBuilder deprecationWarning) {
188 if (deprecatedClass.isAnnotationPresent(MgnlDeprecated.class)) {
189 MgnlDeprecated deprecationAnnotation = deprecatedClass.getAnnotation(MgnlDeprecated.class);
190 deprecationWarning.append("\n").append("Deprecated since: ").append(deprecationAnnotation.since());
191 if (StringUtils.isNotBlank(deprecationAnnotation.description())) {
192 deprecationWarning.append("\n").append("Description: ").append(deprecationAnnotation.description());
193 }
194 }
195 }
196 }