View Javadoc
1   /*
2    * Copyright (c) 2002-2022, City of Paris
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions
7    * are met:
8    *
9    *  1. Redistributions of source code must retain the above copyright notice
10   *     and the following disclaimer.
11   *
12   *  2. Redistributions in binary form must reproduce the above copyright notice
13   *     and the following disclaimer in the documentation and/or other materials
14   *     provided with the distribution.
15   *
16   *  3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
17   *     contributors may be used to endorse or promote products derived from
18   *     this software without specific prior written permission.
19   *
20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
24   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30   * POSSIBILITY OF SUCH DAMAGE.
31   *
32   * License 1.0
33   */
34  
35  package fr.paris.lutece.plugins.publicdashboard.web;
36  
37  import fr.paris.lutece.portal.service.message.AdminMessage;
38  import fr.paris.lutece.portal.service.message.AdminMessageService;
39  import fr.paris.lutece.portal.service.security.SecurityTokenService;
40  import fr.paris.lutece.portal.service.spring.SpringContextService;
41  import fr.paris.lutece.plugins.publicdashboard.business.PublicDashboard;
42  import fr.paris.lutece.plugins.publicdashboard.business.PublicDashboardHome;
43  import fr.paris.lutece.plugins.publicdashboard.service.PublicDashboardService;
44  import fr.paris.lutece.portal.service.admin.AccessDeniedException;
45  import fr.paris.lutece.portal.service.dashboard.IPublicDashboardComponent;
46  import fr.paris.lutece.portal.service.util.AppException;
47  import fr.paris.lutece.portal.util.mvc.admin.annotations.Controller;
48  import fr.paris.lutece.portal.util.mvc.commons.annotations.Action;
49  import fr.paris.lutece.portal.util.mvc.commons.annotations.View;
50  import fr.paris.lutece.util.url.UrlItem;
51  import fr.paris.lutece.util.ReferenceList;
52  import fr.paris.lutece.util.html.AbstractPaginator;
53  
54  import java.util.Comparator;
55  import java.util.HashMap;
56  import java.util.ArrayList;
57  import java.util.Collections;
58  import java.util.List;
59  import java.util.Map;
60  import java.util.Optional;
61  import java.util.stream.Collectors;
62  import javax.servlet.http.HttpServletRequest;
63  
64  /**
65   * This class provides the user interface to manage Dashboard features ( manage, create, modify, remove )
66   */
67  @Controller( controllerJsp = "ManageDashboards.jsp", controllerPath = "jsp/admin/plugins/publicdashboard/", right = "PUBLICDASHBOARD_MANAGEMENT" )
68  public class PublicDashboardJspBean extends AbstractManagePublicDashboardJspBean<Integer, PublicDashboard>
69  {
70      // Templates
71      private static final String TEMPLATE_MANAGE_DASHBOARDS = "/admin/plugins/publicdashboard/manage_dashboards.html";
72      private static final String TEMPLATE_CREATE_DASHBOARD = "/admin/plugins/publicdashboard/create_dashboard.html";
73      private static final String TEMPLATE_MODIFY_DASHBOARD = "/admin/plugins/publicdashboard/modify_dashboard.html";
74  
75      // Parameters
76      private static final String PARAMETER_ID_DASHBOARD = "id";
77  
78      // Properties for page titles
79      private static final String PROPERTY_PAGE_TITLE_MANAGE_DASHBOARDS = "componentdashboard.manage_dashboards.pageTitle";
80      private static final String PROPERTY_PAGE_TITLE_MODIFY_DASHBOARD = "componentdashboard.modify_dashboard.pageTitle";
81      private static final String PROPERTY_PAGE_TITLE_CREATE_DASHBOARD = "componentdashboard.create_dashboard.pageTitle";
82  
83      // Markers
84      private static final String MARK_DASHBOARD = "dashboard";
85      private static final String MARK_MAP_DESCRIPTION_DASHBOARD = "listtypedashboard";
86      private static final String MARK_ZONE_MAP_DASHBOARD = "mapZoneDashboard";
87  
88      private static final String JSP_MANAGE_DASHBOARDS = "jsp/admin/plugins/publicdashboard/ManageDashboards.jsp";
89  
90      // Properties
91      private static final String MESSAGE_CONFIRM_REMOVE_DASHBOARD = "componentdashboard.message.confirmRemoveDashboard";
92  
93      // Validations
94      private static final String VALIDATION_ATTRIBUTES_PREFIX = "componentdashboard.model.entity.dashboard.attribute.";
95  
96      // Views
97      private static final String VIEW_MANAGE_DASHBOARDS = "manageDashboards";
98      private static final String VIEW_CREATE_DASHBOARD = "createDashboard";
99      private static final String VIEW_MODIFY_DASHBOARD = "modifyDashboard";
100 
101     // Actions
102     private static final String ACTION_CREATE_DASHBOARD = "createDashboard";
103     private static final String ACTION_MODIFY_DASHBOARD = "modifyDashboard";
104     private static final String ACTION_REMOVE_DASHBOARD = "removeDashboard";
105     private static final String ACTION_CONFIRM_REMOVE_DASHBOARD = "confirmRemoveDashboard";
106     private static final String ACTION_MOVE_UP_DASHBOARD = "moveUpDashboard";
107     private static final String ACTION_MOVE_DOWN_DASHBOARD = "moveDownDashboard";
108 
109     // Infos
110     private static final String INFO_DASHBOARD_CREATED = "publicdashboard.info.dashboard.created";
111     private static final String INFO_DASHBOARD_UPDATED = "publicdashboard.info.dashboard.updated";
112     private static final String INFO_DASHBOARD_REMOVED = "publicdashboard.info.dashboard.removed";
113 
114     // Errors
115     private static final String ERROR_RESOURCE_NOT_FOUND = "Resource not found";
116 
117     private static final String PARAMETER_ID = "id";
118     private static final String PARAMETER_ZONE = "zone";
119 
120     private static final String CONSTANT_MOVE_UP = "up";
121     private static final String CONSTANT_MOVE_DOWN = "down";
122 
123     // Session variable to store working values
124     private PublicDashboard _dashboard;
125     private List<Integer> _listIdDashboards;
126 
127     /**
128      * Build the Manage View
129      * 
130      * @param request
131      *            The HTTP request
132      * @return The page
133      */
134     @View( value = VIEW_MANAGE_DASHBOARDS, defaultView = true )
135     public String getManageDashboards( HttpServletRequest request )
136     {
137         _dashboard = null;
138 
139         Map<String, Object> model = getModel( );
140 
141         List<IPublicDashboardComponent> lstDashboard = SpringContextService.getBeansOfType( IPublicDashboardComponent.class );
142         Map<String, String> mapDescriptionDashboard = new HashMap<String, String>( );
143 
144         for ( IPublicDashboardComponent dash : lstDashboard )
145         {
146             mapDescriptionDashboard.put( dash.getComponentId( ), dash.getComponentDescription( getLocale( ) ) );
147         }
148 
149         List<PublicDashboard> lstPublicDashboard = PublicDashboardHome.getDashboardsList( );
150         Collections.sort( lstPublicDashboard );
151 
152         Map<String, List<PublicDashboard>> mapZoneDashboard = PublicDashboardHome.getMapZoneDashboard( lstPublicDashboard );
153 
154         model.put( MARK_MAP_DESCRIPTION_DASHBOARD, mapDescriptionDashboard );
155         model.put( MARK_ZONE_MAP_DASHBOARD, mapZoneDashboard );
156 
157         return getPage( PROPERTY_PAGE_TITLE_MANAGE_DASHBOARDS, TEMPLATE_MANAGE_DASHBOARDS, model );
158     }
159 
160     /**
161      * Returns the form to create a dashboard
162      *
163      * @param request
164      *            The Http request
165      * @return the html code of the dashboard form
166      */
167     @View( VIEW_CREATE_DASHBOARD )
168     public String getCreateDashboard( HttpServletRequest request )
169     {
170         _dashboard = ( _dashboard != null ) ? _dashboard : new PublicDashboard( );
171 
172         Map<String, Object> model = getModel( );
173 
174         List<IPublicDashboardComponent> lstDashboard = SpringContextService.getBeansOfType( IPublicDashboardComponent.class );
175         ReferenceList reflstDashboard = new ReferenceList( );
176 
177         for ( IPublicDashboardComponent dash : lstDashboard )
178         {
179             reflstDashboard.addItem( dash.getComponentId( ), dash.getComponentDescription( getLocale( ) ) );
180         }
181 
182         _dashboard.setZone( Integer.valueOf( request.getParameter( PARAMETER_ZONE ) ) );
183 
184         model.put( MARK_DASHBOARD, _dashboard );
185         model.put( MARK_MAP_DESCRIPTION_DASHBOARD, reflstDashboard );
186         model.put( SecurityTokenService.MARK_TOKEN, SecurityTokenService.getInstance( ).getToken( request, ACTION_CREATE_DASHBOARD ) );
187 
188         return getPage( PROPERTY_PAGE_TITLE_CREATE_DASHBOARD, TEMPLATE_CREATE_DASHBOARD, model );
189     }
190 
191     /**
192      * Move up component
193      *
194      * @param request
195      *            The Http request
196      * @return the jsp URL to display modify panel
197      */
198     @Action( ACTION_MOVE_UP_DASHBOARD )
199     public String doMoveUpComponent( HttpServletRequest request )
200     {
201         doMoveDashboard( request, CONSTANT_MOVE_UP );
202 
203         return redirectView( request, VIEW_MANAGE_DASHBOARDS );
204     }
205 
206     /**
207      * move down component
208      *
209      * @param request
210      *            The Http request
211      * @return The jsp URL to display modify panel
212      */
213     @Action( ACTION_MOVE_DOWN_DASHBOARD )
214     public String doMoveDownComponent( HttpServletRequest request )
215     {
216         doMoveDashboard( request, CONSTANT_MOVE_DOWN );
217 
218         return redirectView( request, VIEW_MANAGE_DASHBOARDS );
219     }
220 
221     private void doMoveDashboard( HttpServletRequest request, String movement )
222     {
223         int nId = Integer.parseInt( request.getParameter( PARAMETER_ID ) );
224 
225         Optional<PublicDashboard> opt_public_dashboard = PublicDashboardHome.findByPrimaryKey( nId );
226 
227         if ( opt_public_dashboard.isPresent( ) )
228         {
229             PublicDashboard publicDashboardSelected = opt_public_dashboard.get( );
230             List<PublicDashboard> listDashboard = PublicDashboardHome.getDashboardsListFromZone( Integer.valueOf( request.getParameter( PARAMETER_ZONE ) ) );
231 
232             int nbPosition = 0;
233 
234             for ( PublicDashboard dashboard : listDashboard )
235             {
236                 if ( movement.equals( CONSTANT_MOVE_UP ) )
237                 {
238                     if ( ( dashboard.getId( ) == publicDashboardSelected.getId( ) ) && ( nbPosition != 0 ) )
239                     {
240                         PublicDashboard dashboardNewPosition = listDashboard.get( nbPosition - 1 );
241                         int nNewPosition = dashboardNewPosition.getPosition( );
242                         dashboardNewPosition.setPosition( publicDashboardSelected.getPosition( ) );
243                         publicDashboardSelected.setPosition( nNewPosition );
244                         PublicDashboardHome.update( dashboardNewPosition );
245                         PublicDashboardHome.update( publicDashboardSelected );
246                     }
247                 }
248                 else
249                     if ( movement.equals( CONSTANT_MOVE_DOWN ) )
250                     {
251                         if ( ( dashboard.getId( ) == publicDashboardSelected.getId( ) ) && ( nbPosition != ( listDashboard.size( ) - 1 ) ) )
252                         {
253                             PublicDashboard dashboardNewPosition = listDashboard.get( nbPosition + 1 );
254                             int nNewPosition = dashboardNewPosition.getPosition( );
255                             dashboardNewPosition.setPosition( publicDashboardSelected.getPosition( ) );
256                             publicDashboardSelected.setPosition( nNewPosition );
257                             PublicDashboardHome.update( dashboardNewPosition );
258                             PublicDashboardHome.update( publicDashboardSelected );
259                         }
260                     }
261                 nbPosition++;
262             }
263         }
264     }
265 
266     /**
267      * Process the data capture form of a new dashboard
268      *
269      * @param request
270      *            The Http Request
271      * @return The Jsp URL of the process result
272      * @throws AccessDeniedException
273      */
274     @Action( ACTION_CREATE_DASHBOARD )
275     public String doCreateDashboard( HttpServletRequest request ) throws AccessDeniedException
276     {
277         populate( _dashboard, request, getLocale( ) );
278 
279         if ( !SecurityTokenService.getInstance( ).validate( request, ACTION_CREATE_DASHBOARD ) )
280         {
281             throw new AccessDeniedException( "Invalid security token" );
282         }
283 
284         // Check constraints
285         if ( !validateBean( _dashboard, VALIDATION_ATTRIBUTES_PREFIX ) )
286         {
287             return redirectView( request, VIEW_CREATE_DASHBOARD );
288         }
289         
290         _dashboard.setPosition( PublicDashboardService.getLastPosition(_dashboard) );
291         PublicDashboardHome.create( _dashboard );
292         addInfo( INFO_DASHBOARD_CREATED, getLocale( ) );
293 
294         return redirectView( request, VIEW_MANAGE_DASHBOARDS );
295     }
296 
297     /**
298      * Manages the removal form of a dashboard whose identifier is in the http request
299      *
300      * @param request
301      *            The Http request
302      * @return the html code to confirm
303      */
304     @Action( ACTION_CONFIRM_REMOVE_DASHBOARD )
305     public String getConfirmRemoveDashboard( HttpServletRequest request )
306     {
307         int nId = Integer.parseInt( request.getParameter( PARAMETER_ID_DASHBOARD ) );
308         UrlItem url = new UrlItem( getActionUrl( ACTION_REMOVE_DASHBOARD ) );
309         url.addParameter( PARAMETER_ID_DASHBOARD, nId );
310 
311         String strMessageUrl = AdminMessageService.getMessageUrl( request, MESSAGE_CONFIRM_REMOVE_DASHBOARD, url.getUrl( ), AdminMessage.TYPE_CONFIRMATION );
312 
313         return redirect( request, strMessageUrl );
314     }
315 
316     /**
317      * Handles the removal form of a dashboard
318      *
319      * @param request
320      *            The Http request
321      * @return the jsp URL to display the form to manage dashboards
322      */
323     @Action( ACTION_REMOVE_DASHBOARD )
324     public String doRemoveDashboard( HttpServletRequest request )
325     {
326         int nId = Integer.parseInt( request.getParameter( PARAMETER_ID_DASHBOARD ) );
327 
328         PublicDashboardHome.remove( nId );
329         addInfo( INFO_DASHBOARD_REMOVED, getLocale( ) );
330 
331         return redirectView( request, VIEW_MANAGE_DASHBOARDS );
332     }
333 
334     /**
335      * Returns the form to update info about a dashboard
336      *
337      * @param request
338      *            The Http request
339      * @return The HTML form to update info
340      */
341     @View( VIEW_MODIFY_DASHBOARD )
342     public String getModifyDashboard( HttpServletRequest request )
343     {
344         int nId = Integer.parseInt( request.getParameter( PARAMETER_ID_DASHBOARD ) );
345 
346         if ( _dashboard == null || ( _dashboard.getId( ) != nId ) )
347         {
348             Optional<PublicDashboard> optDashboard = PublicDashboardHome.findByPrimaryKey( nId );
349             _dashboard = optDashboard.orElseThrow( ( ) -> new AppException( ERROR_RESOURCE_NOT_FOUND ) );
350         }
351 
352         Map<String, Object> model = getModel( );
353 
354         List<IPublicDashboardComponent> lstDashboard = SpringContextService.getBeansOfType( IPublicDashboardComponent.class );
355         ReferenceList reflstDashboard = new ReferenceList( );
356 
357         for ( IPublicDashboardComponent dash : lstDashboard )
358         {
359             reflstDashboard.addItem( dash.getComponentId( ), dash.getComponentDescription( getLocale( ) ) );
360         }
361 
362         model.put( MARK_DASHBOARD, _dashboard );
363         model.put( MARK_MAP_DESCRIPTION_DASHBOARD, reflstDashboard );
364         model.put( SecurityTokenService.MARK_TOKEN, SecurityTokenService.getInstance( ).getToken( request, ACTION_MODIFY_DASHBOARD ) );
365 
366         return getPage( PROPERTY_PAGE_TITLE_MODIFY_DASHBOARD, TEMPLATE_MODIFY_DASHBOARD, model );
367     }
368 
369     /**
370      * Process the change form of a dashboard
371      *
372      * @param request
373      *            The Http request
374      * @return The Jsp URL of the process result
375      * @throws AccessDeniedException
376      */
377     @Action( ACTION_MODIFY_DASHBOARD )
378     public String doModifyDashboard( HttpServletRequest request ) throws AccessDeniedException
379     {
380         populate( _dashboard, request, getLocale( ) );
381 
382         if ( !SecurityTokenService.getInstance( ).validate( request, ACTION_MODIFY_DASHBOARD ) )
383         {
384             throw new AccessDeniedException( "Invalid security token" );
385         }
386 
387         // Check constraints
388         if ( !validateBean( _dashboard, VALIDATION_ATTRIBUTES_PREFIX ) )
389         {
390             return redirect( request, VIEW_MODIFY_DASHBOARD, PARAMETER_ID_DASHBOARD, _dashboard.getId( ) );
391         }
392 
393         PublicDashboardHome.update( _dashboard );
394         addInfo( INFO_DASHBOARD_UPDATED, getLocale( ) );
395 
396         return redirectView( request, VIEW_MANAGE_DASHBOARDS );
397     }
398 }