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.pages.app.editor;
35
36 import info.magnolia.cms.core.version.VersionManager;
37 import info.magnolia.cms.i18n.I18nContentSupport;
38 import info.magnolia.event.EventBus;
39 import info.magnolia.i18nsystem.SimpleTranslator;
40 import info.magnolia.objectfactory.Components;
41 import info.magnolia.pages.app.editor.event.NodeSelectedEvent;
42 import info.magnolia.pages.app.editor.pagebar.PageBarPresenter;
43 import info.magnolia.pages.app.editor.statusbar.StatusBarPresenter;
44 import info.magnolia.ui.actionbar.ActionbarPresenter;
45 import info.magnolia.ui.actionbar.ActionbarView;
46 import info.magnolia.ui.actionbar.definition.ActionbarDefinition;
47 import info.magnolia.ui.actionbar.definition.ActionbarGroupDefinition;
48 import info.magnolia.ui.actionbar.definition.ActionbarItemDefinition;
49 import info.magnolia.ui.actionbar.definition.ActionbarSectionDefinition;
50 import info.magnolia.ui.api.action.ActionDefinition;
51 import info.magnolia.ui.api.action.ActionExecutionException;
52 import info.magnolia.ui.api.action.ActionExecutor;
53 import info.magnolia.ui.api.app.AppContext;
54 import info.magnolia.ui.api.app.SubAppContext;
55 import info.magnolia.ui.api.app.SubAppEventBus;
56 import info.magnolia.ui.api.availability.AvailabilityChecker;
57 import info.magnolia.ui.api.availability.AvailabilityDefinition;
58 import info.magnolia.ui.api.event.AdmincentralEventBus;
59 import info.magnolia.ui.api.event.ContentChangedEvent;
60 import info.magnolia.ui.api.i18n.I18NAuthoringSupport;
61 import info.magnolia.ui.api.location.Location;
62 import info.magnolia.ui.api.message.Message;
63 import info.magnolia.ui.api.message.MessageType;
64 import info.magnolia.ui.contentapp.definition.ContentSubAppDescriptor;
65 import info.magnolia.ui.contentapp.detail.DetailLocation;
66 import info.magnolia.ui.contentapp.detail.DetailSubAppDescriptor;
67 import info.magnolia.ui.contentapp.detail.DetailView;
68 import info.magnolia.ui.framework.app.BaseSubApp;
69 import info.magnolia.ui.vaadin.editor.PageEditorListener;
70 import info.magnolia.ui.vaadin.editor.pagebar.PageBarView;
71 import info.magnolia.ui.vaadin.gwt.client.shared.AbstractElement;
72 import info.magnolia.ui.vaadin.gwt.client.shared.PageElement;
73 import info.magnolia.ui.vaadin.integration.contentconnector.ContentConnector;
74 import info.magnolia.ui.workbench.StatusBarView;
75
76 import java.util.Arrays;
77 import java.util.Collections;
78 import java.util.List;
79 import java.util.Locale;
80 import java.util.Map;
81
82 import javax.inject.Inject;
83 import javax.inject.Named;
84
85 import org.apache.commons.lang3.ObjectUtils;
86 import org.apache.commons.lang3.StringUtils;
87 import org.slf4j.Logger;
88 import org.slf4j.LoggerFactory;
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107 public class PagesEditorSubApp extends BaseSubApp<PagesEditorSubAppView> implements PagesEditorSubAppView.Listener, ActionbarPresenter.Listener, PageEditorPresenter.Listener {
108
109 private static final Logger log = LoggerFactory.getLogger(PagesEditorSubApp.class);
110
111 private final ActionExecutor actionExecutor;
112 private final SubAppContext subAppContext;
113 private final PagesEditorSubAppView view;
114 private final EventBus subAppEventBus;
115 private final EventBus admincentralEventBus;
116 private final PageEditorPresenter pageEditorPresenter;
117 private final ActionbarPresenter actionbarPresenter;
118 private final PagesContentConnector contentConnector;
119 private final AvailabilityChecker availabilityChecker;
120 private final StatusBarPresenter statusBar;
121 private final PageBarPresenter pageBar;
122 private final AppContext appContext;
123 private final SimpleTranslator i18n;
124
125 private String caption;
126
127 @Inject
128 public PagesEditorSubApp(final ActionExecutor actionExecutor, final SubAppContext subAppContext, final PagesEditorSubAppView view,
129 final @Named(AdmincentralEventBus.NAME) EventBus admincentralEventBus, final @Named(SubAppEventBus.NAME) EventBus subAppEventBus,
130 final PageEditorPresenter pageEditorPresenter, final ActionbarPresenter actionbarPresenter,
131 final SimpleTranslator i18n, AvailabilityChecker availabilityChecker, final PagesContentConnector contentConnector,
132 final StatusBarPresenter statusBar, final PageBarPresenter pageBar) {
133 super(subAppContext, view);
134 this.actionExecutor = actionExecutor;
135 this.subAppContext = subAppContext;
136 this.view = view;
137 this.subAppEventBus = subAppEventBus;
138 this.admincentralEventBus = admincentralEventBus;
139 this.pageEditorPresenter = pageEditorPresenter;
140 this.actionbarPresenter = actionbarPresenter;
141 this.availabilityChecker = availabilityChecker;
142 this.statusBar = statusBar;
143 this.pageBar = pageBar;
144 this.contentConnector = contentConnector;
145 this.appContext = subAppContext.getAppContext();
146 this.i18n = i18n;
147 bindHandlers();
148 }
149
150
151
152
153 @Deprecated
154 public PagesEditorSubApp(final ActionExecutor actionExecutor, final SubAppContext subAppContext, final PagesEditorSubAppView view, @Named(AdmincentralEventBus.NAME) EventBus admincentralEventBus,
155 final @Named(SubAppEventBus.NAME) EventBus subAppEventBus, final PageEditorPresenter pageEditorPresenter, final ActionbarPresenter actionbarPresenter, VersionManager versionManager, final SimpleTranslator i18n, AvailabilityChecker availabilityChecker,
156 ContentConnector contentConnector, StatusBarPresenter statusBar, PageBarPresenter pageBar) {
157 this(actionExecutor, subAppContext, view, admincentralEventBus, subAppEventBus, pageEditorPresenter, actionbarPresenter, i18n, availabilityChecker, (PagesContentConnector) contentConnector, statusBar, pageBar);
158 }
159
160
161
162
163 @Deprecated
164 public PagesEditorSubApp(final ActionExecutor actionExecutor, final SubAppContext subAppContext, final PagesEditorSubAppView view, @Named(AdmincentralEventBus.NAME) EventBus admincentralEventBus,
165 final @Named(SubAppEventBus.NAME) EventBus subAppEventBus, final PageEditorPresenter pageEditorPresenter, final ActionbarPresenter actionbarPresenter, final PageBarView pageBarView,
166 I18NAuthoringSupport i18NAuthoringSupport, I18nContentSupport i18nContentSupport, VersionManager versionManager, final SimpleTranslator i18n, AvailabilityChecker availabilityChecker,
167 ContentConnector contentConnector, StatusBarView statusBarView) {
168 this(actionExecutor, subAppContext, view, admincentralEventBus, subAppEventBus, pageEditorPresenter, actionbarPresenter, i18n, availabilityChecker, (PagesContentConnector) contentConnector, Components.getComponent(StatusBarPresenter.class), Components.getComponent(PageBarPresenter.class));
169 }
170
171 @Override
172 public String getCaption() {
173 return caption;
174 }
175
176 public void updateCaption(DetailLocation location) {
177 this.caption = contentConnector.getPageTitle(location.getNodePath(), location.getVersion());
178 pageBar.setPageName(caption, location.getNodePath());
179 }
180
181 @Override
182 public void updateCaptionForExternalPage(String title) {
183 this.caption = title;
184 pageBar.setPageName(caption);
185 }
186
187 @Override
188 public PagesEditorSubAppView start(Location location) {
189 view.setListener(this);
190
191 DetailLocation detailLocation = DetailLocation.wrap(location);
192 super.start(detailLocation);
193
194 ActionbarDefinition actionbarDefinition = ((ContentSubAppDescriptor) getSubAppContext().getSubAppDescriptor()).getActionbar();
195 Map<String, ActionDefinition> actionDefinitions = getSubAppContext().getSubAppDescriptor().getActions();
196 actionbarPresenter.setListener(this);
197 ActionbarView actionbar = actionbarPresenter.start(actionbarDefinition, actionDefinitions);
198 hideActionbarSections();
199
200 updateCaption(detailLocation);
201
202 pageEditorPresenter.setListener(this);
203 view.setActionbarView(actionbar);
204 view.setPageBarView(pageBar.start(detailLocation));
205 view.setPageEditorView(pageEditorPresenter.start(detailLocation));
206 view.setStatusBarView(statusBar.start(detailLocation));
207
208 return view;
209 }
210
211
212
213
214
215 protected void updateNodePath(String path) {
216 DetailLocation detailLocation = getCurrentLocation();
217 detailLocation.updateNodePath(path);
218 updateLocationDependentComponents(detailLocation);
219 getAppContext().updateSubAppLocation(getSubAppContext(), detailLocation);
220 pageEditorPresenter.getStatus().setNodePath(path);
221 pageEditorPresenter.updateParameters();
222 }
223
224 @Override
225 public boolean supportsLocation(Location location) {
226 return getCurrentLocation().getNodePath().equals(DetailLocation.wrap(location).getNodePath());
227 }
228
229
230
231
232 @Override
233 public DetailLocation getCurrentLocation() {
234 return DetailLocation.wrap(super.getCurrentLocation());
235 }
236
237 @Override
238 public void deactivateComponents() {
239 updateActionbar();
240 pageBar.deactivateExtensions();
241 statusBar.deactivateExtensions();
242 }
243
244 @Override
245 public void locationChanged(Location location) {
246 DetailLocation itemLocation = DetailLocation.wrap(location);
247 super.locationChanged(itemLocation);
248
249 if (pageEditorPresenter.getStatus().isLocationChanged(itemLocation)) {
250 pageEditorPresenter.reload(itemLocation);
251 updateLocationDependentComponents(itemLocation);
252 }
253 }
254
255 private void updateLocationDependentComponents(DetailLocation location) {
256 pageBar.onLocationUpdate(location);
257 statusBar.onLocationUpdate(location);
258 updateCaption(location);
259 }
260
261 private void bindHandlers() {
262
263 admincentralEventBus.addHandler(ContentChangedEvent.class, new ContentChangedEvent.Handler() {
264
265 @Override
266 public void onContentChanged(ContentChangedEvent event) {
267 if (contentConnector.canHandleItem(event.getItemId())) {
268 if (!contentConnector.itemExists(event.getItemId())) {
269 getSubAppContext().close();
270 }
271 }
272 }
273 });
274
275 subAppEventBus.addHandler(ContentChangedEvent.class, new ContentChangedEvent.Handler() {
276
277 @Override
278 public void onContentChanged(ContentChangedEvent event) {
279
280 AbstractElement element = contentConnector.getElementFrom(event.getItemId());
281 pageEditorPresenter.getStatus().setSelectedElement(element);
282
283
284 pageEditorPresenter.updateParameters();
285
286
287 Locale authoringLocale = subAppContext.getAuthoringLocale();
288 if (authoringLocale != null && ObjectUtils.notEqual(authoringLocale, pageEditorPresenter.getStatus().getLocale())) {
289 updateLocationDependentComponents(getCurrentLocation());
290
291 pageEditorPresenter.loadPageEditor();
292 } else {
293 pageEditorPresenter.refresh();
294 }
295 }
296 });
297
298 subAppEventBus.addHandler(NodeSelectedEvent.class, new NodeSelectedEvent.Handler() {
299
300 @Override
301 public void onItemSelected(NodeSelectedEvent event) {
302 AbstractElement element = event.getElement();
303 if (element instanceof PageElement) {
304 String path = element.getPath();
305 if (StringUtils.isEmpty(path)) {
306 path = "/";
307 }
308 if (!path.equals(getCurrentLocation().getNodePath())) {
309 updateNodePath(path);
310 }
311 }
312 updateActionbar();
313 }
314 });
315
316 }
317
318 @Override
319 public void onActionbarItemClicked(String actionName) {
320 prepareAndExecutePagesEditorAction(actionName);
321 }
322
323
324
325
326
327
328
329 protected void prepareAndExecutePagesEditorAction(String actionName) {
330 AbstractElement selectedElement = pageEditorPresenter.getSelectedElement();
331 if (selectedElement == null) {
332 log.warn("Trying to execute action [{}] but no element was selected. Was the page actually loaded?", actionName);
333 return;
334 }
335 try {
336 actionExecutor.execute(actionName, selectedElement, pageEditorPresenter);
337 } catch (ActionExecutionException e) {
338 Message error = new Message(MessageType.ERROR, i18n.translate("pages.pagesEditorSubapp.actionExecutionException.message"), e.getMessage());
339 log.error("An error occurred while executing action [{}]", actionName, e);
340 appContext.sendLocalMessage(error);
341 }
342 }
343
344 public void updateActionbar() {
345 Object itemId = contentConnector.getItemIdByElement(pageEditorPresenter.getSelectedElement());
346
347
348 List<ActionbarSectionDefinition> sections = getSections();
349 ActionbarSectionDefinition sectionDefinition = getVisibleSection(sections, itemId);
350
351
352 for (ActionbarSectionDefinition section : sections) {
353 actionbarPresenter.hideSection(section.getName());
354 }
355
356 if (sectionDefinition != null) {
357
358 actionbarPresenter.showSection(sectionDefinition.getName());
359
360
361 for (ActionbarGroupDefinition groupDefinition : sectionDefinition.getGroups()) {
362 for (ActionbarItemDefinition itemDefinition : groupDefinition.getItems()) {
363
364 String actionName = itemDefinition.getName();
365 ActionDefinition actionDefinition = actionExecutor.getActionDefinition(actionName);
366 if (actionDefinition != null) {
367 AvailabilityDefinition availability = actionDefinition.getAvailability();
368 if (availabilityChecker.isAvailable(availability, Arrays.asList(itemId))) {
369 actionbarPresenter.enable(actionName);
370 } else {
371 actionbarPresenter.disable(actionName);
372 }
373 }
374 }
375 }
376 }
377 }
378
379 private List<ActionbarSectionDefinition> getSections() {
380 DetailSubAppDescriptor subAppDescriptor = (DetailSubAppDescriptor) getSubAppContext().getSubAppDescriptor();
381 ActionbarDefinition actionbarDefinition = subAppDescriptor.getActionbar();
382 if (actionbarDefinition == null) {
383 return Collections.emptyList();
384 }
385 return actionbarDefinition.getSections();
386 }
387
388 private void hideActionbarSections() {
389 for (ActionbarSectionDefinition sectionDefinition : getSections()) {
390 actionbarPresenter.hideSection(sectionDefinition.getName());
391 }
392 }
393
394 private ActionbarSectionDefinition getVisibleSection(List<ActionbarSectionDefinition> sections, Object itemId) {
395 for (ActionbarSectionDefinition section : sections) {
396 if (availabilityChecker.isAvailable(section.getAvailability(), Arrays.asList(itemId)))
397 return section;
398 }
399 return null;
400 }
401
402 @Override
403 public void onEscape() {
404 if (pageEditorPresenter.isMoving()) {
405 pageEditorPresenter.onAction(PageEditorListener.ACTION_CANCEL_MOVE_COMPONENT);
406 } else {
407
408 if (getCurrentLocation().getViewType().equals(DetailView.ViewType.EDIT)) {
409 prepareAndExecutePagesEditorAction(PageEditorListener.ACTION_VIEW_PREVIEW);
410 } else {
411 prepareAndExecutePagesEditorAction(PageEditorListener.ACTION_VIEW_EDIT);
412 }
413 }
414 }
415
416
417
418
419 @Deprecated
420 protected String getWorkspace() {
421 return ((PagesJcrContentConnector)contentConnector).getContentConnectorDefinition().getWorkspace();
422 }
423
424 @Override
425 public void onMove() {
426 updateActionbar();
427 }
428
429 @Override
430 public void stop() {
431 pageBar.stop();
432 statusBar.stop();
433 }
434 }