View Javadoc
1   /*
2    * Copyright (c) 2002-2014, Mairie de 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  
36  import fr.paris.lutece.portal.service.util.AppLogService;
37  import fr.paris.lutece.portal.web.constants.Parameters;
38  import fr.paris.lutece.portal.web.l10n.LocaleService;
39  import fr.paris.lutece.portal.web.util.LocalizedDelegatePaginator;
40  import fr.paris.lutece.portal.web.util.LocalizedPaginator;
41  import fr.paris.lutece.util.ReferenceList;
42  import fr.paris.lutece.util.UniqueIDGenerator;
43  import fr.paris.lutece.util.html.IPaginator;
44  import fr.paris.lutece.util.html.Paginator;
45  import fr.paris.lutece.util.sort.AttributeComparator;
46  import fr.paris.lutece.util.url.UrlItem;
47  
48  import org.apache.commons.beanutils.BeanUtilsBean;
49  import org.apache.commons.lang.StringUtils;
50  
51  import java.io.Serializable;
52  
53  import java.lang.reflect.InvocationTargetException;
54  import java.lang.reflect.Method;
55  
56  import java.util.ArrayList;
57  import java.util.Collection;
58  import java.util.Collections;
59  import java.util.HashMap;
60  import java.util.List;
61  import java.util.Locale;
62  import java.util.Map;
63  
64  import javax.servlet.http.HttpServletRequest;
65  
66  
67  /**
68   * Class to manage data tables with freemarker macros
69   * @param <T> Type of data to display
70   */
71  public class DataTableManager<T> implements Serializable
72  {
73      /**
74       * Serial version UID
75       */
76      private static final long serialVersionUID = -3906455886374172029L;
77      private static final String CONSTANT_GET = "get";
78      private static final String CONSTANT_IS = "is";
79      private static final String CONSTANT_DATA_TABLE_MANAGER_ID_PREFIX = "dataTableManager";
80      private String _strSortUrl;
81      private List<DataTableColumn> _listColumn = new ArrayList<DataTableColumn>(  );
82      private FilterPanel _filterPanel;
83      private IPaginator<T> _paginator;
84      private String _strCurrentPageIndex = StringUtils.EMPTY;
85      private int _nItemsPerPage;
86      private int _nDefautlItemsPerPage;
87      private boolean _bEnablePaginator;
88      private Locale _locale;
89      private String _strSortedAttributeName;
90      private boolean _bIsAscSort;
91      private String _strUid;
92  
93      /**
94       * Private constructor
95       */
96      protected DataTableManager(  )
97      {
98          generateDataTableId(  );
99      }
100 
101     /**
102      * Constructor of the DataTableManager class
103      * @param strSortUrl URL used by the paginator to sort data
104      * @param strFilterUrl URL used to filter data
105      * @param nDefautlItemsPerPage Default number of items to display per page
106      * @param bEnablePaginator True to enable pagination, false to disable it
107      */
108     public DataTableManager( String strSortUrl, String strFilterUrl, int nDefautlItemsPerPage, boolean bEnablePaginator )
109     {
110         _filterPanel = new FilterPanel( strFilterUrl );
111         _nDefautlItemsPerPage = nDefautlItemsPerPage;
112         _nItemsPerPage = _nDefautlItemsPerPage;
113         _strCurrentPageIndex = "1";
114         _bEnablePaginator = bEnablePaginator;
115         generateDataTableId(  );
116         setSortUrl( strSortUrl );
117     }
118 
119     /**
120      * Add a column to this DataTableManager
121      * @param strColumnTitle I18n key of the title of the column
122      * @param strObjectName Name of the property of objects that should be
123      *            displayed in this column.<br />
124      *            For example, if a class "Data" contains a property named
125      *            "title", then the value of the parameter <i>strObjectName</i>
126      *            should be "title".
127      * @param bSortable True if the column is sortable, false otherwise
128      */
129     public void addColumn( String strColumnTitle, String strObjectName, boolean bSortable )
130     {
131         _listColumn.add( new DataTableColumn( strColumnTitle, strObjectName, bSortable, DataTableColumnType.STRING ) );
132     }
133 
134     /**
135      * Add a label column to this DataTableManager. Values of cells of this
136      * column will be interpreted as i18n keys.
137      * @param strColumnTitle I18n key of the title of the column
138      * @param strObjectName Name of the property of objects that should be
139      *            displayed in this column. This properties must be i18n keys.<br />
140      *            For example, if a class "Data" contains a property named
141      *            "title", then the value of the parameter <i>strObjectName</i>
142      *            should be "title".
143      * @param bSortable True if the column is sortable, false otherwise
144      */
145     public void addLabelColumn( String strColumnTitle, String strObjectName, boolean bSortable )
146     {
147         _listColumn.add( new DataTableColumn( strColumnTitle, strObjectName, bSortable, DataTableColumnType.LABEL ) );
148     }
149 
150     /**
151      * Add an column to this DataTableManager that will display actions on
152      * items. Actions are usually parameterized links. A DataTableManager can
153      * only have 1 action column. The content of the action
154      * column must be generated by a macro.this macro must have one parameter
155      * named "item", and its name must be given to the macro <i>@tableData</i>.
156      * @param strColumnTitle I18n key of the title of the column
157      */
158     public void addActionColumn( String strColumnTitle )
159     {
160         _listColumn.add( new DataTableColumn( strColumnTitle, null, false, DataTableColumnType.ACTION ) );
161     }
162 
163     /**
164      * Add a column to this DataTableManager
165      * @param strColumnTitle I18n key of the title of the column
166      * @param strObjectName Name of the property of objects that should be
167      *            displayed in this column.<br />
168      *            For example, if a class "Data" contains a property named
169      *            "title", then the value of the parameter <i>strObjectName</i>
170      *            should be "title".
171      * @param strLabelTrue I18n key of the label to display when the value is
172      *            true
173      * @param strLabelFalse I18n key of the label to display when the value is
174      *            false
175      */
176     public void addBooleanColumn( String strColumnTitle, String strObjectName, String strLabelTrue, String strLabelFalse )
177     {
178         _listColumn.add( new DataTableColumn( strColumnTitle, strObjectName, false, DataTableColumnType.BOOLEAN,
179                 strLabelTrue, strLabelFalse ) );
180     }
181 
182     /**
183      * Add a free column to this DataTableManager. The content of this column
184      * must be generated by a macro. The macro must have one parameter named
185      * "item".
186      * @param strColumnTitle I18n key of the title of the column
187      * @param strFreemarkerMacroName Name of the freemarker macro that will
188      *            display the content of the column.<br />
189      *            The macro must have a single parameter named <i>item</i> of
190      *            type T that will contain the object associated with a row of
191      *            the table.
192      */
193     public void addFreeColumn( String strColumnTitle, String strFreemarkerMacroName )
194     {
195         _listColumn.add( new DataTableColumn( strColumnTitle, strFreemarkerMacroName, false, DataTableColumnType.ACTION ) );
196     }
197 
198     /**
199      * Add an email column to this DataTableManager. Displayed cell will be a
200      * "mailto:" link.
201      * @param strColumnTitle I18n key of the title of the column
202      * @param strObjectName Name of the property of objects that should be
203      *            displayed in this column.<br />
204      *            For example, if a class "Data" contains a property named
205      *            "title", then the value of the parameter <i>strObjectName</i>
206      *            should be "title".
207      * @param bSortable True if the column is sortable, false otherwise
208      */
209     public void addEmailColumn( String strColumnTitle, String strObjectName, boolean bSortable )
210     {
211         _listColumn.add( new DataTableColumn( strColumnTitle, strObjectName, bSortable, DataTableColumnType.EMAIL ) );
212     }
213 
214     /**
215      * Add a filter to the filter panel of this DataTableManager
216      * @param filterType data type of the filter. For drop down list, use
217      *            {@link DataTableManager#addDropDownListFilter(String, String, ReferenceList)
218      *            addDropDownListFilter} instead
219      * @param strParameterName Name of the parameter of the object to filter.<br/>
220      *            For example, if this filter should be applied on the parameter
221      *            "title" of a class named "Data", then the value of the
222      *            parameter <i>strParameterName</i> should be "title".
223      * @param strFilterLabel Label describing the filter
224      */
225     public void addFilter( DataTableFilterType filterType, String strParameterName, String strFilterLabel )
226     {
227         _filterPanel.addFilter( filterType, strParameterName, strFilterLabel );
228     }
229 
230     /**
231      * Add a drop down list filter to the filter panel of this DataTableManager
232      * @param strParameterName Name of the parameter of the object to filter.<br/>
233      *            For example, if this filter should be applied on the parameter
234      *            "title" of a class named "Data", then the value of the
235      *            parameter <i>strParameterName</i> should be "title".
236      * @param strFilterLabel Label describing the filter
237      * @param refList Reference list containing data of the drop down list
238      */
239     public void addDropDownListFilter( String strParameterName, String strFilterLabel, ReferenceList refList )
240     {
241         _filterPanel.addDropDownListFilter( strParameterName, strFilterLabel, refList );
242     }
243 
244     /**
245      * Apply filters on an objects list, sort it and update pagination values.
246      * @param request The request
247      * @param items Collection of objects to filter, sort and paginate
248      */
249     public void filterSortAndPaginate( HttpServletRequest request, List<T> items )
250     {
251         List<T> filteredSortedPaginatedItems = new ArrayList<T>( items );
252 
253         boolean bSubmitedDataTable = hasDataTableFormBeenSubmited( request );
254 
255         // FILTER
256         Collection<DataTableFilter> listFilters = _filterPanel.getListFilter(  );
257         boolean bUpdateFilter = false;
258         boolean bResetFilter = false;
259 
260         // We check if filters must be updated or cleared
261         if ( bSubmitedDataTable )
262         {
263             bResetFilter = StringUtils.equals( request.getParameter( FilterPanel.PARAM_FILTER_PANEL_PREFIX +
264                         FilterPanel.PARAM_RESET_FILTERS ), Boolean.TRUE.toString(  ) );
265             bUpdateFilter = true;
266 
267             if ( !bResetFilter )
268             {
269                 bUpdateFilter = StringUtils.equals( request.getParameter( FilterPanel.PARAM_FILTER_PANEL_PREFIX +
270                             FilterPanel.PARAM_UPDATE_FILTERS ), Boolean.TRUE.toString(  ) );
271             }
272         }
273 
274         for ( DataTableFilter filter : listFilters )
275         {
276             String strFilterValue;
277 
278             if ( bSubmitedDataTable && bUpdateFilter )
279             {
280                 // We update or clear filters
281                 strFilterValue = request.getParameter( FilterPanel.PARAM_FILTER_PANEL_PREFIX +
282                         filter.getParameterName(  ) );
283 
284                 if ( !bResetFilter && ( filter.getFilterType(  ) == DataTableFilterType.BOOLEAN ) &&
285                         ( strFilterValue == null ) )
286                 {
287                     strFilterValue = Boolean.FALSE.toString(  );
288                 }
289 
290                 filter.setValue( strFilterValue );
291             }
292             else
293             {
294                 strFilterValue = filter.getValue(  );
295             }
296 
297             if ( StringUtils.isNotBlank( strFilterValue ) )
298             {
299                 List<T> bufferList = new ArrayList<T>(  );
300 
301                 for ( T item : filteredSortedPaginatedItems )
302                 {
303                     Method method = getMethod( item, filter.getParameterName(  ), CONSTANT_GET );
304 
305                     if ( ( method == null ) && ( filter.getFilterType(  ) == DataTableFilterType.BOOLEAN ) )
306                     {
307                         method = getMethod( item, filter.getParameterName(  ), CONSTANT_IS );
308                     }
309 
310                     if ( method != null )
311                     {
312                         try
313                         {
314                             Object value = method.invoke( item );
315 
316                             if ( ( value != null ) && strFilterValue.equals( value.toString(  ) ) )
317                             {
318                                 bufferList.add( item );
319                             }
320                         }
321                         catch ( Exception e )
322                         {
323                             AppLogService.error( e.getMessage(  ), e );
324                         }
325                     }
326                 }
327 
328                 filteredSortedPaginatedItems.retainAll( bufferList );
329             }
330         }
331 
332         // SORT
333         if ( bSubmitedDataTable )
334         {
335             // We update the sort parameters
336             String strSortedAttributeName = request.getParameter( Parameters.SORTED_ATTRIBUTE_NAME );
337 
338             if ( strSortedAttributeName != null )
339             {
340                 // We update sort properties
341                 _strSortedAttributeName = strSortedAttributeName;
342                 _bIsAscSort = Boolean.parseBoolean( request.getParameter( Parameters.SORTED_ASC ) );
343             }
344         }
345 
346         // We sort the items
347         if ( _strSortedAttributeName != null )
348         {
349             Collections.sort( filteredSortedPaginatedItems,
350                 new AttributeComparator( _strSortedAttributeName, _bIsAscSort ) );
351         }
352 
353         // PAGINATION
354         if ( bSubmitedDataTable )
355         {
356             // We update the pagination properties
357             if ( _bEnablePaginator )
358             {
359                 int nOldItemsPerPage = _nItemsPerPage;
360                 _nItemsPerPage = Paginator.getItemsPerPage( request, Paginator.PARAMETER_ITEMS_PER_PAGE,
361                         _nItemsPerPage, _nDefautlItemsPerPage );
362 
363                 // If the number of items per page has changed, we switch to the first page
364                 if ( _nItemsPerPage != nOldItemsPerPage )
365                 {
366                     _strCurrentPageIndex = Integer.toString( 1 );
367                 }
368                 else
369                 {
370                     _strCurrentPageIndex = Paginator.getPageIndex( request, Paginator.PARAMETER_PAGE_INDEX,
371                             _strCurrentPageIndex );
372                 }
373             }
374             else
375             {
376                 _strCurrentPageIndex = Integer.toString( 1 );
377                 _nItemsPerPage = filteredSortedPaginatedItems.size(  );
378             }
379         }
380 
381         // We paginate create the new paginator
382         _paginator = new LocalizedPaginator<T>( filteredSortedPaginatedItems, _nItemsPerPage, getSortUrl(  ),
383                 Paginator.PARAMETER_PAGE_INDEX, _strCurrentPageIndex, request.getLocale(  ) );
384     }
385 
386     /**
387      * Get the filter panel of the DataTableManager
388      * @return The filter panel of the DataTableManager
389      */
390     public FilterPanel getFilterPanel(  )
391     {
392         return _filterPanel;
393     }
394 
395     /**
396      * Set the filter panel of the DataTableManager
397      * @param filterPanel Filter panel
398      */
399     public void setFilterPanel( FilterPanel filterPanel )
400     {
401         _filterPanel = filterPanel;
402     }
403 
404     /**
405      * Get the list of columns of this DataTableManager
406      * @return The list of columns of this DataTableManager
407      */
408     public List<DataTableColumn> getListColumn(  )
409     {
410         return _listColumn;
411     }
412 
413     /**
414      * Set the list of columns of this DataTableManager
415      * @param listColumn The list of columns of this DataTableManager
416      */
417     public void setListColumn( List<DataTableColumn> listColumn )
418     {
419         _listColumn = listColumn;
420     }
421 
422     /**
423      * Get the sort url of this DataTableManager
424      * @return The sort url of this DataTableManager
425      */
426     public String getSortUrl(  )
427     {
428         return _strSortUrl;
429     }
430 
431     /**
432      * Set the sort url of this DataTableManager
433      * @param strSortUrl The sort url of this DataTableManager
434      */
435     public void setSortUrl( String strSortUrl )
436     {
437         _strSortUrl = strSortUrl;
438 
439         if ( ( _strSortUrl != null ) && StringUtils.isNotEmpty( _strSortUrl ) &&
440                 !StringUtils.contains( _strSortUrl, getId(  ) ) )
441         {
442             // We add to the sort URL the unique parameter of this data table manager
443             UrlItem urlItem = new UrlItem( _strSortUrl );
444             urlItem.addParameter( getId(  ), getId(  ) );
445             _strSortUrl = urlItem.getUrl(  );
446         }
447     }
448 
449     /**
450      * Get the filtered, sorted and paginated items collection of this
451      * DataTableManager
452      * @return The filtered, sorted and paginated items collection of this
453      *         DataTableManager
454      */
455     public List<T> getItems(  )
456     {
457         return _paginator.getPageItems(  );
458     }
459 
460     /**
461      * Set the items to display. The list of items must be fintered, sorted and
462      * paginated. Methods
463      * {@link DataTableManager#getAndUpdatePaginator(HttpServletRequest )
464      * getAndUpdatePaginator},
465      * {@link DataTableManager#getAndUpdateSort(HttpServletRequest )
466      * getAndUpdateSort} and
467      * {@link DataTableManager#getAndUpdateFilter(HttpServletRequest, Object)
468      * getAndUpdateFilter} must have been
469      * called before the generation of the list of items.
470      * @param items The filtered sorted and paginated list of items to display
471      * @param nTotalItemsNumber The total number of items
472      */
473     public void setItems( List<T> items, int nTotalItemsNumber )
474     {
475         _paginator = new LocalizedDelegatePaginator<T>( items, _nItemsPerPage, getSortUrl(  ),
476                 Paginator.PARAMETER_PAGE_INDEX, _strCurrentPageIndex, nTotalItemsNumber, _locale );
477     }
478 
479     /**
480      * Clear the items stored by this DataTableManager so that the garbage
481      * collector can free the memory they use.
482      */
483     public void clearItems(  )
484     {
485         _paginator = null;
486         _locale = null;
487     }
488 
489     /**
490      * Internal method. Get the paginator.<br/>
491      * Do not use this method, use
492      * {@link DataTableManager#getAndUpdatePaginator(HttpServletRequest )
493      * getAndUpdatePaginator} instead to get up to date values !
494      * @return The paginator
495      */
496     public IPaginator<T> getPaginator(  )
497     {
498         return _paginator;
499     }
500 
501     /**
502      * Get the enable paginator boolean
503      * @return True if pagination is active, false otherwise
504      */
505     public boolean getEnablePaginator(  )
506     {
507         return _bEnablePaginator;
508     }
509 
510     /**
511      * Get the locale
512      * @return The locale
513      */
514     public Locale getLocale(  )
515     {
516         return _locale;
517     }
518 
519     /**
520      * Set the locale
521      * @param locale The locale
522      */
523     public void setLocale( Locale locale )
524     {
525         _locale = locale;
526     }
527 
528     /**
529      * Get the unique id of this data table manager
530      * @return The unique id of this data table manager
531      */
532     public String getId(  )
533     {
534         return _strUid;
535     }
536 
537     /**
538      * Get the paginator updated with values in the request
539      * @param request The request
540      * @return The paginator up to date
541      */
542     public DataTablePaginationProperties getAndUpdatePaginator( HttpServletRequest request )
543     {
544         DataTablePaginationProperties paginationProperties = null;
545 
546         if ( _bEnablePaginator )
547         {
548             paginationProperties = new DataTablePaginationProperties(  );
549 
550             if ( hasDataTableFormBeenSubmited( request ) )
551             {
552                 _strCurrentPageIndex = Paginator.getPageIndex( request, Paginator.PARAMETER_PAGE_INDEX,
553                         _strCurrentPageIndex );
554                 _nItemsPerPage = Paginator.getItemsPerPage( request, Paginator.PARAMETER_ITEMS_PER_PAGE,
555                         _nItemsPerPage, _nDefautlItemsPerPage );
556             }
557 
558             paginationProperties.setItemsPerPage( _nItemsPerPage );
559 
560             int nCurrentPageIndex = 1;
561 
562             if ( !StringUtils.isEmpty( _strCurrentPageIndex ) )
563             {
564                 nCurrentPageIndex = Integer.parseInt( _strCurrentPageIndex );
565             }
566 
567             paginationProperties.setCurrentPageIndex( nCurrentPageIndex );
568         }
569 
570         _locale = ( request != null ) ? request.getLocale(  ) : LocaleService.getDefault(  );
571 
572         return paginationProperties;
573     }
574 
575     /**
576      * Get sort properties updated with values in the request
577      * @param request The request
578      * @return The sort properties up to date
579      */
580     public DataTableSort getAndUpdateSort( HttpServletRequest request )
581     {
582         if ( hasDataTableFormBeenSubmited( request ) )
583         {
584             String strSortedAttributeName = request.getParameter( Parameters.SORTED_ATTRIBUTE_NAME );
585 
586             if ( strSortedAttributeName != null )
587             {
588                 // We update sort properties
589                 _strSortedAttributeName = strSortedAttributeName;
590                 _bIsAscSort = Boolean.parseBoolean( request.getParameter( Parameters.SORTED_ASC ) );
591             }
592         }
593 
594         DataTableSort sort = new DataTableSort( _strSortedAttributeName, _bIsAscSort );
595 
596         return sort;
597     }
598 
599     /**
600      * Get filter properties updated with values in the request
601      * @param request The request
602      * @param <K> Type of the filter to use. This type must have accessors for
603      *            every declared filter.
604      * @param filterObject Filter to apply.
605      * @return The filter properties up to date
606      */
607     public <K> K getAndUpdateFilter( HttpServletRequest request, K filterObject )
608     {
609         List<DataTableFilter> listFilters = _filterPanel.getListFilter(  );
610 
611         boolean bSubmitedDataTable = hasDataTableFormBeenSubmited( request );
612 
613         boolean bResetFilter = false;
614         boolean bUpdateFilter = false;
615 
616         Map<String, Object> mapFilter = new HashMap<String, Object>(  );
617 
618         if ( bSubmitedDataTable )
619         {
620             bUpdateFilter = true;
621             StringUtils.equals( request.getParameter( FilterPanel.PARAM_FILTER_PANEL_PREFIX +
622                     FilterPanel.PARAM_RESET_FILTERS ), Boolean.TRUE.toString(  ) );
623 
624             if ( !bResetFilter )
625             {
626                 bUpdateFilter = StringUtils.equals( request.getParameter( FilterPanel.PARAM_FILTER_PANEL_PREFIX +
627                             FilterPanel.PARAM_UPDATE_FILTERS ), Boolean.TRUE.toString(  ) );
628             }
629         }
630 
631         for ( DataTableFilter filter : listFilters )
632         {
633             if ( bSubmitedDataTable )
634             {
635                 String strFilterValue = request.getParameter( FilterPanel.PARAM_FILTER_PANEL_PREFIX +
636                         filter.getParameterName(  ) );
637 
638                 if ( bUpdateFilter )
639                 {
640                     filter.setValue( strFilterValue );
641                 }
642             }
643 
644             if ( StringUtils.isNotBlank( filter.getValue(  ) ) )
645             {
646                 mapFilter.put( filter.getParameterName(  ), filter.getValue(  ) );
647             }
648         }
649 
650         try
651         {
652             BeanUtilsBean.getInstance(  ).populate( filterObject, mapFilter );
653         }
654         catch ( IllegalAccessException e )
655         {
656             AppLogService.error( e.getMessage(  ), e );
657 
658             return null;
659         }
660         catch ( InvocationTargetException e )
661         {
662             AppLogService.error( e.getMessage(  ), e );
663 
664             return null;
665         }
666 
667         return filterObject;
668     }
669 
670     /**
671      * Internal method. Get the prefix of html attributes used by filters
672      * @return The prefix of html attributes used by filters
673      */
674     public String getFilterPanelPrefix(  )
675     {
676         return FilterPanel.PARAM_FILTER_PANEL_PREFIX;
677     }
678 
679     /**
680      * Return the getter method of the object obj for the attribute
681      * <i>strAttributName</i>
682      * @param obj the object
683      * @param strAttributName The name of the attribute to get the getter
684      * @param strMethodPrefix Prefix of the name of the method
685      * @return method Method of the object obj for the attribute
686      *         <i>strAttributName</i>
687      */
688     private Method getMethod( Object obj, String strAttributName, String strMethodPrefix )
689     {
690         Method method = null;
691         String strFirstLetter = strAttributName.substring( 0, 1 ).toUpperCase(  );
692 
693         String strMethodName = strMethodPrefix + strFirstLetter +
694             strAttributName.substring( 1, strAttributName.length(  ) );
695 
696         try
697         {
698             method = obj.getClass(  ).getMethod( strMethodName );
699         }
700         catch ( Exception e )
701         {
702             AppLogService.debug( e );
703         }
704 
705         return method;
706     }
707 
708     /**
709      * Generates the unique identifier of this data table manager
710      */
711     private void generateDataTableId(  )
712     {
713         this._strUid = CONSTANT_DATA_TABLE_MANAGER_ID_PREFIX + UniqueIDGenerator.getNewId(  );
714     }
715 
716     /**
717      * Check if a request contain data of this data table manager
718      * @param request The request
719      * @return True if a form of this data table manager has been submited,
720      *         false otherwise
721      */
722     private boolean hasDataTableFormBeenSubmited( HttpServletRequest request )
723     {
724         return ( request != null ) ? StringUtils.equals( request.getParameter( getId(  ) ), getId(  ) ) : false;
725     }
726 }