View Javadoc

1   /**
2    * This file Copyright (c) 2013-2014 Magnolia International
3    * Ltd.  (http://www.magnolia-cms.com). All rights reserved.
4    *
5    *
6    * This file is dual-licensed under both the Magnolia
7    * Network Agreement and the GNU General Public License.
8    * You may elect to use one or the other of these licenses.
9    *
10   * This file is distributed in the hope that it will be
11   * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
12   * implied warranty of MERCHANTABILITY or FITNESS FOR A
13   * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
14   * Redistribution, except as permitted by whichever of the GPL
15   * or MNA you select, is prohibited.
16   *
17   * 1. For the GPL license (GPL), you can redistribute and/or
18   * modify this file under the terms of the GNU General
19   * Public License, Version 3, as published by the Free Software
20   * Foundation.  You should have received a copy of the GNU
21   * General Public License, Version 3 along with this program;
22   * if not, write to the Free Software Foundation, Inc., 51
23   * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24   *
25   * 2. For the Magnolia Network Agreement (MNA), this file
26   * and the accompanying materials are made available under the
27   * terms of the MNA which accompanies this distribution, and
28   * is available at http://www.magnolia-cms.com/mna.html
29   *
30   * Any modifications to this file must keep this entire header
31   * intact.
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.context.MgnlContext;
39  import info.magnolia.event.EventBus;
40  import info.magnolia.i18nsystem.SimpleTranslator;
41  import info.magnolia.jcr.util.NodeTypes;
42  import info.magnolia.jcr.util.NodeUtil;
43  import info.magnolia.jcr.util.PropertyUtil;
44  import info.magnolia.jcr.util.SessionUtil;
45  import info.magnolia.link.LinkUtil;
46  import info.magnolia.objectfactory.Components;
47  import info.magnolia.pages.app.editor.event.ComponentMoveEvent;
48  import info.magnolia.pages.app.editor.event.NodeSelectedEvent;
49  import info.magnolia.repository.RepositoryConstants;
50  import info.magnolia.ui.actionbar.ActionbarPresenter;
51  import info.magnolia.ui.actionbar.ActionbarView;
52  import info.magnolia.ui.actionbar.definition.ActionbarDefinition;
53  import info.magnolia.ui.actionbar.definition.ActionbarGroupDefinition;
54  import info.magnolia.ui.actionbar.definition.ActionbarItemDefinition;
55  import info.magnolia.ui.actionbar.definition.ActionbarSectionDefinition;
56  import info.magnolia.ui.api.action.ActionDefinition;
57  import info.magnolia.ui.api.action.ActionExecutionException;
58  import info.magnolia.ui.api.action.ActionExecutor;
59  import info.magnolia.ui.api.app.AppContext;
60  import info.magnolia.ui.api.app.SubAppContext;
61  import info.magnolia.ui.api.app.SubAppEventBus;
62  import info.magnolia.ui.api.availability.AvailabilityChecker;
63  import info.magnolia.ui.api.availability.AvailabilityDefinition;
64  import info.magnolia.ui.api.event.AdmincentralEventBus;
65  import info.magnolia.ui.api.event.ContentChangedEvent;
66  import info.magnolia.ui.api.i18n.I18NAuthoringSupport;
67  import info.magnolia.ui.api.location.Location;
68  import info.magnolia.ui.api.location.LocationChangedEvent;
69  import info.magnolia.ui.api.message.Message;
70  import info.magnolia.ui.api.message.MessageType;
71  import info.magnolia.ui.contentapp.definition.ContentSubAppDescriptor;
72  import info.magnolia.ui.contentapp.definition.EditorDefinition;
73  import info.magnolia.ui.contentapp.detail.DetailLocation;
74  import info.magnolia.ui.contentapp.detail.DetailSubAppDescriptor;
75  import info.magnolia.ui.contentapp.detail.DetailView;
76  import info.magnolia.ui.framework.app.BaseSubApp;
77  import info.magnolia.ui.framework.i18n.DefaultI18NAuthoringSupport;
78  import info.magnolia.ui.vaadin.editor.PageEditorListener;
79  import info.magnolia.ui.vaadin.editor.gwt.shared.PlatformType;
80  import info.magnolia.ui.vaadin.editor.pagebar.PageBarView;
81  import info.magnolia.ui.vaadin.gwt.client.shared.AbstractElement;
82  import info.magnolia.ui.vaadin.gwt.client.shared.AreaElement;
83  import info.magnolia.ui.vaadin.gwt.client.shared.ComponentElement;
84  import info.magnolia.ui.vaadin.gwt.client.shared.PageEditorParameters;
85  import info.magnolia.ui.vaadin.gwt.client.shared.PageElement;
86  import info.magnolia.ui.vaadin.integration.contentconnector.ContentConnector;
87  import info.magnolia.ui.vaadin.integration.contentconnector.JcrContentConnector;
88  import info.magnolia.ui.vaadin.integration.jcr.JcrItemId;
89  import info.magnolia.ui.vaadin.integration.jcr.JcrItemUtil;
90  import info.magnolia.ui.vaadin.integration.jcr.JcrNodeAdapter;
91  import info.magnolia.ui.workbench.StatusBarView;
92  
93  import java.util.Arrays;
94  import java.util.List;
95  import java.util.Locale;
96  import java.util.Map;
97  
98  import javax.inject.Inject;
99  import javax.inject.Named;
100 import javax.jcr.Node;
101 import javax.jcr.RepositoryException;
102 import javax.jcr.Session;
103 
104 import org.apache.commons.lang3.StringUtils;
105 import org.slf4j.Logger;
106 import org.slf4j.LoggerFactory;
107 
108 /**
109  * PagesEditorSubApp.
110  */
111 public class PagesEditorSubApp extends BaseSubApp<PagesEditorSubAppView> implements PagesEditorSubAppView.Listener, ActionbarPresenter.Listener, PageBarView.Listener {
112 
113     private static final Logger log = LoggerFactory.getLogger(PagesEditorSubApp.class);
114 
115     protected static final String PROPERTY_TITLE = "title";
116 
117     protected static final String SECTION_PAGE = "pageActions";
118     protected static final String SECTION_PAGE_PREVIEW = "pagePreviewActions";
119     protected static final String SECTION_AREA = "areaActions";
120     protected static final String SECTION_EDITABLE_AREA = "editableAreaActions";
121     protected static final String SECTION_COMPONENT = "componentActions";
122     protected static final String SECTION_PAGE_DELETE = "pageDeleteActions";
123     protected static final String SECTION_OPTIONAL_AREA = "optionalAreaActions";
124     protected static final String SECTION_OPTIONAL_EDITABLE_AREA = "optionalEditableAreaActions";
125     protected static final String[] ALL_SECTIONS = new String[] { SECTION_AREA, SECTION_COMPONENT, SECTION_EDITABLE_AREA,
126             SECTION_OPTIONAL_AREA, SECTION_OPTIONAL_EDITABLE_AREA, SECTION_PAGE, SECTION_PAGE_DELETE, SECTION_PAGE_PREVIEW };
127 
128     private final ActionExecutor actionExecutor;
129     private final PagesEditorSubAppView view;
130     private final EventBus subAppEventBus;
131     private final EventBus admincentralEventBus;
132     private final PageEditorPresenter pageEditorPresenter;
133     private final ActionbarPresenter actionbarPresenter;
134     private final PageBarView pageBarView;
135     private final I18NAuthoringSupport i18NAuthoringSupport;
136     private final I18nContentSupport i18nContentSupport;
137     private AvailabilityChecker availabilityChecker;
138     private final StatusBarView statusBarView;
139     private final EditorDefinition editorDefinition;
140     private final String workspace;
141     private final AppContext appContext;
142     private final VersionManager versionManager;
143     private final SimpleTranslator i18n;
144 
145     private PageEditorParameters parameters;
146     private PlatformType targetPreviewPlatform = PlatformType.DESKTOP;
147     private Locale currentLocale;
148     private String caption;
149 
150     /**
151      * @deprecated since 5.2.4 - use info.magnolia.pages.app.editor.PagesEditorSubApp#PagesEditorSubApp(info.magnolia.ui.api.action.ActionExecutor, info.magnolia.ui.api.app.SubAppContext, info.magnolia.pages.app.editor.PagesEditorSubAppView, info.magnolia.event.EventBus, info.magnolia.event.EventBus, info.magnolia.pages.app.editor.PageEditorPresenter, info.magnolia.ui.actionbar.ActionbarPresenter, info.magnolia.ui.vaadin.editor.pagebar.PageBarView, info.magnolia.ui.api.i18n.I18NAuthoringSupport, info.magnolia.cms.i18n.I18nContentSupport, info.magnolia.cms.core.version.VersionManager, info.magnolia.i18nsystem.SimpleTranslator, info.magnolia.ui.api.availability.AvailabilityChecker, info.magnolia.ui.vaadin.integration.contentconnector.ContentConnector)
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, final PageBarView pageBarView,
156             I18NAuthoringSupport i18NAuthoringSupport, I18nContentSupport i18nContentSupport, VersionManager versionManager, final SimpleTranslator i18n, AvailabilityChecker availabilityChecker,
157             ContentConnector contentConnector) {
158         this(actionExecutor, subAppContext, view, admincentralEventBus, subAppEventBus, pageEditorPresenter, actionbarPresenter, pageBarView, i18NAuthoringSupport, i18nContentSupport, versionManager, i18n, availabilityChecker, contentConnector, Components.getComponent(StatusBarView.class));
159     }
160 
161     @Inject
162     public PagesEditorSubApp(final ActionExecutor actionExecutor, final SubAppContext subAppContext, final PagesEditorSubAppView view, @Named(AdmincentralEventBus.NAME) EventBus admincentralEventBus,
163             final @Named(SubAppEventBus.NAME) EventBus subAppEventBus, final PageEditorPresenter pageEditorPresenter, final ActionbarPresenter actionbarPresenter, final PageBarView pageBarView,
164             I18NAuthoringSupport i18NAuthoringSupport, I18nContentSupport i18nContentSupport, VersionManager versionManager, final SimpleTranslator i18n, AvailabilityChecker availabilityChecker,
165             ContentConnector contentConnector, StatusBarView statusBarView) {
166         super(subAppContext, view);
167         this.actionExecutor = actionExecutor;
168         this.view = view;
169         this.subAppEventBus = subAppEventBus;
170         this.admincentralEventBus = admincentralEventBus;
171         this.pageEditorPresenter = pageEditorPresenter;
172         this.actionbarPresenter = actionbarPresenter;
173         this.pageBarView = pageBarView;
174         this.i18NAuthoringSupport = i18NAuthoringSupport;
175         this.i18nContentSupport = i18nContentSupport;
176         this.availabilityChecker = availabilityChecker;
177         this.statusBarView = statusBarView;
178         this.editorDefinition = ((DetailSubAppDescriptor) subAppContext.getSubAppDescriptor()).getEditor();
179         this.workspace = ((JcrContentConnector) contentConnector).getContentConnectorDefinition().getWorkspace();
180         this.appContext = subAppContext.getAppContext();
181         this.currentLocale = i18nContentSupport.getLocale();
182         this.versionManager = versionManager;
183         this.i18n = i18n;
184         view.setListener(this);
185         bindHandlers();
186     }
187 
188     @Override
189     public String getCaption() {
190         return caption;
191     }
192 
193     public void updateCaption(DetailLocation location) {
194         this.caption = getPageTitle(location);
195         pageBarView.setPageName(caption, location.getNodePath());
196     }
197 
198     @Override
199     public PagesEditorSubAppView start(Location location) {
200         DetailLocation detailLocation = DetailLocation.wrap(location);
201         super.start(detailLocation);
202 
203         ActionbarDefinition actionbarDefinition = ((ContentSubAppDescriptor) getSubAppContext().getSubAppDescriptor()).getActionbar();
204         Map<String, ActionDefinition> actionDefinitions = getSubAppContext().getSubAppDescriptor().getActions();
205         actionbarPresenter.setListener(this);
206         ActionbarView actionbar = actionbarPresenter.start(actionbarDefinition, actionDefinitions);
207 
208         pageBarView.setListener(this);
209 
210         view.setActionbarView(actionbar);
211         view.setPageBarView(pageBarView);
212         view.setPageEditorView(pageEditorPresenter.start());
213         view.setStatusBarView(statusBarView);
214 
215         subAppEventBus.addHandler(ContentChangedEvent.class, new ContentChangedEvent.Handler() {
216 
217             @Override
218             public void onContentChanged(ContentChangedEvent event) {
219                 view.setStatusBarView(statusBarView);
220             }
221         });
222 
223         admincentralEventBus.addHandler(ContentChangedEvent.class, new ContentChangedEvent.Handler() {
224 
225             @Override
226             public void onContentChanged(ContentChangedEvent event) {
227                 view.setStatusBarView(statusBarView);
228             }
229         });
230 
231         admincentralEventBus.addHandler(LocationChangedEvent.class, new LocationChangedEvent.Handler() {
232             @Override
233             public void onLocationChanged(LocationChangedEvent event) {
234                 view.setStatusBarView(statusBarView);
235             }
236         });
237 
238         goToLocation(detailLocation);
239         return view;
240     }
241 
242     private void updateActions() {
243         updateActionsAccordingToOperationPermissions();
244         // actions currently always disabled
245         actionbarPresenter.disable(PageEditorListener.ACTION_CANCEL_MOVE_COMPONENT, PageEditorListener.ACTION_COPY_COMPONENT,
246                 PageEditorListener.ACTION_PASTE_COMPONENT, PageEditorListener.ACTION_UNDO, PageEditorListener.ACTION_REDO);
247     }
248 
249     /**
250      * Informs the app framework when navigating pages inside the page editor.
251      * Updates the shell fragment, caption and current location.
252      */
253     protected void updateNodePath(String path) {
254         DetailLocation detailLocation = getCurrentLocation();
255         detailLocation.updateNodePath(path);
256         setPageEditorParameters(detailLocation);
257         getAppContext().updateSubAppLocation(getSubAppContext(), detailLocation);
258         view.setStatusBarView(statusBarView); // update page status bar
259         pageEditorPresenter.updateParameters(parameters);
260     }
261 
262     /**
263      * Show/Hide actions buttons according to operation permissions.
264      */
265     private void updateActionsAccordingToOperationPermissions() {
266         AbstractElement element = pageEditorPresenter.getSelectedElement();
267 
268         if (element instanceof ComponentElement) {
269             ComponentElement componentElement = (ComponentElement) element;
270 
271             if (componentElement.getDeletable() != null && !componentElement.getDeletable()) {
272                 actionbarPresenter.disable(PageEditorListener.ACTION_DELETE_COMPONENT);
273             }
274             if (componentElement.getMoveable() != null && !componentElement.getMoveable()) {
275                 actionbarPresenter.disable(PageEditorListener.ACTION_START_MOVE_COMPONENT);
276             }
277             if (componentElement.getWritable() != null && !componentElement.getWritable()) {
278                 actionbarPresenter.disable(PageEditorListener.ACTION_EDIT_COMPONENT);
279             }
280 
281         } else if (element instanceof AreaElement) {
282             AreaElement areaElement = (AreaElement) element;
283 
284             if (areaElement.getAddible() != null && !areaElement.getAddible()) {
285                 actionbarPresenter.disable(PageEditorListener.ACTION_ADD_COMPONENT);
286             }
287         }
288     }
289 
290     @Override
291     public boolean supportsLocation(Location location) {
292         return getCurrentLocation().getNodePath().equals(DetailLocation.wrap(location).getNodePath());
293     }
294 
295     /**
296      * Wraps the current DefaultLocation in a DetailLocation. Providing getter and setters for used parameters.
297      */
298     @Override
299     public DetailLocation getCurrentLocation() {
300         return DetailLocation.wrap(super.getCurrentLocation());
301     }
302 
303     @Override
304     public void locationChanged(Location location) {
305         DetailLocation itemLocation = DetailLocation.wrap(location);
306         super.locationChanged(itemLocation);
307         goToLocation(itemLocation);
308     }
309 
310     private void goToLocation(DetailLocation location) {
311         if (isLocationChanged(location)) {
312             doGoToLocation(location);
313         }
314     }
315 
316     protected void doGoToLocation(DetailLocation location) {
317         setPageEditorParameters(location);
318         hideAllSections();
319         pageEditorPresenter.loadPageEditor(parameters);
320         updatePageBarAvailableLanguages(location);
321     }
322 
323     private void updatePageBarAvailableLanguages(DetailLocation location) {
324         Node node = SessionUtil.getNode(workspace, location.getNodePath());
325         List<Locale> locales = i18NAuthoringSupport.getAvailableLocales(node);
326         pageBarView.setAvailableLanguages(locales);
327         Locale locale = currentLocale != null ? currentLocale : i18nContentSupport.getLocale();
328         pageBarView.setCurrentLanguage(locale);
329     }
330 
331     private void setPageEditorParameters(DetailLocation location) {
332         DetailView.ViewType action = location.getViewType();
333         String path = location.getNodePath();
334         boolean isPreview = DetailView.ViewType.VIEW.getText().equals(action.getText());
335         this.parameters = new PageEditorParameters(MgnlContext.getContextPath(), path, isPreview);
336         this.parameters.setPlatformType(targetPreviewPlatform);
337         try {
338             Node node = MgnlContext.getJCRSession(workspace).getNode(path);
339             String uri = i18NAuthoringSupport.createI18NURI(node, currentLocale);
340             StringBuffer sb = new StringBuffer(uri);
341 
342             if (isPreview) {
343                 LinkUtil.addParameter(sb, "mgnlPreview", Boolean.toString(true));
344             } else {
345                 // reset channel
346                 this.targetPreviewPlatform = PlatformType.DESKTOP;
347                 this.parameters.setPlatformType(targetPreviewPlatform);
348                 pageBarView.setPlatFormType(targetPreviewPlatform);
349 
350                 LinkUtil.addParameter(sb, "mgnlPreview", Boolean.toString(false));
351             }
352             LinkUtil.addParameter(sb, "mgnlChannel", targetPreviewPlatform.getId());
353 
354             if (location.hasVersion()) {
355                 LinkUtil.addParameter(sb, "mgnlVersion", location.getVersion());
356             }
357             uri = sb.toString();
358             this.parameters.setUrl(uri);
359             updateCaption(location);
360             pageBarView.togglePreviewMode(isPreview);
361         } catch (RepositoryException e) {
362             log.error(e.getMessage(), e);
363         }
364     }
365 
366     private boolean isLocationChanged(DetailLocation location) {
367         DetailView.ViewType action = location.getViewType();
368         String path = location.getNodePath();
369 
370         if (parameters != null && (parameters.getNodePath().equals(path) && parameters.isPreview() == DetailView.ViewType.VIEW.getText().equals(action.getText())) && !location.hasVersion()) {
371             return false;
372         }
373         return true;
374     }
375 
376     private String getPageTitle(DetailLocation location) {
377         String caption = StringUtils.EMPTY;
378         try {
379             Session session = MgnlContext.getJCRSession(workspace);
380             Node node = session.getNode(location.getNodePath());
381             if (StringUtils.isNotBlank(location.getVersion())) {
382                 node = versionManager.getVersion(node, location.getVersion());
383                 caption = i18n.translate("subapp.versioned_page", PropertyUtil.getString(node, PROPERTY_TITLE, node.getName()), location.getVersion());
384             } else {
385                 caption = PropertyUtil.getString(node, PROPERTY_TITLE, node.getName());
386             }
387 
388         } catch (RepositoryException e) {
389             log.warn("Could not set page Tab Title for item : {}", location.getNodePath(), e);
390         }
391         return caption;
392     }
393 
394     private void hideAllSections() {
395         actionbarPresenter.hideSection(ALL_SECTIONS);
396     }
397 
398     private void bindHandlers() {
399 
400         admincentralEventBus.addHandler(ContentChangedEvent.class, new ContentChangedEvent.Handler() {
401 
402             @Override
403             public void onContentChanged(ContentChangedEvent event) {
404                 JcrItemId itemId = (JcrItemId) event.getItemId();
405                 if (itemId.getWorkspace().equals(RepositoryConstants.WEBSITE)) {
406                     // Check if the node still exist
407                     try {
408                         String currentNodePath = getCurrentLocation().getNodePath();
409                         if (!MgnlContext.getJCRSession(RepositoryConstants.WEBSITE).nodeExists(currentNodePath)) {
410                             getSubAppContext().close();
411                         }
412                     } catch (RepositoryException e) {
413                         log.warn("Could not determine if currently edited page exists", e);
414                     }
415                 }
416             }
417         });
418 
419         subAppEventBus.addHandler(ComponentMoveEvent.class, new ComponentMoveEvent.Handler() {
420             @Override
421             public void onMove(ComponentMoveEvent event) {
422                 if (event.isStart()) {
423                     actionbarPresenter.disable(PageEditorListener.ACTION_START_MOVE_COMPONENT);
424                     actionbarPresenter.enable(PageEditorListener.ACTION_CANCEL_MOVE_COMPONENT);
425                 } else {
426                     actionbarPresenter.enable(PageEditorListener.ACTION_START_MOVE_COMPONENT);
427                     actionbarPresenter.disable(PageEditorListener.ACTION_CANCEL_MOVE_COMPONENT);
428                 }
429             }
430         });
431 
432         subAppEventBus.addHandler(NodeSelectedEvent.class, new NodeSelectedEvent.Handler() {
433 
434             @Override
435             public void onItemSelected(NodeSelectedEvent event) {
436                 AbstractElement element = event.getElement();
437                 updateActionbar(element);
438             }
439         });
440     }
441 
442     @Override
443     public void onActionbarItemClicked(String actionName) {
444         prepareAndExecutePagesEditorAction(actionName);
445     }
446 
447     protected void prepareAndExecutePagesEditorAction(String actionName) {
448         AbstractElement selectedElement = pageEditorPresenter.getSelectedElement();
449         try {
450             Session session = MgnlContext.getJCRSession(workspace);
451             final javax.jcr.Item item = session.getItem(selectedElement.getPath());
452             actionExecutor.execute(actionName, new JcrNodeAdapter((Node) item), selectedElement, pageEditorPresenter);
453 
454         } catch (RepositoryException e) {
455             Message error = new Message(MessageType.ERROR, i18n.translate("pages.pagesEditorSubapp.actionExecutionException.message"), e.getMessage());
456             log.error("An error occurred while executing action [{}]", actionName, e);
457             appContext.sendLocalMessage(error);
458         } catch (ActionExecutionException e) {
459             Message error = new Message(MessageType.ERROR, i18n.translate("pages.pagesEditorSubapp.actionExecutionException.message"), e.getMessage());
460             log.error("An error occurred while executing action [{}]", actionName, e);
461             appContext.sendLocalMessage(error);
462         }
463     }
464 
465     @Override
466     public void languageSelected(Locale locale) {
467         if (locale != null && !locale.equals(currentLocale)) {
468             this.currentLocale = locale;
469             if (i18NAuthoringSupport instanceof DefaultI18NAuthoringSupport) {
470                 ((DefaultI18NAuthoringSupport) i18NAuthoringSupport).setAuthorLocale(locale);
471             }
472             doGoToLocation(getCurrentLocation());
473         }
474     }
475 
476     @Override
477     public void platformSelected(PlatformType platformType) {
478         if (platformType != null && !platformType.equals(targetPreviewPlatform)) {
479             this.targetPreviewPlatform = platformType;
480             doGoToLocation(getCurrentLocation());
481         }
482     }
483 
484     /**
485      * This method has package visibility for testing purposes only.
486      */
487     final PageEditorParameters getParameters() {
488         return parameters;
489     }
490 
491     private boolean isDeletedNode(String workspace, String path) {
492         Node node = SessionUtil.getNode(workspace, path);
493         try {
494             if (node != null) {
495                 return NodeUtil.hasMixin(node, NodeTypes.Deleted.NAME);
496             } else {
497                 return false;
498             }
499         } catch (RepositoryException re) {
500             log.warn("Not able to check if node has MixIn");
501             return false;
502         }
503     }
504 
505     private void updateActionbar(final AbstractElement element) {
506         String path = element.getPath();
507         String dialog = element.getDialog();
508         if (StringUtils.isEmpty(path)) {
509             path = "/";
510         }
511         hideAllSections();
512 
513         if (isDeletedNode(workspace, path)) {
514             actionbarPresenter.showSection(SECTION_PAGE_DELETE);
515 
516             if (!getCurrentLocation().hasVersion()) {
517                 actionbarPresenter.enable("showPreviousVersion");
518             } else {
519                 actionbarPresenter.disable("showPreviousVersion");
520             }
521             actionbarPresenter.enable("restorePreviousVersion");
522             actionbarPresenter.enable("activateDelete");
523 
524         } else {
525 
526             ActionbarSectionDefinition def;
527             String sectionName = null;
528 
529             if (element instanceof PageElement) {
530 
531                 if (!path.equals(parameters.getNodePath())) {
532                     updateNodePath(path);
533                 }
534 
535                 if (parameters.isPreview()) {
536                     sectionName = SECTION_PAGE_PREVIEW;
537                 } else {
538                     sectionName = SECTION_PAGE;
539                 }
540 
541             } else if (element instanceof AreaElement) {
542                 if (dialog == null) {
543                     sectionName = SECTION_AREA;
544                 } else {
545                     sectionName = SECTION_EDITABLE_AREA;
546                 }
547 
548             } else if (element instanceof ComponentElement) {
549                 sectionName = SECTION_COMPONENT;
550             }
551 
552             if (sectionName != null) {
553                 actionbarPresenter.showSection(sectionName);
554                 def = getActionbarSectionDefinitionByName(sectionName);
555                 enableOrDisableActions(def, path);
556             }
557             updateActions();
558         }
559     }
560 
561     private void enableOrDisableActions(final ActionbarSectionDefinition def, final String path) {
562         if (def == null) {
563             return;
564         }
565         // Evaluate availability of each action within the section
566         Node node = SessionUtil.getNode(workspace, path);
567         for (ActionbarGroupDefinition groupDefinition : def.getGroups()) {
568             for (ActionbarItemDefinition itemDefinition : groupDefinition.getItems()) {
569 
570                 String actionName = itemDefinition.getName();
571                 AvailabilityDefinition availabilityDefinition = actionExecutor.getActionDefinition(actionName).getAvailability();
572                 try {
573                     Object itemId = JcrItemUtil.getItemId(node);
574                     if (availabilityChecker.isAvailable(availabilityDefinition, Arrays.asList(itemId))) {
575                         actionbarPresenter.enable(actionName);
576                     } else {
577                         actionbarPresenter.disable(actionName);
578                     }
579                 } catch (RepositoryException e) {
580                     log.error("Failed to update action availability: " + e.getMessage(), e);
581                 }
582             }
583         }
584     }
585 
586     private ActionbarSectionDefinition getActionbarSectionDefinitionByName(final String sectionName) {
587         ActionbarDefinition actionbarDefinition = ((DetailSubAppDescriptor) getSubAppContext().getSubAppDescriptor()).getActionbar();
588         if (actionbarDefinition == null) {
589             log.warn("No actionbar definition found, returning null");
590             return null;
591         }
592 
593         for (ActionbarSectionDefinition section : actionbarDefinition.getSections()) {
594             if (section.getName().equals(sectionName)) {
595                 return section;
596             }
597         }
598         log.warn("No section named [{}] found, returning null", sectionName);
599         return null;
600     }
601 
602     @Override
603     public void onEscape() {
604         if (pageEditorPresenter.isMoving()) {
605             pageEditorPresenter.onAction(PageEditorListener.ACTION_CANCEL_MOVE_COMPONENT);
606         } else {
607             // Toggle preview and edit mode.
608             if (getCurrentLocation().getViewType().equals(DetailView.ViewType.EDIT)) {
609                 prepareAndExecutePagesEditorAction(PageEditorListener.ACTION_VIEW_PREVIEW);
610             } else {
611                 prepareAndExecutePagesEditorAction(PageEditorListener.ACTION_VIEW_EDIT);
612             }
613         }
614     }
615 
616     protected String getWorkspace() {
617         return workspace;
618     }
619 
620 }