/** * NOTE: This copyright does *not* cover user programs that use HQ * program services by normal system calls through the application * program interfaces provided as part of the Hyperic Plug-in Development * Kit or the Hyperic Client Development Kit - this is merely considered * normal use of the program, and does *not* fall under the heading of * "derived work". * * Copyright (C) [2009-2010], VMware, Inc. * This file is part of HQ. * * HQ is free software; you can redistribute it and/or modify * it under the terms version 2 of the GNU General Public License as * published by the Free Software Foundation. This program is distributed * in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA. * */ package org.hyperic.hq.ui.util; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.text.StringCharacterIterator; import java.util.HashMap; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hyperic.hq.appdef.shared.AppdefEntityID; import org.hyperic.hq.authz.server.session.AuthzSubject; import org.hyperic.hq.bizapp.shared.AuthzBoss; import org.hyperic.hq.context.Bootstrap; import org.hyperic.hq.ui.Constants; import org.hyperic.hq.ui.WebUser; import org.hyperic.hq.ui.action.resource.common.monitor.visibility.ViewChartFormNG; import org.hyperic.hq.ui.server.session.DashboardConfig; import org.hyperic.hq.ui.server.session.RoleDashboardConfig; import org.hyperic.hq.ui.server.session.UserDashboardConfig; import org.hyperic.hq.ui.shared.DashboardManager; import org.hyperic.util.config.ConfigResponse; abstract public class SaveChartToDashboardUtil { private static Log log = LogFactory.getLog(SaveChartToDashboardUtil.class .getName()); private static Pattern AEID_PATTERN_A = Pattern.compile( ".*[?&]type=(\\d+).*&rid=(\\d+).*", Pattern.CASE_INSENSITIVE); private static Pattern AEID_PATTERN_B = Pattern.compile( ".*[?&]rid=(\\d+).*&type=(\\d+).*", Pattern.CASE_INSENSITIVE); private static Pattern AEID_PATTERN_C = Pattern.compile( ".*[?&]eid=(\\d:\\d+).*", Pattern.CASE_INSENSITIVE); public enum ResultCode { SUCCESS, DUPLICATE, ERROR } // Moving this logic into a util method as it's being used by more than one // class /* * public static ResultCode saveChartToDashboard(ServletContext ctx, * HttpServletRequest request, ActionForward success, ViewChartForm * chartForm, AppdefEntityID adeId, String chartName, boolean isEE, * DashboardManager dashboardManager) throws Exception { AuthzBoss boss = * Bootstrap.getBean(AuthzBoss.class); WebUser user = * RequestUtils.getWebUser(request); String[] dashboardIds = * request.getParameterValues(Constants.DASHBOARD_ID_PARAM); String url = * generateChartUrl(success, chartForm, adeId, isEE); ResultCode result = * ResultCode.ERROR; // Initialize as error, so that we can be proved wrong * * if (dashboardIds != null) { for (int x = 0; x < dashboardIds.length; x++) * { Integer dashId = Integer.valueOf(dashboardIds[x]); DashboardConfig * dashboardConfig = dashboardManager.findDashboard(dashId, user, boss); * * result = addChartToDashboard(forHTMLTag(chartName), url, dashboardConfig, * boss, user, request); * * // Something's wrong, break out if (result.equals(ResultCode.ERROR)) * break; } } else { AuthzSubject me = * boss.findSubjectById(user.getSessionId(), user.getSubject().getId()); * DashboardConfig dashboardConfig = dashboardManager.getUserDashboard(me, * me); * * result = addChartToDashboard(forHTMLTag(chartName), url, dashboardConfig, * boss, user, request); } * * return result; } */ // Moving this logic into a util method as it's being used by more than one // class public static ResultCode saveChartToDashboard(ServletContext ctx, HttpServletRequest request, String success, ViewChartFormNG chartForm, AppdefEntityID adeId, String chartName, boolean isEE, DashboardManager dashboardManager) throws Exception { AuthzBoss boss = Bootstrap.getBean(AuthzBoss.class); WebUser user = RequestUtils.getWebUser(request); String[] dashboardIds = request .getParameterValues(Constants.DASHBOARD_ID_PARAM); String url = generateChartUrl(success, chartForm, adeId, isEE); ResultCode result = ResultCode.ERROR; // Initialize as error, so that we // can be proved wrong if (dashboardIds != null) { for (int x = 0; x < dashboardIds.length; x++) { Integer dashId = Integer.valueOf(dashboardIds[x]); DashboardConfig dashboardConfig = dashboardManager .findDashboard(dashId, user, boss); result = addChartToDashboard(forHTMLTag(chartName), url, dashboardConfig, boss, user, request); // Something's wrong, break out if (result.equals(ResultCode.ERROR)) break; } } else { AuthzSubject me = boss.findSubjectById(user.getSessionId(), user .getSubject().getId()); DashboardConfig dashboardConfig = dashboardManager .getUserDashboard(me, me); result = addChartToDashboard(forHTMLTag(chartName), url, dashboardConfig, boss, user, request); } return result; } public static AppdefEntityID getAppdefEntityIDFromChartUrl(String url) { AppdefEntityID id = null; Matcher matcher = AEID_PATTERN_A.matcher(url); if (matcher.matches()) { id = new AppdefEntityID(matcher.group(1) + ':' + matcher.group(2)); } else { matcher = AEID_PATTERN_B.matcher(url); if (matcher.matches()) { id = new AppdefEntityID(matcher.group(2) + ':' + matcher.group(1)); } } if (id == null) { matcher = AEID_PATTERN_C.matcher(url); if (matcher.matches()) { id = new AppdefEntityID(matcher.group(1)); } } if (id == null) { try { matcher = AEID_PATTERN_C.matcher(URLDecoder .decode(url, "UTF-8")); if (matcher.matches()) { id = new AppdefEntityID(matcher.group(1)); } } catch (UnsupportedEncodingException e) { // could not decode, it's OK the URL is incorrect } } return id; } /* * private static String generateChartUrl(ActionForward success, * ViewChartForm chartForm, AppdefEntityID adeId, boolean isEE) throws * Exception { // build the chart URL Map<String, Object> chartParams = new * HashMap<String, Object>(); * * chartParams.put("m", chartForm.getM()); chartParams.put("showPeak", new * Boolean(chartForm.getShowPeak())); chartParams.put("showValues", new * Boolean(chartForm.getShowValues())); chartParams.put("showAverage", new * Boolean(chartForm.getShowAverage())); chartParams.put("showLow", new * Boolean(chartForm.getShowLow())); chartParams.put("threshold", * chartForm.getThreshold()); * * if (isEE) { chartParams.put("showHighRange", new * Boolean(chartForm.getShowHighRange())); chartParams.put("showLowRange", * new Boolean(chartForm.getShowLowRange())); chartParams.put("showEvents", * new Boolean(chartForm.getShowEvents())); chartParams.put("showBaseline", * new Boolean(chartForm.getShowBaseline())); } * * if(adeId.isGroup()) { chartParams.put( "mode", chartForm.getMode() ); * chartParams.put( "r", chartForm.getResourceIds() ); } * * if (chartForm.getCtype() != null && chartForm.getCtype().length() > 0) { * chartParams.put( "mode", chartForm.getMode() ); chartParams.put( "ctype", * chartForm.getCtype() ); } * * return ActionUtils.changeUrl(success.getPath(), chartParams); } */ private static String generateChartUrl(String success, ViewChartFormNG chartForm, AppdefEntityID adeId, boolean isEE) throws Exception { // build the chart URL Map<String, Object> chartParams = new HashMap<String, Object>(); chartParams.put("m", chartForm.getM()); chartParams.put("showPeak", new Boolean(chartForm.getShowPeak())); chartParams.put("showValues", new Boolean(chartForm.getShowValues())); chartParams.put("showAverage", new Boolean(chartForm.getShowAverage())); chartParams.put("showLow", new Boolean(chartForm.getShowLow())); chartParams.put("threshold", chartForm.getThreshold()); if (isEE) { chartParams.put("showHighRange", new Boolean(chartForm.getShowHighRange())); chartParams.put("showLowRange", new Boolean(chartForm.getShowLowRange())); chartParams.put("showEvents", new Boolean(chartForm.getShowEvents())); chartParams.put("showBaseline", new Boolean(chartForm.getShowBaseline())); } if (adeId.isGroup()) { chartParams.put("mode", chartForm.getMode()); chartParams.put("r", chartForm.getResourceIds()); } if (chartForm.getCtype() != null && chartForm.getCtype().length() > 0) { chartParams.put("mode", chartForm.getMode()); chartParams.put("ctype", chartForm.getCtype()); } int mLocation = success.indexOf("m="); if (mLocation > -1) { int nextAmp = success.indexOf("&", mLocation); String tmpUrl = success.substring(0, mLocation); if (nextAmp > -1) { tmpUrl += success.substring(nextAmp); } success = tmpUrl; } return ActionUtils.changeUrl(success, chartParams); } private static ResultCode addChartToDashboard(String name, String url, DashboardConfig dashboardConfig, AuthzBoss boss, WebUser user, HttpServletRequest request) throws Exception { ConfigResponse configResponse = dashboardConfig.getConfig(); String charts = configResponse.getValue( Constants.USER_DASHBOARD_CHARTS, ""); // make sure its not a duplicate chart if (charts.indexOf(name + "," + url) > -1) { // If it's a dup, it's already there and our work is done return ResultCode.DUPLICATE; } // Now see if the name is already used String chartname = name; for (int i = 2; charts.indexOf(chartname + ",") > -1; i++) { // Hard-code name to be a number in parenthesis to differentiate chartname = name + " (" + i + ")"; } charts += Constants.DASHBOARD_DELIMITER + chartname + "," + url; configResponse.setValue(Constants.USER_DASHBOARD_CHARTS, charts); if (dashboardConfig instanceof RoleDashboardConfig) { RoleDashboardConfig roleDashboardConfig = (RoleDashboardConfig) dashboardConfig; Bootstrap.getBean(ConfigurationProxy.class) .setRoleDashboardPreferences(configResponse, user, roleDashboardConfig.getRole()); } else if (dashboardConfig instanceof UserDashboardConfig) { Bootstrap.getBean(ConfigurationProxy.class) .setUserDashboardPreferences(configResponse, user); } else { // Neither role or user dashboard. This shouldn't happen, but if it // somehow does, treat it as an error. return ResultCode.ERROR; } if (log.isDebugEnabled()) { log.debug("Saving chart to dashboard ...\n\tchartName=" + name + "\n\turl=" + url); } // success return ResultCode.SUCCESS; } // -------------------------------------------------------------------------------- // -- private helpers // -------------------------------------------------------------------------------- // forHTMLTag is copy-n-pasted from: // http://www.javapractices.com/Topic96.cjp // used to be in our util.StringUtil, we should really use jakarta's // StringEscapeUtils.escapeHTML() /** * Replace characters having special meaning <em>inside</em> HTML tags with * their escaped equivalents, using character entities such as * <tt>'&'</tt>. * * <P> * The escaped characters are : * <ul> * <li>< * <li>> * <li>" * <li>' * <li>\ * <li>& * </ul> * * <P> * This method ensures that arbitrary text appearing inside a tag does not * "confuse" the tag. For example, <tt>HREF='Blah.do?Page=1&Sort=ASC'</tt> * does not comply with strict HTML because of the ampersand, and should be * changed to <tt>HREF='Blah.do?Page=1&Sort=ASC'</tt>. This is commonly * seen in building query strings. (In JSTL, the c:url tag performs this * task automatically.) */ private static String forHTMLTag(String aTagFragment) { final StringBuffer result = new StringBuffer(); final StringCharacterIterator iterator = new StringCharacterIterator( aTagFragment); for (char character = iterator.current(); character != StringCharacterIterator.DONE; character = iterator .next()) { switch (character) { case '<': result.append("<"); break; case '>': result.append(">"); break; case '\"': result.append("""); break; case '\'': result.append("'"); break; case '\\': result.append("\"); break; case '&': result.append("&"); break; case '|': result.append("|"); break; case ',': result.append(","); break; default: // the char is not a special one add it to the result as is result.append(character); break; } } return result.toString(); } }