View Javadoc
1   /*
2    * Copyright (c) 2002-2023, 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   
36  package fr.paris.lutece.plugins.broadcastproxy.web;
37  
38  import java.util.ArrayList;
39  import java.util.Comparator;
40  import java.util.List;
41  import java.util.Map;
42  import java.util.Optional;
43  import java.util.stream.Collectors;
44  
45  import javax.servlet.http.HttpServletRequest;
46  
47  import org.apache.commons.fileupload.FileItem;
48  import org.apache.commons.lang3.StringUtils;
49  
50  import fr.paris.lutece.plugins.broadcastproxy.business.SubscriptionLink;
51  import fr.paris.lutece.plugins.broadcastproxy.business.SubscriptionLinkHome;
52  import fr.paris.lutece.portal.service.admin.AccessDeniedException;
53  import fr.paris.lutece.portal.service.file.FileService;
54  import fr.paris.lutece.portal.service.file.FileServiceException;
55  import fr.paris.lutece.portal.service.fileimage.FileImagePublicService;
56  import fr.paris.lutece.portal.service.message.AdminMessage;
57  import fr.paris.lutece.portal.service.message.AdminMessageService;
58  import fr.paris.lutece.portal.service.security.SecurityTokenService;
59  import fr.paris.lutece.portal.service.util.AppException;
60  import fr.paris.lutece.portal.service.util.AppLogService;
61  import fr.paris.lutece.portal.util.mvc.admin.annotations.Controller;
62  import fr.paris.lutece.portal.util.mvc.commons.annotations.Action;
63  import fr.paris.lutece.portal.util.mvc.commons.annotations.View;
64  import fr.paris.lutece.portal.web.upload.MultipartHttpServletRequest;
65  import fr.paris.lutece.util.html.AbstractPaginator;
66  import fr.paris.lutece.util.url.UrlItem;
67  
68  /**
69   * This class provides the user interface to manage SubscriptionLink features ( manage, create, modify, remove )
70   */
71  @Controller( controllerJsp = "ManageSubscriptionLinks.jsp", controllerPath = "jsp/admin/plugins/broadcastproxy/", right = "BROADCASTPROXY_MANAGEMENT_NEWSLETTERS" )
72  public class SubscriptionLinkJspBean extends AbstractManageSubscriptionJspBean <Integer, SubscriptionLink>
73  {
74      // Templates
75      private static final String TEMPLATE_MANAGE_SUBSCRIPTIONLINKS = "/admin/plugins/broadcastproxy/manage_subscriptionlinks.html";
76      private static final String TEMPLATE_CREATE_SUBSCRIPTIONLINK = "/admin/plugins/broadcastproxy/create_subscriptionlink.html";
77      private static final String TEMPLATE_MODIFY_SUBSCRIPTIONLINK = "/admin/plugins/broadcastproxy/modify_subscriptionlink.html";
78  
79      // Parameters
80      private static final String PARAMETER_ID_SUBSCRIPTIONLINK = "id";
81  
82      // Properties for page titles
83      private static final String PROPERTY_PAGE_TITLE_MANAGE_SUBSCRIPTIONLINKS = "broadcastproxy.manage_subscriptionlinks.pageTitle";
84      private static final String PROPERTY_PAGE_TITLE_MODIFY_SUBSCRIPTIONLINK = "broadcastproxy.modify_subscriptionlink.pageTitle";
85      private static final String PROPERTY_PAGE_TITLE_CREATE_SUBSCRIPTIONLINK = "broadcastproxy.create_subscriptionlink.pageTitle";
86  
87      // Markers
88      private static final String MARK_SUBSCRIPTIONLINK_LIST = "subscriptionlink_list";
89      private static final String MARK_SUBSCRIPTIONLINK = "subscriptionlink";
90      private static final String MARK_PICTOGRAMME = "pictogramme";
91      
92      private static final String JSP_MANAGE_SUBSCRIPTIONLINKS = "jsp/admin/plugins/broadcastproxy/ManageSubscriptionLinks.jsp";
93  
94      // Properties
95      private static final String MESSAGE_CONFIRM_REMOVE_SUBSCRIPTIONLINK = "broadcastproxy.message.confirmRemoveSubscriptionLink";
96  
97      // Validations
98      private static final String VALIDATION_ATTRIBUTES_PREFIX = "broadcastproxy.model.entity.subscriptionlink.attribute.";
99  
100     // Views
101     private static final String VIEW_MANAGE_SUBSCRIPTIONLINKS = "manageSubscriptionLinks";
102     private static final String VIEW_CREATE_SUBSCRIPTIONLINK = "createSubscriptionLink";
103     private static final String VIEW_MODIFY_SUBSCRIPTIONLINK = "modifySubscriptionLink";
104 
105     // Actions
106     private static final String ACTION_CREATE_SUBSCRIPTIONLINK = "createSubscriptionLink";
107     private static final String ACTION_MODIFY_SUBSCRIPTIONLINK = "modifySubscriptionLink";
108     private static final String ACTION_REMOVE_SUBSCRIPTIONLINK = "removeSubscriptionLink";
109     private static final String ACTION_CONFIRM_REMOVE_SUBSCRIPTIONLINK = "confirmRemoveSubscriptionLink";
110     private static final String ACTION_DELETE_PICTOGRAMME = "deletePictogramme";
111   
112 
113     // Infos
114     private static final String INFO_SUBSCRIPTIONLINK_CREATED = "broadcastproxy.info.subscriptionlink.created";
115     private static final String INFO_SUBSCRIPTIONLINK_UPDATED = "broadcastproxy.info.subscriptionlink.updated";
116     private static final String INFO_SUBSCRIPTIONLINK_REMOVED = "broadcastproxy.info.subscriptionlink.removed";
117     
118     // Warnings
119     private static final String WARNING_SUBSCRIPTIONLINK_ENABLED = "broadcastproxy.warning.subscriptionlink.enabled";
120     
121     // Errors
122     private static final String ERROR_RESOURCE_NOT_FOUND = "Resource not found";
123 
124     
125     // Session variable to store working values
126     private SubscriptionLink _subscriptionlink;
127     private List<Integer> _listIdSubscriptionLinks;
128     
129     /**
130      * Build the Manage View
131      * @param request The HTTP request
132      * @return The page
133      */
134     @View( value = VIEW_MANAGE_SUBSCRIPTIONLINKS, defaultView = true )
135     public String getManageSubscriptionLinks( HttpServletRequest request )
136     {
137         _subscriptionlink = null;
138         
139         if ( request.getParameter( AbstractPaginator.PARAMETER_PAGE_INDEX) == null || _listIdSubscriptionLinks.isEmpty( ) )
140         {
141         	_listIdSubscriptionLinks = SubscriptionLinkHome.getIdSubscriptionLinksList(  );
142         }
143         
144         Map<String, Object> model = getPaginatedListModel( request, MARK_SUBSCRIPTIONLINK_LIST, _listIdSubscriptionLinks, JSP_MANAGE_SUBSCRIPTIONLINKS );
145         
146         if ( SubscriptionLinkHome.existDisabledNewsletter( ) )  
147         {
148             addWarning( WARNING_SUBSCRIPTIONLINK_ENABLED, getLocale( ) );
149         }
150         return getPage( PROPERTY_PAGE_TITLE_MANAGE_SUBSCRIPTIONLINKS, TEMPLATE_MANAGE_SUBSCRIPTIONLINKS, model );
151     }
152 
153 	/**
154      * Get Items from Ids list
155      * @param listIds
156      * @return the populated list of items corresponding to the id List
157      */
158 	@Override
159 	List<SubscriptionLink> getItemsFromIds( List<Integer> listIds ) 
160 	{
161 		List<SubscriptionLink> listSubscriptionLink = SubscriptionLinkHome.getSubscriptionLinksListByIds( listIds );
162 		
163 		// keep original order
164         return listSubscriptionLink.stream()
165                  .sorted(Comparator.comparingInt( notif -> listIds.indexOf( notif.getId())))
166                  .collect(Collectors.toList());
167 	}
168     
169     /**
170     * reset the _listIdSubscriptionLinks list
171     */
172     public void resetListId( )
173     {
174     	_listIdSubscriptionLinks = new ArrayList<>( );
175     }
176 
177     /**
178      * Returns the form to create a subscriptionlink
179      *
180      * @param request The Http request
181      * @return the html code of the subscriptionlink form
182      */
183     @View( VIEW_CREATE_SUBSCRIPTIONLINK )
184     public String getCreateSubscriptionLink( HttpServletRequest request )
185     {
186         _subscriptionlink = ( _subscriptionlink != null ) ? _subscriptionlink : new SubscriptionLink(  );
187 
188         Map<String, Object> model = getModel(  );
189         model.put( MARK_SUBSCRIPTIONLINK, _subscriptionlink );
190         model.put( SecurityTokenService.MARK_TOKEN, SecurityTokenService.getInstance( ).getToken( request, ACTION_CREATE_SUBSCRIPTIONLINK ) );
191 
192         return getPage( PROPERTY_PAGE_TITLE_CREATE_SUBSCRIPTIONLINK, TEMPLATE_CREATE_SUBSCRIPTIONLINK, model );
193     }
194 
195     /**
196      * Process the data capture form of a new subscriptionlink
197      *
198      * @param request The Http Request
199      * @return The Jsp URL of the process result
200      * @throws AccessDeniedException
201      */
202     @Action( ACTION_CREATE_SUBSCRIPTIONLINK )
203     public String doCreateSubscriptionLink( HttpServletRequest request ) throws AccessDeniedException
204     {
205         populate( _subscriptionlink, request, getLocale( ) );
206         
207         if ( !SecurityTokenService.getInstance( ).validate( request, ACTION_CREATE_SUBSCRIPTIONLINK ) )
208         {
209             throw new AccessDeniedException ( "Invalid security token" );
210         }
211         // Check constraints
212         if ( !validateBean( _subscriptionlink, VALIDATION_ATTRIBUTES_PREFIX ) )
213         {
214             return redirectView( request, VIEW_CREATE_SUBSCRIPTIONLINK );
215         }
216         
217         MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
218 
219         FileItem fileParameterBinaryValue = multipartRequest.getFile( "pictogramme" );
220 
221         FileImagePublicService.init( );
222         if( fileParameterBinaryValue.getSize( ) > 0 )
223         {
224             _subscriptionlink.setPictogramme( FileImagePublicService.getInstance( ).addImageResource( fileParameterBinaryValue ));
225         }
226         
227         SubscriptionLinkHome.create( _subscriptionlink );
228         addInfo( INFO_SUBSCRIPTIONLINK_CREATED, getLocale(  ) );
229         resetListId( );
230 
231         return redirectView( request, VIEW_MANAGE_SUBSCRIPTIONLINKS );
232     }
233 
234     /**
235      * Manages the removal form of a subscriptionlink whose identifier is in the http
236      * request
237      *
238      * @param request The Http request
239      * @return the html code to confirm
240      */
241     @Action( ACTION_CONFIRM_REMOVE_SUBSCRIPTIONLINK )
242     public String getConfirmRemoveSubscriptionLink( HttpServletRequest request )
243     {
244         int nId = Integer.parseInt( request.getParameter( PARAMETER_ID_SUBSCRIPTIONLINK ) );
245         UrlItem url = new UrlItem( getActionUrl( ACTION_REMOVE_SUBSCRIPTIONLINK ) );
246         url.addParameter( PARAMETER_ID_SUBSCRIPTIONLINK, nId );
247 
248         String strMessageUrl = AdminMessageService.getMessageUrl( request, MESSAGE_CONFIRM_REMOVE_SUBSCRIPTIONLINK, url.getUrl(  ), AdminMessage.TYPE_CONFIRMATION );
249 
250         return redirect( request, strMessageUrl );
251     }
252 
253     /**
254      * Handles the removal form of a subscriptionlink
255      *
256      * @param request The Http request
257      * @return the jsp URL to display the form to manage subscriptionlinks
258      */
259     @Action( ACTION_REMOVE_SUBSCRIPTIONLINK )
260     public String doRemoveSubscriptionLink( HttpServletRequest request )
261     {
262         int nId = Integer.parseInt( request.getParameter( PARAMETER_ID_SUBSCRIPTIONLINK ) );
263         
264         if ( _subscriptionlink == null || ( _subscriptionlink.getId(  ) != nId ) )
265         {
266             Optional<SubscriptionLink> optSubscriptionLink = SubscriptionLinkHome.findByPrimaryKey( nId );
267             _subscriptionlink = optSubscriptionLink.orElseThrow( ( ) -> new AppException(ERROR_RESOURCE_NOT_FOUND ) );
268         }
269         
270         if ( StringUtils.isNumeric( _subscriptionlink.getPictogramme( ) ) )
271         {
272             try {
273 				FileService.getInstance( ).getFileStoreServiceProvider( ).delete( _subscriptionlink.getPictogramme( ) );
274 			} catch (FileServiceException e) {
275 				AppLogService.error(e);
276 			}
277         }
278         
279         SubscriptionLinkHome.remove( nId );
280         addInfo( INFO_SUBSCRIPTIONLINK_REMOVED, getLocale(  ) );
281         resetListId( );
282 
283         return redirectView( request, VIEW_MANAGE_SUBSCRIPTIONLINKS );
284     }
285 
286     /**
287      * Returns the form to update info about a subscriptionlink
288      *
289      * @param request The Http request
290      * @return The HTML form to update info
291      */
292     @View( VIEW_MODIFY_SUBSCRIPTIONLINK )
293     public String getModifySubscriptionLink( HttpServletRequest request )
294     {
295         int nId = Integer.parseInt( request.getParameter( PARAMETER_ID_SUBSCRIPTIONLINK ) );
296 
297         if ( _subscriptionlink == null || ( _subscriptionlink.getId(  ) != nId ) )
298         {
299             Optional<SubscriptionLink> optSubscriptionLink = SubscriptionLinkHome.findByPrimaryKey( nId );
300             _subscriptionlink = optSubscriptionLink.orElseThrow( ( ) -> new AppException(ERROR_RESOURCE_NOT_FOUND ) );
301         }
302 
303         FileImagePublicService.init( );
304         Map<String, Object> model = getModel(  );
305         model.put( MARK_SUBSCRIPTIONLINK, _subscriptionlink );
306         model.put( SecurityTokenService.MARK_TOKEN, SecurityTokenService.getInstance( ).getToken( request, ACTION_MODIFY_SUBSCRIPTIONLINK ) );
307 
308         return getPage( PROPERTY_PAGE_TITLE_MODIFY_SUBSCRIPTIONLINK, TEMPLATE_MODIFY_SUBSCRIPTIONLINK, model );
309     }
310 
311     /**
312      * Process the change form of a subscriptionlink
313      *
314      * @param request The Http request
315      * @return The Jsp URL of the process result
316      * @throws AccessDeniedException
317      */
318     @Action( ACTION_MODIFY_SUBSCRIPTIONLINK )
319     public String doModifySubscriptionLink( HttpServletRequest request ) throws AccessDeniedException
320     {   
321         populate( _subscriptionlink, request, getLocale( ) );
322 		
323 		
324         if ( !SecurityTokenService.getInstance( ).validate( request, ACTION_MODIFY_SUBSCRIPTIONLINK ) )
325         {
326             throw new AccessDeniedException ( "Invalid security token" );
327         }
328 
329         // Check constraints
330         if ( !validateBean( _subscriptionlink, VALIDATION_ATTRIBUTES_PREFIX ) )
331         {
332             return redirect( request, VIEW_MODIFY_SUBSCRIPTIONLINK, PARAMETER_ID_SUBSCRIPTIONLINK, _subscriptionlink.getId( ) );
333         }
334         
335         FileImagePublicService.init( );
336         if( StringUtils.isEmpty( _subscriptionlink.getPictogramme( ) ) 
337                 || FileImagePublicService.getInstance( ).getImageResource( Integer.parseInt( _subscriptionlink.getPictogramme( ) ) ) == null  )
338         {
339             MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;   
340             FileItem fileParameterBinaryValue = multipartRequest.getFile( "pictogramme" );
341             
342             if( fileParameterBinaryValue.getSize( ) > 0 )
343             {
344                 _subscriptionlink.setPictogramme( FileImagePublicService.getInstance( ).addImageResource( fileParameterBinaryValue ));
345             }
346         }
347 
348         SubscriptionLinkHome.update( _subscriptionlink );
349         addInfo( INFO_SUBSCRIPTIONLINK_UPDATED, getLocale(  ) );
350         resetListId( );
351 
352         return redirectView( request, VIEW_MANAGE_SUBSCRIPTIONLINKS );
353     }
354     
355     @Action( ACTION_DELETE_PICTOGRAMME )
356     public String doDeletePictogramme( HttpServletRequest request )
357     {
358         String strIdPictogramme = request.getParameter( MARK_PICTOGRAMME );
359         int nId = Integer.parseInt( request.getParameter( PARAMETER_ID_SUBSCRIPTIONLINK ) );
360 
361         if ( _subscriptionlink == null || ( _subscriptionlink.getId(  ) != nId ) )
362         {
363             Optional<SubscriptionLink> optSubscriptionLink = SubscriptionLinkHome.findByPrimaryKey( nId );
364             _subscriptionlink = optSubscriptionLink.orElseThrow( ( ) -> new AppException(ERROR_RESOURCE_NOT_FOUND ) );
365         }
366 
367         if ( StringUtils.isNumeric( strIdPictogramme ) )
368         {
369             try {
370 				FileService.getInstance( ).getFileStoreServiceProvider( ).delete( strIdPictogramme );
371 				_subscriptionlink.setPictogramme( StringUtils.EMPTY );
372 	            SubscriptionLinkHome.update( _subscriptionlink );
373 			} catch (FileServiceException e) {
374 				AppLogService.error(e);
375 				return "{\"status\":\"failed\"}";
376 			}            
377         }
378 
379         return "{\"status\":\"success\"}";
380     }
381     
382 }