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.objectfactory.ComponentProvider;
38 import info.magnolia.ui.actionbar.ActionbarPresenter;
39 import info.magnolia.ui.actionbar.definition.ActionbarDefinition;
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.AppContext;
44 import info.magnolia.ui.api.app.SubAppContext;
45 import info.magnolia.ui.api.app.SubAppEventBus;
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.imageprovider.ImageProvider;
51 import info.magnolia.ui.imageprovider.definition.ImageProviderDefinition;
52 import info.magnolia.ui.vaadin.actionbar.ActionbarView;
53 import info.magnolia.ui.vaadin.integration.jcr.AbstractJcrNodeAdapter;
54 import info.magnolia.ui.vaadin.integration.jcr.JcrItemAdapter;
55 import info.magnolia.ui.vaadin.integration.jcr.JcrItemUtil;
56 import info.magnolia.ui.vaadin.integration.jcr.JcrNodeAdapter;
57 import info.magnolia.ui.vaadin.integration.jcr.JcrPropertyAdapter;
58 import info.magnolia.ui.workbench.WorkbenchPresenter;
59 import info.magnolia.ui.workbench.WorkbenchView;
60 import info.magnolia.ui.workbench.event.ItemDoubleClickedEvent;
61 import info.magnolia.ui.workbench.event.ItemEditedEvent;
62 import info.magnolia.ui.workbench.event.ItemShortcutKeyEvent;
63 import info.magnolia.ui.workbench.event.SearchEvent;
64 import info.magnolia.ui.workbench.event.SelectionChangedEvent;
65
66 import java.util.ArrayList;
67 import java.util.List;
68
69 import javax.inject.Inject;
70 import javax.inject.Named;
71 import javax.jcr.Node;
72 import javax.jcr.PathNotFoundException;
73 import javax.jcr.Property;
74 import javax.jcr.RepositoryException;
75
76 import org.apache.commons.lang.StringUtils;
77 import org.slf4j.Logger;
78 import org.slf4j.LoggerFactory;
79
80 import com.vaadin.data.Item;
81 import com.vaadin.event.ShortcutAction;
82 import com.vaadin.server.Resource;
83
84
85
86
87
88
89
90
91
92
93
94
95
96 public class BrowserPresenter implements ActionbarPresenter.Listener, BrowserView.Listener {
97
98 private static final Logger log = LoggerFactory.getLogger(BrowserPresenter.class);
99
100 private WorkbenchPresenter workbenchPresenter;
101
102 private final ActionExecutor actionExecutor;
103
104 private BrowserSubAppDescriptor subAppDescriptor;
105
106 private final BrowserView view;
107
108 private final EventBus admincentralEventBus;
109
110 private final EventBus subAppEventBus;
111
112 private final ActionbarPresenter actionbarPresenter;
113
114 private final ImageProvider imageProvider;
115
116 private final AppContext appContext;
117
118 @Inject
119 public BrowserPresenter(final ActionExecutor actionExecutor, final SubAppContext subAppContext, final BrowserView view, @Named(AdmincentralEventBus.NAME) final EventBus admincentralEventBus,
120 final @Named(SubAppEventBus.NAME) EventBus subAppEventBus,
121 final ActionbarPresenter actionbarPresenter, final ComponentProvider componentProvider, WorkbenchPresenter workbenchPresenter) {
122 this.workbenchPresenter = workbenchPresenter;
123 this.actionExecutor = actionExecutor;
124 this.view = view;
125 this.admincentralEventBus = admincentralEventBus;
126 this.subAppEventBus = subAppEventBus;
127 this.actionbarPresenter = actionbarPresenter;
128 this.appContext = subAppContext.getAppContext();
129 this.subAppDescriptor = (BrowserSubAppDescriptor) subAppContext.getSubAppDescriptor();
130
131 ImageProviderDefinition imageProviderDefinition = subAppDescriptor.getImageProvider();
132 if (imageProviderDefinition == null) {
133 this.imageProvider = null;
134 } else {
135 this.imageProvider = componentProvider.newInstance(imageProviderDefinition.getImageProviderClass(), imageProviderDefinition);
136 }
137 }
138
139 public BrowserView start() {
140 actionbarPresenter.setListener(this);
141
142 WorkbenchView workbenchView = workbenchPresenter.start(subAppDescriptor.getWorkbench(), subAppDescriptor.getImageProvider(), subAppEventBus);
143 ActionbarView actionbar = actionbarPresenter.start(subAppDescriptor.getActionbar());
144
145 view.setWorkbenchView(workbenchView);
146 view.setActionbarView(actionbar);
147 view.setListener(this);
148
149 bindHandlers();
150 return view;
151 }
152
153 private void bindHandlers() {
154 admincentralEventBus.addHandler(ContentChangedEvent.class, new ContentChangedEvent.Handler() {
155
156 @Override
157 public void onContentChanged(ContentChangedEvent event) {
158 if (event.getWorkspace().equals(getWorkspace())) {
159
160 workbenchPresenter.refresh();
161
162 workbenchPresenter.select(getSelectedItemIds());
163
164 if (event.isItemContentChanged()) {
165 workbenchPresenter.expand(event.getItemId());
166 }
167
168
169 String itemId = getSelectedItemIds().get(0);
170 try {
171 if (JcrItemUtil.itemExists(getWorkspace(), itemId)) {
172 refreshActionbarPreviewImage(itemId, event.getWorkspace());
173 }
174 } catch (RepositoryException e) {
175 log.warn("Unable to get node or property [{}] for preview image", itemId, e);
176 }
177 }
178 }
179 });
180
181 subAppEventBus.addHandler(SelectionChangedEvent.class, new SelectionChangedEvent.Handler() {
182
183 @Override
184 public void onSelectionChanged(SelectionChangedEvent event) {
185
186 refreshActionbarPreviewImage(event.getFirstItemId(), event.getWorkspace());
187 }
188 });
189
190 subAppEventBus.addHandler(ItemDoubleClickedEvent.class, new ItemDoubleClickedEvent.Handler() {
191
192 @Override
193 public void onItemDoubleClicked(ItemDoubleClickedEvent event) {
194 executeDefaultAction();
195 }
196 });
197
198 subAppEventBus.addHandler(SearchEvent.class, new SearchEvent.Handler() {
199
200 @Override
201 public void onSearch(SearchEvent event) {
202 workbenchPresenter.doSearch(event.getSearchExpression());
203 }
204 });
205
206 subAppEventBus.addHandler(ItemEditedEvent.class, new ItemEditedEvent.Handler() {
207
208 @Override
209 public void onItemEdited(ItemEditedEvent event) {
210 editItem(event);
211 }
212 });
213
214 subAppEventBus.addHandler(ItemShortcutKeyEvent.class, new ItemShortcutKeyEvent.Handler() {
215
216 @Override
217 public void onItemShortcutKeyEvent(ItemShortcutKeyEvent event) {
218 int keyCode = event.getKeyCode();
219 switch (keyCode) {
220 case ShortcutAction.KeyCode.ENTER:
221 executeDefaultAction();
222 break;
223 case ShortcutAction.KeyCode.DELETE:
224 executeDeleteAction();
225 break;
226 }
227
228 }
229 });
230 }
231
232 public List<String> getSelectedItemIds() {
233 return workbenchPresenter.getSelectedIds();
234 }
235
236
237
238
239
240 public String getDefaultViewType() {
241 return workbenchPresenter.getDefaultViewType();
242 }
243
244 public boolean hasViewType(String viewType) {
245 return workbenchPresenter.hasViewType(viewType);
246 }
247
248 public BrowserView getView() {
249 return view;
250 }
251
252 public ActionbarPresenter getActionbarPresenter() {
253 return actionbarPresenter;
254 }
255
256 public String getWorkspace() {
257 return workbenchPresenter.getWorkspace();
258 }
259
260
261
262
263
264 public void resync(final List<String> itemIds, final String viewType, final String query) {
265 workbenchPresenter.resynch(itemIds, viewType, query);
266 }
267
268 private void refreshActionbarPreviewImage(final String itemId, final String workspace) {
269 if (StringUtils.isBlank(itemId)) {
270 actionbarPresenter.setPreview(null);
271 } else {
272 if (imageProvider != null) {
273 Object previewResource = imageProvider.getThumbnailResourceById(workspace, itemId, ImageProvider.PORTRAIT_GENERATOR);
274 if (previewResource instanceof Resource) {
275 actionbarPresenter.setPreview((Resource) previewResource);
276 } else {
277 actionbarPresenter.setPreview(null);
278 }
279 }
280 }
281 }
282
283 private void editItem(ItemEditedEvent event) {
284 Item item = event.getItem();
285
286
287 if (!(item instanceof JcrItemAdapter)) {
288 return;
289 }
290
291
292 if (!((JcrItemAdapter) item).hasChangedProperties()) {
293 return;
294 }
295
296 if (item instanceof AbstractJcrNodeAdapter) {
297
298 AbstractJcrNodeAdapter nodeAdapter = (AbstractJcrNodeAdapter) item;
299 try {
300
301 Node node = nodeAdapter.applyChanges();
302 node.getSession().save();
303 } catch (RepositoryException e) {
304 log.error("Could not save changes to node", e);
305 }
306
307 } else if (item instanceof JcrPropertyAdapter) {
308
309 JcrPropertyAdapter propertyAdapter = (JcrPropertyAdapter) item;
310 try {
311
312 Node parent = propertyAdapter.getJcrItem().getParent();
313
314
315 propertyAdapter.applyChanges();
316 parent.getSession().save();
317
318
319 List<String> ids = new ArrayList<String>();
320 ids.add(JcrItemUtil.getItemId(propertyAdapter.getJcrItem()));
321 workbenchPresenter.select(ids);
322
323 } catch (RepositoryException e) {
324 log.error("Could not save changes to property", e);
325 }
326 }
327 }
328
329 @Override
330 public void onActionbarItemClicked(String itemName) {
331 executeAction(itemName);
332 }
333
334 @Override
335 public void onActionBarSelection(String actionName) {
336 executeAction(actionName);
337 }
338
339 @Override
340 public String getLabel(String itemName) {
341 ActionDefinition actionDefinition = actionExecutor.getActionDefinition(itemName);
342 return actionDefinition != null ? actionDefinition.getLabel() : null;
343 }
344
345 @Override
346 public String getIcon(String itemName) {
347 ActionDefinition actionDefinition = actionExecutor.getActionDefinition(itemName);
348 return actionDefinition != null ? actionDefinition.getIcon() : null;
349 }
350
351
352
353
354 private void executeDefaultAction() {
355 ActionbarDefinition actionbarDefinition = subAppDescriptor.getActionbar();
356 if (actionbarDefinition == null) {
357 return;
358 }
359 String defaultAction = actionbarDefinition.getDefaultAction();
360 if (StringUtils.isNotEmpty(defaultAction)) {
361 executeAction(defaultAction);
362 }
363 }
364
365
366
367
368 private void executeDeleteAction() {
369 ActionbarDefinition actionbarDefinition = subAppDescriptor.getActionbar();
370 if (actionbarDefinition == null) {
371 return;
372 }
373 String deleteAction = actionbarDefinition.getDeleteAction();
374 if (StringUtils.isNotEmpty(deleteAction)) {
375 executeAction(deleteAction);
376 }
377 }
378
379 private void executeAction(String actionName) {
380 try {
381 if (getSelectedItemIds().size() == 1) {
382
383
384
385
386 javax.jcr.Item item = JcrItemUtil.getJcrItem(getWorkspace(), getSelectedItemIds().get(0));
387 String workbenchRootId = JcrItemUtil.getItemId(getWorkspace(), subAppDescriptor.getWorkbench().getPath());
388 boolean isWorkbenchRoot = JcrItemUtil.getItemId(item).equals(workbenchRootId);
389
390 if (actionExecutor.isAvailable(actionName, isWorkbenchRoot ? null : item)) {
391 actionExecutor.execute(actionName, item.isNode() ? new JcrNodeAdapter((Node) item) : new JcrPropertyAdapter((Property) item));
392 }
393 } else {
394 List<Item> items = new ArrayList<Item>(getSelectedItemIds().size());
395 List<javax.jcr.Item> jcrItems = new ArrayList<javax.jcr.Item>(getSelectedItemIds().size());
396 for (String itemId : getSelectedItemIds()) {
397 javax.jcr.Item item = JcrItemUtil.getJcrItem(getWorkspace(), itemId);
398 jcrItems.add(item);
399 JcrItemAdapter adapter = item.isNode() ? new JcrNodeAdapter((Node) item) : new JcrPropertyAdapter((Property) item);
400 items.add(adapter);
401 }
402 if (actionExecutor.isAvailable(actionName, jcrItems.toArray(new javax.jcr.Item[] {}))) {
403 actionExecutor.execute(actionName, items);
404 }
405 }
406 } catch (PathNotFoundException p) {
407 Message error = new Message(MessageType.ERROR, "Could not get item ", "Following Item not found :" + getSelectedItemIds().get(0));
408 appContext.sendLocalMessage(error);
409 } catch (RepositoryException e) {
410 Message error = new Message(MessageType.ERROR, "Could not get item: " + getSelectedItemIds().get(0), e.getMessage());
411 log.error("An error occurred while executing action [{}]", actionName, e);
412 appContext.sendLocalMessage(error);
413 } catch (ActionExecutionException e) {
414 Message error = new Message(MessageType.ERROR, "An error occurred while executing an action.", e.getMessage());
415 log.error("An error occurred while executing action [{}]", actionName, e);
416 appContext.sendLocalMessage(error);
417 }
418 }
419
420 }