/* Copyright (c) 2006 Google 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 sample.gbase.recipe; import com.google.api.gbase.client.GoogleBaseService; import com.google.api.gbase.client.ServiceErrors; import com.google.gdata.util.ServiceException; import java.io.IOException; import java.util.HashSet; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Contains the names of the HTML input fields used to edit a recipe. * Has methods that are generally useful, for example for logging * or validating values. * Has methods to extract values from servlet context init parameters. * Has methods used for passing objects from a servlet to a JSP. */ public class RecipeUtil { public static final String ID_PARAMETER = "oid"; public static final String APPLICATION_NAME_PARAMETER = "applicationName"; public static final String TITLE_PARAMETER = "title"; public static final String URL_PARAMETER = "url"; public static final String DESCRIPTION_PARAMETER = "description"; public static final String MAIN_INGREDIENT_PARAMETER = "mainIngredient"; public static final String CUISINE_PARAMETER = "cuisine"; public static final String COOKING_TIME_PARAMETER = "cookingTime"; public static final String DEVELOPER_KEY_PARAMETER = "key"; public static final String COOKING_TIME_UNIT = "minutes"; public static final String RECIPE_ATTRIBUTE = "recipe"; public static final String RECIPESEARCH_ATTRIBUTE = "recipeSearch"; public static final String RECIPESEARCH_ERROR = "recipeSearchError"; public static final String RECIPESEARCH_ERROR_DESCRIPTION = "recipeSearchErrorDescription"; public static final String RECIPESEARCH_ERROR_OBJECT = "recipeSearchErrorService"; public static final String MESSAGE_ATTRIBUTE = "message"; public static final String RECIPE_ITEMTYPE_QUERY = "[item type : recipe | recipes]"; /** Pattern used for finding the unsupported characters in the query string.*/ private static final Pattern QUERY_REPLACE_PATTERN = Pattern.compile("\\p{Punct}"); public static final String ERROR_JSP = "/WEB-INF/recipeError.jsp"; /** * Builds a HashSet containing the specified values, * filtering the null and empty ones. * * @param values usually an array returned by request.getParameterValues() * @return a HashSet containing the nonempty values */ public static Set<String> validateValues(String[] values) { Set<String> valuesList = new HashSet<String>(); if (values != null) { for (String value : values) { value = cleanQueryString(value); if (value != null && ! "".equals(value)) { valuesList.add(value); } } } return valuesList; } /** * Cleans the {@code searchString} set by the user, by removing the special * punctuation characters not allowed directly in a query. * * @param searchString the string set by the user * @return the String to be used for executing the query to Google Base. */ public static String cleanQueryString(String searchString) { Matcher matcher = QUERY_REPLACE_PATTERN.matcher(searchString); return matcher.replaceAll(" ").trim(); } /** * Logs an exception in a convenient format, * using the log method of a servlet context. * * @param servlet the servlet used to log the exception * @param e exception to be logged */ public static void logServiceException(HttpServlet servlet, ServiceException e) { if (e.getResponseBody() != null) { // Log the full error message and response code. servlet.log(e.getMessage() + " " + e.getHttpErrorCodeOverride() + " " + e.getResponseContentType() + ": " + e.getResponseBody(), e); } } /** * Sets a RecipeSearch as an attribute of a HttpServletRequest. * * @param request a request that will be passed to a JSP * @param results the RecipeSearch, executed or not */ public static void setRecipeSearch(HttpServletRequest request, RecipeSearch results) { request.setAttribute(RECIPESEARCH_ATTRIBUTE, results); } /** * Gets from a HttpServletRequest a RecipeSearch that was previously set * using {@link #setRecipeSearch}. * If it is missing, a NullPointerException is thrown. * * @param request a request passed from a Servlet * @return a non-null RecipeSearch */ public static RecipeSearch getRecipeSearch(HttpServletRequest request) { RecipeSearch results = (RecipeSearch)request.getAttribute( RECIPESEARCH_ATTRIBUTE); if (null == results) { throw new NullPointerException("recipe search results are missing"); } return results; } /** * Gets the error message, or {@code null} if no error message was set in the * request. * * @param request the request in which the method will locate the error * @return the error message, or {@code null} if no message was set */ public static String getRecipeError(HttpServletRequest request) { return (String)request.getAttribute(RECIPESEARCH_ERROR); } /** * Gets the error message, or {@code null} if no error message was set in the * request. * * @param request the request in which the method will locate the error * @return the error message, or {@code null} if no message was set */ public static String getRecipeErrorDescription(HttpServletRequest request) { return (String)request.getAttribute(RECIPESEARCH_ERROR_DESCRIPTION); } /** * Gets the errors obtained from Google Base, or {@code null} if no service * error was set in the request. * * @param request the request in which the method will locate the error * @return the service errors, or {@code null} if no service errors were set */ public static ServiceErrors getRecipeErrorObject(HttpServletRequest request) { return (ServiceErrors)request.getAttribute(RECIPESEARCH_ERROR_OBJECT); } /** * Forwards the request to the error page, for displaying the specified * {@code errorMessage} and the {@code description}. No service errors will * be displayed. * * @param request the request object * @param response the response object * @param errorMessage the error message to be displayed * @param description the description of the error message, {@code null} if * no description should be displayed. * @throws ServletException * @throws IOException */ public static void forwardToErrorPage(HttpServletRequest request, HttpServletResponse response, String errorMessage) throws ServletException, IOException { request.setAttribute(RECIPESEARCH_ERROR, errorMessage); request.getRequestDispatcher(ERROR_JSP).forward(request, response); } /** * Forwards the request to the error page, for displaying the information * contained by the {@code se} parameter. This method registers the service * errors too, using a {@link ServiceErrors} object. * * @param request the request object * @param response the response object * @param se the service error containing the information for the error page * @throws ServletException * @throws IOException */ public static void forwardToErrorPage(HttpServletRequest request, HttpServletResponse response, ServiceException se) throws ServletException, IOException { request.setAttribute(RECIPESEARCH_ERROR, se.getMessage()); request.setAttribute(RECIPESEARCH_ERROR_DESCRIPTION, se.getResponseBody()); request.setAttribute(RECIPESEARCH_ERROR_OBJECT, new ServiceErrors(se)); request.getRequestDispatcher(ERROR_JSP).forward(request, response); } /** * Gets the GoogleBaseService object created by {@link AuthenticationFilter} * or creates a new one if <code>AuthenticationFilter</code> has not been * applied yet. * * @param req * @param servletContext * @return a GoogleBaseService object */ public static GoogleBaseService getGoogleBaseService(HttpServletRequest req, ServletContext servletContext) { GoogleBaseService service; service = (GoogleBaseService) req.getAttribute( AuthenticationFilter.SERVICE_ATTRIBUTE); if (service == null) { service = new GoogleBaseService( servletContext.getInitParameter(APPLICATION_NAME_PARAMETER), servletContext.getInitParameter(DEVELOPER_KEY_PARAMETER)); req.setAttribute(AuthenticationFilter.SERVICE_ATTRIBUTE, service); } return service; } /** * Gets a MostUsedValues that was previously set using * {@link #setMostUsedValues}. * * @param servletContext * @return a non-null initialized MostUsedValues */ public static MostUsedValues getMostUsedValues(ServletContext servletContext) throws ServletException { MostUsedValues mostUsedValues = (MostUsedValues) servletContext.getAttribute(RecipeListener.MOST_USED_VALUES_ATTRIBUTE); if (null == mostUsedValues) { throw new ServletException("Most used values cache is missing"); } return mostUsedValues; } public static void setMostUsedValues(ServletContext servletContext, MostUsedValues mostUsedValues) { servletContext.setAttribute(RecipeListener.MOST_USED_VALUES_ATTRIBUTE, mostUsedValues); } }