package org.sigmah.shared.servlet; /* * #%L * Sigmah * %% * Copyright (C) 2010 - 2016 URD * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * 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, see * <http://www.gnu.org/licenses/gpl-3.0.html>. * #L% */ import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.sigmah.client.page.PageManager; import org.sigmah.client.page.RequestParameter; import org.sigmah.client.security.AuthenticationProvider; import org.sigmah.client.util.ClientUtils; import org.sigmah.shared.servlet.ServletConstants.Servlet; import org.sigmah.shared.servlet.ServletConstants.ServletMethod; import com.google.gwt.http.client.URL; /** * Convenient servlet URL builder. * * @author Denis Colliot (dcolliot@ideia.fr) */ public final class ServletUrlBuilder { // Injected resources. private final AuthenticationProvider authenticationProvider; private final PageManager pageManager; // Servlet URL required resources. private final Servlet servlet; private final ServletMethod servletMethod; private final Map<String, List<String>> parameters; /** * Builds a new {@code ServletUrlBuilder} with the given parameters. * * @param authenticationProvider * @param pageManager * @param servlet * The servlet (required). * @param method * The servlet method to execute (required). */ public ServletUrlBuilder(AuthenticationProvider authenticationProvider, PageManager pageManager, final Servlet servlet, final ServletMethod method) { this.authenticationProvider = authenticationProvider; this.pageManager = pageManager; this.servlet = servlet; this.servletMethod = method; this.parameters = new HashMap<String, List<String>>(); } /** * <p> * Adds a parameter to the request URL. * If a previous parameter was already present with the given {@code key}, its value is override. * </p> * <p> * Empty and {@code null} values are skipped. * {@code String.valueOf(value)} is used for each preserved value. * </p> * * @param key * The parameter key. * @param values * The parameter value(s). * @return The current instance of the builder. */ public ServletUrlBuilder addParameter(final RequestParameter key, final Object... values) { return addParameter(key, values != null ? Arrays.asList(values) : null); } /** * <p> * Adds a parameter to the request URL. * If a previous parameter was already present with the given {@code key}, its value is override. * </p> * <p> * Empty and {@code null} values are skipped. * {@code String.valueOf(value)} is used for each preserved value. * </p> * * @param key * The parameter key. * @param values * The parameter value(s). * @return The current instance of the builder. */ public ServletUrlBuilder addParameter(final RequestParameter key, final List<? extends Object> values) { return addParameter(key != null ? key.getRequestName() : null, values); } /** * <p> * Adds a parameter to the request URL. * If a previous parameter was already present with the given {@code key}, its value is override. * </p> * <p> * Empty and {@code null} values are skipped. * {@code String.valueOf(value)} is used for each preserved value. * </p> * * @param key * The parameter key. * @param values * The parameter value(s). * @return The current instance of the builder. */ ServletUrlBuilder addParameter(final String key, final List<? extends Object> values) { if (ClientUtils.isBlank(key) || ClientUtils.isEmpty(values)) { return this; } final List<String> stringValues = new ArrayList<String>(); for (final Object value : values) { if (value == null || ClientUtils.isBlank(value.toString())) { continue; } stringValues.add(String.valueOf(value)); } parameters.put(key, stringValues); return this; } /** * Removes the given parameter {@code key} from the request URL. * * @param key * The parameter key. * @return the current instance of the builder. */ public ServletUrlBuilder removeParameter(final RequestParameter key) { if (key != null) { parameters.remove(key.getRequestName()); } return this; } /** * <p> * Builds the URL with all its parameters. * </p> * <p> * Necessary parameters (<em>authentication token</em>, etc.) are automatically added into the request parameters. * </p> * * @return The generated URL. */ private String buildUrl() { // Adds session token id in parameters map. addParameter(ServletConstants.AUTHENTICATION_TOKEN, ClientUtils.toList(authenticationProvider.get().getAuthenticationToken())); addParameter(ServletConstants.SERVLET_METHOD, ClientUtils.toList(servletMethod.getName())); addParameter(ServletConstants.ORIGIN_PAGE_TOKEN, ClientUtils.toList(pageManager.getCurrentPageToken())); addParameter(ServletConstants.RANDOM, ClientUtils.toList(Math.random())); final StringBuilder builder = new StringBuilder(); builder.append(servlet.getUrl()).append('?'); final Iterator<String> keyIt = parameters.keySet().iterator(); while (keyIt.hasNext()) { final String key = keyIt.next(); final String encodedKey = URL.encodeQueryString(key); final List<String> params = parameters.get(key); builder.append(encodedKey).append('='); if (ClientUtils.isNotEmpty(params)) { // Key value(s). final Iterator<String> paramIt = params.iterator(); while (paramIt.hasNext()) { builder.append(URL.encodeQueryString(paramIt.next())); if (paramIt.hasNext()) { builder.append('&').append(encodedKey).append('='); } } } if (keyIt.hasNext()) { builder.append('&'); } } return builder.toString(); } /** * Displays the full URL with all its parameters. * * @return The displayed URL. * @see #buildUrl() */ @Override public String toString() { return buildUrl(); } }