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.ui.contentapp.detail;
35
36 import info.magnolia.event.EventBus;
37 import info.magnolia.i18nsystem.I18nizer;
38 import info.magnolia.i18nsystem.SimpleTranslator;
39 import info.magnolia.objectfactory.ComponentProvider;
40 import info.magnolia.ui.api.action.ActionDefinition;
41 import info.magnolia.ui.api.action.ActionExecutionException;
42 import info.magnolia.ui.api.action.ActionExecutor;
43 import info.magnolia.ui.api.app.SubAppContext;
44 import info.magnolia.ui.api.availability.AvailabilityChecker;
45 import info.magnolia.ui.api.availability.AvailabilityDefinition;
46 import info.magnolia.ui.api.event.AdmincentralEventBus;
47 import info.magnolia.ui.api.event.ContentChangedEvent;
48 import info.magnolia.ui.api.message.Message;
49 import info.magnolia.ui.api.message.MessageType;
50 import info.magnolia.ui.contentapp.definition.EditorDefinition;
51 import info.magnolia.ui.dialog.DialogView;
52 import info.magnolia.ui.dialog.actionarea.ActionListener;
53 import info.magnolia.ui.dialog.actionarea.EditorActionAreaPresenter;
54 import info.magnolia.ui.dialog.actionarea.definition.FormActionItemDefinition;
55 import info.magnolia.ui.dialog.actionarea.view.EditorActionAreaView;
56 import info.magnolia.ui.dialog.formdialog.FormBuilder;
57 import info.magnolia.ui.dialog.formdialog.FormView;
58 import info.magnolia.ui.form.EditorCallback;
59 import info.magnolia.ui.form.EditorValidator;
60 import info.magnolia.ui.form.definition.FormDefinition;
61 import info.magnolia.ui.form.definition.TabDefinition;
62 import info.magnolia.ui.form.field.definition.ConfiguredFieldDefinition;
63 import info.magnolia.ui.form.field.definition.FieldDefinition;
64 import info.magnolia.ui.framework.app.SubAppActionExecutor;
65 import info.magnolia.ui.vaadin.integration.contentconnector.ContentConnector;
66
67 import java.util.Arrays;
68 import java.util.HashMap;
69 import java.util.LinkedList;
70 import java.util.List;
71 import java.util.Map;
72
73 import javax.inject.Inject;
74 import javax.inject.Named;
75
76 import org.slf4j.Logger;
77 import org.slf4j.LoggerFactory;
78
79 import com.rits.cloning.Cloner;
80 import com.vaadin.data.Item;
81 import com.vaadin.event.ShortcutListener;
82 import com.vaadin.ui.Button;
83
84
85
86
87
88 public class DetailPresenter implements EditorCallback, EditorValidator, ActionListener {
89
90 private Logger log = LoggerFactory.getLogger(getClass());
91
92 private SubAppContext subAppContext;
93
94 private final EventBus eventBus;
95
96 private final DetailView view;
97
98 private FormBuilder formBuilder;
99
100 private ComponentProvider componentProvider;
101
102 private ActionExecutor executor;
103
104 private EditorDefinition editorDefinition;
105
106 private Item item;
107
108 private Object itemId;
109
110 private DialogView dialogView;
111
112 private final I18nizer i18nizer;
113
114 private final SimpleTranslator i18n;
115
116 private AvailabilityChecker checker;
117 private ContentConnector contentConnector;
118
119 @Inject
120 public DetailPresenter(SubAppContext subAppContext, final @Named(AdmincentralEventBus.NAME) EventBus eventBus, DetailView view,
121 FormBuilder formBuilder, ComponentProvider componentProvider, SubAppActionExecutor executor, I18nizer i18nizer, SimpleTranslator i18n, AvailabilityChecker checker, ContentConnector contentConnector) {
122 this.subAppContext = subAppContext;
123 this.eventBus = eventBus;
124 this.view = view;
125 this.formBuilder = formBuilder;
126 this.componentProvider = componentProvider;
127 this.executor = executor;
128 this.i18nizer = i18nizer;
129 this.i18n = i18n;
130 this.checker = checker;
131 this.contentConnector = contentConnector;
132 }
133
134 public DetailView start(EditorDefinition editorDefinition, DetailView.ViewType viewType, Object itemId) {
135 this.editorDefinition = editorDefinition;
136 this.item = contentConnector.getItem(itemId);
137 this.itemId = itemId;
138 setItemView(viewType);
139 return view;
140 }
141
142 private void setItemView(DetailView.ViewType viewType) {
143 FormView formView = componentProvider.getComponent(FormView.class);
144 this.dialogView = formView;
145
146 FormDefinition formDefinition;
147
148 switch (viewType) {
149 case VIEW:
150 formDefinition = cloneFormDefinitionReadOnly(editorDefinition.getForm());
151 break;
152 case EDIT:
153 default:
154 formDefinition = editorDefinition.getForm();
155 break;
156 }
157
158 initActions();
159 formBuilder.buildForm(formView, formDefinition, item, null);
160 view.setItemView(dialogView.asVaadinComponent(), viewType);
161 }
162
163 private void initActions() {
164 EditorActionAreaPresenter editorActionAreaPresenter = componentProvider.newInstance(editorDefinition.getActionArea().getPresenterClass());
165 EditorActionAreaView editorActionAreaView = editorActionAreaPresenter.start(filterSubAppActions(), editorDefinition.getActionArea(), this, subAppContext);
166 dialogView.setActionAreaView(editorActionAreaView);
167 }
168
169 private Iterable<ActionDefinition> filterSubAppActions() {
170 Map<String, ActionDefinition> subAppActions = subAppContext.getSubAppDescriptor().getActions();
171 List<ActionDefinition> filteredActions = new LinkedList<ActionDefinition>();
172 List<FormActionItemDefinition> editorActions = editorDefinition.getActions();
173 for (FormActionItemDefinition editorAction : editorActions) {
174 ActionDefinition def = subAppActions.get(editorAction.getName());
175 AvailabilityDefinition availability = executor.getActionDefinition(editorAction.getName()).getAvailability();
176 if (def != null && checker.isAvailable(availability, Arrays.asList(itemId))) {
177 filteredActions.add(def);
178 } else {
179 log.debug("Action is configured for an editor but not configured for sub-app: " + editorAction.getName());
180 }
181 }
182 return filteredActions;
183 }
184
185
186
187
188
189
190 private FormDefinition cloneFormDefinitionReadOnly(FormDefinition formDefinition) {
191 Cloner cloner = new Cloner();
192 FormDefinition formDefinitionClone = cloner.deepClone(formDefinition);
193
194 for (TabDefinition tab : formDefinitionClone.getTabs()) {
195 for (FieldDefinition field : tab.getFields()) {
196 ((ConfiguredFieldDefinition) field).setReadOnly(true);
197 }
198 }
199
200 return formDefinitionClone;
201 }
202
203 @Override
204 public void onCancel() {
205
206 subAppContext.close();
207 }
208
209 @Override
210 public void onSuccess(String actionName) {
211 eventBus.fireEvent(new ContentChangedEvent(itemId));
212
213 subAppContext.close();
214 }
215
216 @Override
217 public void showValidation(boolean visible) {
218 if (dialogView instanceof FormView) {
219 ((FormView) dialogView).showValidation(visible);
220 }
221 }
222
223 @Override
224 public boolean isValid() {
225 return dialogView instanceof FormView ? ((FormView) dialogView).isValid() : true;
226 }
227
228 @Override
229 public void onActionFired(String actionName, Object... actionContextParams) {
230 Object[] providedParameters = new Object[] { this, item };
231 Object[] combinedParameters = new Object[providedParameters.length + actionContextParams.length];
232 System.arraycopy(providedParameters, 0, combinedParameters, 0, providedParameters.length);
233 System.arraycopy(actionContextParams, 0, combinedParameters, providedParameters.length, actionContextParams.length);
234 try {
235 executor.execute(actionName, combinedParameters);
236 } catch (ActionExecutionException e) {
237 log.error("An error occurred while executing an action.", e);
238 Message error = new Message(MessageType.ERROR, i18n.translate("ui-contentapp.error.action.execution"), e.getMessage());
239 subAppContext.getAppContext().sendLocalMessage(error);
240 }
241 }
242
243 private EditorDefinition getEditorDefinition() {
244 return ((DetailSubAppDescriptor)subAppContext.getSubAppDescriptor()).getEditor();
245 }
246
247 public Item getItem() {
248 return item;
249 }
250
251
252
253
254 public void addClickShortcut(String actionName, int KeyCode){
255 Button button = (Button)(dialogView.getActionAreaView().getViewForAction(actionName).asVaadinComponent());
256 button.setClickShortcut(KeyCode);
257 }
258
259
260
261
262 public void addShortcut(final String actionName, final int keyCode, final int... modifiers) {
263 dialogView.addShortcut(new ShortcutListener(actionName, keyCode, modifiers) {
264 @Override
265 public void handleAction(Object sender, Object target) {
266 onActionFired(actionName, new HashMap<String, Object>());
267 }
268 });
269 }
270
271 public void addShortcut(ShortcutListener shortcut) {
272 dialogView.addShortcut(shortcut);
273 }
274
275 }