Java tutorial
/** * Copyright (c) 2009--2014 Red Hat, Inc. * * This software is licensed to you under the GNU General Public License, * version 2 (GPLv2). There is NO WARRANTY for this software, express or * implied, including the implied warranties of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 * along with this software; if not, see * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. * * Red Hat trademarks are not licensed under GPLv2. No permission is * granted to use or replicate Red Hat trademarks that are incorporated * in this software or its documentation. */ package com.redhat.rhn.frontend.struts; import com.redhat.rhn.common.localization.LocalizationService; import com.redhat.rhn.common.security.PermissionException; import com.redhat.rhn.domain.errata.Errata; import com.redhat.rhn.domain.kickstart.KickstartData; import com.redhat.rhn.domain.kickstart.KickstartFactory; import com.redhat.rhn.domain.org.Org; import com.redhat.rhn.domain.org.OrgFactory; import com.redhat.rhn.domain.role.RoleFactory; import com.redhat.rhn.domain.server.ManagedServerGroup; import com.redhat.rhn.domain.server.Server; import com.redhat.rhn.domain.session.WebSession; import com.redhat.rhn.domain.token.ActivationKey; import com.redhat.rhn.domain.token.ActivationKeyFactory; import com.redhat.rhn.domain.token.TokenFactory; import com.redhat.rhn.domain.user.User; import com.redhat.rhn.domain.user.UserFactory; import com.redhat.rhn.frontend.action.common.BadParameterException; import com.redhat.rhn.frontend.servlets.PxtSessionDelegate; import com.redhat.rhn.frontend.servlets.PxtSessionDelegateFactory; import com.redhat.rhn.manager.errata.ErrataManager; import com.redhat.rhn.manager.system.ServerGroupManager; import com.redhat.rhn.manager.system.SystemManager; import com.redhat.rhn.manager.user.UserManager; import org.apache.commons.lang.StringUtils; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.TreeMap; import javax.servlet.http.HttpServletRequest; /** * Utility methods for accessing various objects in the scope * of a request. The objects are created by looking at request * parameters for their ID's and then retrieving them from the * appropriate manager. * * @version $Rev$ */ public class RequestContext { // Request IDs go here. public static final String LABEL = "label"; public static final String USER_ID = "uid"; public static final String ORG_ID = "oid"; public static final String ERRATA_ID = "eid"; public static final String SID = "sid"; public static final String SID1 = "sid_1"; public static final String CID = "cid"; public static final String PRID = "prid"; public static final String COBBLER_ID = "cobbler_id"; public static final String FILTER_STRING = "filter_string"; public static final String PREVIOUS_FILTER_STRING = "prev_filter_value"; public static final String LIST_DISPLAY_EXPORT = "lde"; public static final String TOKEN_ID = "tid"; public static final String LIST_SORT = "sort"; public static final String SORT_ORDER = "order"; public static final String SORT_ASC = "asc"; public static final String SORT_DESC = "desc"; public static final String METHOD_ID = "cmid"; public static final String KICKSTART_ID = "ksid"; public static final String KSTREE_ID = "kstid"; public static final String KEY_ID = "key_id"; public static final String FILE_LIST_ID = "file_list_id"; public static final String KICKSTART_SCRIPT_ID = "kssid"; public static final String CONFIG_FILE_ID = "cfid"; public static final String SERVER_GROUP_ID = "sgid"; public static final String NAME = "name"; // Request Attributes go here: public static final String ACTIVATION_KEY = "activationkey"; public static final String KICKSTART = "ksdata"; public static final String ORG = "org"; public static final String SYSTEM = "system"; public static final String SERVER_GROUP = "systemgroup"; public static final String KICKSTART_SESSION = "ksession"; public static final String REQUESTED_URI = "requestedUri"; public static final String KSTREE = "kstree"; public static final String KICKSTART_STATE_DESC = "statedescription"; public static final String PAGE_LIST = "pageList"; public static final String DISPATCH = "dispatch"; public static final String CONFIRM = "confirm"; public static final String FILTER_KEY = "Go"; public static final String NO_SCRIPT = "noscript"; public static final String MODE = "mode"; public static final String POST = "POST"; private final HttpServletRequest request; private User currentUser; /** * Create a new context object that looks up objects * from the request <code>req0</code> * * @param req0 the request from which to look up objects */ public RequestContext(HttpServletRequest req0) { request = req0; } /** * Return the request that is used by the context for * object lookup * @return the current request */ public HttpServletRequest getRequest() { return request; } /** * Return the currently LOGged in user that is making the * request. * * @return the currently LOGged in user that is making the * request. */ public User getCurrentUser() { if (currentUser == null) { currentUser = getLoggedInUser(); } return currentUser; } /** * Get the currently LOGged in User from the pxt session. * * @return Currently LOGged in User. */ private User getLoggedInUser() { /* * XMLRPC calls handle authentication on their own. We return null * because findUserSession is never going to correctly find an XMLRPC * user's sessions. */ if (request.getRequestURI().startsWith("/rhn/rpc/api")) { return null; } PxtSessionDelegateFactory factory = PxtSessionDelegateFactory.getInstance(); PxtSessionDelegate pxtDelegate = factory.newPxtSessionDelegate(); Long uid = pxtDelegate.getWebUserId(request); return ((uid == null) ? null : UserFactory.lookupById(uid)); } /** * Get the user on the request based on the "uid" paramter. Used * when editing Users other than the LOGged in user. * * @return User found. */ // TODO Write unit tests for getUserFromUIDParameter() public User getUserFromUIDParameter() { Long uid = getParamAsLong(USER_ID); User user = UserManager.lookupUser(getCurrentUser(), uid); return user; } /** * Return the erratum with the ID given by the request's * {@link #ERRATA_ID}parameter * @return the erratum with the ID given by the request's * {@link #ERRATA_ID}parameter * @throws com.redhat.rhn.frontend.action.common.BadParameterException if the request * does not contain the required parameter, or if the parameter can not be converted * to a <code>Long</code> * @throws IllegalArgumentException if no erratum with the ID given in * the request can be found */ public Errata lookupErratum() throws BadParameterException, IllegalArgumentException { Long errataId = getRequiredParam(ERRATA_ID); Errata retval = ErrataManager.lookupErrata(errataId, getCurrentUser()); assertObjectFound(retval, errataId, ERRATA_ID, "erratum"); return retval; } /** * Return the server with the ID given by the request's {@link #SID} * parameter * @return the server with the ID given by the request's {@link #SID} * parameter * @throws com.redhat.rhn.frontend.action.common.BadParameterException if the request * does not contain the required parameter, or if the parameter can not be converted * to a <code>Long</code> * @throws IllegalArgumentException if no server with the ID given in the * request can be found */ // TODO Write unit tests for lookupServer() public Server lookupServer() throws BadParameterException, IllegalArgumentException { Long serverId = getRequiredParam(SID); Server retval = SystemManager.lookupByIdAndUser(serverId, getCurrentUser()); assertObjectFound(retval, serverId, SID, "server"); return retval; } /** * Return the server with the ID given by the request's {@link #SID} * parameter. Puts the server in the request attributes. * @return the server with the ID given by the request's {@link #SID} * parameter * @throws com.redhat.rhn.frontend.action.common.BadParameterException if the request * does not contain the required parameter, or if the parameter can not be converted * to a <code>Long</code> * @throws IllegalArgumentException if no server with the ID given in the * request can be found */ // TODO Write unit tests for lookupServer() public Server lookupAndBindServer() throws BadParameterException, IllegalArgumentException { if (request.getAttribute(SYSTEM) == null) { request.setAttribute(SYSTEM, lookupServer()); } return (Server) request.getAttribute(SYSTEM); } /** * Return the Activation Key with the ID given by the request's {@link #TOKEN_ID} * parameter. Puts the activation key in the request attributes. * @return the Activation Key with the ID given by the request's {@link #TOKEN_ID} * parameter * @throws com.redhat.rhn.frontend.action.common.BadParameterException if the request * does not contain the required parameter, or if the parameter can not be converted * to a <code>Long</code> * @throws IllegalArgumentException if no Activation Key with the ID given in the * request can be found */ public ActivationKey lookupAndBindActivationKey() { if (request.getAttribute(ACTIVATION_KEY) == null) { Long id = getRequiredParam(TOKEN_ID); ActivationKey key = ActivationKeyFactory .lookupByToken(TokenFactory.lookup(id, getCurrentUser().getOrg())); request.setAttribute(ACTIVATION_KEY, key); } return (ActivationKey) request.getAttribute(ACTIVATION_KEY); } /** * Return the Org with the ID given by the request's {@link #TOKEN_ID} * parameter. Puts the Orgin the request attributes. * @return the Org with the ID given by the request's {@link #TOKEN_ID} * parameter * @throws com.redhat.rhn.frontend.action.common.BadParameterException if the request * does not contain the required parameter, or if the parameter can not be converted * to a <code>Long</code> * @throws IllegalArgumentException if no Org with the ID given in the * request can be found */ public Org lookupAndBindOrg() { if (request.getAttribute(ORG) == null) { Long id = getRequiredParam(ORG_ID); Org org = null; if (getCurrentUser().hasRole(RoleFactory.SAT_ADMIN)) { org = OrgFactory.lookupById(id); } assertObjectFound(org, id, ORG_ID, "Org"); request.setAttribute(ORG, org); } return (Org) request.getAttribute(ORG); } /** * Return the KickstartData with the ID given by the request's {@link #KICKSTART_ID} * parameter. Puts the activation key in the request attributes. * @return the KickstartDatay with the ID given by the request's {@link #KICKSTART_ID} * parameter * @throws com.redhat.rhn.frontend.action.common.BadParameterException if the request * does not contain the required parameter, or if the parameter can not be converted * to a <code>Long</code> * @throws IllegalArgumentException if no Kickstart Data with the ID given in the * request can be found */ public KickstartData lookupAndBindKickstartData() { if (request.getAttribute(KICKSTART) == null) { Long id = getRequiredParam(KICKSTART_ID); KickstartData data = KickstartFactory.lookupKickstartDataByIdAndOrg(getCurrentUser().getOrg(), id); assertObjectFound(data, id, KICKSTART_ID, "Kickstart Data"); request.setAttribute(KICKSTART, data); } return (KickstartData) request.getAttribute(KICKSTART); } /** * Return the ServerGroup with the ID given by the request's {@link #SERVER_GROUP_ID} * parameter. Puts the ServerGroupin the request attributes. * @return the ServerGroup with the ID given by the request's {@link #SERVER_GROUP_ID} * @throws IllegalArgumentException if no ServerGroup with the ID given in the * request can be found */ public ManagedServerGroup lookupAndBindServerGroup() { if (request.getAttribute(SERVER_GROUP) == null) { Long id = getRequiredParam(SERVER_GROUP_ID); ServerGroupManager manager = ServerGroupManager.getInstance(); User user = getCurrentUser(); ManagedServerGroup sg = manager.lookup(id, user); if (sg == null) { String msg = "No server group with id = [%s] found."; throw new IllegalArgumentException(String.format(msg, id)); } request.setAttribute(SERVER_GROUP, sg); } return (ManagedServerGroup) request.getAttribute(SERVER_GROUP); } private void assertObjectFound(Object obj, Long id, String paramName, String objName) { if (obj == null) { throw new IllegalArgumentException("Could not find " + objName + " with ID " + paramName + "=" + id); } } /** * Get the parameter <code>paramName</code> from the request. If * <code>required</code> is <code>true</code>, this method will never * return <code>null</code>; instead, it will throw a * <code>BadParameterException</code> if the parameter is not in the * request. If <code>required</code> is <code>false</code>, the return * value can be <code>null</code>. * @param paramName the name of the parameter * @param required whether this parameter must be present * @return the parameter value or null if not required. */ // TODO Refactor getParam(String, boolean) // This method is awkward in that if the required flag is set, an exception may be // throw. No exception will be thrown though if the flag is not set. Refactor the // method by removing the boolean argument, and adding a new method, // getRequiredParam(String) which throws the exception public String getParam(String paramName, boolean required) { String param = request.getParameter(paramName); if (required && param == null) { throw new BadParameterException("Required parameter [" + paramName + "] is null"); } return param; } /** * Get whether a parameter is present in the request. * @param name The parameter name. * @return True if the named parameter is in the request. */ public boolean hasParam(String name) { return (request.getParameter(name) != null); } /** * Returns the value of the parameter named param of the request as a Long. * * This method will trim the String as well to check for "" and " ". If the * String is "1234 " it will return a Long with value: 1234. If the String * is "" and required is true it will treat it like a null value and throw * BadParameterException. * * @param param Name of request parameter to be converted. * * @throws BadParameterException if the parameter <code>param</code> can * not be converted to a Long * * @return the value of the parameter named param of the request as a Long. * <code>null</code> if the parameter is blank. */ public Long getParamAsLong(String param) { String p = request.getParameter(param); Long result = null; // Make sure we catch empty strings as well if (!StringUtils.isBlank(p)) { try { result = Long.valueOf(p.trim()); } catch (NumberFormatException e) { BadParameterException bad = new BadParameterException( "The parameter " + param + " must be a Long, but was '" + p + "'", e); bad.setStackTrace(e.getStackTrace()); throw bad; } } return result; } /** * Get the parameter <code>paramName</code> from the request and convert * it to a <code>Long</code>. A BadParameterException is thrown if the * parameter is not present in the request or can not be converted. * @param paramName the name of the parameter * @return the parameter value converted to a <code>Long</code> */ public Long getRequiredParam(String paramName) { Long result = getParamAsLong(paramName); if (result == null) { // TODO: One day, BadParameterException will take a message and we // can do // throw new BadParameterException("The parameter " + param + // " is required and must be a Long, but was '" + p +"'"); // That one day has finally arrived! And the coders rejoiced. throw new BadParameterException( "The parameter " + paramName + " is required, when accessing " + request.getRequestURI()); } return result; } /** * Get the parameter <code>paramName</code> from the request * A BadParameterException is thrown if the * parameter is not present in the request or is empty * @param paramName the name of the parameter * @return the parameter value converted to a <code>Long</code> */ public String getRequiredParamAsString(String paramName) { String p = request.getParameter(paramName); if (StringUtils.isBlank(p)) { throw new BadParameterException("The parameter " + paramName + " is required."); } return p; } /** * Get the parameter <code>paramName</code> from the request * A BadParameterException is thrown if the * parameter is not present in the request or is empty * @param paramName the name of the parameter * @return the parameter value converted to a <code>Long</code> */ public Long getRequiredParamAsLong(String paramName) { Long p = getParamAsLong(paramName); if (p == null) { throw new BadParameterException("The parameter " + paramName + " is required."); } return p; } /** * If this current Request includes a parameter to indicate the User is attempting * to produce an export of viewable data then return true. * * Only for use with the Old list tag's exporter. The new list tag doesn't use * "lde" as a parameter, it uses lde_unique(listName). * * @return if this request includes an export param */ // TODO Write unit tests for isRequestedExport() public boolean isRequestedExport() { String lde = request.getParameter(LIST_DISPLAY_EXPORT); return (lde != null && lde.equals("1")); } /** * Retrieves the currently Logged in user's pxt session. If it doesn't exist, a new * session is created. * * @return The currently Logged in user's pxt session. If it doesn't exist, a new * session is created. */ public WebSession getWebSession() { PxtSessionDelegateFactory factory = PxtSessionDelegateFactory.getInstance(); PxtSessionDelegate pxtDelegate = factory.newPxtSessionDelegate(); return pxtDelegate.getPxtSession(request); } /** * Get the value for the lowest part of the list to display. This is * protected so that the setup actions can get this value for redirecting * the request. * @return the lowest value to display. */ public String processPagination() { String lower; if (request.getParameter("First") != null || request.getParameter("First.x") != null) { lower = request.getParameter("first_lower"); } else if (request.getParameter("Prev") != null || request.getParameter("Prev.x") != null) { lower = request.getParameter("prev_lower"); } else if (request.getParameter("Next") != null || request.getParameter("Next.x") != null) { lower = request.getParameter("next_lower"); } else if (request.getParameter("Last") != null || request.getParameter("Last.x") != null) { lower = request.getParameter("last_lower"); } else { lower = request.getParameter("lower"); } return lower; } /** * Creates a hashmap with pagination vars added. * @return Returns a new hashmap containing the parameters */ // TODO Write unit tests for makeParamMapWithPagination() public Map<String, Object> makeParamMapWithPagination() { Map<String, Object> params = new HashMap<String, Object>(); String lower = processPagination(); if (lower != null && lower.length() > 0 && StringUtils.isNumeric(lower)) { params.put("lower", lower); } return params; } /** * Take a HttpServletRequest and build a self-link to the requested page and * include a name/value parameter. Won't re-append the parameter if adding * it is re-attempted. * * @param name of parameter to add * @param value value of paramter * @return url that is built. */ public String buildPageLink(String name, String value) { StringBuilder page = new StringBuilder((String) request.getAttribute("requestedUri")); if (request.getQueryString() != null) { int index = request.getQueryString().indexOf(name + "="); // if we already have this param in the query string we have to // reset it to the new value if (index >= 0) { Map<String, String> parammap = new TreeMap<String, String>(); String[] params = StringUtils.split(request.getQueryString(), '&'); // Convert the parameters into a map so we can // easily replace the value and reformat the query string. for (String param : params) { String[] nameval = StringUtils.split(param, '='); parammap.put(nameval[0], nameval[1]); } parammap.remove(name); parammap.put(name, value); page.append("?"); Iterator<String> i = parammap.keySet().iterator(); while (i.hasNext()) { String key = i.next(); page.append(key + "=" + parammap.get(key)); if (i.hasNext()) { page.append("&"); } } } else { page.append("?" + name + "=" + value + "&" + request.getQueryString()); return page.toString(); } } else { page.append("?" + name + "=" + value); } return page.toString(); } /** * Copies an attached parameter to the attributes list * This is useful when we want to propagate a parameter * that was passed to us, like sid * @param paramId the param to copy */ public void copyParamToAttributes(String paramId) { HttpServletRequest req = getRequest(); String param = req.getParameter(paramId); if (param != null) { req.setAttribute(paramId, param); } } /** * Examines a submit action of the name "dispatch" * with the i18n'ed value of the key passed in. * This is useful for example in the following * scenario.. Lets say you have the following html input * <input type = "submit" name="dispatch" * value="rhn:localize('copy.to.local')"/> * Lets suppose 'copy.to.local' was the message key * you'd pass to localizationService if i18n'ing... * Lets suppose the en_US value of copy.to.local = Copy To Local * When the button is submitted, IE will submit * "dispatch=Copy To Local" * This means in the submit action we need to i18n * the button value again when doing a lookup... * This method is supposed to help there.. * One can just do * if (requestContext.wasDispatched("copy.to.local")) * Alternatively one can also extend * RhnLookupDispatchAction to achieve the same. * @param messageKey the message key to be i18ned. * @return true if a "dispatch" parameter * was set and that equaled the i18ned * value of the message key */ public boolean wasDispatched(String messageKey) { HttpServletRequest req = getRequest(); if (req.getParameter(DISPATCH) == null) { return false; } String action = req.getParameter(DISPATCH); LocalizationService ls = LocalizationService.getInstance(); return ls.getMessage(messageKey).equals(action); } /** * Returns if javascript is enabled/not in this page. * This needs to be used in conjuction with rhn noscript * taglib.. If you need to use this method add the following line * to your jsp after the form, so that it gets submitted * <rhn:noscript/> * @return true if java script is enabled, false other wise. */ public boolean isJavaScriptEnabled() { return !Boolean.TRUE.toString().equals(getParam(NO_SCRIPT, false)); } /** * Simple util to check if the Form on a page was submitted * This needs to be used in conjuction with rhn submitted * taglib.. If you need to use this method add the following line * to your jsp after the form, so that it gets submitted * <rhn:submitted/> * @return true if the form was submitted, false other wise */ public boolean isSubmitted() { return Boolean.TRUE.toString().equals(getParam(RhnAction.SUBMITTED, false)); } /** * verify that the request is a POST and throw an exception otherwise. */ public void requirePost() { if (!POST.equals(request.getMethod())) { throw new PermissionException(LocalizationService.getInstance().getMessage("request.post.check")); } } }