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.browser;
35
36 import info.magnolia.event.EventBus;
37 import info.magnolia.ui.actionbar.ActionbarPresenter;
38 import info.magnolia.ui.actionbar.ActionbarView;
39 import info.magnolia.ui.actionbar.definition.ActionbarDefinition;
40 import info.magnolia.ui.api.action.ActionExecutionException;
41 import info.magnolia.ui.api.action.ActionExecutor;
42 import info.magnolia.ui.api.app.AppContext;
43 import info.magnolia.ui.api.app.SubAppContext;
44 import info.magnolia.ui.api.app.SubAppEventBus;
45 import info.magnolia.ui.api.availability.AvailabilityChecker;
46 import info.magnolia.ui.api.availability.AvailabilityDefinition;
47 import info.magnolia.ui.api.event.AdmincentralEventBus;
48 import info.magnolia.ui.api.event.ContentChangedEvent;
49 import info.magnolia.ui.api.message.Message;
50 import info.magnolia.ui.api.message.MessageType;
51 import info.magnolia.ui.imageprovider.ImageProvider;
52 import info.magnolia.ui.vaadin.integration.NullItem;
53 import info.magnolia.ui.vaadin.integration.contentconnector.ContentConnector;
54 import info.magnolia.ui.workbench.WorkbenchPresenter;
55 import info.magnolia.ui.workbench.WorkbenchView;
56 import info.magnolia.ui.workbench.event.ActionEvent;
57 import info.magnolia.ui.workbench.event.ItemDoubleClickedEvent;
58 import info.magnolia.ui.workbench.event.ItemShortcutKeyEvent;
59 import info.magnolia.ui.workbench.event.SearchEvent;
60 import info.magnolia.ui.workbench.event.SelectionChangedEvent;
61
62 import java.util.ArrayList;
63 import java.util.Arrays;
64 import java.util.Iterator;
65 import java.util.List;
66 import java.util.Set;
67
68 import javax.inject.Inject;
69 import javax.inject.Named;
70
71 import org.apache.commons.lang3.StringUtils;
72 import org.slf4j.Logger;
73 import org.slf4j.LoggerFactory;
74
75 import com.vaadin.data.Item;
76 import com.vaadin.event.ShortcutAction;
77 import com.vaadin.server.Resource;
78
79
80
81
82
83
84
85
86
87
88
89
90
91 public class BrowserPresenter implements ActionbarPresenter.Listener, BrowserView.Listener {
92
93 private static final Logger log = LoggerFactory.getLogger(BrowserPresenter.class);
94
95 private final WorkbenchPresenter workbenchPresenter;
96
97 private final ActionExecutor actionExecutor;
98
99 private final BrowserSubAppDescriptor subAppDescriptor;
100
101 private final BrowserView view;
102
103 private final EventBus admincentralEventBus;
104
105 private final EventBus subAppEventBus;
106
107 private final ActionbarPresenter actionbarPresenter;
108
109 private final AvailabilityChecker availabilityChecker;
110
111 private final AppContext appContext;
112
113 private final ContentConnector contentConnector;
114
115 private final ImageProvider imageProvider;
116
117 @Inject
118 public BrowserPresenter(
119 BrowserView view,
120 SubAppContext subAppContext,
121 ActionExecutor actionExecutor,
122 @Named(AdmincentralEventBus.NAME) EventBus admincentralEventBus,
123 @Named(SubAppEventBus.NAME) EventBus subAppEventBus,
124 ContentConnector contentConnector,
125 ImageProvider imageProvider,
126 WorkbenchPresenter workbenchPresenter,
127 ActionbarPresenter actionbarPresenter,
128 AvailabilityChecker availabilityChecker) {
129 this.view = view;
130 this.appContext = subAppContext.getAppContext();
131 this.subAppDescriptor = (BrowserSubAppDescriptor) subAppContext.getSubAppDescriptor();
132 this.actionExecutor = actionExecutor;
133 this.admincentralEventBus = admincentralEventBus;
134 this.subAppEventBus = subAppEventBus;
135 this.contentConnector = contentConnector;
136 this.imageProvider = imageProvider;
137 this.workbenchPresenter = workbenchPresenter;
138 this.actionbarPresenter = actionbarPresenter;
139 this.availabilityChecker = availabilityChecker;
140 }
141
142 public BrowserView start() {
143 actionbarPresenter.setListener(this);
144
145 WorkbenchView workbenchView = workbenchPresenter.start(subAppDescriptor.getWorkbench(), subAppDescriptor.getImageProvider(), subAppEventBus);
146 ActionbarView actionbar = actionbarPresenter.start(subAppDescriptor.getActionbar(), subAppDescriptor.getActions());
147
148 view.setWorkbenchView(workbenchView);
149 view.setActionbarView(actionbar);
150 view.setListener(this);
151
152 bindHandlers();
153 return view;
154 }
155
156 private void bindHandlers() {
157 admincentralEventBus.addHandler(ContentChangedEvent.class, new ContentChangedEvent.Handler() {
158
159 @Override
160 public void onContentChanged(ContentChangedEvent event) {
161 if (contentConnector.canHandleItem(event.getItemId())) {
162
163 workbenchPresenter.refresh();
164
165 List<Object> existingSelectedItemIds = new ArrayList<Object>(getSelectedItemIds());
166 Iterator<Object> it = existingSelectedItemIds.iterator();
167 while (it.hasNext()) {
168 if (!verifyItemExists(it.next())) {
169 it.remove();
170 }
171 }
172 workbenchPresenter.select(existingSelectedItemIds);
173
174 if (event.isItemContentChanged()) {
175 workbenchPresenter.expand(event.getItemId());
176 }
177
178
179 if (!existingSelectedItemIds.isEmpty() && verifyItemExists(existingSelectedItemIds.get(0))) {
180 refreshActionbarPreviewImage(existingSelectedItemIds.get(0));
181 }
182
183 }
184 }
185 });
186
187 subAppEventBus.addHandler(SelectionChangedEvent.class, new SelectionChangedEvent.Handler() {
188
189 @Override
190 public void onSelectionChanged(SelectionChangedEvent event) {
191
192 refreshActionbarPreviewImage(event.getFirstItemId());
193 }
194 });
195
196 subAppEventBus.addHandler(ItemDoubleClickedEvent.class, new ItemDoubleClickedEvent.Handler() {
197
198 @Override
199 public void onItemDoubleClicked(ItemDoubleClickedEvent event) {
200 executeDefaultAction();
201 }
202 });
203
204 subAppEventBus.addHandler(SearchEvent.class, new SearchEvent.Handler() {
205
206 @Override
207 public void onSearch(SearchEvent event) {
208 workbenchPresenter.doSearch(event.getSearchExpression());
209 }
210 });
211
212 subAppEventBus.addHandler(ActionEvent.class, new ActionEvent.Handler() {
213
214 @Override
215 public void onAction(ActionEvent event) {
216 executeAction(event.getActionName(), event.getItemIds(), event.getParameters());
217 }
218 });
219
220 subAppEventBus.addHandler(ItemShortcutKeyEvent.class, new ItemShortcutKeyEvent.Handler() {
221
222 @Override
223 public void onItemShortcutKeyEvent(ItemShortcutKeyEvent event) {
224 int keyCode = event.getKeyCode();
225 switch (keyCode) {
226 case ShortcutAction.KeyCode.ENTER:
227 executeDefaultAction();
228 break;
229 case ShortcutAction.KeyCode.DELETE:
230 executeDeleteAction();
231 break;
232 }
233
234 }
235 });
236 }
237
238 private void refreshActionbarPreviewImage(Object itemId) {
239 Object previewResource = getPreviewImageForId(itemId);
240 if (previewResource instanceof Resource) {
241 getActionbarPresenter().setPreview((Resource) previewResource);
242 } else {
243 getActionbarPresenter().setPreview(null);
244 }
245 }
246
247 protected boolean verifyItemExists(Object itemId) {
248 return contentConnector.getItem(itemId) != null;
249 }
250
251 public List<Object> getSelectedItemIds() {
252 return workbenchPresenter.getSelectedIds();
253 }
254
255
256
257
258
259 public String getDefaultViewType() {
260 return workbenchPresenter.getDefaultViewType();
261 }
262
263 public boolean hasViewType(String viewType) {
264 return workbenchPresenter.hasViewType(viewType);
265 }
266
267 public BrowserView getView() {
268 return view;
269 }
270
271 public ActionbarPresenter getActionbarPresenter() {
272 return actionbarPresenter;
273 }
274
275
276
277
278
279 public void resync(final List<Object> itemIds, final String viewType, final String query) {
280 workbenchPresenter.resynch(itemIds, viewType, query);
281 }
282
283 protected Object getPreviewImageForId(Object itemId) {
284 if (imageProvider != null) {
285 return imageProvider.getThumbnailResource(itemId, ImageProvider.PORTRAIT_GENERATOR);
286 }
287 return null;
288 }
289
290 @Override
291 public void onActionbarItemClicked(String actionName) {
292 executeAction(actionName);
293 }
294
295 @Override
296 public void onActionBarSelection(String actionName) {
297 executeAction(actionName);
298 }
299
300
301
302
303 private void executeDefaultAction() {
304 ActionbarDefinition actionbarDefinition = subAppDescriptor.getActionbar();
305 if (actionbarDefinition == null) {
306 return;
307 }
308 String defaultAction = actionbarDefinition.getDefaultAction();
309 if (StringUtils.isNotEmpty(defaultAction)) {
310 executeAction(defaultAction);
311 }
312 }
313
314
315
316
317 private void executeDeleteAction() {
318 ActionbarDefinition actionbarDefinition = subAppDescriptor.getActionbar();
319 if (actionbarDefinition == null) {
320 return;
321 }
322 String deleteAction = actionbarDefinition.getDeleteAction();
323 if (StringUtils.isNotEmpty(deleteAction)) {
324 executeAction(deleteAction);
325 }
326 }
327
328 private void executeAction(String actionName) {
329 try {
330 AvailabilityDefinition availability = actionExecutor.getActionDefinition(actionName).getAvailability();
331 if (availabilityChecker.isAvailable(availability, getSelectedItemIds())) {
332 Object[] args = prepareActionArgs();
333 actionExecutor.execute(actionName, args);
334 }
335 } catch (ActionExecutionException e) {
336 Message error = new Message(MessageType.ERROR, "An error occurred while executing an action.", e.getMessage());
337 log.error("An error occurred while executing action [{}]", actionName, e);
338 appContext.sendLocalMessage(error);
339 }
340 }
341
342 private void executeAction(String actionName, Set<Object> itemIds, Object... parameters) {
343 try {
344 AvailabilityDefinition availability = actionExecutor.getActionDefinition(actionName).getAvailability();
345 if (availabilityChecker.isAvailable(availability, getSelectedItemIds())) {
346 List<Object> args = new ArrayList<Object>();
347 args.add(itemIds);
348 args.addAll(Arrays.asList(parameters));
349 actionExecutor.execute(actionName, new Object[] { args.toArray(new Object[args.size()]) });
350 }
351 } catch (ActionExecutionException e) {
352 Message error = new Message(MessageType.ERROR, "An error occurred while executing an action.", e.getMessage());
353 log.error("An error occurred while executing action [{}]", actionName, e);
354 appContext.sendLocalMessage(error);
355 }
356 }
357
358 protected Object[] prepareActionArgs() {
359 List<Object> argList = new ArrayList<Object>();
360 List<Item> selectedItems = new ArrayList<Item>();
361
362 List<Object> selectedIds = getSelectedItemIds();
363 if (selectedIds.isEmpty()) {
364 selectedIds.add(contentConnector.getDefaultItemId());
365 }
366 Iterator<Object> idIt = selectedIds.iterator();
367 while (idIt.hasNext()) {
368 selectedItems.add(contentConnector.getItem(idIt.next()));
369 }
370
371 if (selectedItems.size() <= 1) {
372
373 argList.add(selectedItems.isEmpty() ? new NullItem() : selectedItems.get(0));
374 argList.add(selectedItems);
375 } else {
376
377 argList.add(selectedItems);
378 }
379 return argList.toArray(new Object[argList.size()]);
380 }
381 }