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.module.blossom.dialog;
35
36 import java.lang.annotation.Annotation;
37 import java.lang.reflect.Method;
38 import java.lang.reflect.Modifier;
39 import java.util.ArrayList;
40 import java.util.List;
41
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
44 import org.springframework.util.ClassUtils;
45 import org.springframework.util.ReflectionUtils;
46
47 import info.magnolia.module.admininterface.SaveHandler;
48 import info.magnolia.module.blossom.annotation.DialogFactory;
49 import info.magnolia.module.blossom.annotation.I18nBasename;
50 import info.magnolia.module.blossom.annotation.InitSaveHandler;
51 import info.magnolia.module.blossom.annotation.TabOrder;
52
53
54
55
56
57
58 public class DialogDescriptionBuilder {
59
60 private final Logger logger = LoggerFactory.getLogger(getClass());
61
62 public BlossomDialogDescription buildDescription(Object factoryObject) {
63 return buildDescription(factoryObject, null);
64 }
65
66 public List<BlossomDialogDescription> buildDescriptions(final Object handler) {
67
68 final List<Method> factoryMethods = new ArrayList<Method>();
69
70 ReflectionUtils.doWithMethods(handler.getClass(), new ReflectionUtils.MethodCallback() {
71 public void doWith(Method method) {
72 DialogFactory dialogFactory = method.getAnnotation(DialogFactory.class);
73 if (dialogFactory != null && method.equals(ClassUtils.getMostSpecificMethod(method, handler.getClass()))) {
74 if (Modifier.isStatic(method.getModifiers())) {
75 throw new IllegalStateException("DialogFactory annotation is not supported on static methods");
76 }
77 factoryMethods.add(method);
78 }
79 }
80 });
81
82 List<BlossomDialogDescription> descriptions = new ArrayList<BlossomDialogDescription>();
83
84 for (Method method : factoryMethods) {
85 descriptions.add(buildDescription(handler, method));
86 }
87
88 return descriptions;
89 }
90
91 public BlossomDialogDescription buildDescription(Object factoryObject, Method factoryMethod) {
92 DialogFactory annotation = findAnnotation(DialogFactory.class, factoryObject, factoryMethod);
93 return buildDescription(annotation.value(), annotation.label(), factoryObject, factoryMethod);
94 }
95
96 public BlossomDialogDescription buildDescription(String name, String label, Object factoryObject) {
97 return buildDescription(name, label, factoryObject, null);
98 }
99
100 protected BlossomDialogDescription buildDescription(String name, String label, Object factoryObject, Method factoryMethod) {
101 TabOrder tabOrder = findAnnotation(TabOrder.class, factoryObject, factoryMethod);
102 I18nBasename i18nBasename = findAnnotation(I18nBasename.class, factoryObject, factoryMethod);
103 DialogFactoryMetaData factoryMetaData = new DialogFactoryMetaData();
104 factoryMetaData.setLabel(label);
105 factoryMetaData.setI18nBasename(i18nBasename != null ? i18nBasename.value() : null);
106 factoryMetaData.setFactoryObject(factoryObject);
107 factoryMetaData.setFactoryMethod(factoryMethod);
108 factoryMetaData.setTabOrder(tabOrder != null ? tabOrder.value() : null);
109 factoryMetaData.setInitSaveHandlerMethod(findInitSaveHandlerMethod(factoryObject));
110
111 BlossomDialogDescription dialogDescription = new BlossomDialogDescription();
112 dialogDescription.setName(name);
113 dialogDescription.setFactoryMetaData(factoryMetaData);
114 dialogDescription.setDialogClass(BlossomConfiguredDialog.class.getName());
115
116 return dialogDescription;
117 }
118
119 protected <T extends Annotation> T findAnnotation(Class<T> annotationClass, Object factoryObject, Method factoryMethod) {
120 if (factoryMethod != null)
121 return factoryMethod.getAnnotation(annotationClass);
122 return factoryObject.getClass().getAnnotation(annotationClass);
123 }
124
125 protected Method findInitSaveHandlerMethod(final Object factoryObject) {
126
127 final Class<?> handlerClass = factoryObject.getClass();
128
129 final List<Method> matchingMethods = new ArrayList<Method>();
130
131
132
133 Class<?> clazz = factoryObject.getClass();
134 while (matchingMethods.isEmpty() && clazz != null) {
135 Method[] methods = clazz.getDeclaredMethods();
136 for (final Method method : methods) {
137
138
139 if (!method.isAnnotationPresent(InitSaveHandler.class))
140 continue;
141
142
143 if (!method.equals(ClassUtils.getMostSpecificMethod(method, handlerClass)))
144 continue;
145
146 if (!method.getReturnType().equals(SaveHandler.class)) {
147 if (logger.isDebugEnabled())
148 logger.debug("Method annotated with @InitSaveHandler has wrong return type [" + method.getClass() + "] should be SaveHandler.");
149 continue;
150 }
151
152 matchingMethods.add(method);
153 }
154 clazz = clazz.getSuperclass();
155 }
156
157 if (!matchingMethods.isEmpty()) {
158 if (matchingMethods.size() == 1) {
159 return matchingMethods.get(0);
160 } else {
161 logger.error("Multiple @InitSaveHandler annotated methods found in [" + factoryObject.getClass() + "]");
162 }
163 }
164
165 return null;
166 }
167 }