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.aop.support.AopUtils;
45 import org.springframework.util.ClassUtils;
46 import org.springframework.util.ReflectionUtils;
47
48 import info.magnolia.module.blossom.annotation.DialogFactory;
49 import info.magnolia.module.blossom.annotation.I18nBasename;
50 import info.magnolia.module.blossom.annotation.TabFactory;
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 private DialogCreator dialogCreator;
63
64 public void setDialogCreator(DialogCreator dialogCreator) {
65 this.dialogCreator = dialogCreator;
66 }
67
68 public DialogCreator getDialogCreator() {
69 if (dialogCreator == null) {
70 dialogCreator = new DefaultDialogCreator();
71 }
72 return dialogCreator;
73 }
74
75 public BlossomDialogDescription buildDescription(Object factoryObject) {
76 return buildDescription(factoryObject, null);
77 }
78
79 public List<BlossomDialogDescription> buildDescriptions(final Object handler) {
80
81 final List<Method> factoryMethods = new ArrayList<Method>();
82
83 final Class<?> handlerClass = AopUtils.getTargetClass(handler);
84 ReflectionUtils.doWithMethods(handlerClass, new ReflectionUtils.MethodCallback() {
85
86 @Override
87 public void doWith(Method method) {
88 DialogFactory dialogFactory = method.getAnnotation(DialogFactory.class);
89 if (dialogFactory != null && method.equals(ClassUtils.getMostSpecificMethod(method, handlerClass))) {
90 if (Modifier.isStatic(method.getModifiers())) {
91 throw new IllegalStateException("DialogFactory annotation is not supported on static methods");
92 }
93 factoryMethods.add(method);
94 }
95 }
96 });
97
98 List<BlossomDialogDescription> descriptions = new ArrayList<BlossomDialogDescription>();
99
100 for (Method method : factoryMethods) {
101 descriptions.add(buildDescription(handler, method));
102 }
103
104 return descriptions;
105 }
106
107 public BlossomDialogDescription buildDescription(Object factoryObject, Method factoryMethod) {
108 DialogFactory annotation = findAnnotation(DialogFactory.class, factoryObject, factoryMethod);
109 return buildDescription(annotation.value(), annotation.label(), factoryObject, factoryMethod);
110 }
111
112 public BlossomDialogDescription buildDescription(String id, String label, Object factoryObject) {
113 return buildDescription(id, label, factoryObject, null);
114 }
115
116 protected BlossomDialogDescription buildDescription(String id, String label, Object factoryObject, Method factoryMethod) {
117 TabOrder tabOrder = findAnnotation(TabOrder.class, factoryObject, factoryMethod);
118 I18nBasename i18nBasename = findAnnotation(I18nBasename.class, factoryObject, factoryMethod);
119 final DialogFactoryMetaData factoryMetaData = new DialogFactoryMetaData();
120 factoryMetaData.setLabel(label);
121 factoryMetaData.setI18nBasename(i18nBasename != null ? i18nBasename.value() : null);
122 factoryMetaData.setFactoryObject(factoryObject);
123 factoryMetaData.setFactoryMethod(factoryMethod);
124 factoryMetaData.setTabOrder(tabOrder != null ? tabOrder.value() : null);
125
126 final Class<?> factoryClass = AopUtils.getTargetClass(factoryObject);
127
128 ReflectionUtils.doWithMethods(factoryClass, new ReflectionUtils.MethodCallback() {
129
130 @Override
131 public void doWith(Method method) {
132 if (method.isAnnotationPresent(TabFactory.class) && method.equals(ClassUtils.getMostSpecificMethod(method, factoryClass))) {
133 if (Modifier.isStatic(method.getModifiers())) {
134 throw new IllegalStateException("TabFactory annotation is not supported on static methods");
135 }
136 factoryMetaData.addTabFactory(method);
137 }
138 }
139 });
140
141 BlossomDialogDescription dialogDescription = new BlossomDialogDescription();
142 dialogDescription.setId(id);
143 dialogDescription.setFactoryMetaData(factoryMetaData);
144 dialogDescription.setDialogCreator(getDialogCreator());
145
146 return dialogDescription;
147 }
148
149 protected <T extends Annotation> T findAnnotation(Class<T> annotationClass, Object factoryObject, Method factoryMethod) {
150 if (factoryMethod != null) {
151 return factoryMethod.getAnnotation(annotationClass);
152 }
153 Class<?> factoryClass = AopUtils.getTargetClass(factoryObject);
154 return factoryClass.getAnnotation(annotationClass);
155 }
156 }