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.components; import org.jboss.dashboard.LocaleManager; import org.jboss.dashboard.commons.cdi.CDIBeanLocator; import org.jboss.dashboard.ui.controller.requestChain.CSRFTokenGenerator; import org.jboss.dashboard.ui.controller.requestChain.CSRFTokenProcessor; import org.jboss.dashboard.workspace.Panel; import org.jboss.dashboard.workspace.Parameters; import org.jboss.dashboard.workspace.Section; import org.jboss.dashboard.workspace.WorkspaceImpl; import org.jboss.dashboard.ui.HTTPSettings; import org.jboss.dashboard.ui.controller.RequestContext; import org.jboss.dashboard.ui.formatters.FactoryURL; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import javax.servlet.ServletRequest; import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.HashMap; import java.util.Iterator; import java.util.Map; /** * Generates the url markup for a Factory command. */ @ApplicationScoped public class URLMarkupGenerator { public static final String COMMAND_RUNNER = "Controller"; public static final String FRIENDLY_PREFIX = "workspace"; public static final String JSP_PREFIX = "jsp"; public static final String PARAM_SEPARATOR = "\u0026"; @Inject private transient Logger log; /** * Get a permanent link to a given action on a bean * * @param bean Bean handler that will perform the action * @param action Bean's method that will be invoked * @param params Extra parameters for link * @return A link url to a bean action, independent on the page. */ public String getPermanentLink(String bean, String action, Map params) { try { BeanHandler element = (BeanHandler) CDIBeanLocator.getBeanByNameOrType(bean); if (element == null) throw new RuntimeException("Bean '" + bean + "' not found."); StringBuffer sb = new StringBuffer(); String base = RequestContext.lookup().getRequest().getRequestObject().getContextPath() + "/" + COMMAND_RUNNER; sb.append(base).append("?"); params.put(FactoryURL.PARAMETER_BEAN, element.getBeanName()); params.put(FactoryURL.PARAMETER_ACTION, action); sb.append(getParamsMarkup(params)); element.setEnabledForActionHandling(true); return postProcessURL(sb).toString(); } catch (ClassCastException cce) { log.error("Bean " + bean + " is not a BeanHandler."); return "#"; } } /** * Get the base URI for any markup, that is, the base path plus the servlet mapping. Any uri * constructed on top of it will go to the Controller servlet * * @return the base URI for any markup */ public String getServletMapping() { StringBuffer buf = new StringBuffer(_getServletMapping()); return postProcessURL(buf).toString(); } protected String _getServletMapping() { HttpServletRequest request = RequestContext.lookup().getRequest().getRequestObject(); if (request != null) { return request.getContextPath() + "/" + COMMAND_RUNNER; } else { // Do the best we can, this is a relative URL that might not work if AJAX handler does not convert it to // absolute or a <base> tag is specified in the generated HTML return COMMAND_RUNNER; } } /** * Mapping to the controller servlet. By default it is Controller, but in case there is friendly url, can be * replaced by workspace/<friendly_url> It is NOT preceded by "/" * * @return Mapping to the controller servlet. */ public String getBaseURI() { // Avoid an extra Controller in URL when it is already friendly Panel panel = RequestContext.lookup().getActivePanel(); if (panel != null) { // There will be a friendly url here return getLinkToPage(panel.getSection(), true); } return getServletMapping(); } /** * Generate a link to a factory component action * * @param beanName Factory component that will perform the action * @param action Bean's property (method) that will be invoked * @param params Extra parameters for link * @return A link url to a bean action */ public String getMarkup(String beanName, String action, Map params) { try { if (params == null) params = new HashMap(); Panel panel = RequestContext.lookup().getActivePanel(); if (panel != null) { params.put(Parameters.DISPATCH_IDPANEL, panel.getPanelId()); params.put(Parameters.DISPATCH_ACTION, "_factory"); } StringBuffer sb = new StringBuffer(); sb.append(_getServletMapping()).append("?"); BeanHandler bean = (BeanHandler) CDIBeanLocator.getBeanByNameOrType(beanName); params.put(FactoryURL.PARAMETER_BEAN, bean.getBeanName()); params.put(FactoryURL.PARAMETER_ACTION, bean.getActionName(action)); sb.append(getParamsMarkup(params)); bean.setEnabledForActionHandling(true); return postProcessURL(sb).toString(); } catch (ClassCastException cce) { log.error("Bean " + beanName + " is not a BeanHandler."); return "#"; } } /** * Convert a parameter map (string->string) to its URL form name1=value1&name2=value2 ... * * @param params parameter map to process. * @return A String representation for the received parameter map */ public String getParamsMarkup(Map params) { StringBuffer sb = new StringBuffer(); for (Iterator it = params.keySet().iterator(); it.hasNext();) { String paramName = (String) it.next(); Object paramValue = params.get(paramName); sb.append(getParameterMarkup(paramName, paramValue)); if (it.hasNext()) { sb.append(PARAM_SEPARATOR); } } return sb.toString(); } protected String getParameterMarkup(String name, Object value) { StringBuffer sb = new StringBuffer(); try { HTTPSettings webSettings = HTTPSettings.lookup(); sb.append(URLEncoder.encode(name, webSettings.getEncoding())).append("=") .append(URLEncoder.encode(String.valueOf(value), webSettings.getEncoding())); } catch (UnsupportedEncodingException e) { log.error("Error: ", e); } return sb.toString(); } public String getContextHost(ServletRequest request) { StringBuffer sb = new StringBuffer(); String context = ((HttpServletRequest) request).getContextPath(); String protocol = request.getScheme(); while (context.startsWith("/")) context = context.substring(1); sb.append(protocol.toLowerCase()).append("://").append(request.getServerName()); if (request.getServerPort() != 80) { sb.append(":").append(request.getServerPort()); } return sb.toString(); } /** * Get the base href for current request * @param request * @return a String with the form http://host[:port]/[context/] * @throws IOException */ public String getBaseHref(ServletRequest request) throws IOException { StringBuffer sb = new StringBuffer(); String context = ((HttpServletRequest) request).getContextPath(); String protocol = request.getScheme(); while (context.startsWith("/")) { context = context.substring(1); } sb.append(protocol.toLowerCase()).append("://").append(request.getServerName()); if (request.getServerPort() != 80) { sb.append(":").append(request.getServerPort()); } sb.append("/"); if (!StringUtils.isEmpty(context)) { sb.append(context).append("/"); } return sb.toString(); } /** * Get an absolute url that leads to a given workspace * * @param workspace Workspace to take to * @param allowFriendly allow friendly url * @return an url that leads to a given workspace */ public String getLinkToWorkspace(WorkspaceImpl workspace, boolean allowFriendly) { return getLinkToWorkspace(workspace, allowFriendly, LocaleManager.currentLang()); } /** * Get an absolute url that leads to a given workspace in a given lang * * @param workspace Workspace to take to * @param allowFriendly allow friendly url * @return an url that leads to a given workspace */ public String getLinkToWorkspace(WorkspaceImpl workspace, boolean allowFriendly, String lang) { StringBuffer link = getRelativeLinkToWorkspace(workspace, allowFriendly, lang); return postProcessURL(link).toString(); } /** * Get an absolute url that leads to a given page * * @param page Page to take to * @param allowFriendly allow friendly url * @return an url that leads to a given workspace */ public String getLinkToPage(Section page, boolean allowFriendly) { return getLinkToPage(page, allowFriendly, LocaleManager.currentLang()); } /** * Get an absolute url that leads to a given page in a given lang * * @param page Page to take to * @param allowFriendly allow friendly url * @param lang lang to switch to * @return an url that leads to a given workspace */ public String getLinkToPage(Section page, boolean allowFriendly, String lang) { StringBuffer link = getRelativeLinkToPage(page, allowFriendly, lang); return postProcessURL(link).toString(); } protected StringBuffer getRelativeLinkToPage(Section page, boolean allowFriendly, String lang) { StringBuffer sb = new StringBuffer(); sb.append(getRelativeLinkToWorkspace(page.getWorkspace(), allowFriendly, lang)); String pageFriendlyUrl = page.getId().toString(); if (allowFriendly) { pageFriendlyUrl = StringUtils.defaultIfEmpty(page.getFriendlyUrl(), page.getId().toString()); } sb.append("/").append(pageFriendlyUrl); return sb; } protected StringBuffer getRelativeLinkToWorkspace(WorkspaceImpl workspace, boolean allowFriendly, String lang) { StringBuffer sb = new StringBuffer(); String friendlyUrl = workspace.getId(); if (allowFriendly) { friendlyUrl = StringUtils.defaultIfEmpty(workspace.getFriendlyUrl(), workspace.getId()); } sb.append(RequestContext.lookup().getRequest().getRequestObject().getContextPath() + "/" + FRIENDLY_PREFIX + "/").append(lang).append("/").append(friendlyUrl); return sb; } /** * Generate a link to the given JSP * @param jsp The JSP file path relative to the webapp root. * @param paramsMap Extra params to be added to the URL. */ public String getLinkToJsp(String jsp, Map paramsMap) { StringBuffer sb = new StringBuffer(); sb.append(RequestContext.lookup().getRequest().getRequestObject().getContextPath()); sb.append("/").append(JSP_PREFIX); if (!jsp.startsWith("/")) sb.append("/"); sb.append(jsp); if (paramsMap != null && !paramsMap.isEmpty()) { String paramsMarkup = getParamsMarkup(paramsMap); sb.append("?").append(paramsMarkup); } return postProcessURL(sb).toString(); } /** * Get an url that leads to a given panel action * * @param panel Page to take to * @param allowFriendly allow friendly url * @param action action to perform on panel * @param extraParams Aditional parameters * @return an url that leads to a given panel */ public String getLinkToPanelAction(Panel panel, String action, String extraParams, boolean allowFriendly) { StringBuffer sb = new StringBuffer(); Map paramsMap = new HashMap(); paramsMap.put(Parameters.DISPATCH_IDPANEL, panel.getPanelId()); paramsMap.put(Parameters.DISPATCH_ACTION, action); sb.append(getRelativeLinkToPage(panel.getSection(), allowFriendly, LocaleManager.currentLang())); sb.append("?"); String paramsMarkup = getParamsMarkup(paramsMap); sb.append(paramsMarkup); if (extraParams != null) { sb.append(PARAM_SEPARATOR).append(extraParams); } return postProcessURL(sb).toString(); } /** * Get an url that leads to a given panel action * * @param panel Page to take to * @param allowFriendly allow friendly url * @param action action to perform on panel * @return an url that leads to a given workspace */ public String getLinkToPanelAction(Panel panel, String action, boolean allowFriendly) { return getLinkToPanelAction(panel, action, null, allowFriendly); } /** * Apply a final post-processing on generated URLs in order to add some extra information such as CSRF tokens or * propagate some behavioural parameters via URL-rewriting. */ protected StringBuffer postProcessURL(StringBuffer url) { // Keep the embedded mode using URL rewriting. RequestContext reqCtx = RequestContext.lookup(); if (reqCtx != null) { HttpServletRequest request = reqCtx.getRequest().getRequestObject(); boolean embeddedMode = Boolean.parseBoolean(request.getParameter(Parameters.PARAM_EMBEDDED)); String embeddedParam = Parameters.PARAM_EMBEDDED + "=true"; if (embeddedMode && url.indexOf(embeddedParam) == -1) { url.append(url.indexOf("?") != -1 ? PARAM_SEPARATOR : "?"); url.append(embeddedParam); } } // Add the CSRF protection token if (CSRFTokenProcessor.lookup().isEnabled()) { CSRFTokenGenerator csrfTokenGenerator = CSRFTokenGenerator.lookup(); String token = csrfTokenGenerator.getLastToken(); url.append(url.indexOf("?") != -1 ? PARAM_SEPARATOR : "?"); url.append(csrfTokenGenerator.getTokenName()).append("=").append(token); } return url; } }