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.controller.requestChain; import org.apache.commons.lang3.StringUtils; import org.jboss.dashboard.LocaleManager; import org.jboss.dashboard.annotation.config.Config; import org.jboss.dashboard.ui.NavigationManager; import org.jboss.dashboard.ui.UIServices; import org.jboss.dashboard.ui.components.URLMarkupGenerator; import org.jboss.dashboard.ui.controller.RequestContext; 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.SectionPermission; import org.jboss.dashboard.users.UserStatus; import org.slf4j.Logger; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import javax.servlet.http.HttpServletRequest; import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.StringTokenizer; @ApplicationScoped public class FriendlyUrlProcessor extends AbstractChainProcessor { @Inject private transient Logger log; @Inject @Config("true") private boolean showLoginBackDoorOnPermissionDenied; public static final String FRIENDLY_MAPPING = "/" + URLMarkupGenerator.FRIENDLY_PREFIX; public static final String LOCALE_PARAMETER = "locale"; public boolean isShowLoginBackDoorOnPermissionDenied() { return showLoginBackDoorOnPermissionDenied; } /** * Make required processing of request. * * @return true if processing must continue, false otherwise. */ public boolean processRequest() throws Exception { HttpServletRequest request = getHttpRequest(); String servletPath = request.getServletPath(); NavigationManager navigationManager = NavigationManager.lookup(); UserStatus userStatus = UserStatus.lookup(); RequestContext requestContext = RequestContext.lookup(); // ---- Apply locale information, -------------- LocaleManager localeManager = LocaleManager.lookup(); // First check if a locale parameter is present in the URI query string. Locale localeToSet = null; String localeParam = request.getParameter(LOCALE_PARAMETER); if (localeParam != null && localeParam.trim().length() > 0) { localeToSet = localeManager.getLocaleById(localeParam); if (localeToSet != null) { localeManager.setCurrentLocale(localeToSet); } } // No friendly -> nothing to do. if (!servletPath.startsWith(FRIENDLY_MAPPING)) return true; String contextPath = request.getContextPath(); requestContext.consumeURIPart(FRIENDLY_MAPPING); navigationManager.setShowingConfig(false); String requestUri = request.getRequestURI(); String relativeUri = requestUri.substring(contextPath == null ? 0 : (contextPath.length())); relativeUri = relativeUri.substring(servletPath == null ? 0 : (servletPath.length())); // Empty URI -> nothing to do. if (StringUtils.isBlank(relativeUri)) return true; /* * Check if the locale information is in the URI value in order to consume it. * Locale information is expected in the URI after "/workspace". * Examples: * - /workspace/en/.... * - /workspace/es/.... * - /workspace/en_ES/.... * NOTES: * - Available locales matched in the URI parameter are obtained from JVM available locales. * - If the locale is found as platform available, the locale is set. * - Otherwise, do nothing, the locale used will be the last one set or default. * - In both cases URI locale parameter will be consumed. */ int startLocaleUri = relativeUri.indexOf("/"); int endLocaleUri = relativeUri.indexOf("/", startLocaleUri + 1); endLocaleUri = endLocaleUri > 0 ? endLocaleUri : relativeUri.length(); String localeUri = relativeUri.substring(startLocaleUri + 1, endLocaleUri); Locale uriLocale = localeManager.getLocaleById(localeUri); if (uriLocale != null) { requestContext.consumeURIPart("/" + localeUri); relativeUri = relativeUri.substring(localeUri.length() + 1); // Use the locale specified in the URI value only if no locale specified in the qeury string. if (localeToSet == null) localeManager.setCurrentLocale(uriLocale); } // Tokenize the friendly URI. StringTokenizer tokenizer = new StringTokenizer(relativeUri, "/", false); List tokens = new ArrayList(); int i = 0; while (tokenizer.hasMoreTokens()) { String token = tokenizer.nextToken(); if (i < 2) { tokens.add(token); i++; } else if (tokens.size() == 2) { tokens.add("/" + token); } else { tokens.set(2, tokens.get(2) + "/" + token); } } try { // Get the target workspace/section spcified. log.debug("Tokens=" + tokens); String workspaceCandidate = null; String sectionCandidate = null; if (tokens.size() > 0) workspaceCandidate = (String) tokens.get(0); if (tokens.size() > 1) sectionCandidate = (String) tokens.get(1); if (log.isDebugEnabled()) { log.debug("workspaceCandidate=" + workspaceCandidate); log.debug("sectionCandidate=" + sectionCandidate); } WorkspaceImpl workspace = null; Section section = null; if (workspaceCandidate != null) { workspace = (WorkspaceImpl) UIServices.lookup().getWorkspacesManager() .getWorkspace(workspaceCandidate); if (workspace == null) workspace = (WorkspaceImpl) UIServices.lookup().getWorkspacesManager() .getWorkspaceByUrl(workspaceCandidate); } if (workspace != null && sectionCandidate != null) { try { section = workspace.getSection(Long.decode(sectionCandidate)); } catch (NumberFormatException nfe) { section = workspace.getSectionByUrl(sectionCandidate); } } // Check the user has access permissions to the target workspace. if (workspace != null && section == null) { try { Workspace currentWorkspace = navigationManager.getCurrentWorkspace(); log.debug("currentWorkspace = " + (currentWorkspace == null ? "null" : currentWorkspace.getId()) + " workspaceCandidate = " + workspaceCandidate); if (!workspace.equals(currentWorkspace)) { WorkspacePermission workspacePerm = WorkspacePermission.newInstance(workspace, WorkspacePermission.ACTION_LOGIN); if (userStatus.hasPermission(workspacePerm)) { navigationManager.setCurrentWorkspace(workspace); log.debug("SessionManager.setWorkspace(" + workspace.getId() + ")"); } else { if (log.isDebugEnabled()) log.debug("User has no " + WorkspacePermission.ACTION_LOGIN + " permission in workspace " + workspaceCandidate); if (isShowLoginBackDoorOnPermissionDenied()) { navigationManager.setUserRequiresLoginBackdoor(true); navigationManager.setCurrentWorkspace(workspace); } } } requestContext.consumeURIPart("/" + workspaceCandidate); } catch (Exception e) { log.error("Cannot set current workspace.", e); } } // Check the user has access permissions to the target section. else if (section != null) { try { if (!section.equals(navigationManager.getCurrentSection())) { WorkspacePermission workspacePerm = WorkspacePermission.newInstance(section.getWorkspace(), WorkspacePermission.ACTION_LOGIN); SectionPermission sectionPerm = SectionPermission.newInstance(section, SectionPermission.ACTION_VIEW); if (userStatus.hasPermission(workspacePerm) && userStatus.hasPermission(sectionPerm)) { if (log.isDebugEnabled()) log.debug("SessionManager.setSection(" + section.getId() + ")"); navigationManager.setCurrentSection(section); } else { if (log.isDebugEnabled()) log.debug("User has no " + WorkspacePermission.ACTION_LOGIN + " permission in workspace " + workspaceCandidate); if (isShowLoginBackDoorOnPermissionDenied()) { navigationManager.setUserRequiresLoginBackdoor(true); navigationManager.setCurrentSection(section); } } } requestContext.consumeURIPart("/" + workspaceCandidate); requestContext.consumeURIPart("/" + sectionCandidate); } catch (Exception e) { log.error("Cannot set current section.", e); } } } catch (Exception e) { log.error("Exception processing friendly URI", e); } return true; } }