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