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