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.config.registry.DefinitionProvider;
37 import info.magnolia.config.registry.DefinitionProviderWrapper;
38 import info.magnolia.config.registry.Registry;
39 import info.magnolia.config.registry.decoration.DefinitionDecorator;
40 import info.magnolia.config.registry.decoration.DefinitionDecoratorMetadata;
41 import info.magnolia.objectfactory.Components;
42 import info.magnolia.objectfactory.MgnlInstantiationException;
43 import info.magnolia.objectfactory.NoSuchComponentException;
44 import info.magnolia.ui.admincentral.dialog.action.CancelDialogActionDefinition;
45 import info.magnolia.ui.admincentral.dialog.action.SaveDialogActionDefinition;
46 import info.magnolia.ui.api.app.AppContext;
47 import info.magnolia.ui.api.app.AppController;
48 import info.magnolia.ui.contentapp.configuration.ContentAppDescriptor;
49 import info.magnolia.ui.dialog.DialogDefinition;
50 import info.magnolia.ui.dialog.definition.ConfiguredFormDialogDefinition;
51
52 import java.util.Optional;
53 import java.util.function.Predicate;
54
55 import org.slf4j.Logger;
56 import org.slf4j.LoggerFactory;
57
58
59
60
61 public class DialogCreatorDefinitionDecorator implements DefinitionDecorator<DialogDefinition> {
62 private static final Logger log = LoggerFactory.getLogger(DialogCreatorDefinitionDecorator.class);
63 private final BlossomDialogDescription dialogDescription;
64
65 public DialogCreatorDefinitionDecorator(BlossomDialogDescription dialogDescription) {
66 this.dialogDescription = dialogDescription;
67 }
68
69 @Override
70 public DefinitionDecoratorMetadata metadata() {
71 return () -> "blossom";
72 }
73
74 @Override
75 public boolean appliesTo(DefinitionProvider<DialogDefinition> definitionProvider) {
76 if (definitionProvider instanceof BlossomDialogDefinitionProvider
77 && dialogDescription.getId().equals(definitionProvider.get().getId())) {
78 return new CompatibilityAppsPredicate().test(((BlossomDialogDefinitionProvider) definitionProvider));
79 }
80 return false;
81 }
82
83 @Override
84 public DefinitionProvider<DialogDefinition> decorate(DefinitionProvider<DialogDefinition> definitionProvider) {
85
86 DialogCreationContext context = Optional.ofNullable(DialogCreationContextHolder.get())
87 .orElse(new DialogCreationContext());
88
89 context.setId(dialogDescription.getId());
90
91 DialogCreator dialogCreator = dialogDescription.getDialogCreator();
92 DialogFactoryMetaData factoryMetaData = dialogDescription.getFactoryMetaData();
93 try {
94 dialogCreator.createDialog(factoryMetaData, context);
95 } catch (Exception e) {
96 String factoryMetaDataInfo = factoryMetaData.getFactoryMethod() != null ?
97 factoryMetaData.getFactoryMethod().toString() :
98 factoryMetaData.getFactoryObject().getClass().toString();
99 log.error("Failed to create dialog for {}", factoryMetaDataInfo, e);
100 throw new Registry.InvalidDefinitionException(dialogDescription.getId());
101 }
102
103 ConfiguredFormDialogDefinition dialog = context.getDialog();
104
105 if (dialog != null && dialog.getActions().isEmpty()) {
106 SaveDialogActionDefinition callbackAction = new SaveDialogActionDefinition();
107 callbackAction.setName("commit");
108 callbackAction.setLabel("save");
109 dialog.getActions().put(callbackAction.getName(), callbackAction);
110
111 CancelDialogActionDefinition cancelAction = new CancelDialogActionDefinition();
112 cancelAction.setName("cancel");
113 cancelAction.setLabel("cancel");
114 dialog.getActions().put(cancelAction.getName(), cancelAction);
115 }
116
117 return new DefinitionProviderWrapper<DialogDefinition>(definitionProvider) {
118 @Override
119 public DialogDefinition get() throws Registry.InvalidDefinitionException {
120 return dialog;
121 }
122 };
123 }
124
125
126
127
128
129
130
131
132
133
134 class CompatibilityAppsPredicate implements Predicate<BlossomDialogDefinitionProvider> {
135 @Override
136 public boolean test(BlossomDialogDefinitionProvider definitionProvider) {
137 AppController appController;
138 try {
139 appController = Components.getComponent(AppController.class);
140 } catch (MgnlInstantiationException | NoSuchComponentException e) {
141 log.warn("No AppController available while invoking Blossom dialog with id {}. Not invoking dialog controller.", definitionProvider.getMetadata().getReferenceId());
142 return false;
143 }
144
145 Optional<AppContext> appContext = appController.getCurrentAppContext();
146 if (!appContext.isPresent()) {
147 log.warn("Unable to determine current app while invoking Blossom dialog with id {}. Not invoking dialog controller.", definitionProvider.getMetadata().getReferenceId());
148 return false;
149 }
150
151
152
153 try {
154 if (Class.forName("info.magnolia.definitions.app.DefinitionsAppDescriptor").isAssignableFrom(appContext.get().getAppDescriptor().getClass())) {
155 log.debug("Dialog creator invoked while in Definitions app. Skipping dialog controller.");
156 return false;
157 }
158 } catch (ClassNotFoundException e) {
159 log.debug("Couldn't find DefinitionsAppDescriptor.");
160 }
161
162
163 if (info.magnolia.ui.contentapp.ContentAppDescriptor.class.isAssignableFrom(appContext.get().getAppDescriptor().getClass())) {
164 if (DialogCreationContextHolder.get() == null) {
165 log.debug("Dialog creator initially invoked for old content app without a DialogCreationContext set. Skipping dialog controller.");
166 return false;
167 } else {
168 log.debug("Dialog creator invoked from a Magnolia 5 content-app with DialogCreationContext set.");
169 return true;
170 }
171 } else if (ContentAppDescriptor.class.isAssignableFrom(appContext.get().getAppDescriptor().getClass())) {
172 log.warn("Dialog creator invoked from a Magnolia 6 content-app. Injecting dialog context objects is not supported yet.");
173 return true;
174 }
175
176 log.debug("Dialog creator invoked outside of old/new content app. Skipping dialog controller.");
177 return false;
178 }
179 }
180 }