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 info.magnolia.cms.security.MgnlUser;
37 import info.magnolia.cms.security.User;
38 import info.magnolia.context.Context;
39 import info.magnolia.context.MgnlContext;
40 import info.magnolia.context.WebContext;
41 import info.magnolia.init.MagnoliaConfigurationProperties;
42 import info.magnolia.module.blossom.BlossomModule;
43 import info.magnolia.module.blossom.annotation.TabFactory;
44 import info.magnolia.module.blossom.support.MethodInvocationUtils;
45 import info.magnolia.module.blossom.support.ParameterResolver;
46 import info.magnolia.objectfactory.Components;
47 import info.magnolia.ui.dialog.config.DialogBuilder;
48 import info.magnolia.ui.dialog.definition.ConfiguredFormDialogDefinition;
49 import info.magnolia.ui.dialog.definition.FormDialogDefinition;
50 import info.magnolia.ui.form.config.TabBuilder;
51 import info.magnolia.ui.form.definition.ConfiguredFormDefinition;
52 import info.magnolia.ui.form.definition.TabDefinition;
53 import info.magnolia.ui.framework.config.UiConfig;
54
55 import java.lang.reflect.Method;
56 import java.util.Collections;
57 import java.util.Comparator;
58
59 import javax.jcr.Node;
60
61 import org.apache.commons.lang3.ArrayUtils;
62 import org.apache.commons.lang3.StringUtils;
63 import org.springframework.beans.BeanUtils;
64 import org.springframework.beans.factory.InitializingBean;
65 import org.springframework.util.ClassUtils;
66
67 import com.vaadin.v7.data.Item;
68
69
70
71
72
73
74
75
76
77
78 public class DefaultDialogCreator implements DialogCreator, InitializingBean {
79
80 public static final String SORT_TABS_BY_LABEL_PROPERTY_NAME = "magnolia.blossom.sortTabsByLabel";
81 public static final Boolean SORT_TABS_BY_LABEL_PROPERTY_DEFAULT = Boolean.TRUE;
82
83 public static final String SET_TAB_LABELS_PROPERTY_NAME = "magnolia.blossom.setTabLabels";
84 public static final Boolean SET_TAB_LABELS_PROPERTY_DEFAULT = Boolean.TRUE;
85
86 private static final String[] DAM_CONFIG_CLASS_NAMES = new String[]{
87 "info.magnolia.dam.app.ui.config.DamConfig",
88 "info.magnolia.dam.asset.config.DamConfig"
89 };
90
91 private Class damConfigClass;
92 private Boolean setTabLabels;
93 private Boolean sortTabsByLabel;
94
95 public DefaultDialogCreator() {
96 ClassLoader classLoader = this.getClass().getClassLoader();
97 for (String damConfigClassName : DAM_CONFIG_CLASS_NAMES) {
98 if (ClassUtils.isPresent(damConfigClassName, classLoader)) {
99 damConfigClass = ClassUtils.resolveClassName(damConfigClassName, classLoader);
100 break;
101 }
102 }
103 }
104
105 public Boolean getSetTabLabels() {
106 return setTabLabels;
107 }
108
109 public void setSetTabLabels(Boolean setTabLabels) {
110 this.setTabLabels = setTabLabels;
111 }
112
113 public Boolean getSortTabsByLabel() {
114 return sortTabsByLabel;
115 }
116
117 public void setSortTabsByLabel(Boolean sortTabsByLabel) {
118 this.sortTabsByLabel = sortTabsByLabel;
119 }
120
121 @Override
122 public void createDialog(DialogFactoryMetaData metaData, final DialogCreationContext context) throws Exception {
123
124 DialogBuilder dialogBuilder = new DialogBuilder(context.getId());
125 context.setDialog(dialogBuilder.definition());
126 context.getDialog().setForm(new ConfiguredFormDefinition());
127 context.getDialog().setPresenterClass(Components.getComponent(BlossomModule.class).getFormDialogPresenterClass());
128
129 if (StringUtils.isNotEmpty(metaData.getLabel())) {
130 ConfiguredFormDefinition form = (ConfiguredFormDefinition) dialogBuilder.definition().getForm();
131 form.setLabel(metaData.getLabel());
132 dialogBuilder.label(metaData.getLabel());
133 }
134
135 if (metaData.getFactoryMethod() != null) {
136 invokeMethodDialogFactory(metaData, context, dialogBuilder);
137 } else {
138 invokeClassDialogFactory(metaData, context, dialogBuilder);
139 }
140 }
141
142 protected void invokeMethodDialogFactory(DialogFactoryMetaData metaData, DialogCreationContext context, DialogBuilder dialogBuilder) {
143
144 if (StringUtils.isNotEmpty(metaData.getI18nBasename())) {
145 dialogBuilder.i18nBasename(metaData.getI18nBasename());
146 }
147
148 ParameterResolver parameters = getDialogFactoryParameters(metaData, context, dialogBuilder);
149 MethodInvocationUtils.invoke(metaData.getFactoryMethod(), metaData.getFactoryObject(), parameters);
150
151 if (metaData.getTabOrder() != null) {
152 sortTabs(context.getDialog(), metaData.getTabOrder());
153 }
154 }
155
156 protected void invokeClassDialogFactory(DialogFactoryMetaData metaData, DialogCreationContext context, DialogBuilder dialogBuilder) {
157
158 if (metaData.getI18nBasename() != null) {
159 dialogBuilder.i18nBasename(metaData.getI18nBasename());
160 }
161
162 Object factoryObject = metaData.getFactoryObject();
163
164 for (DialogFactoryClassMetaData classMetaData : metaData.getClassMetaData()) {
165
166 int tabPosition = 0;
167
168 for (Method tabFactory : classMetaData.getTabFactories()) {
169
170 TabFactory annotation = tabFactory.getAnnotation(TabFactory.class);
171 TabBuilder tabBuilder = new TabBuilder(annotation.value());
172 if (setTabLabels == null || setTabLabels) {
173 tabBuilder.label(annotation.value());
174 }
175 dialogBuilder.form().definition().getTabs().add(tabPosition++, tabBuilder.definition());
176
177 ParameterResolver parameters = getTabFactoryParameters(metaData, context, tabBuilder);
178 MethodInvocationUtils.invoke(tabFactory, metaData.getFactoryObject(), parameters);
179 }
180
181 for (Method postCreateMethod : classMetaData.getPostCreateCallbacks()) {
182
183 ParameterResolver parameters = getPostCreateCallbackParameters(metaData, context, dialogBuilder);
184 MethodInvocationUtils.invoke(postCreateMethod, factoryObject, parameters);
185 }
186 }
187
188 for (Method postCreateMethod : metaData.getPostCreateCallbacks()) {
189
190 ParameterResolver parameters = getPostCreateCallbackParameters(metaData, context, dialogBuilder);
191 MethodInvocationUtils.invoke(postCreateMethod, factoryObject, parameters);
192 }
193
194 if (metaData.getTabOrder() != null) {
195 sortTabs(context.getDialog(), metaData.getTabOrder());
196 }
197 }
198
199 protected void sortTabs(FormDialogDefinition dialog, final String[] order) {
200 Collections.sort(dialog.getForm().getTabs(), new Comparator<Object>() {
201
202 @Override
203 public int compare(Object o1, Object o2) {
204 switch (((o1 instanceof TabDefinition) ? 2 : 0) + ((o2 instanceof TabDefinition) ? 1 : 0)) {
205 case 0:
206 return 0;
207 case 1:
208 return -1;
209 case 2:
210 return 1;
211 case 3:
212 if (sortTabsByLabel == null || sortTabsByLabel) {
213 return ArrayUtils.indexOf(order, ((TabDefinition) o1).getLabel()) - ArrayUtils.indexOf(order, ((TabDefinition) o2).getLabel());
214 } else {
215 return ArrayUtils.indexOf(order, ((TabDefinition) o1).getName()) - ArrayUtils.indexOf(order, ((TabDefinition) o2).getName());
216 }
217 }
218 return 0;
219 }
220 });
221 }
222
223 protected ParameterResolver getDialogFactoryParameters(DialogFactoryMetaData metaData, DialogCreationContext context, final DialogBuilder dialogBuilder) {
224 return new ParameterResolver(getStandardParameters(metaData, context)) {
225
226 @Override
227 public Object resolveParameter(Class<?> parameterType) {
228 if (parameterType.equals(DialogBuilder.class)) {
229 return dialogBuilder;
230 }
231 return super.resolveParameter(parameterType);
232 }
233 };
234 }
235
236 protected ParameterResolver getTabFactoryParameters(DialogFactoryMetaData metaData, DialogCreationContext context, final TabBuilder tabBuilder) {
237 return new ParameterResolver(getStandardParameters(metaData, context)) {
238
239 @Override
240 public Object resolveParameter(Class<?> parameterType) {
241 if (parameterType.equals(TabBuilder.class)) {
242 return tabBuilder;
243 }
244 return super.resolveParameter(parameterType);
245 }
246 };
247 }
248
249 protected ParameterResolver getPostCreateCallbackParameters(DialogFactoryMetaData metaData, DialogCreationContext context, final DialogBuilder dialogBuilder) {
250 return new ParameterResolver(getStandardParameters(metaData, context)) {
251
252 @Override
253 public Object resolveParameter(Class<?> parameterType) {
254 if (parameterType.isAssignableFrom(DialogBuilder.class)) {
255 return dialogBuilder;
256 }
257 return super.resolveParameter(parameterType);
258 }
259 };
260 }
261
262 protected ParameterResolver getStandardParameters(DialogFactoryMetaData metaData, final DialogCreationContext context) {
263 return new ParameterResolver() {
264
265 @Override
266 public Object resolveParameter(Class<?> parameterType) {
267 if (parameterType.isAssignableFrom(ConfiguredFormDialogDefinition.class)) {
268 return context.getDialog();
269 }
270 if (parameterType.equals(DialogCreationContext.class)) {
271 return context;
272 }
273 if (parameterType.equals(Node.class)) {
274 return context.getContentNode();
275 }
276 if (parameterType.equals(Item.class)) {
277 return context.getItem();
278 }
279 if (parameterType.equals(UiConfig.class)) {
280 return new UiConfig();
281 }
282 if (damConfigClass != null && parameterType == damConfigClass) {
283 return BeanUtils.instantiate(damConfigClass);
284 }
285 if (parameterType.isAssignableFrom(WebContext.class)) {
286 return MgnlContext.getWebContext();
287 }
288 if (parameterType.isAssignableFrom(Context.class)) {
289 return MgnlContext.getInstance();
290 }
291 if (parameterType.isAssignableFrom(User.class)) {
292 return MgnlContext.getUser();
293 }
294 if (parameterType.isAssignableFrom(MgnlUser.class)) {
295 return MgnlContext.getUser();
296 }
297 return super.resolveParameter(parameterType);
298 }
299 };
300 }
301
302 @Override
303 public void afterPropertiesSet() throws Exception {
304 MagnoliaConfigurationProperties configurationProperties = Components.getComponent(MagnoliaConfigurationProperties.class);
305 if (this.sortTabsByLabel == null) {
306 String property = configurationProperties.getProperty(SORT_TABS_BY_LABEL_PROPERTY_NAME);
307 this.sortTabsByLabel = property != null ? Boolean.valueOf(property) : SORT_TABS_BY_LABEL_PROPERTY_DEFAULT;
308 }
309 if (this.setTabLabels == null) {
310 String property = configurationProperties.getProperty(SET_TAB_LABELS_PROPERTY_NAME);
311 this.setTabLabels = property != null ? Boolean.valueOf(property) : SET_TAB_LABELS_PROPERTY_DEFAULT;
312 }
313 }
314 }