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.service;
35  
36  import fr.paris.lutece.plugins.announce.business.*;
37  import fr.paris.lutece.plugins.announce.web.AnnounceApp;
38  import fr.paris.lutece.plugins.module.announce.subscribe.business.AnnounceSubscribtionDTO;
39  import fr.paris.lutece.plugins.module.announce.subscribe.service.AnnounceSubscriptionService;
40  import fr.paris.lutece.plugins.subscribe.business.Subscription;
41  import fr.paris.lutece.plugins.subscribe.business.SubscriptionFilter;
42  import fr.paris.lutece.plugins.subscribe.service.ISubscriptionProviderService;
43  import fr.paris.lutece.portal.service.security.LuteceUser;
44  import fr.paris.lutece.portal.service.security.LuteceUserService;
45  import fr.paris.lutece.portal.service.spring.SpringContextService;
46  import fr.paris.lutece.portal.service.template.AppTemplateService;
47  import fr.paris.lutece.portal.web.LocalVariables;
48  import fr.paris.lutece.util.html.HtmlTemplate;
49  
50  import org.apache.commons.collections.CollectionUtils;
51  import org.apache.commons.lang3.StringUtils;
52  
53  import java.util.HashMap;
54  import java.util.List;
55  import java.util.Locale;
56  import java.util.Map;
57  
58  /**
59   * Subscription provider service for announces
60   */
61  public class AnnounceSubscriptionProvider implements ISubscriptionProviderService
62  {
63      /**
64       * Subscription key to subscribe to announces published by users
65       */
66      public static final String SUBSCRIPTION_USER = "announce_user";
67  
68      /**
69       * Subscription key to subscribe to announces of a given category
70       */
71      public static final String SUBSCRIPTION_CATEGORY = "announce_category";
72  
73      /**
74       * Subscription key to subscribe to announces matching a filter
75       */
76      public static final String SUBSCRIPTION_FILTER = "announce_filter";
77  
78      // Markers
79      private static final String MARK_FILTER = "filter";
80      private static final String MARK_CATEGORY = "category";
81      private static final String MARK_USER_NAME = "user_name";
82      private static final String MARK_USER = "user";
83      private static final String PROVIDER_NAME = "announce.announceSubscriptionProvider";
84      private static final String BEAN_NAME = "announce.announceSubscriptionProvider";
85  
86      // Templates
87      private static final String TEMPLATE_FILTER_SUBSCRIPTION_DESCRIPTION = "skin/plugins/announce/subscription/filter_subscriction_description.html";
88      private static final String TEMPLATE_USER_SUBSCRIPTION_DESCRIPTION = "skin/plugins/announce/subscription/user_subscriction_description.html";
89      private static final String TEMPLATE_CATEGORY_SUBSCRIPTION_DESCRIPTION = "skin/plugins/announce/subscription/category_subscriction_description.html";
90      private static volatile AnnounceSubscriptionProvider _instance;
91  
92      /**
93       * {@inheritDoc}
94       */
95      @Override
96      public String getProviderName( )
97      {
98          return PROVIDER_NAME;
99      }
100 
101     /**
102      * Get the instance of the service
103      * 
104      * @return The instance of the service
105      */
106     public static AnnounceSubscriptionProvider getService( )
107     {
108         if ( _instance == null )
109         {
110             _instance = SpringContextService.getBean( BEAN_NAME );
111         }
112 
113         return _instance;
114     }
115 
116     /**
117      * {@inheritDoc}
118      */
119     @Override
120     public String getSubscriptionHtmlDescription( LuteceUser user, String strSubscriptionKey, String strIdSubscribedResource, Locale locale )
121     {
122         if ( StringUtils.equals( SUBSCRIPTION_USER, strSubscriptionKey ) )
123         {
124             Map<String, Object> model = new HashMap<>( );
125             LuteceUser subscribedUser = LuteceUserService.getLuteceUserFromName( strIdSubscribedResource );
126 
127             model.put( MARK_USER_NAME, strIdSubscribedResource );
128             model.put( MARK_USER, subscribedUser );
129 
130             HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_USER_SUBSCRIPTION_DESCRIPTION, locale, model );
131 
132             return template.getHtml( );
133         }
134         else
135             if ( StringUtils.equals( SUBSCRIPTION_CATEGORY, strSubscriptionKey ) )
136             {
137                 Map<String, Object> model = new HashMap<>( );
138 
139                 int nIdCategory = Integer.parseInt( strIdSubscribedResource );
140 
141                 model.put( MARK_CATEGORY, CategoryHome.findByPrimaryKey( nIdCategory ) );
142 
143                 HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_CATEGORY_SUBSCRIPTION_DESCRIPTION, locale, model );
144 
145                 return template.getHtml( );
146             }
147             else
148                 if ( StringUtils.equals( SUBSCRIPTION_FILTER, strSubscriptionKey ) )
149                 {
150                     AnnounceSearchFilter filter = AnnounceSearchFilterHome.findByPrimaryKey( Integer.parseInt( strIdSubscribedResource ) );
151                     Map<String, Object> model = new HashMap<>( );
152                     model.put( MARK_FILTER, filter );
153 
154                     if ( filter.getIdCategory( ) > 0 )
155                     {
156                         model.put( MARK_CATEGORY, CategoryHome.findByPrimaryKey( filter.getIdCategory( ) ) );
157                     }
158 
159                     HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_FILTER_SUBSCRIPTION_DESCRIPTION, locale, model );
160 
161                     return template.getHtml( );
162                 }
163 
164         return StringUtils.EMPTY;
165     }
166 
167     /**
168      * {@inheritDoc}
169      */
170     @Override
171     public String getSubscriptionHtmlDescriptionBis( LuteceUser user, String strSubscriptionKey, String strIdSubscribedResource, Locale locale, String userSub )
172     {
173         if ( StringUtils.equals( SUBSCRIPTION_USER, strSubscriptionKey ) )
174         {
175             Map<String, Object> model = new HashMap<>( );
176 
177             List<Announce> listAnn = AnnounceHome.findAllPublished( AnnounceSort.DEFAULT_SORT );
178             String strUserSub = "";
179             for ( Announce ann : listAnn )
180             {
181                 if ( userSub.compareTo( ann.getUserName( ) ) == 0 )
182                 {
183                     strUserSub = ann.getUserLastName( ) + " " + ann.getUserSecondName( );
184                     break;
185                 }
186             }
187 
188             model.put( MARK_USER_NAME, strIdSubscribedResource );
189             model.put( "strUserSub", strUserSub );
190 
191             HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_USER_SUBSCRIPTION_DESCRIPTION, locale, model );
192 
193             return template.getHtml( );
194         }
195         else
196             if ( StringUtils.equals( SUBSCRIPTION_CATEGORY, strSubscriptionKey ) )
197             {
198                 Map<String, Object> model = new HashMap<>( );
199 
200                 int nIdCategory = Integer.parseInt( strIdSubscribedResource );
201 
202                 model.put( MARK_CATEGORY, CategoryHome.findByPrimaryKey( nIdCategory ) );
203 
204                 HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_CATEGORY_SUBSCRIPTION_DESCRIPTION, locale, model );
205 
206                 return template.getHtml( );
207             }
208             else
209                 if ( StringUtils.equals( SUBSCRIPTION_FILTER, strSubscriptionKey ) )
210                 {
211                     AnnounceSearchFilter filter = AnnounceSearchFilterHome.findByPrimaryKey( Integer.parseInt( strIdSubscribedResource ) );
212                     Map<String, Object> model = new HashMap<>( );
213                     model.put( MARK_FILTER, filter );
214 
215                     if ( filter.getIdCategory( ) > 0 )
216                     {
217                         model.put( MARK_CATEGORY, CategoryHome.findByPrimaryKey( filter.getIdCategory( ) ) );
218                     }
219 
220                     HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_FILTER_SUBSCRIPTION_DESCRIPTION, locale, model );
221 
222                     return template.getHtml( );
223                 }
224 
225         return StringUtils.EMPTY;
226     }
227 
228     /**
229      * {@inheritDoc}
230      */
231     @Override
232     public boolean isSubscriptionRemovable( LuteceUser user, String strSubscriptionKey, String strIdSubscribedResource )
233     {
234         // Subscriptions to user and filters are always removable
235         return true;
236     }
237 
238     /**
239      * {@inheritDoc}
240      */
241     @Override
242     public String getUrlModifySubscription( LuteceUser user, String strSubscriptionKey, String strIdSubscribedResource )
243     {
244         if ( StringUtils.equals( SUBSCRIPTION_FILTER, strSubscriptionKey ) )
245         {
246             int nIdFilter = ( StringUtils.isNotEmpty( strIdSubscribedResource ) && StringUtils.isNumeric( strIdSubscribedResource ) )
247                     ? Integer.parseInt( strIdSubscribedResource )
248                     : 0;
249 
250             if ( nIdFilter > 0 )
251             {
252                 return AnnounceApp.getUrlSearchAnnounce( LocalVariables.getRequest( ), nIdFilter );
253             }
254         }
255         else
256             if ( StringUtils.equals( SUBSCRIPTION_USER, strSubscriptionKey ) )
257             {
258                 return AnnounceApp.getUrlViewUserAnnounces( LocalVariables.getRequest( ), strIdSubscribedResource );
259             }
260             else
261                 if ( StringUtils.equals( SUBSCRIPTION_CATEGORY, strSubscriptionKey ) )
262                 {
263                     int nIdCategory = ( StringUtils.isNotEmpty( strIdSubscribedResource ) && StringUtils.isNumeric( strIdSubscribedResource ) )
264                             ? Integer.parseInt( strIdSubscribedResource )
265                             : 0;
266 
267                     return AnnounceApp.getUrlViewCategory( LocalVariables.getRequest( ), nIdCategory );
268                 }
269 
270         return null;
271     }
272 
273     /**
274      * {@inheritDoc}
275      */
276     @Override
277     public void notifySubscriptionRemoval( Subscription subscription )
278     {
279         if ( StringUtils.equals( subscription.getSubscriptionKey( ), SUBSCRIPTION_FILTER ) && StringUtils.isNotEmpty( subscription.getIdSubscribedResource( ) )
280                 && StringUtils.isNumeric( subscription.getIdSubscribedResource( ) ) )
281         {
282             int nIdFilter = Integer.parseInt( subscription.getIdSubscribedResource( ) );
283             AnnounceSearchFilterHome.delete( nIdFilter );
284         }
285 
286         // We do nothing for users and category subscriptions
287     }
288 
289     /**
290      * Create a subscription to a user
291      * 
292      * @param user
293      *            The user that subscribe to another one
294      * @param strUserName
295      *            The name of the user to subscribe to
296      */
297     public void createSubscriptionToUser( LuteceUser user, String strUserName )
298     {
299         createSubscription( user, strUserName, SUBSCRIPTION_USER );
300     }
301 
302     /**
303      * Create a subscription to a filter
304      * 
305      * @param user
306      *            The user that subscribe to the filter
307      * @param nIdFilter
308      *            The id of the filter to subscribe to
309      */
310     public void createSubscriptionToFilter( LuteceUser user, int nIdFilter )
311     {
312         createSubscription( user, Integer.toString( nIdFilter ), SUBSCRIPTION_FILTER );
313     }
314 
315     /**
316      * Create a subscription to a category
317      * 
318      * @param user
319      *            The user that subscribe to the category
320      * @param nIdCategory
321      *            The id of the category to subscribe to
322      */
323     public void createSubscriptionToCategory( LuteceUser user, int nIdCategory )
324     {
325         createSubscription( user, Integer.toString( nIdCategory ), SUBSCRIPTION_CATEGORY );
326     }
327 
328     /**
329      * Remove a subscription to a user
330      * 
331      * @param user
332      *            The user that subscribe to another one
333      * @param strUserName
334      *            The name of the user to subscribe to
335      */
336     public void removeSubscriptionToUser( LuteceUser user, String strUserName )
337     {
338         removeSubscription( user, strUserName, SUBSCRIPTION_USER );
339     }
340 
341     /**
342      * Remove a subscription to a filter
343      * 
344      * @param user
345      *            The user that subscribe to the filter
346      * @param nIdFilter
347      *            The id of the filter to subscribe to
348      */
349     public void removeSubscriptionToFilter( LuteceUser user, int nIdFilter )
350     {
351         removeSubscription( user, Integer.toString( nIdFilter ), SUBSCRIPTION_FILTER );
352     }
353 
354     /**
355      * Remove a subscription to a category
356      * 
357      * @param user
358      *            The user that subscribe to the category
359      * @param nIdCategory
360      *            The id of the category to subscribe to
361      */
362     public void removeSubscriptionToCategory( LuteceUser user, int nIdCategory )
363     {
364         removeSubscription( user, Integer.toString( nIdCategory ), SUBSCRIPTION_CATEGORY );
365     }
366 
367     /**
368      * Do create a subscription to a user, a filter or a category
369      * 
370      * @param user
371      *            The user to subscribe to
372      * @param strIdResource
373      *            the id of the resource to subscribe to
374      * @param strSubscriptionKey
375      *            The subscription key
376      */
377     private void createSubscription( LuteceUser user, String strIdResource, String strSubscriptionKey )
378     {
379         AnnounceSubscribtionDTO subscription = new AnnounceSubscribtionDTO( );
380         subscription.setIdSubscribedResource( strIdResource );
381         subscription.setSubscriptionKey( strSubscriptionKey );
382         subscription.setSubscriptionProvider( getProviderName( ) );
383         subscription.setUserId( user.getName( ) );
384         subscription.setEmailSubscribes( user.getUserInfo( LuteceUser.BUSINESS_INFO_ONLINE_EMAIL ) );
385         AnnounceSubscriptionService.getInstance( ).createSubscription( subscription );
386     }
387 
388     /**
389      * Do remove a subscription
390      * 
391      * @param user
392      *            The user
393      * @param strIdResource
394      *            The id of the resource to remove the subscription to
395      * @param strSubscriptionKey
396      *            The subscription key of the subscription to remove
397      */
398     private void removeSubscription( LuteceUser user, String strIdResource, String strSubscriptionKey )
399     {
400         SubscriptionFilter filter = new SubscriptionFilter( user.getName( ), getProviderName( ), strSubscriptionKey, strIdResource );
401         List<AnnounceSubscribtionDTO> listSubscriptions = AnnounceSubscriptionService.getInstance( ).findByFilter( filter );
402 
403         for ( AnnounceSubscribtionDTO subscription : listSubscriptions )
404         {
405             AnnounceSubscriptionService.getInstance( ).removeSubscription( subscription, false );
406         }
407     }
408 
409     /**
410      * Check if a user has subscribed to another user
411      * 
412      * @param user
413      *            The subscriber user
414      * @param userName
415      *            The name of the subscribed user
416      * @return True if the user has subscribed to another user, false otherwise
417      */
418     public boolean hasSubscribedToUser( LuteceUser user, String userName )
419     {
420         return hasSubscribedtoResource( user, userName, SUBSCRIPTION_USER );
421     }
422 
423     /**
424      * Check if a user has subscribed to a category
425      * 
426      * @param user
427      *            The subscriber user
428      * @param nIdCategory
429      *            The id of the subscribed category
430      * @return True if the user has subscribed to a category, false otherwise
431      */
432     public boolean hasSubscribedToCategory( LuteceUser user, int nIdCategory )
433     {
434         if ( nIdCategory == 0 )
435         {
436             return false;
437         }
438 
439         return hasSubscribedtoResource( user, Integer.toString( nIdCategory ), SUBSCRIPTION_CATEGORY );
440     }
441 
442     /**
443      * Check if a user has subscribed to a given resource
444      * 
445      * @param user
446      *            The user to check the subscription of
447      * @param strIdResource
448      *            The id of the resource
449      * @param strSubscriptionKey
450      *            The subscription key
451      * @return True if the user has subscribed to the given resource, false otherwise
452      */
453     private boolean hasSubscribedtoResource( LuteceUser user, String strIdResource, String strSubscriptionKey )
454     {
455         SubscriptionFilter filter = new SubscriptionFilter( user.getName( ), getProviderName( ), strSubscriptionKey, strIdResource );
456         List<AnnounceSubscribtionDTO> listSubscription = AnnounceSubscriptionService.getInstance( ).findByFilter( filter );
457 
458         return CollectionUtils.isNotEmpty( listSubscription );
459     }
460 
461     /**
462      * Get the list of subscriptions to users
463      * 
464      * @return The list of subscriptions to users
465      */
466     public List<AnnounceSubscribtionDTO> getSubscriptionsToUsers( )
467     {
468         return getSubscriptionsToResource( SUBSCRIPTION_USER );
469     }
470 
471     /**
472      * Get the list of subscriptions to categories
473      * 
474      * @return The list of subscriptions to categories
475      */
476     public List<AnnounceSubscribtionDTO> getsubscriptionsToCategories( )
477     {
478         return getSubscriptionsToResource( SUBSCRIPTION_CATEGORY );
479     }
480 
481     /**
482      * Get the list of subscriptions to filters
483      * 
484      * @return The list of subscriptions to filters
485      */
486     public List<AnnounceSubscribtionDTO> getSubscriptionsToFilters( )
487     {
488         return getSubscriptionsToResource( SUBSCRIPTION_FILTER );
489     }
490 
491     /**
492      * Get the list of subscriptions of a given type
493      * 
494      * @param strSubscriptionKey
495      *            The type of subscriptions to get
496      * @return The list of subscriptions of the given type
497      */
498     public List<AnnounceSubscribtionDTO> getSubscriptionsToResource( String strSubscriptionKey )
499     {
500         SubscriptionFilter filter = new SubscriptionFilter( );
501         filter.setSubscriptionKey( strSubscriptionKey );
502         filter.setSubscriptionProvider( getProviderName( ) );
503 
504         return AnnounceSubscriptionService.getInstance( ).findByFilter( filter );
505     }
506 
507     public List<AnnounceSubscribtionDTO> getSubscriptionsByAnnounce( String userId, String categoryId, String numberOfAnnounceToNotify )
508     {
509         return AnnounceSubscriptionService.getInstance( ).findByFilterOr( userId, categoryId, numberOfAnnounceToNotify );
510     }
511 }