Java tutorial
/** * Copyright (C) 2012 JBoss Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jboss.dashboard.ui; import org.jboss.dashboard.LocaleManager; import org.jboss.dashboard.commons.cdi.CDIBeanLocator; import org.jboss.dashboard.database.hibernate.HibernateTxFragment; import org.jboss.dashboard.security.BackOfficePermission; import org.jboss.dashboard.security.UIPermission; import org.jboss.dashboard.ui.components.BeanHandler; import org.jboss.dashboard.ui.config.ConfigurationTree; import org.jboss.dashboard.ui.config.ConfigurationTreeStatus; import org.jboss.dashboard.ui.controller.CommandRequest; import org.jboss.dashboard.ui.controller.RequestContext; import org.jboss.dashboard.ui.config.Tree; import org.jboss.dashboard.ui.config.TreeNode; import org.jboss.dashboard.ui.config.TreeStatus; import org.jboss.dashboard.workspace.Panel; import org.jboss.dashboard.workspace.Workspace; import org.jboss.dashboard.workspace.WorkspaceImpl; import org.jboss.dashboard.workspace.Section; import org.jboss.dashboard.security.WorkspacePermission; import org.jboss.dashboard.security.PanelPermission; import org.jboss.dashboard.security.SectionPermission; import org.jboss.dashboard.users.LogoutSurvivor; import org.jboss.dashboard.users.UserStatus; import org.hibernate.Session; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import java.util.*; import javax.enterprise.context.SessionScoped; import javax.inject.Inject; import javax.inject.Named; /** * Manager class that handles the user navigation. It is used to store in which workspace and page is located the user */ @SessionScoped @Named("navigation_manager") public class NavigationManager extends BeanHandler implements LogoutSurvivor { /** * Retrieves the NavigationManager instance for the current session */ public static NavigationManager lookup() { return CDIBeanLocator.getBeanByType(NavigationManager.class); } @Inject private transient Logger log; public static final String WORKSPACE_ID = "workspace"; public static final String PAGE_ID = "page"; // Used to cache in request current workspace and page public static final String CURRENT_WORKSPACE_ATTR = "currentWorkspace"; public static final String CURRENT_PAGE_ATTR = "currentPage"; private String currentWorkspaceId; private Long currentSectionId; private boolean showingConfig = false; private boolean userRequiresLoginBackdoor = false; public boolean isUserRequiresLoginBackdoor() { return userRequiresLoginBackdoor; } public void setUserRequiresLoginBackdoor(boolean userRequiresLoginBackdoor) { this.userRequiresLoginBackdoor = userRequiresLoginBackdoor; } public boolean isShowingConfig() { return showingConfig; } public void setShowingConfig(boolean showingConfig) { this.showingConfig = showingConfig; } public UserStatus getUserStatus() { return UserStatus.lookup(); } public String getCurrentWorkspaceId() { return currentWorkspaceId; } public Long getCurrentSectionId() { return currentSectionId; } protected void setCurrentSectionId(Long id) { this.currentSectionId = id; } public synchronized void setCurrentWorkspace(WorkspaceImpl workspace) { setCurrentWorkspaceId(workspace == null ? null : workspace.getDbid()); } protected synchronized void setCurrentWorkspaceId(String workspaceId) { boolean workspaceChanged = false; if (workspaceId != null) { if (!workspaceId.equals(getCurrentWorkspaceId())) { pageLeft(doGetCurrentSection()); currentWorkspaceId = workspaceId; setCurrentSectionId(null); repositionSection(); // Set a current section by default. if (!isValidUbication()) setCurrentSectionId(null); clearRequestCache(); workspaceChanged = true; } } else { pageLeft(doGetCurrentSection()); currentWorkspaceId = null; setCurrentSectionId(null); clearRequestCache(); workspaceChanged = true; } if (workspaceChanged) { getUserStatus().invalidateUserPrincipals(); } } public boolean userIsAdminInCurrentWorkspace() { if (getUserStatus().isRootUser()) return true; Workspace currentWorkspace = getCurrentWorkspace(); if (currentWorkspace == null) return false; WorkspacePermission workspacePerm = WorkspacePermission.newInstance(currentWorkspace, WorkspacePermission.ACTION_ADMIN); return getUserStatus().hasPermission(workspacePerm); } public boolean isAdminBarVisible() { if (getUserStatus().isRootUser()) return true; Workspace currentWorkspace = getCurrentWorkspace(); if (currentWorkspace == null) return false; UserStatus us = getUserStatus(); UIPermission perm = WorkspacePermission.newInstance(currentWorkspace, WorkspacePermission.ACTION_ADMIN); if (us.hasPermission(perm)) return true; perm = WorkspacePermission.newInstance(currentWorkspace, WorkspacePermission.ACTION_CREATE_PAGE); if (us.hasPermission(perm)) return true; perm = WorkspacePermission.newInstance(currentWorkspace, WorkspacePermission.ACTION_EDIT); if (us.hasPermission(perm)) return true; perm = WorkspacePermission.newInstance(currentWorkspace, WorkspacePermission.ACTION_DELETE); if (us.hasPermission(perm)) return true; perm = BackOfficePermission.newInstance(currentWorkspace, BackOfficePermission.ACTION_CREATE_WORKSPACE); if (us.hasPermission(perm)) return true; perm = BackOfficePermission.newInstance(currentWorkspace, BackOfficePermission.ACTION_USE_GRAPHIC_RESOURCES); if (us.hasPermission(perm)) return true; perm = BackOfficePermission.newInstance(currentWorkspace, BackOfficePermission.ACTION_USE_PERMISSIONS); if (us.hasPermission(perm)) return true; return false; } public synchronized void setCurrentSection(Section section) { if (section != null) { if (section.getId() != null && !section.getDbid().equals(getCurrentSectionId())) { pageLeft(doGetCurrentSection()); setCurrentWorkspace(section.getWorkspace()); } setCurrentSectionId(section.getDbid()); } else { pageLeft(doGetCurrentSection()); setCurrentSectionId(null); currentWorkspaceId = null; } clearRequestCache(); //logCurrentStatus("setCurrentSection"); } protected void pageLeft(Section oldSection) { if (oldSection != null) { if (log.isDebugEnabled()) log.debug("Invalidating panelSessions in section " + oldSection.getId() + " from workspace " + oldSection.getWorkspace().getId()); for (Panel panel : oldSection.getPanels()) { panel.pageLeft(); } } } private void logCurrentStatus(String method) { try { log.info(method + " set currentWorkspaceId = " + currentWorkspaceId + " (" + (currentWorkspaceId != null ? LocaleManager.lookup() .localize(UIServices.lookup().getWorkspacesManager() .getWorkspace(currentWorkspaceId).getName()) : "") + ") currentSectionId = " + getCurrentSectionId() + "(" + (getCurrentSectionId() != null ? LocaleManager.lookup().localize(doGetCurrentSection().getTitle()) : "") + ")"); log.info("From... ", new Exception()); } catch (Exception e) { log.error("Error: ", e); } } protected void clearRequestCache() { RequestContext rqctx = RequestContext.lookup(); rqctx.getRequest().getRequestObject().removeAttribute(CURRENT_WORKSPACE_ATTR); rqctx.getRequest().getRequestObject().removeAttribute(CURRENT_PAGE_ATTR); } protected WorkspaceImpl getCurrentWorkspaceFromCache() { RequestContext rqctx = RequestContext.lookup(); WorkspaceImpl currentWorkspace = (WorkspaceImpl) rqctx.getRequest().getRequestObject() .getAttribute(CURRENT_WORKSPACE_ATTR); return currentWorkspace; } protected Section getCurrentPageFromCache() { RequestContext rqctx = RequestContext.lookup(); Section currentPage = (Section) rqctx.getRequest().getRequestObject().getAttribute(CURRENT_PAGE_ATTR); return currentPage; } /** * Performance improvement that fixes current navigation status, ensuring it won't change * until the end of the request. Current workspace and page are stored as request attributes, and * subsequent calls to getCurrentWorkspace and getCurrentSection get the cached version. * Called just before rendering the page, as rendering shouldn't * modify navigation location */ public void freezeNavigationStatus() { RequestContext rqctx = RequestContext.lookup(); rqctx.getRequest().getRequestObject().setAttribute(CURRENT_WORKSPACE_ATTR, getCurrentWorkspace()); rqctx.getRequest().getRequestObject().setAttribute(CURRENT_PAGE_ATTR, getCurrentSection()); } /** * Get the current workspace, repositioning the navigation in case it is not correct. * * @return current workspace after checking ubication is correct */ public synchronized WorkspaceImpl getCurrentWorkspace() { WorkspaceImpl currentWorkspace = getCurrentWorkspaceFromCache(); if (currentWorkspace != null) return currentWorkspace; if (!isValidUbication()) reposition(); currentWorkspace = doGetCurrentWorkspace(); return currentWorkspace; } /** * Get the current page, repositioning the navigation in case it is not correct. * * @return current page after checking ubication is correct */ public synchronized Section getCurrentSection() { // First check in request cache Section currentSection = getCurrentPageFromCache(); if (currentSection != null) return currentSection; if (!isValidUbication()) reposition(); currentSection = doGetCurrentSection(); return currentSection; } public WorkspaceImpl doGetCurrentWorkspace() { try { if (currentWorkspaceId != null) { return (WorkspaceImpl) UIServices.lookup().getWorkspacesManager().getWorkspace(currentWorkspaceId); } } catch (Exception e) { log.error("Error: ", e); } return null; } public Section doGetCurrentSection() { try { if (getCurrentSectionId() == null) return null; final Section[] sectionToReturn = new Section[] { null }; new HibernateTxFragment() { protected void txFragment(Session session) throws Exception { sectionToReturn[0] = (Section) session.get(Section.class, getCurrentSectionId()); } }.execute(); return sectionToReturn[0]; } catch (Exception e) { log.error("Error: ", e); return null; } } protected boolean isValidUbication() { if (userRequiresLoginBackdoor) return true; if (getCurrentWorkspaceId() == null) return false; WorkspacePermission workspacePerm = WorkspacePermission.newInstance(doGetCurrentWorkspace(), WorkspacePermission.ACTION_LOGIN); if (!getUserStatus().hasPermission(workspacePerm)) return false; if (getCurrentSectionId() != null) { SectionPermission sectionPerm = SectionPermission.newInstance(doGetCurrentSection(), SectionPermission.ACTION_VIEW); if (!getUserStatus().hasPermission(sectionPerm)) return false; } else { // Config is valid when there is no current section, but user can admin workspace. WorkspacePermission adminWorkspacePerm = WorkspacePermission.newInstance(doGetCurrentWorkspace(), WorkspacePermission.ACTION_ADMIN); if (!getUserStatus().hasPermission(adminWorkspacePerm)) return false; } // All security checks are met. return true; } /** * Calculate new ubication */ protected void reposition() { try { List<String> workspaceIds = getSortedWorkspaceIds(); for (String wsId : workspaceIds) { currentWorkspaceId = wsId; repositionSection(); if (isValidUbication()) return; } // We've tried all workspaces and sections without success. Try all workspaces without sections, in case admin is logging in. for (String wsId : workspaceIds) { currentWorkspaceId = wsId; clearRequestCache(); if (isValidUbication()) return; } } catch (Exception e) { log.error("Error: ", e); } // We've tried all. No valid ubication. Show login page. currentWorkspaceId = null; setCurrentSectionId(null); clearRequestCache(); log.warn("Couldn't reposition navigation to a valid ubication."); } protected void repositionSection() { WorkspaceImpl workspace = doGetCurrentWorkspace(); Section[] pages = workspace.getAllRootSections(); // First search root sections in order for (int i = 0; i < pages.length; i++) { Section page = pages[i]; setCurrentSectionId(page.getDbid()); clearRequestCache(); if (isValidUbication()) return; } // Then, the rest of sections pages = workspace.getAllSections(); for (int i = 0; i < pages.length; i++) { Section page = pages[i]; if (!page.isRoot()) { setCurrentSectionId(page.getId()); clearRequestCache(); if (isValidUbication()) return; } } } protected List<String> getSortedWorkspaceIds() throws Exception { // Order workspaces as follows: current workspace, default workspace, other sorted by id on order to make home search algorithm determinist. Set<String> availableWorkspaces = new TreeSet<String>( UIServices.lookup().getWorkspacesManager().getAllWorkspacesIdentifiers()); List<String> workspaceIds = new ArrayList<String>(availableWorkspaces.size()); if (currentWorkspaceId != null) { availableWorkspaces.remove(currentWorkspaceId); workspaceIds.add(currentWorkspaceId); } Workspace defaultWorkspace = UIServices.lookup().getWorkspacesManager().getDefaultWorkspace(); if (defaultWorkspace != null) { availableWorkspaces.remove(defaultWorkspace.getId()); workspaceIds.add(defaultWorkspace.getId()); } workspaceIds.addAll(availableWorkspaces); return workspaceIds; } // ACTIONS /** * Cancels config mode */ public void actionCancelConfig(CommandRequest request) throws Exception { setShowingConfig(false); } public void actionNavigateToWorkspace(CommandRequest request) throws Exception { String workspaceId = request.getParameter(WORKSPACE_ID); if (workspaceId != null) { setCurrentWorkspaceId(workspaceId); } } public void actionNavigateToPage(CommandRequest request) throws Exception { String workspaceId = request.getParameter(WORKSPACE_ID); String pageId = request.getParameter(PAGE_ID); if (workspaceId != null && pageId != null) { WorkspaceImpl workspace = (WorkspaceImpl) UIServices.lookup().getWorkspacesManager() .getWorkspace(workspaceId); if (workspace != null) { setCurrentSection(workspace.getSection(Long.decode(pageId))); } } } /** * Go to config page */ public void actionConfig(CommandRequest request) throws Exception { setShowingConfig(true); Tree tree = CDIBeanLocator.getBeanByType(ConfigurationTree.class); TreeStatus treeStatus = CDIBeanLocator.getBeanByType(ConfigurationTreeStatus.class); TreeNode node = treeStatus.getLastEditedNode(tree); if (node != null) node.onEdit(); } /** * Determine if it is possible to navigate to given url for current user. * * @param url Url to go * @return true if it is possible to navigate to given url for current user. */ public boolean isLocationReadable(String url) { NavigationPoint navigationPoint = new NavigationPoint(url); try { return isLocationReadable(navigationPoint); } catch (Exception e) { log.error("Error: ", e); return false; } } /** * Determine if it is possible to navigate to given point for current user. * * @param navigationPoint point to go * @return true if it is possible to navigate to given point for current user. */ public boolean isLocationReadable(NavigationPoint navigationPoint) throws Exception { Workspace workspace = navigationPoint.getWorkspace(); if (workspace != null) { WorkspacePermission workspacePerm = WorkspacePermission.newInstance(workspace, WorkspacePermission.ACTION_LOGIN); if (!getUserStatus().hasPermission(workspacePerm)) { // No access permission in workspace return false; } Section section = navigationPoint.getPage(); if (section != null) { SectionPermission sectionPerm = SectionPermission.newInstance(section, SectionPermission.ACTION_VIEW); if (!getUserStatus().hasPermission(sectionPerm)) { // No access permission in page return false; } Panel panel = navigationPoint.getPanel(); String actionName = navigationPoint.getActionName(); if (panel != null) { PanelPermission panelPerm = PanelPermission.newInstance(panel, PanelPermission.ACTION_VIEW); if (!getUserStatus().hasPermission(panelPerm)) { // No view permission in panel return false; } if (!StringUtils.isEmpty(actionName)) { // Can I invoke the action? return panel.getProvider().getDriver().canInvokeAction(panel, actionName); } else { // No action? strange anyway return true; } } else { // No panel... return true; } } else { // Page doesn't exist !!! return false; } } else { // Workspace doesn't exist !!! return false; } } }