# BasePresenter.java

    /*
    ** Module   : BasePresenter.java
    ** Abstract : BasePresenter implements common business methods available for views.
    **
    ** Copyright (c) 2017, Golden Code Development Corporation.
    **
    ** -#- -I- --Date-- ----------------Description----------------------
    ** 001 SBI 20170601 Created initial version.
    */
    /*
    ** This program is free software: you can redistribute it and/or modify
    ** it under the terms of the GNU Affero 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 Affero General Public License for more details.
    **
    ** You may find a copy of the GNU Affero GPL version 3 at the following
    ** location: https://www.gnu.org/licenses/agpl-3.0.en.html
    **
    ** Additional terms under GNU Affero GPL version 3 section 7:
    **
    **   Under Section 7 of the GNU Affero GPL version 3, the following additional
    **   terms apply to the works covered under the License.  These additional terms
    **   are non-permissive additional terms allowed under Section 7 of the GNU
    **   Affero GPL version 3 and may not be removed by you.
    **
    **   0. Attribution Requirement.
    **
    **     You must preserve all legal notices or author attributions in the covered
    **     work or Appropriate Legal Notices displayed by works containing the covered
    **     work.  You may not remove from the covered work any author or developer
    **     credit already included within the covered work.
    **
    **   1. No License To Use Trademarks.
    **
    **     This license does not grant any license or rights to use the trademarks
    **     Golden Code, FWD, any Golden Code or FWD logo, or any other trademarks
    **     of Golden Code Development Corporation. You are not authorized to use the
    **     name Golden Code, FWD, or the names of any author or contributor, for
    **     publicity purposes without written authorization.
    **
    **   2. No Misrepresentation of Affiliation.
    **
    **     You may not represent yourself as Golden Code Development Corporation or FWD.
    **
    **     You may not represent yourself for publicity purposes as associated with
    **     Golden Code Development Corporation, FWD, or any author or contributor to
    **     the covered work, without written authorization.
    **
    **   3. No Misrepresentation of Source or Origin.
    **
    **     You may not represent the covered work as solely your work.  All modified
    **     versions of the covered work must be marked in a reasonable way to make it
    **     clear that the modified work is not originating from Golden Code Development
    **     Corporation or FWD.  All modified versions must contain the notices of
    **     attribution required in this license.
    */

    package com.goldencode.p2j.admin.client.application.home;

    import java.util.HashMap;
    import java.util.LinkedHashMap;
    import java.util.Map;
    import java.util.logging.Logger;

    import com.goldencode.p2j.admin.AdminHelper;
    import com.google.gwt.event.shared.GwtEvent;
    import com.google.gwt.http.client.URL;
    import com.google.gwt.regexp.shared.RegExp;
    import com.google.web.bindery.event.shared.EventBus;
    import com.gwtplatform.mvp.client.Presenter;
    import com.gwtplatform.mvp.client.View;
    import com.gwtplatform.mvp.client.proxy.PlaceManager;
    import com.gwtplatform.mvp.client.proxy.Proxy;
    import com.gwtplatform.mvp.client.proxy.RevealContentHandler;
    import com.gwtplatform.mvp.shared.proxy.PlaceRequest;

    /**
     * BasePresenter implements common business methods available for views.
     *
     * @param    <V>
     *           A view type
     * @param    <Proxy_>
     *           A controller's proxy type
     */
    public abstract class BasePresenter<V extends View, Proxy_ extends Proxy<?>>
    extends Presenter<V, Proxy_>
    {
       /** Filter GET parameter */
       public static final String FILTER = "filter";

       /** The call logger */
       protected Logger logger = Logger.getLogger(getClass().getSimpleName());

       /** Place manager */
       private final PlaceManager placeManager;

       /** Filter regular expression */
       protected RegExp filterExp;

       /**
        * Creates a base presenter for the GWTP framework.
        *
        * @param    eventBus
        *           The event bus
        * @param    view
        *           The view
        * @param    proxy
        *           The place proxy
        * @param    slot
        *           The slot
        * @param    placeManager
        *           The place manager
        */
       public BasePresenter(EventBus eventBus,
                            V view,
                            Proxy_ proxy,
                            GwtEvent.Type<RevealContentHandler<?>> slot,
                            PlaceManager placeManager)
       {
          super(eventBus, view, proxy, slot);

          this.placeManager = placeManager;
       }

       /**
        * Update browser's history and its url
        *
        * @param    key
        *           The key parameter to update
        * @param    value
        *           The new value
        */
       protected void updateBrowserHistory(String key, String value)
       {
          PlaceRequest current = getPlaceManager().getCurrentPlaceRequest();
          Map<String, String> parameters = new HashMap<>(current.getParameterNames().size() + 1);
          current.getParameterNames().forEach(name -> {
             if (!name.equals(key))
             {
                parameters.put(name, current.getParameter(name, ""));
             }
          });
          PlaceRequest placeRequest = new PlaceRequest.Builder().nameToken(current.getNameToken())
                   .with(parameters).with(key, value).build();
          getPlaceManager().updateHistory(placeRequest, true);
       }

       /**
        * Removes this parameter from the browser's history and its url.
        *
        * @param    parameter
        *           The GET parameter to remove
        */
       protected void clearRequestParameter(String parameter)
       {
          PlaceRequest current = getPlaceManager().getCurrentPlaceRequest();
          Map<String, String> parameters = new HashMap<>(current.getParameterNames().size());
          current.getParameterNames().forEach(key -> {
             if (!key.equals(parameter))
             {
                parameters.put(key, current.getParameter(key, ""));
             }
          });
          PlaceRequest placeRequest = new PlaceRequest.Builder().nameToken(current.getNameToken())
                   .with(parameters).build();
          getPlaceManager().updateHistory(placeRequest, true);
       }

       /**
        * Returns the GWTP place manager.
        *
        * @return   The GWTP place manager
        */
       protected PlaceManager getPlaceManager()
       {
          return placeManager;
       }

       /**
        * Gets the current GET parameter value if it is found in the current url, otherwise returns
        * the provided value.
        *
        * @param    key
        *           The GET parameter name
        * @param    defaultValue
        *           The provided default value
        *
        * @return   The current GET parameter value if it is found in the current url, otherwise
        *           returns the provided value.
        */
       protected String getCurrentParameter(String key, String defaultValue)
       {
          PlaceRequest current = getPlaceManager().getCurrentPlaceRequest();
          return current.getParameter(key, defaultValue);
       }

       /**
        * Gets the current browser's query string.
        *
        * @return   The current browser's query string
        */
       protected String getQueryString()
       {
          return getQueryString(getPlaceManager().getCurrentPlaceRequest());
       }

       /**
        * Gets the query string for the given request (the history or current one).
        *
        * @param    current
        *           The given request
        *
        * @return   The query string for the given request
        */
       protected String getQueryString(PlaceRequest current)
       {
          StringBuilder builder = new StringBuilder();
          current.getParameterNames().forEach(
             key ->
             {
                if (builder.length() > 0)
                {
                   builder.append('&');
                }

                builder.append(key)
                       .append("=")
                       .append(URL.encodeQueryString(current.getParameter(key, "")));
             });

          return builder.toString();
       }

       /**
        * Gets the query parameters map for the given request (the history or current one).
        *
        * @param    current
        *           The given request
        *
        * @return   The query parameters map for the given request
        */
       protected Map<String, String> getQueryParametersMap(PlaceRequest current)
       {
          Map<String, String> builder = new LinkedHashMap<String, String>();
          current.getParameterNames().forEach(
             key ->
             {
                builder.put(key, current.getParameter(key, ""));
             });

          return builder;
       }

       /**
        * Sets the current search filter.
        *
        * @param    value
        *           The current search template
        */
       public void setFilter(String value)
       {
          if (value == null || value.isEmpty())
          {
             filterExp = null;
             clearRequestParameter(FILTER);
          }
          else
          {
             filterExp = RegExp.compile(AdminHelper.wrapIntoCaseInsensitivePattern(value));
             updateBrowserHistory(FILTER, value);
          }
       }

       /**
        * Gets the current search template.
        *
        * @return   The current search template
        */
       public String getCurrentFilter()
       {
          return getCurrentParameter(FILTER, "");
       }

       /**
        * Navigates to the given history or current request.
        *
        * @param    request
        *           The given history or current request
        */
       protected void backTo(PlaceRequest request)
       {
          removeFromParentSlot();
          getPlaceManager().revealPlace(request);
       }
    }