View Javadoc
1   /*
2    * Copyright (c) 2002-2021, 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.plugins.blog.web;
35  
36  import java.sql.Date;
37  import java.text.ParseException;
38  import java.text.SimpleDateFormat;
39  import java.util.ArrayList;
40  import java.util.Collection;
41  import java.util.HashMap;
42  import java.util.Map;
43  
44  import javax.servlet.http.HttpServletRequest;
45  
46  import fr.paris.lutece.plugins.blog.service.BlogParameterService;
47  import org.apache.commons.lang3.StringUtils;
48  
49  import fr.paris.lutece.plugins.blog.business.portlet.BlogListPortlet;
50  import fr.paris.lutece.plugins.blog.business.portlet.BlogListPortletHome;
51  import fr.paris.lutece.plugins.blog.business.portlet.BlogPortlet;
52  import fr.paris.lutece.plugins.blog.business.portlet.BlogPortletHome;
53  import fr.paris.lutece.plugins.blog.business.portlet.BlogPublication;
54  import fr.paris.lutece.plugins.blog.business.portlet.BlogPublicationHome;
55  import fr.paris.lutece.plugins.blog.business.portlet.PortletFilter;
56  import fr.paris.lutece.plugins.blog.business.portlet.PortletOrder;
57  import fr.paris.lutece.plugins.blog.service.BlogService;
58  import fr.paris.lutece.plugins.blog.service.PublishingService;
59  import fr.paris.lutece.portal.business.portlet.Portlet;
60  import fr.paris.lutece.portal.business.portlet.PortletHome;
61  import fr.paris.lutece.portal.business.portlet.PortletType;
62  import fr.paris.lutece.portal.service.i18n.I18nService;
63  import fr.paris.lutece.portal.service.portal.PortalService;
64  import fr.paris.lutece.portal.service.portlet.PortletResourceIdService;
65  import fr.paris.lutece.portal.service.portlet.PortletService;
66  import fr.paris.lutece.portal.service.rbac.RBACService;
67  import fr.paris.lutece.portal.service.template.AppTemplateService;
68  import fr.paris.lutece.portal.service.util.AppPropertiesService;
69  import fr.paris.lutece.portal.util.mvc.admin.annotations.Controller;
70  import fr.paris.lutece.portal.util.mvc.commons.annotations.Action;
71  import fr.paris.lutece.portal.util.mvc.commons.annotations.View;
72  import fr.paris.lutece.util.ReferenceItem;
73  import fr.paris.lutece.util.html.HtmlTemplate;
74  import fr.paris.lutece.api.user.User;
75  import fr.paris.lutece.util.html.AbstractPaginator;
76  import fr.paris.lutece.portal.web.util.LocalizedPaginator;
77  
78  /**
79   * This class provides the user interface to manage HtmlDoc features ( manage, create, modify, remove )
80   */
81  @Controller( controllerJsp = "ManagePublicationBlogs.jsp", controllerPath = "jsp/admin/plugins/blog/", right = "BLOG_MANAGEMENT" )
82  public class BlogPublicationJspBean extends BlogJspBean
83  {
84  
85      private static final long serialVersionUID = -2768032240064881165L;
86      private static final String TEMPLATE_PUBLICATION_HTMLDOC = "/admin/plugins/blog/publication_blog.html";
87      private static final String TEMPLATE_PORTLET_PAGE_PATH = "/admin/plugins/blog/portlet_page_path.html";
88  
89      // Properties for page titles
90  
91      // Properties
92      private static final String PROPERTY_PAGE_TITLE_PUBLICATION_HTMLDOC = "blog.publication_blogpageTitle";
93  
94      // Markers
95      public static final String MARK_PORTLET_LIST = "portlet_list";
96      private static final String MARK_PORTLET_FILTER_ERROR = "portlet_filter_error";
97      private static final String MARK_ORDER_PORTLET = "order_portlet";
98      private static final String MARK_ORDER_PORTLET_ASC = "order_portlet_asc";
99      private static final String MARK_PORTLET = "portlet";
100     private static final String MARK_LIST_PAGE = "page_list";
101 
102     private static final String MARK_DOCUMENT_PORTLET_LIST = "document_portlet_list";
103     private static final String MARK_DOCUMENT_LIST_PORTLET_LIST = "document_list_portlet_list";
104     private static final String MARK_PORTLET_FILTER = "portlet_filter";
105 
106     // Properties
107 
108     // Validations
109 
110     // Views
111     private static final String VIEW_MANAGE_PUBLICATION = "manageBlogsPublication";
112 
113     // Actions
114     private static final String ACTION_PUBLISHE_DOCUMENT = "publishDocument";
115     private static final String ACTION_UNPUBLISHE_DOCUMENT = "unPublishDocument";
116 
117     // Infos
118 
119     // Filter Marks
120     // Parma
121     private static final String PARAMETER_PUBLISHED_DATE = "dateBeginPublishing";
122     private static final String PARAMETER_UNPUBLISHED_DATE = "dateEndPublishing";
123     private static final String PARAMETER_PORTLET_ID = "idPortlet";
124 
125     private static final String PARAMETER_ORDER_PORTLET = "order_portlet";
126     private static final String PARAMETER_ORDER_PORTLET_ASC = "order_portlet_asc";
127     private static final String PARAMETER_PORTLET_FILTER_TYPE = "portlet_filter_type";
128     private static final String PARAMETER_PORTLET_FILTER_VALUE = "portlet_filter_value";
129     private static final String MARK_NB_ITEMS_PER_PAGE = "nb_items_per_page";
130     private static final String PROPERTY_DEFAULT_LIST_ITEM_PER_PAGE = "blog.listItems.itemsPerPage";
131     private static final String PARAMETER_PAGE_INDEX = "page_index";
132 
133     private static final String PARAMETER_IS_DISPLAY_LATEST_PORTLETS = "is_display_latest_portlets";
134 
135     // Message
136     private static final String ERROR_MESSAGE_NOT_NUMERIC_FIELD = "blog.message.notNumericField";
137     private static final String ERROR_MESSAGE_MESSAGE_MANDATORY_SEARCH_FIELD = "blog.message.mandatory.searchField";
138 
139     // Session variable to store working values
140     protected BlogPublication _blogPublication;
141 
142     /**
143      * Build the Manage View
144      * 
145      * @param request
146      *            The HTTP request
147      * @return The page
148      */
149     @View( value = VIEW_MANAGE_PUBLICATION )
150     public String getManageBlogPublication( HttpServletRequest request )
151     {
152         int nId = Integer.parseInt( request.getParameter( PARAMETER_ID_BLOG ) );
153         String strErrorFilter = null;
154         _blogPublication = ( _blogPublication != null ) ? _blogPublication : new BlogPublication( );
155 
156         if ( _blog == null || ( _blog.getId( ) != nId ) )
157         {
158 
159             _blog = BlogService.getInstance( ).findByPrimaryKeyWithoutBinaries( nId );
160 
161         }
162         PortletOrder/business/portlet/PortletOrder.html#PortletOrder">PortletOrder pOrder = new PortletOrder( );
163         String strOrderPortlet = request.getParameter( PARAMETER_ORDER_PORTLET );
164         boolean bIsDisplayPortlets = ( ( request.getParameter( PARAMETER_IS_DISPLAY_LATEST_PORTLETS ) == null )
165                 || Boolean.valueOf( request.getParameter( PARAMETER_IS_DISPLAY_LATEST_PORTLETS ) ) );
166 
167         String strOrderPortletAsc = request.getParameter( PARAMETER_ORDER_PORTLET_ASC );
168         int nOrderPortlet = -1;
169         int nOrderPortletAsc = -1;
170 
171         Map<String, Object> model = getModel( );
172         PortletFilter portletFilter = null;
173         if ( !bIsDisplayPortlets )
174         {
175 
176             portletFilter = new PortletFilter( );
177             portletFilter.setPortletFilterType( request.getParameter( PARAMETER_PORTLET_FILTER_TYPE ) );
178             portletFilter.setDisplayLatestPortlets( bIsDisplayPortlets );
179             portletFilter.setSearchValue( request.getParameter( PARAMETER_PORTLET_FILTER_VALUE ) );
180             strErrorFilter = setFillFilter( portletFilter );
181 
182             if ( strErrorFilter != null )
183             {
184                 model.put( MARK_PORTLET_FILTER_ERROR, strErrorFilter );
185             }
186 
187         }
188 
189         if ( StringUtils.isNotBlank( strOrderPortlet ) && StringUtils.isNumeric( strOrderPortlet ) && StringUtils.isNotBlank( strOrderPortletAsc )
190                 && StringUtils.isNumeric( strOrderPortletAsc ) )
191         {
192             nOrderPortlet = Integer.parseInt( strOrderPortlet );
193             nOrderPortletAsc = Integer.parseInt( strOrderPortletAsc );
194             pOrder.setTypeOrder( nOrderPortlet );
195             pOrder.setSortAsc( nOrderPortletAsc == PortletOrder.SORT_ASC );
196         }
197 
198         Collection<ReferenceItem> listDocumentListPortlets = getListAuthorizedDocumentListPortlets( _blog.getId( ), pOrder,
199                 ( strErrorFilter == null ) ? portletFilter : null );
200         Collection<ReferenceItem> listDocumentPortlets = getListAuthorizedDocumentPortlets( _blog.getId( ), pOrder,
201                 ( strErrorFilter == null ) ? portletFilter : null );
202         // PAGINATOR
203         java.util.List<ReferenceItem> listDocumentPortletsRef = new ArrayList<>( listDocumentListPortlets );
204         model = getPaginatedListModel( request, MARK_DOCUMENT_LIST_PORTLET_LIST, listDocumentPortletsRef, getHomeUrl( request ), model );
205         model.put( MARK_DOCUMENT_PORTLET_LIST, listDocumentPortlets );
206         model.put( MARK_BLOG, _blog );
207         model.put( MARK_PORTLET_LIST, PublishingService.getInstance( ).getBlogsPortletstoPublish( ) );
208         model.put( MARK_ORDER_PORTLET, nOrderPortlet );
209         model.put( MARK_ORDER_PORTLET_ASC, nOrderPortletAsc );
210         model.put( MARK_PORTLET_FILTER, portletFilter );
211         return getPage( PROPERTY_PAGE_TITLE_PUBLICATION_HTMLDOC, TEMPLATE_PUBLICATION_HTMLDOC, model );
212     }
213 
214     /**
215      * Publish a document in the portlet
216      * 
217      * @param request
218      * @return View mange publication
219      * @throws ParseException
220      */
221     @Action( ACTION_PUBLISHE_DOCUMENT )
222     public String doPublishDocument( HttpServletRequest request ) throws ParseException
223     {
224         populateBlogPublication( _blogPublication, request );
225 
226         if ( _blogPublication.getDateBeginPublishing( ) == null )
227         {
228 
229             _blogPublication.setDateBeginPublishing( new Date( System.currentTimeMillis( ) ) );
230         }
231         if ( _blogPublication.getDateEndPublishing( ) == null )
232         {
233             _blogPublication.setDateEndPublishing(BlogParameterService.getInstance().getDefaultDateEndPublishing());
234         }
235         if ( _blogPublication.getIdPortlet( ) != 0 )
236         {
237 
238             BlogPublicationHome.create( _blogPublication );
239 
240             _blog = BlogService.getInstance( ).findByPrimaryKeyWithoutBinaries( _blogPublication.getIdBlog( ) );
241         }
242 
243         return getManageBlogPublication( request );
244 
245     }
246 
247     /**
248      * Unpublish a document in the portlet
249      * 
250      * @param request
251      *            The request
252      * @return view manage blog publication
253      */
254     @Action( ACTION_UNPUBLISHE_DOCUMENT )
255     public String doUnPublishDocument( HttpServletRequest request )
256     {
257         _blogPublication = new BlogPublication( );
258         populate( _blogPublication, request );
259 
260         BlogPublicationHome.remove( _blogPublication.getIdBlog( ), _blogPublication.getIdPortlet( ) );
261         _blog = BlogService.getInstance( ).findByPrimaryKeyWithoutBinaries( _blogPublication.getIdBlog( ) );
262 
263         return getManageBlogPublication( request );
264 
265     }
266 
267     /**
268      * Populate BlogPublication object
269      * 
270      * @param blogPublication
271      *            The BlogPublication
272      * @param request
273      *            The request
274      * @throws ParseException
275      */
276     private void populateBlogPublication( BlogPublication htmldocPublication, HttpServletRequest request ) throws ParseException
277     {
278 
279         int nIdDoc = Integer.parseInt( request.getParameter( PARAMETER_ID_BLOG ) );
280         String strIdPortlet = request.getParameter( PARAMETER_PORTLET_ID );
281         int nIdPortlet = Integer.parseInt( strIdPortlet != null ? strIdPortlet : "0" );
282 
283         String dateBeginPublishingStr = request.getParameter( PARAMETER_PUBLISHED_DATE );
284         String dateEndPublishingStr = request.getParameter( PARAMETER_UNPUBLISHED_DATE );
285         java.sql.Date dateBeginPublishing = null;
286         java.sql.Date dateEndPublishing = null;
287 
288         SimpleDateFormat sdf = new SimpleDateFormat( "dd/MM/yyyy" );
289         java.util.Date parsed;
290 
291         if ( dateBeginPublishingStr != null && !dateBeginPublishingStr.isEmpty( ) )
292         {
293             parsed = sdf.parse( dateBeginPublishingStr );
294             dateBeginPublishing = new java.sql.Date( parsed.getTime( ) );
295         }
296         if ( dateEndPublishingStr != null && !dateEndPublishingStr.isEmpty( ) )
297         {
298             parsed = sdf.parse( dateEndPublishingStr );
299             dateEndPublishing = new java.sql.Date( parsed.getTime( ) );
300         }
301         int nBlogOrder = BlogListPortletHome.getMinDocBlogOrder( );
302         nBlogOrder = nBlogOrder - 1;
303 
304         htmldocPublication.setIdBlog( nIdDoc );
305         htmldocPublication.setIdPortlet( nIdPortlet );
306         htmldocPublication.setDateBeginPublishing( dateBeginPublishing );
307         htmldocPublication.setDateEndPublishing( dateEndPublishing );
308         htmldocPublication.setBlogOrder( nBlogOrder );
309 
310     }
311 
312     /**
313      * Fill the searchFilter
314      * 
315      * @param portletFilter
316      *            {@link PortletFilter}
317      * @return return error message if an error appear
318      */
319     public String setFillFilter( PortletFilter portletFilter )
320     {
321         String strErrorMessage = null;
322         String strValue;
323 
324         if ( ( portletFilter.getSearchValue( ) != null ) && !portletFilter.getSearchValue( ).trim( ).equals( "" )
325                 && ( portletFilter.getPortletFilterType( ) != null ) )
326         {
327             strValue = portletFilter.getSearchValue( ).trim( );
328 
329             if ( portletFilter.getPortletFilterType( ).equals( PortletFilter.PAGE_NAME ) )
330             {
331                 portletFilter.setPageName( strValue.split( PortletFilter.CONSTANTE_SPACE_STRING ) );
332             }
333             else
334                 if ( portletFilter.getPortletFilterType( ).equals( PortletFilter.PORTLET_NAME ) )
335                 {
336                     portletFilter.setPortletName( strValue.split( PortletFilter.CONSTANTE_SPACE_STRING ) );
337                 }
338                 else
339                     if ( portletFilter.getPortletFilterType( ).equals( PortletFilter.PAGE_ID ) )
340                     {
341                         if ( StringUtils.isNumeric( strValue ) )
342                         {
343                             portletFilter.setIdPage( Integer.parseInt( strValue ) );
344                         }
345                         else
346                         {
347                             strErrorMessage = I18nService.getLocalizedString( ERROR_MESSAGE_NOT_NUMERIC_FIELD, getLocale( ) );
348                         }
349                     }
350         }
351 
352         else
353         {
354             strErrorMessage = I18nService.getLocalizedString( ERROR_MESSAGE_MESSAGE_MANDATORY_SEARCH_FIELD, getLocale( ) );
355         }
356 
357         return strErrorMessage;
358     }
359 
360     /**
361      * Get the list of authorized portlets.
362      *
363      * Check :
364      * <ul>
365      * <li>if user is authorized to manage DocumentListPortlet</li>
366      * <li>if user is authorized to manage DocumentPortlet</li>
367      * <li>For each portlet :
368      * <ul>
369      * <li>if user is authorized to manage the linked page</li>
370      * <li>if portlet isn't in autopublication mode</li>
371      * </ul>
372      * </li>
373      * </ul>
374      *
375      * @param nDocumentId
376      *            The document id
377      * @param pOrder
378      *            The portlet order
379      * @param pFilter
380      *            The portlet filter
381      * @return A collection of {@link ReferenceItem}
382      */
383     private Collection<ReferenceItem> getListAuthorizedDocumentListPortlets( int nDocumentId, PortletOrder pOrder, PortletFilter pFilter )
384     {
385         Collection<ReferenceItem> listPortlets = new ArrayList<>( );
386 
387         // Check role PERMISSION_MANAGE for DocumentListPortlet
388         if ( RBACService.isAuthorized( PortletType.RESOURCE_TYPE, BlogListPortlet.RESOURCE_ID, PortletResourceIdService.PERMISSION_MANAGE, (User) getUser( ) ) )
389         {
390             listPortlets.addAll( BlogListPortletHome.findByFilter( nDocumentId, pOrder, pFilter ) );
391         }
392 
393         // check ROLE PERMISSION_MANAGE for PAGE and WORKGROUP
394         return filterByWorkgroup( listPortlets, pFilter );
395     }
396 
397     /**
398      * Filter the given portlets list by its workgroup
399      *
400      * @param listPortlets
401      *            a collection of {@link ReferenceItem}
402      * @param pFilter
403      *            The portlet filter
404      * @return a collection of {@link ReferenceItem}
405      */
406     private Collection<ReferenceItem> filterByWorkgroup( Collection<ReferenceItem> listPortlets, PortletFilter pFilter )
407     {
408         // check ROLE PERMISSION_MANAGE for PAGE and WORKGROUP
409         Collection<ReferenceItem> listFilteredPortlets = new ArrayList<>( );
410 
411         // Check role PERMISSION_MANAGE for workgroup and page and check if
412         // portlet isn't autopublished
413         for ( ReferenceItem item : listPortlets )
414         {
415             Portlet portlet = PortletHome.findByPrimaryKey( Integer.parseInt( item.getCode( ) ) );
416 
417             if ( ( portlet != null ) && PortletService.getInstance( ).isAuthorized( portlet, getUser( ) ) )
418             {
419                 Map<String, Object> subModel = new HashMap<>( );
420                 subModel.put( MARK_LIST_PAGE, PortalService.getPagePath( PortletHome.findByPrimaryKey( Integer.parseInt( item.getCode( ) ) ).getPageId( ) ) );
421                 subModel.put( MARK_PORTLET, item );
422 
423                 HtmlTemplate subTemplate = AppTemplateService.getTemplate( TEMPLATE_PORTLET_PAGE_PATH, getLocale( ), subModel );
424                 item.setName( subTemplate.getHtml( ) );
425 
426                 listFilteredPortlets.add( item );
427 
428             }
429         }
430 
431         return listFilteredPortlets;
432     }
433 
434     /**
435      * Get the list of authorized portlets.
436      *
437      * Check :
438      * <ul>
439      * <li>if user is authorized to manage DocumentListPortlet</li>
440      * <li>if user is authorized to manage DocumentPortlet</li>
441      * <li>For each portlet :
442      * <ul>
443      * <li>if user is authorized to manage the linked page</li>
444      * <li>if portlet isn't in autopublication mode</li>
445      * </ul>
446      * </li>
447      * </ul>
448      *
449      * @param nDocumentId
450      *            The document id
451      * 
452      * @param pOrder
453      *            The portlet order
454      * @param pFilter
455      *            The portlet filter
456      * @return A collection of {@link ReferenceItem}
457      */
458     private Collection<ReferenceItem> getListAuthorizedDocumentPortlets( int nDocumentId, PortletOrder pOrder, PortletFilter pFilter )
459     {
460         Collection<ReferenceItem> listPortlets = new ArrayList<>( );
461 
462         // Check role PERMISSION_MANAGE for DocumentPortlet
463         if ( RBACService.isAuthorized( PortletType.RESOURCE_TYPE, BlogPortlet.RESOURCE_ID, PortletResourceIdService.PERMISSION_MANAGE, (User) getUser( ) ) )
464         {
465             listPortlets.addAll( BlogPortletHome.findByFilter( nDocumentId, pOrder, pFilter ) );
466         }
467 
468         return filterByWorkgroup( listPortlets, pFilter );
469     }
470 
471     /**
472      * Return a model that contains the list and paginator infos
473      *
474      * @param request
475      *            The HTTP request
476      * @param strBookmark
477      *            The bookmark
478      * @param list
479      *            The list of item
480      * @param strManageJsp
481      *            The JSP
482      * @return The model
483      */
484     protected Map<String, Object> getPaginatedListModel( HttpServletRequest request, String strBookmark, java.util.List list, String strManageJsp, Map<String, Object> model)
485     {
486         _strCurrentPageIndex = AbstractPaginator.getPageIndex( request, AbstractPaginator.PARAMETER_PAGE_INDEX, _strCurrentPageIndex );
487         int defaultItemsPerPage = AppPropertiesService.getPropertyInt( PROPERTY_DEFAULT_LIST_ITEM_PER_PAGE, 50 );
488         _nItemsPerPage = AbstractPaginator.getItemsPerPage( request, AbstractPaginator.PARAMETER_ITEMS_PER_PAGE, _nItemsPerPage, defaultItemsPerPage );
489 
490         fr.paris.lutece.util.url.UrlItem url = new fr.paris.lutece.util.url.UrlItem( strManageJsp );
491         String strUrl = url.getUrl( );
492 
493         // SORT
494         String strSortedAttributeName = request.getParameter( MARK_SORTED_ATTRIBUTE );
495 
496         if ( strSortedAttributeName != null || _bIsSorted )
497         {
498             if ( strSortedAttributeName == null )
499             {
500                 strSortedAttributeName = _strSortedAttributeName;
501             }
502             String strAscSort = request.getParameter( MARK_ASC_SORT );
503 
504             boolean bIsAscSort = Boolean.parseBoolean( strAscSort );
505             if ( strAscSort == null )
506             {
507                 bIsAscSort = _bIsAscSort;
508             }
509 
510             java.util.Collections.sort( list, new fr.paris.lutece.util.sort.AttributeComparator( strSortedAttributeName, bIsAscSort ) );
511 
512             _bIsSorted = true;
513 
514             _strSortedAttributeName = strSortedAttributeName;
515             _bIsAscSort = bIsAscSort;
516         }
517 
518         // PAGINATOR
519         LocalizedPaginator paginator = new LocalizedPaginator( list, _nItemsPerPage, strUrl, PARAMETER_PAGE_INDEX, _strCurrentPageIndex, getLocale( ) );
520 
521 
522         model.put( MARK_NB_ITEMS_PER_PAGE, _nItemsPerPage );
523         model.put( MARK_PAGINATOR, paginator );
524         model.put( strBookmark, paginator.getPageItems( ) );
525 
526         return model;
527     }
528 
529 }