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.announce.web;
35  
36  import java.util.Collection;
37  import java.util.HashMap;
38  import java.util.List;
39  import java.util.Map;
40  
41  import javax.servlet.http.HttpServletRequest;
42  
43  import org.apache.commons.lang3.StringUtils;
44  
45  import fr.paris.lutece.api.user.User;
46  import fr.paris.lutece.plugins.announce.business.Sector;
47  import fr.paris.lutece.plugins.announce.business.SectorHome;
48  import fr.paris.lutece.plugins.announce.service.SectorResourceIdService;
49  import fr.paris.lutece.plugins.announce.utils.AnnounceUtils;
50  import fr.paris.lutece.portal.business.rbac.RBAC;
51  import fr.paris.lutece.portal.service.admin.AccessDeniedException;
52  import fr.paris.lutece.portal.service.message.AdminMessage;
53  import fr.paris.lutece.portal.service.message.AdminMessageService;
54  import fr.paris.lutece.portal.service.plugin.Plugin;
55  import fr.paris.lutece.portal.service.rbac.RBACService;
56  import fr.paris.lutece.portal.service.template.AppTemplateService;
57  import fr.paris.lutece.portal.service.util.AppPropertiesService;
58  import fr.paris.lutece.portal.web.admin.PluginAdminPageJspBean;
59  import fr.paris.lutece.portal.web.constants.Messages;
60  import fr.paris.lutece.util.ReferenceList;
61  import fr.paris.lutece.util.html.AbstractPaginator;
62  import fr.paris.lutece.util.html.HtmlTemplate;
63  import fr.paris.lutece.util.html.Paginator;
64  import fr.paris.lutece.util.url.UrlItem;
65  
66  /**
67   * This class provides the user interface to manage sector features ( manage, create, modify, remove )
68   */
69  public class SectorJspBean extends PluginAdminPageJspBean
70  {
71      /**
72       * Right to manage this feature
73       */
74      public static final String RIGHT_MANAGE_ANNOUNCE = "ANNOUNCE_MANAGEMENT";
75      private static final long serialVersionUID = 4236427473368477581L;
76  
77      /* parameter */
78      private static final String PARAMETER_PAGE_INDEX = "page_index";
79      private static final String PARAMETER_FIELD_ID = "sector_id";
80      private static final String PARAMETER_FIELD_LABEL = "sector_label";
81      private static final String PARAMETER_FIELD_DESCRIPTION = "sector_description";
82      private static final String PARAMETER_FIELD_ANNOUNCES_VALIDATION = "sector_announces_validation";
83      private static final String CHECKBOX_ON = "on";
84      private static final String PARAMETER_FIELD_ORDER = "sector_order";
85      private static final String PARAMETER_TAGS = "tags";
86      private static final String UNAUTHORIZED = "Unauthorized";
87  
88      /* properties */
89      private static final String PROPERTY_PAGE_TITLE_MANAGE_FIELDS = "announce.manage_sector.pageTitle";
90      private static final String PROPERTY_PAGE_TITLE_CREATE_FIELD = "announce.create_sector.pageTitle";
91      private static final String PROPERTY_PAGE_TITLE_MODIFY_FIELD = "announce.modify_sector.pageTitle";
92      private static final String PROPERTY_DEFAULT_LIST_FIELD_PER_PAGE = "announce.sector.itemsPerPage";
93  
94      /* templates */
95      private static final String TEMPLATE_MANAGE_FIELDS = "admin/plugins/announce/manage_sectors.html";
96      private static final String TEMPLATE_CREATE_FIELD = "admin/plugins/announce/create_sector.html";
97      private static final String TEMPLATE_MODIFY_FIELD = "admin/plugins/announce/modify_sector.html";
98  
99      /* Jsp Definition */
100     private static final String JSP_DO_REMOVE_FIELD = "jsp/admin/plugins/announce/DoRemoveSector.jsp";
101     private static final String JSP_MANAGE_FIELDS = "jsp/admin/plugins/announce/ManageSectors.jsp";
102     private static final String JSP_REDIRECT_TO_MANAGE_FIELDS = "ManageSectors.jsp";
103 
104     /* Messages */
105     private static final String MESSAGE_CONFIRM_REMOVE_FIELD = "announce.message.confirmRemoveSector";
106     private static final String MESSAGE_CANNOT_REMOVE_FIELD = "announce.message.cannotRemoveSector";
107 
108     /* Markers */
109     private static final String MARK_FIELD = "sector";
110     private static final String MARK_LIST_FIELDS = "list_sectors";
111     private static final String MARK_PAGINATOR = "paginator";
112     private static final String MARK_NB_ITEMS_PER_PAGE = "nb_items_per_page";
113     private static final String MARK_FIELD_ORDER_LIST = "sector_order_list";
114 
115     /* Misc */
116     private static final String REGEX_ID = "^[\\d]+$";
117 
118     /* Variables */
119     private String _strCurrentPageIndex;
120     private int _nItemsPerPage;
121 
122     /**
123      * {@inheritDoc}
124      */
125     @Override
126     public Plugin getPlugin( )
127     {
128         Plugin plugin = super.getPlugin( );
129 
130         if ( plugin == null )
131         {
132             plugin = AnnounceUtils.getPlugin( );
133         }
134 
135         return plugin;
136     }
137 
138     /**
139      * Returns the list of sector
140      *
141      * @param request
142      *            The Http request
143      * @return the sectors list
144      */
145     public String getManageSectors( HttpServletRequest request )
146     {
147         setPageTitleProperty( PROPERTY_PAGE_TITLE_MANAGE_FIELDS );
148 
149         _strCurrentPageIndex = AbstractPaginator.getPageIndex( request, AbstractPaginator.PARAMETER_PAGE_INDEX, _strCurrentPageIndex );
150         int defaultItemsPerPage = AppPropertiesService.getPropertyInt( PROPERTY_DEFAULT_LIST_FIELD_PER_PAGE, 50 );
151         _nItemsPerPage = AbstractPaginator.getItemsPerPage( request, AbstractPaginator.PARAMETER_ITEMS_PER_PAGE, _nItemsPerPage, defaultItemsPerPage );
152 
153         Collection<Sector> listSectors = SectorHome.findAll( );
154 
155         Paginator<Sector> paginator = new Paginator<>( (List<Sector>) listSectors, _nItemsPerPage, getUrlPage( ), PARAMETER_PAGE_INDEX, _strCurrentPageIndex );
156 
157         Map<String, Object> model = new HashMap<>( );
158 
159         model.put( MARK_NB_ITEMS_PER_PAGE, "" + _nItemsPerPage );
160         model.put( MARK_PAGINATOR, paginator );
161         model.put( MARK_LIST_FIELDS, paginator.getPageItems( ) );
162         model.put( MARK_FIELD_ORDER_LIST, getSectorOrderList( ) );
163 
164         HtmlTemplate templateList = AppTemplateService.getTemplate( TEMPLATE_MANAGE_FIELDS, getLocale( ), model );
165 
166         return getAdminPage( templateList.getHtml( ) );
167     }
168 
169     /**
170      * Returns the form to create a sector
171      * 
172      * @return the html code of the sector form
173      * @param request
174      *            The Http request
175      * @throws fr.paris.lutece.portal.service.admin.AccessDeniedException
176      *             access denied exception
177      */
178     public String getCreateSector( HttpServletRequest request ) throws AccessDeniedException
179     {
180         User user = getUser( );
181 
182         if ( !RBACService.isAuthorized( Sector.RESOURCE_TYPE, RBAC.WILDCARD_RESOURCES_ID, SectorResourceIdService.PERMISSION_CREATE, user ) )
183         {
184             throw new AccessDeniedException( UNAUTHORIZED );
185         }
186 
187         setPageTitleProperty( PROPERTY_PAGE_TITLE_CREATE_FIELD );
188 
189         Collection<Sector> listSectors = SectorHome.findAll( );
190 
191         HashMap<String, Object> model = new HashMap<>( );
192         model.put( MARK_LIST_FIELDS, listSectors );
193 
194         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_CREATE_FIELD, getLocale( ), model );
195 
196         return getAdminPage( template.getHtml( ) );
197     }
198 
199     /**
200      * Process the data capture form of a new sector
201      * 
202      * @return The Jsp URL of the process result
203      * @param request
204      *            The Http Request
205      * @throws fr.paris.lutece.portal.service.admin.AccessDeniedException
206      *             access denied exception
207      */
208     public String doCreateSector( HttpServletRequest request ) throws AccessDeniedException
209     {
210         User user = getUser( );
211 
212         if ( !RBACService.isAuthorized( Sector.RESOURCE_TYPE, RBAC.WILDCARD_RESOURCES_ID, SectorResourceIdService.PERMISSION_CREATE, user ) )
213         {
214             throw new AccessDeniedException( UNAUTHORIZED );
215         }
216 
217         String strSectorLabel = request.getParameter( PARAMETER_FIELD_LABEL );
218         String strSectorDescription = request.getParameter( PARAMETER_FIELD_DESCRIPTION );
219         String strTags = request.getParameter( PARAMETER_TAGS );
220 
221         String strAnnouncesValidation = request.getParameter( PARAMETER_FIELD_ANNOUNCES_VALIDATION );
222 
223         Sectors/announce/business/Sector.html#Sector">Sector sector = new Sector( );
224         sector.setLabel( strSectorLabel );
225         sector.setDescription( strSectorDescription );
226         sector.setTags( strTags );
227 
228         if ( strAnnouncesValidation == null )
229         {
230             sector.setAnnouncesValidation( false );
231         }
232         else
233             if ( strAnnouncesValidation.equals( CHECKBOX_ON ) )
234             {
235                 sector.setAnnouncesValidation( true );
236             }
237 
238         // Mandatory sectors
239         if ( ( strSectorLabel == null ) || ( strSectorDescription == null ) || strSectorDescription.equals( "" ) || strSectorLabel.equals( "" ) )
240         {
241             return AdminMessageService.getMessageUrl( request, Messages.MANDATORY_FIELDS, AdminMessage.TYPE_STOP );
242         }
243 
244         SectorHome.create( sector, getPlugin( ) );
245 
246         // if the operation occurred well, redirects towards the list
247         return JSP_REDIRECT_TO_MANAGE_FIELDS;
248     }
249 
250     /**
251      * Returns the form to update info about a sector
252      * 
253      * @return The HTML form to update info
254      * @param request
255      *            The Http request
256      * @throws fr.paris.lutece.portal.service.admin.AccessDeniedException
257      *             access denied exception
258      */
259     public String getModifySector( HttpServletRequest request ) throws AccessDeniedException
260     {
261         setPageTitleProperty( PROPERTY_PAGE_TITLE_MODIFY_FIELD );
262 
263         Sector sector = getAuthorizedSector( request, SectorResourceIdService.PERMISSION_MODIFY );
264         HashMap<String, Object> model = new HashMap<>( );
265         model.put( MARK_FIELD, sector );
266 
267         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_MODIFY_FIELD, getLocale( ), model );
268 
269         return getAdminPage( template.getHtml( ) );
270     }
271 
272     /**
273      * Process the change form of a sector
274      * 
275      * @return The Jsp URL of the process result
276      * @param request
277      *            The Http request
278      * @throws fr.paris.lutece.portal.service.admin.AccessDeniedException
279      *             access denied exception
280      */
281     public String doModifySector( HttpServletRequest request ) throws AccessDeniedException
282     {
283         String strSectorLabel = request.getParameter( PARAMETER_FIELD_LABEL );
284         String strSectorDescription = request.getParameter( PARAMETER_FIELD_DESCRIPTION );
285         String strAnnouncesValidation = request.getParameter( PARAMETER_FIELD_ANNOUNCES_VALIDATION );
286         String strTags = request.getParameter( PARAMETER_TAGS );
287 
288         // Mandatory sectors
289         if ( StringUtils.isEmpty( strSectorLabel ) || StringUtils.isEmpty( strSectorDescription ) )
290         {
291             return AdminMessageService.getMessageUrl( request, Messages.MANDATORY_FIELDS, AdminMessage.TYPE_STOP );
292         }
293 
294         Sector sector = getAuthorizedSector( request, SectorResourceIdService.PERMISSION_MODIFY );
295 
296         if ( strAnnouncesValidation == null )
297         {
298             sector.setAnnouncesValidation( false );
299         }
300         else
301             if ( strAnnouncesValidation.equals( CHECKBOX_ON ) )
302             {
303                 sector.setAnnouncesValidation( true );
304             }
305 
306         sector.setLabel( strSectorLabel );
307         sector.setDescription( strSectorDescription );
308         sector.setTags( strTags );
309         SectorHome.update( sector, getPlugin( ) );
310 
311         // if the operation occurred well, redirects towards the list
312         return JSP_REDIRECT_TO_MANAGE_FIELDS;
313     }
314 
315     /**
316      * Manages the removal form of a sector whose identifier is in the http request
317      * 
318      * @return the html code to confirm
319      * @param request
320      *            The Http request
321      * @throws fr.paris.lutece.portal.service.admin.AccessDeniedException
322      *             access denied exception
323      */
324     public String getConfirmRemoveSector( HttpServletRequest request ) throws AccessDeniedException
325     {
326         int nIdSector = Integer.parseInt( request.getParameter( PARAMETER_FIELD_ID ) );
327         Sector sector = getAuthorizedSector( request, SectorResourceIdService.PERMISSION_DELETE );
328 
329         if ( sector.getNumberCategories( ) == 0 )
330         {
331             UrlItem url = new UrlItem( JSP_DO_REMOVE_FIELD );
332             url.addParameter( PARAMETER_FIELD_ID, nIdSector );
333 
334             return AdminMessageService.getMessageUrl( request, MESSAGE_CONFIRM_REMOVE_FIELD, url.getUrl( ), AdminMessage.TYPE_CONFIRMATION );
335         }
336 
337         return AdminMessageService.getMessageUrl( request, MESSAGE_CANNOT_REMOVE_FIELD, AdminMessage.TYPE_STOP );
338     }
339 
340     /**
341      * Treats the removal form of a sector
342      * 
343      * @return the jsp URL to display the form to manage sectors
344      * @param request
345      *            The Http request
346      * @throws fr.paris.lutece.portal.service.admin.AccessDeniedException
347      *             access denied exception
348      */
349     public String doDeleteSector( HttpServletRequest request ) throws AccessDeniedException
350     {
351         int nIdSector = Integer.parseInt( request.getParameter( PARAMETER_FIELD_ID ) );
352 
353         Sector sector = getAuthorizedSector( request, SectorResourceIdService.PERMISSION_DELETE );
354         int nOrder = SectorHome.getOrderById( nIdSector );
355         int nNewOrder = SectorHome.getMaxOrderSector( );
356         modifySectorOrder( nOrder, nNewOrder, nIdSector );
357         SectorHome.remove( sector, getPlugin( ) );
358 
359         // if the operation occurred well, redirects towards the list
360         return JSP_REDIRECT_TO_MANAGE_FIELDS;
361     }
362 
363     /**
364      * Modifies the order in the list of contactLists
365      *
366      * @param request
367      *            The Http request
368      * @return The Jsp URL of the process result
369      */
370     public String doModifySectorOrder( HttpServletRequest request )
371     {
372         int nIdSector = Integer.parseInt( request.getParameter( PARAMETER_FIELD_ID ) );
373 
374         int nOrder = SectorHome.getOrderById( nIdSector );
375         int nNewOrder = Integer.parseInt( request.getParameter( PARAMETER_FIELD_ORDER ) );
376         modifySectorOrder( nOrder, nNewOrder, nIdSector );
377 
378         return JSP_REDIRECT_TO_MANAGE_FIELDS;
379     }
380 
381     /**
382      * Builts a list of sequence numbers
383      * 
384      * @return the list of sequence numbers
385      */
386     private ReferenceList getSectorOrderList( )
387     {
388         int nMax = SectorHome.getMaxOrderSector( );
389         ReferenceList list = new ReferenceList( );
390 
391         for ( int i = 1; i < ( nMax + 1 ); i++ )
392         {
393             list.addItem( i, Integer.toString( i ) );
394         }
395 
396         return list;
397     }
398 
399     /**
400      * Modify the place in the list for sector
401      * 
402      * @param nOrder
403      *            the actual place in the list
404      * @param nNewOrder
405      *            the new place in the list
406      * @param nIdSector
407      *            the id of the sector
408      */
409     private void modifySectorOrder( int nOrder, int nNewOrder, int nIdSector )
410     {
411         if ( nNewOrder < nOrder )
412         {
413             for ( int i = nOrder - 1; i > ( nNewOrder - 1 ); i-- )
414             {
415                 int nIdSectorOrder = SectorHome.getIdByOrder( i );
416                 SectorHome.updateOrder( i + 1, nIdSectorOrder );
417             }
418 
419             SectorHome.updateOrder( nNewOrder, nIdSector );
420         }
421         else
422         {
423             for ( int i = nOrder; i < ( nNewOrder + 1 ); i++ )
424             {
425                 int nIdSectorOrder = SectorHome.getIdByOrder( i );
426                 SectorHome.updateOrder( i - 1, nIdSectorOrder );
427             }
428 
429             SectorHome.updateOrder( nNewOrder, nIdSector );
430         }
431     }
432 
433     /**
434      * Return UrlPage Url
435      * 
436      * @return url
437      */
438     private String getUrlPage( )
439     {
440         UrlItem url = new UrlItem( JSP_MANAGE_FIELDS );
441 
442         return url.getUrl( );
443     }
444 
445     /**
446      * Get the authorized Sector
447      *
448      * @param request
449      *            The {@link HttpServletRequest}
450      * @param strPermissionType
451      *            The type of permission (see {@link SectorResourceIdService} class)
452      * @return The sector or null if user have no access
453      * @throws AccessDeniedException
454      *             If the user is not authorized to access this feature
455      */
456     private Sector getAuthorizedSector( HttpServletRequest request, String strPermissionType ) throws AccessDeniedException
457     {
458         String strIdSector = request.getParameter( PARAMETER_FIELD_ID );
459 
460         if ( ( strIdSector == null ) || !strIdSector.matches( REGEX_ID ) )
461         {
462             throw new AccessDeniedException( UNAUTHORIZED );
463         }
464 
465         User user = getUser( );
466         int nIdSector = Integer.parseInt( strIdSector );
467         Sector sector = SectorHome.findByPrimaryKey( nIdSector );
468 
469         if ( ( sector == null ) || !RBACService.isAuthorized( Sector.RESOURCE_TYPE, String.valueOf( sector.getId( ) ), strPermissionType, user ) )
470         {
471             throw new AccessDeniedException( UNAUTHORIZED );
472         }
473 
474         return sector;
475     }
476 }