DataTableManager.java

  1. /*
  2.  * Copyright (c) 2002-2022, City of Paris
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  *
  9.  *  1. Redistributions of source code must retain the above copyright notice
  10.  *     and the following disclaimer.
  11.  *
  12.  *  2. Redistributions in binary form must reproduce the above copyright notice
  13.  *     and the following disclaimer in the documentation and/or other materials
  14.  *     provided with the distribution.
  15.  *
  16.  *  3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
  17.  *     contributors may be used to endorse or promote products derived from
  18.  *     this software without specific prior written permission.
  19.  *
  20.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  21.  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  22.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  23.  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
  24.  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  25.  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  26.  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  27.  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  28.  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  29.  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  30.  * POSSIBILITY OF SUCH DAMAGE.
  31.  *
  32.  * License 1.0
  33.  */
  34. package fr.paris.lutece.util.datatable;

  35. import java.io.Serializable;
  36. import java.lang.reflect.InvocationTargetException;
  37. import java.lang.reflect.Method;
  38. import java.util.ArrayList;
  39. import java.util.Collection;
  40. import java.util.Collections;
  41. import java.util.HashMap;
  42. import java.util.List;
  43. import java.util.Locale;
  44. import java.util.Map;

  45. import javax.servlet.http.HttpServletRequest;

  46. import org.apache.commons.beanutils.BeanUtilsBean;
  47. import org.apache.commons.lang3.StringUtils;

  48. import fr.paris.lutece.portal.service.util.AppLogService;
  49. import fr.paris.lutece.portal.web.constants.Parameters;
  50. import fr.paris.lutece.portal.web.l10n.LocaleService;
  51. import fr.paris.lutece.portal.web.util.LocalizedDelegatePaginator;
  52. import fr.paris.lutece.portal.web.util.LocalizedPaginator;
  53. import fr.paris.lutece.util.ReferenceList;
  54. import fr.paris.lutece.util.UniqueIDGenerator;
  55. import fr.paris.lutece.util.html.AbstractPaginator;
  56. import fr.paris.lutece.util.html.IPaginator;
  57. import fr.paris.lutece.util.sort.AttributeComparator;
  58. import fr.paris.lutece.util.url.UrlItem;

  59. /**
  60.  * Class to manage data tables with freemarker macros
  61.  *
  62.  * @param <T>
  63.  *            Type of data to display
  64.  */
  65. public class DataTableManager<T> implements Serializable
  66. {
  67.     /**
  68.      * Serial version UID
  69.      */
  70.     private static final long serialVersionUID = -3906455886374172029L;
  71.     private static final String CONSTANT_GET = "get";
  72.     private static final String CONSTANT_IS = "is";
  73.     private static final String CONSTANT_DATA_TABLE_MANAGER_ID_PREFIX = "dataTableManager";
  74.     private String _strSortUrl;
  75.     private List<DataTableColumn> _listColumn = new ArrayList<>( );
  76.     private FilterPanel _filterPanel;
  77.     private IPaginator<T> _paginator;
  78.     private String _strCurrentPageIndex = StringUtils.EMPTY;
  79.     private int _nItemsPerPage;
  80.     private int _nDefautlItemsPerPage;
  81.     private boolean _bEnablePaginator;
  82.     private Locale _locale;
  83.     private String _strSortedAttributeName;
  84.     private boolean _bIsAscSort;
  85.     private String _strUid;

  86.     /**
  87.      * Private constructor
  88.      */
  89.     protected DataTableManager( )
  90.     {
  91.         generateDataTableId( );
  92.     }

  93.     /**
  94.      * Constructor of the DataTableManager class
  95.      *
  96.      * @param strSortUrl
  97.      *            URL used by the paginator to sort data
  98.      * @param strFilterUrl
  99.      *            URL used to filter data
  100.      * @param nDefautlItemsPerPage
  101.      *            Default number of items to display per page
  102.      * @param bEnablePaginator
  103.      *            True to enable pagination, false to disable it
  104.      */
  105.     public DataTableManager( String strSortUrl, String strFilterUrl, int nDefautlItemsPerPage, boolean bEnablePaginator )
  106.     {
  107.         _filterPanel = new FilterPanel( strFilterUrl );
  108.         _nDefautlItemsPerPage = nDefautlItemsPerPage;
  109.         _nItemsPerPage = _nDefautlItemsPerPage;
  110.         _strCurrentPageIndex = "1";
  111.         _bEnablePaginator = bEnablePaginator;
  112.         generateDataTableId( );
  113.         setSortUrl( strSortUrl );
  114.     }

  115.     /**
  116.      * Add a column to this DataTableManager
  117.      *
  118.      * @param strColumnTitle
  119.      *            I18n key of the title of the column
  120.      * @param strObjectName
  121.      *            Name of the property of objects that should be displayed in this column.<br>
  122.      *            For example, if a class "Data" contains a property named "title", then the value of the parameter <i>strObjectName</i> should be "title".
  123.      * @param bSortable
  124.      *            True if the column is sortable, false otherwise
  125.      */
  126.     public void addColumn( String strColumnTitle, String strObjectName, boolean bSortable )
  127.     {
  128.         _listColumn.add( new DataTableColumn( strColumnTitle, strObjectName, bSortable, DataTableColumnType.STRING ) );
  129.     }

  130.     /**
  131.      * Add a label column to this DataTableManager. Values of cells of this column will be interpreted as i18n keys.
  132.      *
  133.      * @param strColumnTitle
  134.      *            I18n key of the title of the column
  135.      * @param strObjectName
  136.      *            Name of the property of objects that should be displayed in this column. This properties must be i18n keys.<br>
  137.      *            For example, if a class "Data" contains a property named "title", then the value of the parameter <i>strObjectName</i> should be "title".
  138.      * @param bSortable
  139.      *            True if the column is sortable, false otherwise
  140.      */
  141.     public void addLabelColumn( String strColumnTitle, String strObjectName, boolean bSortable )
  142.     {
  143.         _listColumn.add( new DataTableColumn( strColumnTitle, strObjectName, bSortable, DataTableColumnType.LABEL ) );
  144.     }

  145.     /**
  146.      * Add an column to this DataTableManager that will display actions on items. Actions are usually parameterized links. A DataTableManager can only have 1
  147.      * action column. The content of the action column must be generated by a macro.this macro must have one parameter named "item", and its name must be given
  148.      * to the macro <i>@tableData</i>.
  149.      *
  150.      * @param strColumnTitle
  151.      *            I18n key of the title of the column
  152.      */
  153.     public void addActionColumn( String strColumnTitle )
  154.     {
  155.         _listColumn.add( new DataTableColumn( strColumnTitle, null, false, DataTableColumnType.ACTION ) );
  156.     }

  157.     /**
  158.      * Add a column to this DataTableManager
  159.      *
  160.      * @param strColumnTitle
  161.      *            I18n key of the title of the column
  162.      * @param strObjectName
  163.      *            Name of the property of objects that should be displayed in this column.<br>
  164.      *            For example, if a class "Data" contains a property named "title", then the value of the parameter <i>strObjectName</i> should be "title".
  165.      * @param strLabelTrue
  166.      *            I18n key of the label to display when the value is true
  167.      * @param strLabelFalse
  168.      *            I18n key of the label to display when the value is false
  169.      */
  170.     public void addBooleanColumn( String strColumnTitle, String strObjectName, String strLabelTrue, String strLabelFalse )
  171.     {
  172.         _listColumn.add( new DataTableColumn( strColumnTitle, strObjectName, false, DataTableColumnType.BOOLEAN, strLabelTrue, strLabelFalse ) );
  173.     }

  174.     /**
  175.      * Add a free column to this DataTableManager. The content of this column must be generated by a macro. The macro must have one parameter named "item".
  176.      *
  177.      * @param strColumnTitle
  178.      *            I18n key of the title of the column
  179.      * @param strFreemarkerMacroName
  180.      *            Name of the freemarker macro that will display the content of the column.<br>
  181.      *            The macro must have a single parameter named <i>item</i> of type T that will contain the object associated with a row of the table.
  182.      */
  183.     public void addFreeColumn( String strColumnTitle, String strFreemarkerMacroName )
  184.     {
  185.         _listColumn.add( new DataTableColumn( strColumnTitle, strFreemarkerMacroName, false, DataTableColumnType.ACTION ) );
  186.     }

  187.     /**
  188.      * Add an email column to this DataTableManager. Displayed cell will be a "mailto:" link.
  189.      *
  190.      * @param strColumnTitle
  191.      *            I18n key of the title of the column
  192.      * @param strObjectName
  193.      *            Name of the property of objects that should be displayed in this column.<br>
  194.      *            For example, if a class "Data" contains a property named "title", then the value of the parameter <i>strObjectName</i> should be "title".
  195.      * @param bSortable
  196.      *            True if the column is sortable, false otherwise
  197.      */
  198.     public void addEmailColumn( String strColumnTitle, String strObjectName, boolean bSortable )
  199.     {
  200.         _listColumn.add( new DataTableColumn( strColumnTitle, strObjectName, bSortable, DataTableColumnType.EMAIL ) );
  201.     }

  202.     /**
  203.      * Add a filter to the filter panel of this DataTableManager
  204.      *
  205.      * @param filterType
  206.      *            data type of the filter. For drop down list, use {@link DataTableManager#addDropDownListFilter(String, String, ReferenceList)
  207.      *            addDropDownListFilter} instead
  208.      * @param strParameterName
  209.      *            Name of the parameter of the object to filter.<br>
  210.      *            For example, if this filter should be applied on the parameter "title" of a class named "Data", then the value of the parameter
  211.      *            <i>strParameterName</i> should be "title".
  212.      * @param strFilterLabel
  213.      *            Label describing the filter
  214.      */
  215.     public void addFilter( DataTableFilterType filterType, String strParameterName, String strFilterLabel )
  216.     {
  217.         _filterPanel.addFilter( filterType, strParameterName, strFilterLabel );
  218.     }

  219.     /**
  220.      * Add a drop down list filter to the filter panel of this DataTableManager
  221.      *
  222.      * @param strParameterName
  223.      *            Name of the parameter of the object to filter.<br>
  224.      *            For example, if this filter should be applied on the parameter "title" of a class named "Data", then the value of the parameter
  225.      *            <i>strParameterName</i> should be "title".
  226.      * @param strFilterLabel
  227.      *            Label describing the filter
  228.      * @param refList
  229.      *            Reference list containing data of the drop down list
  230.      */
  231.     public void addDropDownListFilter( String strParameterName, String strFilterLabel, ReferenceList refList )
  232.     {
  233.         _filterPanel.addDropDownListFilter( strParameterName, strFilterLabel, refList );
  234.     }

  235.     /**
  236.      * Apply filters on an objects list, sort it and update pagination values.
  237.      *
  238.      * @param request
  239.      *            The request
  240.      * @param items
  241.      *            Collection of objects to filter, sort and paginate
  242.      */
  243.     public void filterSortAndPaginate( HttpServletRequest request, List<T> items )
  244.     {
  245.         List<T> filteredSortedPaginatedItems = new ArrayList<>( items );

  246.         boolean bSubmitedDataTable = hasDataTableFormBeenSubmited( request );

  247.         // FILTER
  248.         Collection<DataTableFilter> listFilters = _filterPanel.getListFilter( );
  249.         boolean bUpdateFilter = false;
  250.         boolean bResetFilter = false;

  251.         // We check if filters must be updated or cleared
  252.         if ( bSubmitedDataTable )
  253.         {
  254.             bResetFilter = StringUtils.equals( request.getParameter( FilterPanel.PARAM_FILTER_PANEL_PREFIX + FilterPanel.PARAM_RESET_FILTERS ),
  255.                     Boolean.TRUE.toString( ) );
  256.             bUpdateFilter = true;

  257.             if ( !bResetFilter )
  258.             {
  259.                 bUpdateFilter = StringUtils.equals( request.getParameter( FilterPanel.PARAM_FILTER_PANEL_PREFIX + FilterPanel.PARAM_UPDATE_FILTERS ),
  260.                         Boolean.TRUE.toString( ) );
  261.             }
  262.         }

  263.         for ( DataTableFilter filter : listFilters )
  264.         {
  265.             String strFilterValue;

  266.             if ( bSubmitedDataTable && bUpdateFilter )
  267.             {
  268.                 // We update or clear filters
  269.                 strFilterValue = request.getParameter( FilterPanel.PARAM_FILTER_PANEL_PREFIX + filter.getParameterName( ) );

  270.                 if ( !bResetFilter && ( filter.getFilterType( ) == DataTableFilterType.BOOLEAN ) && ( strFilterValue == null ) )
  271.                 {
  272.                     strFilterValue = Boolean.FALSE.toString( );
  273.                 }

  274.                 filter.setValue( strFilterValue );
  275.             }
  276.             else
  277.             {
  278.                 strFilterValue = filter.getValue( );
  279.             }

  280.             if ( StringUtils.isNotBlank( strFilterValue ) )
  281.             {
  282.                 List<T> bufferList = new ArrayList<>( );

  283.                 for ( T item : filteredSortedPaginatedItems )
  284.                 {
  285.                     Method method = getMethod( item, filter.getParameterName( ), CONSTANT_GET );

  286.                     if ( ( method == null ) && ( filter.getFilterType( ) == DataTableFilterType.BOOLEAN ) )
  287.                     {
  288.                         method = getMethod( item, filter.getParameterName( ), CONSTANT_IS );
  289.                     }

  290.                     if ( method != null )
  291.                     {
  292.                         try
  293.                         {
  294.                             Object value = method.invoke( item );

  295.                             if ( ( value != null ) && strFilterValue.equals( value.toString( ) ) )
  296.                             {
  297.                                 bufferList.add( item );
  298.                             }
  299.                         }
  300.                         catch( Exception e )
  301.                         {
  302.                             AppLogService.error( e.getMessage( ), e );
  303.                         }
  304.                     }
  305.                 }

  306.                 filteredSortedPaginatedItems.retainAll( bufferList );
  307.             }
  308.         }

  309.         // SORT
  310.         if ( bSubmitedDataTable )
  311.         {
  312.             // We update the sort parameters
  313.             String strSortedAttributeName = request.getParameter( Parameters.SORTED_ATTRIBUTE_NAME );

  314.             if ( strSortedAttributeName != null )
  315.             {
  316.                 // We update sort properties
  317.                 _strSortedAttributeName = strSortedAttributeName;
  318.                 _bIsAscSort = Boolean.parseBoolean( request.getParameter( Parameters.SORTED_ASC ) );
  319.             }
  320.         }

  321.         // We sort the items
  322.         if ( _strSortedAttributeName != null )
  323.         {
  324.             Collections.sort( filteredSortedPaginatedItems, new AttributeComparator( _strSortedAttributeName, _bIsAscSort ) );
  325.         }

  326.         // PAGINATION
  327.         if ( bSubmitedDataTable )
  328.         {
  329.             // We update the pagination properties
  330.             if ( _bEnablePaginator )
  331.             {
  332.                 int nOldItemsPerPage = _nItemsPerPage;
  333.                 _nItemsPerPage = AbstractPaginator.getItemsPerPage( request, AbstractPaginator.PARAMETER_ITEMS_PER_PAGE, _nItemsPerPage,
  334.                         _nDefautlItemsPerPage );

  335.                 // If the number of items per page has changed, we switch to the first page
  336.                 if ( _nItemsPerPage != nOldItemsPerPage )
  337.                 {
  338.                     _strCurrentPageIndex = Integer.toString( 1 );
  339.                 }
  340.                 else
  341.                 {
  342.                     _strCurrentPageIndex = AbstractPaginator.getPageIndex( request, AbstractPaginator.PARAMETER_PAGE_INDEX, _strCurrentPageIndex );
  343.                 }
  344.             }
  345.             else
  346.             {
  347.                 _strCurrentPageIndex = Integer.toString( 1 );
  348.                 _nItemsPerPage = filteredSortedPaginatedItems.size( );
  349.             }
  350.         }

  351.         if ( request != null )
  352.         {
  353.             // We paginate create the new paginator
  354.             _paginator = new LocalizedPaginator<>( filteredSortedPaginatedItems, _nItemsPerPage, getSortUrl( ), AbstractPaginator.PARAMETER_PAGE_INDEX,
  355.                     _strCurrentPageIndex, request.getLocale( ) );
  356.         }
  357.     }

  358.     /**
  359.      * Get the filter panel of the DataTableManager
  360.      *
  361.      * @return The filter panel of the DataTableManager
  362.      */
  363.     public FilterPanel getFilterPanel( )
  364.     {
  365.         return _filterPanel;
  366.     }

  367.     /**
  368.      * Set the filter panel of the DataTableManager
  369.      *
  370.      * @param filterPanel
  371.      *            Filter panel
  372.      */
  373.     public void setFilterPanel( FilterPanel filterPanel )
  374.     {
  375.         _filterPanel = filterPanel;
  376.     }

  377.     /**
  378.      * Get the list of columns of this DataTableManager
  379.      *
  380.      * @return The list of columns of this DataTableManager
  381.      */
  382.     public List<DataTableColumn> getListColumn( )
  383.     {
  384.         return _listColumn;
  385.     }

  386.     /**
  387.      * Set the list of columns of this DataTableManager
  388.      *
  389.      * @param listColumn
  390.      *            The list of columns of this DataTableManager
  391.      */
  392.     public void setListColumn( List<DataTableColumn> listColumn )
  393.     {
  394.         _listColumn = listColumn;
  395.     }

  396.     /**
  397.      * Get the sort url of this DataTableManager
  398.      *
  399.      * @return The sort url of this DataTableManager
  400.      */
  401.     public String getSortUrl( )
  402.     {
  403.         return _strSortUrl;
  404.     }

  405.     /**
  406.      * Set the sort url of this DataTableManager
  407.      *
  408.      * @param strSortUrl
  409.      *            The sort url of this DataTableManager
  410.      */
  411.     public void setSortUrl( String strSortUrl )
  412.     {
  413.         _strSortUrl = strSortUrl;

  414.         if ( ( _strSortUrl != null ) && StringUtils.isNotEmpty( _strSortUrl ) && !StringUtils.contains( _strSortUrl, getId( ) ) )
  415.         {
  416.             // We add to the sort URL the unique parameter of this data table manager
  417.             UrlItem urlItem = new UrlItem( _strSortUrl );
  418.             urlItem.addParameter( getId( ), getId( ) );
  419.             _strSortUrl = urlItem.getUrl( );
  420.         }
  421.     }

  422.     /**
  423.      * Get the filtered, sorted and paginated items collection of this DataTableManager
  424.      *
  425.      * @return The filtered, sorted and paginated items collection of this DataTableManager
  426.      */
  427.     public List<T> getItems( )
  428.     {
  429.         return _paginator.getPageItems( );
  430.     }

  431.     /**
  432.      * Set the items to display. The list of items must be fintered, sorted and paginated. Methods
  433.      * {@link DataTableManager#getAndUpdatePaginator(HttpServletRequest ) getAndUpdatePaginator}, {@link DataTableManager#getAndUpdateSort(HttpServletRequest )
  434.      * getAndUpdateSort} and {@link DataTableManager#getAndUpdateFilter(HttpServletRequest, Object) getAndUpdateFilter} must have been called before the
  435.      * generation of the list of items.
  436.      *
  437.      * @param items
  438.      *            The filtered sorted and paginated list of items to display
  439.      * @param nTotalItemsNumber
  440.      *            The total number of items
  441.      */
  442.     public void setItems( List<T> items, int nTotalItemsNumber )
  443.     {
  444.         _paginator = new LocalizedDelegatePaginator<>( items, _nItemsPerPage, getSortUrl( ), AbstractPaginator.PARAMETER_PAGE_INDEX, _strCurrentPageIndex,
  445.                 nTotalItemsNumber, _locale );
  446.     }

  447.     /**
  448.      * Clear the items stored by this DataTableManager so that the garbage collector can free the memory they use.
  449.      */
  450.     public void clearItems( )
  451.     {
  452.         _paginator = null;
  453.         _locale = null;
  454.     }

  455.     /**
  456.      * Internal method. Get the paginator.
  457.      *
  458.      * Do not use this method, use {@link DataTableManager#getAndUpdatePaginator(HttpServletRequest ) getAndUpdatePaginator} instead to get up to date values !
  459.      *
  460.      * @return The paginator
  461.      */
  462.     public IPaginator<T> getPaginator( )
  463.     {
  464.         return _paginator;
  465.     }

  466.     /**
  467.      * Get the enable paginator boolean
  468.      *
  469.      * @return True if pagination is active, false otherwise
  470.      */
  471.     public boolean getEnablePaginator( )
  472.     {
  473.         return _bEnablePaginator;
  474.     }

  475.     /**
  476.      * Get the locale
  477.      *
  478.      * @return The locale
  479.      */
  480.     public Locale getLocale( )
  481.     {
  482.         return _locale;
  483.     }

  484.     /**
  485.      * Set the locale
  486.      *
  487.      * @param locale
  488.      *            The locale
  489.      */
  490.     public void setLocale( Locale locale )
  491.     {
  492.         _locale = locale;
  493.     }

  494.     /**
  495.      * Get the unique id of this data table manager
  496.      *
  497.      * @return The unique id of this data table manager
  498.      */
  499.     public String getId( )
  500.     {
  501.         return _strUid;
  502.     }

  503.     /**
  504.      * Get the paginator updated with values in the request
  505.      *
  506.      * @param request
  507.      *            The request
  508.      * @return The paginator up to date
  509.      */
  510.     public DataTablePaginationProperties getAndUpdatePaginator( HttpServletRequest request )
  511.     {
  512.         DataTablePaginationProperties paginationProperties = null;

  513.         if ( _bEnablePaginator )
  514.         {
  515.             paginationProperties = new DataTablePaginationProperties( );

  516.             if ( hasDataTableFormBeenSubmited( request ) )
  517.             {
  518.                 _strCurrentPageIndex = AbstractPaginator.getPageIndex( request, AbstractPaginator.PARAMETER_PAGE_INDEX, _strCurrentPageIndex );
  519.                 _nItemsPerPage = AbstractPaginator.getItemsPerPage( request, AbstractPaginator.PARAMETER_ITEMS_PER_PAGE, _nItemsPerPage,
  520.                         _nDefautlItemsPerPage );
  521.             }

  522.             paginationProperties.setItemsPerPage( _nItemsPerPage );

  523.             int nCurrentPageIndex = 1;

  524.             if ( !StringUtils.isEmpty( _strCurrentPageIndex ) )
  525.             {
  526.                 nCurrentPageIndex = Integer.parseInt( _strCurrentPageIndex );
  527.             }

  528.             paginationProperties.setCurrentPageIndex( nCurrentPageIndex );
  529.         }

  530.         _locale = ( request != null ) ? request.getLocale( ) : LocaleService.getDefault( );

  531.         return paginationProperties;
  532.     }

  533.     /**
  534.      * Get sort properties updated with values in the request
  535.      *
  536.      * @param request
  537.      *            The request
  538.      * @return The sort properties up to date
  539.      */
  540.     public DataTableSort getAndUpdateSort( HttpServletRequest request )
  541.     {
  542.         if ( hasDataTableFormBeenSubmited( request ) )
  543.         {
  544.             String strSortedAttributeName = request.getParameter( Parameters.SORTED_ATTRIBUTE_NAME );

  545.             if ( strSortedAttributeName != null )
  546.             {
  547.                 // We update sort properties
  548.                 _strSortedAttributeName = strSortedAttributeName;
  549.                 _bIsAscSort = Boolean.parseBoolean( request.getParameter( Parameters.SORTED_ASC ) );
  550.             }
  551.         }

  552.         return new DataTableSort( _strSortedAttributeName, _bIsAscSort );
  553.     }

  554.     /**
  555.      * Get filter properties updated with values in the request
  556.      *
  557.      * @param request
  558.      *            The request
  559.      * @param <K>
  560.      *            Type of the filter to use. This type must have accessors for every declared filter.
  561.      * @param filterObject
  562.      *            Filter to apply.
  563.      * @return The filter properties up to date
  564.      */
  565.     public <K> K getAndUpdateFilter( HttpServletRequest request, K filterObject )
  566.     {
  567.         List<DataTableFilter> listFilters = _filterPanel.getListFilter( );

  568.         boolean bSubmitedDataTable = hasDataTableFormBeenSubmited( request );

  569.         boolean bUpdateFilter = false;

  570.         Map<String, Object> mapFilter = new HashMap<>( );

  571.         if ( bSubmitedDataTable )
  572.         {
  573.             StringUtils.equals( request.getParameter( FilterPanel.PARAM_FILTER_PANEL_PREFIX + FilterPanel.PARAM_RESET_FILTERS ), Boolean.TRUE.toString( ) );

  574.             bUpdateFilter = StringUtils.equals( request.getParameter( FilterPanel.PARAM_FILTER_PANEL_PREFIX + FilterPanel.PARAM_UPDATE_FILTERS ),
  575.                     Boolean.TRUE.toString( ) );
  576.         }

  577.         for ( DataTableFilter filter : listFilters )
  578.         {
  579.             if ( bSubmitedDataTable )
  580.             {
  581.                 String strFilterValue = request.getParameter( FilterPanel.PARAM_FILTER_PANEL_PREFIX + filter.getParameterName( ) );

  582.                 if ( bUpdateFilter )
  583.                 {
  584.                     filter.setValue( strFilterValue );
  585.                 }
  586.             }

  587.             if ( StringUtils.isNotBlank( filter.getValue( ) ) )
  588.             {
  589.                 mapFilter.put( filter.getParameterName( ), filter.getValue( ) );
  590.             }
  591.         }

  592.         try
  593.         {
  594.             BeanUtilsBean.getInstance( ).populate( filterObject, mapFilter );
  595.         }
  596.         catch( InvocationTargetException | IllegalAccessException e )
  597.         {
  598.             AppLogService.error( e.getMessage( ), e );

  599.             return null;
  600.         }

  601.         return filterObject;
  602.     }

  603.     /**
  604.      * Internal method. Get the prefix of html attributes used by filters
  605.      *
  606.      * @return The prefix of html attributes used by filters
  607.      */
  608.     public String getFilterPanelPrefix( )
  609.     {
  610.         return FilterPanel.PARAM_FILTER_PANEL_PREFIX;
  611.     }

  612.     /**
  613.      * Return the getter method of the object obj for the attribute <i>strAttributName</i>
  614.      *
  615.      * @param obj
  616.      *            the object
  617.      * @param strAttributName
  618.      *            The name of the attribute to get the getter
  619.      * @param strMethodPrefix
  620.      *            Prefix of the name of the method
  621.      * @return method Method of the object obj for the attribute <i>strAttributName</i>
  622.      */
  623.     private Method getMethod( Object obj, String strAttributName, String strMethodPrefix )
  624.     {
  625.         Method method = null;
  626.         String strFirstLetter = strAttributName.substring( 0, 1 ).toUpperCase( );

  627.         String strMethodName = strMethodPrefix + strFirstLetter + strAttributName.substring( 1, strAttributName.length( ) );

  628.         try
  629.         {
  630.             method = obj.getClass( ).getMethod( strMethodName );
  631.         }
  632.         catch( Exception e )
  633.         {
  634.             AppLogService.debug( e.getMessage( ), e );
  635.         }

  636.         return method;
  637.     }

  638.     /**
  639.      * Generates the unique identifier of this data table manager
  640.      */
  641.     private void generateDataTableId( )
  642.     {
  643.         this._strUid = CONSTANT_DATA_TABLE_MANAGER_ID_PREFIX + UniqueIDGenerator.getNewId( );
  644.     }

  645.     /**
  646.      * Check if a request contain data of this data table manager
  647.      *
  648.      * @param request
  649.      *            The request
  650.      * @return True if a form of this data table manager has been submited, false otherwise
  651.      */
  652.     private boolean hasDataTableFormBeenSubmited( HttpServletRequest request )
  653.     {
  654.         return request != null && StringUtils.equals( request.getParameter( getId( ) ), getId( ) );
  655.     }
  656. }