View Javadoc

1   /*
2    * Copyright (c) 2002-2014, Mairie de 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.digglike.service.subscription;
35  
36  import java.sql.Timestamp;
37  import java.util.ArrayList;
38  import java.util.Date;
39  import java.util.HashMap;
40  import java.util.List;
41  import java.util.Locale;
42  import java.util.Map;
43  import java.util.Map.Entry;
44  
45  import org.apache.commons.lang.StringUtils;
46  
47  import fr.paris.lutece.plugins.digglike.business.CommentSubmit;
48  import fr.paris.lutece.plugins.digglike.business.CommentSubmitHome;
49  import fr.paris.lutece.plugins.digglike.business.Digg;
50  import fr.paris.lutece.plugins.digglike.business.DiggFilter;
51  import fr.paris.lutece.plugins.digglike.business.DiggHome;
52  import fr.paris.lutece.plugins.digglike.business.DiggSubmit;
53  import fr.paris.lutece.plugins.digglike.business.DiggSubmitHome;
54  import fr.paris.lutece.plugins.digglike.business.SubmitFilter;
55  import fr.paris.lutece.plugins.digglike.service.DiggSubmitService;
56  import fr.paris.lutece.plugins.digglike.service.DigglikePlugin;
57  import fr.paris.lutece.plugins.digglike.utils.DiggUtils;
58  import fr.paris.lutece.plugins.subscribe.business.Subscription;
59  import fr.paris.lutece.plugins.subscribe.business.SubscriptionFilter;
60  import fr.paris.lutece.plugins.subscribe.service.SubscriptionService;
61  import fr.paris.lutece.portal.service.daemon.Daemon;
62  import fr.paris.lutece.portal.service.datastore.DatastoreService;
63  import fr.paris.lutece.portal.service.mail.MailService;
64  import fr.paris.lutece.portal.service.plugin.Plugin;
65  import fr.paris.lutece.portal.service.plugin.PluginService;
66  import fr.paris.lutece.portal.service.security.LuteceUser;
67  import fr.paris.lutece.portal.service.security.LuteceUserService;
68  import fr.paris.lutece.portal.service.template.AppTemplateService;
69  import fr.paris.lutece.portal.service.util.AppPathService;
70  import fr.paris.lutece.util.html.HtmlTemplate;
71  
72  
73  /**
74   * Daemon to send notifications to users that subscribed to diggs digg
75   * categories or digg submits
76   */
77  public class DiggSubscribersNotificationDaemon extends Daemon
78  {
79      private static final String DATASTORE_DAEMON_LAST_RUN_KEY = "digglike.diggSubscribersNotificationDaemon.lastRunDate";
80      private static final String MARK_COMMENTS = "comments";
81      private static final String MARK_DIGG_SUBMIT = "diggSubmits";
82      private static final String MARK_BASE_URL = "base_url";
83      private Map<String, List<CommentSubmit>> _mapCommentNotif;
84      private Map<String, List<DiggSubmit>> _mapDiggSubmitNotif;
85  
86      /**
87       * {@inheritDoc}
88       */
89      @Override
90      public void run(  )
91      {
92          synchronized ( this )
93          {
94              Date date = new Date(  );
95              String strLastRunDate = DatastoreService.getInstanceDataValue( DATASTORE_DAEMON_LAST_RUN_KEY, null );
96  
97              if ( StringUtils.isNotEmpty( strLastRunDate ) && StringUtils.isNumeric( strLastRunDate ) )
98              {
99                  resetNotifSend(  );
100 
101                 Plugin plugin = PluginService.getPlugin( DigglikePlugin.PLUGIN_NAME );
102                 Date dateLastRun = new Date( Long.parseLong( strLastRunDate ) );
103                 
104 
105                 // We get the list of comments posted after the last run of this daemon
106                 List<CommentSubmit> listComment = CommentSubmitHome.findDiggCommentByDate( dateLastRun, plugin );
107                 if ( ( listComment != null ) && ( listComment.size(  ) > 0 ) )
108                 {
109                     // We order the list of comments by digg submit
110                     Map<Integer, List<CommentSubmit>> mapCommentsByDiggSubmitId = new HashMap<Integer, List<CommentSubmit>>( listComment.size(  ) );
111                    
112                     for ( CommentSubmit comment : listComment )
113                     {
114                     	comment.setDiggSubmit( DiggSubmitHome.findByPrimaryKey( 
115                                 comment.getDiggSubmit(  ).getIdDiggSubmit(  ), plugin ));
116                         addCommentToMap( comment, mapCommentsByDiggSubmitId );
117                     }
118 
119                     // Now that the map contain every comment ordered by digg submit, we just have to generate notifications
120 
121                     // We get the list of subscriptions to digg submits
122                     SubscriptionFilter subscriptionFilter = new SubscriptionFilter(  );
123                     subscriptionFilter.setSubscriptionKey( DigglikeSubscriptionProviderService.SUBSCRIPTION_DIGG_SUBMIT );
124                     subscriptionFilter.setSubscriptionProvider( DigglikeSubscriptionProviderService.getService(  )
125                                                                                                    .getProviderName(  ) );
126 
127                     List<Subscription> listSubscription = SubscriptionService.getInstance(  )
128                                                                              .findByFilter( subscriptionFilter );
129 
130                     if ( ( listSubscription != null ) && ( listSubscription.size(  ) > 0 ) )
131                     {
132                         for ( Subscription subscription : listSubscription )
133                         {
134                             if ( StringUtils.isNotEmpty( subscription.getIdSubscribedResource(  ) ) &&
135                                     StringUtils.isNumeric( subscription.getIdSubscribedResource(  ) ) )
136                             {
137                                 int nIdDiggSubmit = Integer.parseInt( subscription.getIdSubscribedResource(  ) );
138                                 List<CommentSubmit> listComments = mapCommentsByDiggSubmitId.get( nIdDiggSubmit );
139 
140                                 if ( ( listComments != null ) && ( listComments.size(  ) > 0 ) )
141                                 {
142                                     registerCommentNotificationToSend( listComments, subscription.getUserId(  ) );
143                                 }
144                             }
145                         }
146 
147                         sendRegisteredCommentNotifications( plugin );
148                         // We clear registered notifications
149                         _mapCommentNotif = null;
150                     }
151                 }
152 
153                 SubmitFilter submitFilter = new SubmitFilter(  );
154                 submitFilter.setDateFirst( new Timestamp( dateLastRun.getTime(  ) ) );
155 
156                 List<DiggSubmit> listCreatedDiggSubmit = DiggSubmitService.getService(  )
157                                                                           .getDiggSubmitList( submitFilter, plugin );
158                 
159                 	
160 
161                 if ( ( listCreatedDiggSubmit != null ) && ( listCreatedDiggSubmit.size(  ) > 0 ) )
162                 {
163                     // We get the list of subscriptions to digg categories
164                     SubscriptionFilter subscriptionFilter = new SubscriptionFilter(  );
165                     subscriptionFilter.setSubscriptionKey( DigglikeSubscriptionProviderService.SUBSCRIPTION_DIGG_CATEGORY );
166                     subscriptionFilter.setSubscriptionProvider( DigglikeSubscriptionProviderService.getService(  )
167                                                                                                    .getProviderName(  ) );
168 
169                     List<Subscription> listSubscription = SubscriptionService.getInstance(  )
170                                                                              .findByFilter( subscriptionFilter );
171 
172                     if ( ( listSubscription != null ) && ( listSubscription.size(  ) > 0 ) )
173                     {
174                         for ( Subscription subscription : listSubscription )
175                         {
176                             if ( StringUtils.isNotEmpty( subscription.getIdSubscribedResource(  ) ) &&
177                                     StringUtils.isNumeric( subscription.getIdSubscribedResource(  ) ) )
178                             {
179                                 int nIdCategory = DiggUtils.getIntegerParameter( subscription.getIdSubscribedResource(  ) );
180 
181                                 for ( DiggSubmit diggSubmit : listCreatedDiggSubmit )
182                                 {
183                                     if ( nIdCategory!=DiggUtils.CONSTANT_ID_NULL && diggSubmit.getCategory(  )!=null &&  nIdCategory == diggSubmit.getCategory(  ).getIdCategory(  ) )
184                                     {
185                                         registerDiggSubmitNotificationToSend( diggSubmit, subscription.getUserId(  ) );
186                                     }
187                                 }
188                             }
189                         }
190                     }
191 
192                     subscriptionFilter = new SubscriptionFilter(  );
193                     subscriptionFilter.setSubscriptionKey( DigglikeSubscriptionProviderService.SUBSCRIPTION_DIGG );
194                     subscriptionFilter.setSubscriptionProvider( DigglikeSubscriptionProviderService.getService(  )
195                                                                                                    .getProviderName(  ) );
196                     listSubscription = SubscriptionService.getInstance(  ).findByFilter( subscriptionFilter );
197 
198                     if ( ( listSubscription != null ) && ( listSubscription.size(  ) > 0 ) )
199                     {
200                         for ( Subscription subscription : listSubscription )
201                         {
202                             if ( StringUtils.isNotEmpty( subscription.getIdSubscribedResource(  ) ) &&
203                                     StringUtils.isNumeric( subscription.getIdSubscribedResource(  ) ) )
204                             {
205                                 int nIdDigg = Integer.parseInt( subscription.getIdSubscribedResource(  ) );
206 
207                                 for ( DiggSubmit diggSubmit : listCreatedDiggSubmit )
208                                 {
209                                     if ( nIdDigg == diggSubmit.getDigg(  ).getIdDigg(  ) )
210                                     {
211                                         registerDiggSubmitNotificationToSend( diggSubmit, subscription.getUserId(  ) );
212                                     }
213                                 }
214                             }
215                         }
216                     }
217 
218                     sendRegisteredDiggSubmitNotifications(plugin  );
219                 }
220             }
221 
222             DatastoreService.setInstanceDataValue( DATASTORE_DAEMON_LAST_RUN_KEY, Long.toString( date.getTime(  ) ) );
223         }
224     }
225 
226     /**
227      * Add a comment to a map of digg submit ids and list of comments
228      * @param comment The comment to add
229      * @param mapCommentsByDiggSubmitId The map to add the comment in
230      */
231     private void addCommentToMap( CommentSubmit comment, Map<Integer, List<CommentSubmit>> mapCommentsByDiggSubmitId )
232     {
233         List<CommentSubmit> listComments = mapCommentsByDiggSubmitId.get( comment.getDiggSubmit(  ).getIdDiggSubmit(  ) );
234 
235         if ( listComments == null )
236         {
237             listComments = new ArrayList<CommentSubmit>(  );
238             mapCommentsByDiggSubmitId.put( comment.getDiggSubmit(  ).getIdDiggSubmit(  ), listComments );
239         }
240 
241         listComments.add( comment );
242     }
243 
244     /**
245      * Reset notifications to send
246      */
247     private void resetNotifSend(  )
248     {
249         this._mapCommentNotif = new HashMap<String, List<CommentSubmit>>(  );
250         this._mapDiggSubmitNotif = new HashMap<String, List<DiggSubmit>>(  );
251     }
252 
253     /**
254      * Register a list of comments to send to a user. If a comment has already
255      * been registered for the user, then it is ignored
256      * @param listComments The list of comments to send
257      * @param strUserId The user to send the notification to
258      */
259     private void registerCommentNotificationToSend( List<CommentSubmit> listComments, String strUserId )
260     {
261         List<CommentSubmit> listRegisteredCopmments = _mapCommentNotif.get( strUserId );
262 
263         if ( listRegisteredCopmments == null )
264         {
265             listRegisteredCopmments = new ArrayList<CommentSubmit>( listComments );
266             _mapCommentNotif.put( strUserId, listRegisteredCopmments );
267         }
268         else
269         {
270             List<CommentSubmit> listCommentsToAdd = new ArrayList<CommentSubmit>(  );
271 
272             for ( CommentSubmit comment : listComments )
273             {
274                 boolean bAddComment = true;
275 
276                 for ( CommentSubmit registeredComment : listRegisteredCopmments )
277                 {
278                     if ( registeredComment.getIdCommentSubmit(  ) == comment.getIdCommentSubmit(  ) )
279                     {
280                         bAddComment = false;
281 
282                         break;
283                     }
284                 }
285 
286                 if ( bAddComment )
287                 {
288                     listCommentsToAdd.add( comment );
289                 }
290             }
291 
292             listRegisteredCopmments.addAll( listCommentsToAdd );
293         }
294     }
295 
296     /**
297      * Send all registered comment notifications
298      * @param plugin the plugin 
299      */
300     private void sendRegisteredCommentNotifications( Plugin plugin )
301     {
302     	
303     	 DiggFilter filter = new DiggFilter(  );
304          filter.setIdState( Digg.STATE_ENABLE );
305          List<Digg> listDigg = DiggHome.getDiggList( filter, plugin );
306     	for(Digg digg:listDigg)
307     	{
308     		
309     		for ( Entry<String, List<CommentSubmit>> entry : _mapCommentNotif.entrySet(  ) )
310 	        {
311     			List<CommentSubmit> listCommentSubmitsTmp=new ArrayList<CommentSubmit>();
312         		
313     			for(CommentSubmit commentSubmitTmp:entry.getValue(  ))
314     			{
315     				
316     				if(digg.getIdDigg()==commentSubmitTmp.getDiggSubmit().getDigg().getIdDigg())
317     				{
318     					
319     					listCommentSubmitsTmp.add(commentSubmitTmp);
320     				}
321     				
322     			}
323     		
324 				if(!listCommentSubmitsTmp.isEmpty())
325 				{
326 					sendCommentNotification(digg, listCommentSubmitsTmp, entry.getKey(  ) );
327 				}
328 	        }
329 			
330     	}
331     }
332 
333     /**
334      * Send a single comment notification
335      * @param digg the Digg link to the notification
336      * @param listComments The list of comments to include into the notification
337      * @param strUserName The name of the lutece user to send the notification
338      *            to
339      */
340     private void sendCommentNotification(Digg digg, List<CommentSubmit> listComments, String strUserName )
341     {
342         LuteceUser user = LuteceUserService.getLuteceUserFromName( strUserName );
343         String strEmail = getEmailFromLuteceUser( user );
344 
345         if ( StringUtils.isNotEmpty( strEmail ) )
346         {
347             Locale locale = Locale.getDefault(  );
348 
349             Map<String, Object> model = new HashMap<String, Object>(  );
350             model.put( MARK_COMMENTS, listComments );
351             model.put( MARK_BASE_URL, AppPathService.getProdUrl(  ) );
352 
353             HtmlTemplate templateBody = AppTemplateService.getTemplateFromStringFtl(digg.getNotificationNewCommentBody(), locale, model);
354             HtmlTemplate templateTitle = AppTemplateService.getTemplateFromStringFtl(digg.getNotificationNewCommentTitle(), locale, model);
355             MailService.sendMailHtml( strEmail, !StringUtils.isBlank(digg.getNotificationNewCommentSenderName())?digg.getNotificationNewCommentSenderName():digg.getTitle(), MailService.getNoReplyEmail(  ),
356                 templateTitle.getHtml(  ), templateBody.getHtml(  ) );
357         }
358     }
359 
360     /**
361      * Register a digg submit to send to a user
362      * @param diggSubmit The digg submit to register
363      * @param strUserName The name of the lutece user to send the notification
364      *            to
365      */
366     private void registerDiggSubmitNotificationToSend( DiggSubmit diggSubmit, String strUserName )
367     {
368         List<DiggSubmit> listRegisteredDiggSubmit = _mapDiggSubmitNotif.get( strUserName );
369 
370         if ( listRegisteredDiggSubmit == null )
371         {
372             listRegisteredDiggSubmit = new ArrayList<DiggSubmit>(  );
373             listRegisteredDiggSubmit.add( diggSubmit );
374             _mapDiggSubmitNotif.put( strUserName, listRegisteredDiggSubmit );
375         }
376         else
377         {
378             boolean bAddDiggSubmit = true;
379             int nIdDiggsubmit = diggSubmit.getIdDiggSubmit(  );
380 
381             for ( DiggSubmit registeredDiggSubmit : listRegisteredDiggSubmit )
382             {
383                 if ( registeredDiggSubmit.getIdDiggSubmit(  ) == nIdDiggsubmit )
384                 {
385                     bAddDiggSubmit = false;
386 
387                     break;
388                 }
389             }
390 
391             if ( bAddDiggSubmit )
392             {
393                 listRegisteredDiggSubmit.add( diggSubmit );
394             }
395         }
396     }
397 
398     /**
399      * Send all registered comment notifications
400      * @param plugin plugin
401      */
402     private void sendRegisteredDiggSubmitNotifications(Plugin plugin  )
403     {
404     	 DiggFilter filter = new DiggFilter(  );
405          filter.setIdState( Digg.STATE_ENABLE );
406          List<Digg> listDigg = DiggHome.getDiggList( filter, plugin );
407     	for(Digg digg:listDigg)
408     	{
409     		
410     		for ( Entry<String, List<DiggSubmit>> entry : _mapDiggSubmitNotif.entrySet(  ) )
411 	        {
412     			List<DiggSubmit> listDiggSubmitTmp=new ArrayList<DiggSubmit>();
413         		
414     			for(DiggSubmit diggSubmitTmp:entry.getValue(  ))
415     			{
416     				
417     				if(digg.getIdDigg()==diggSubmitTmp.getDigg().getIdDigg())
418     				{
419     					
420     					listDiggSubmitTmp.add(diggSubmitTmp);
421     				}
422     				
423     			}
424     		
425 				if(!listDiggSubmitTmp.isEmpty())
426 				{
427 					sendDiggSubmitNotification(digg, listDiggSubmitTmp, entry.getKey(  ) );
428 				}
429 	        }
430 			
431     	}
432     }
433 
434     /**
435      * Send a single digg submit notification
436      * @param digg the Digg link to the notification
437      * @param listDiggSubmit The list of digg submit to include into the
438      *            notification
439      * @param strUserName The name of the lutece user to send the notification
440      *            to
441      */
442     private void sendDiggSubmitNotification( Digg digg,List<DiggSubmit> listDiggSubmit, String strUserName )
443     {
444         LuteceUser user = LuteceUserService.getLuteceUserFromName( strUserName );
445         String strEmail = getEmailFromLuteceUser( user );
446 
447         if ( StringUtils.isNotEmpty( strEmail ) )
448         {
449             Locale locale = Locale.getDefault(  );
450 
451             Map<String, Object> model = new HashMap<String, Object>(  );
452             model.put( MARK_DIGG_SUBMIT, listDiggSubmit );
453             model.put( MARK_BASE_URL, AppPathService.getProdUrl(  ) );
454 
455             HtmlTemplate templateBody = AppTemplateService.getTemplateFromStringFtl(digg.getNotificationNewDiggSubmitBody(), locale, model);
456             HtmlTemplate templateTitle = AppTemplateService.getTemplateFromStringFtl(digg.getNotificationNewDiggSubmitTitle(), locale, model);
457           MailService.sendMailHtml( strEmail, !StringUtils.isBlank(digg.getNotificationNewDiggSubmitSenderName())?digg.getNotificationNewDiggSubmitSenderName():digg.getTitle(), MailService.getNoReplyEmail(  ),
458                 templateTitle.getHtml(  ), templateBody.getHtml(  ) );
459         }
460     }
461 
462     /**
463      * Get the email from the lutece user
464      * @param user The user to get the email of
465      * @return The email of the user, or null if he has none
466      */
467     private String getEmailFromLuteceUser( LuteceUser user )
468     {
469         String strEmail = user.getUserInfo( LuteceUser.BUSINESS_INFO_ONLINE_EMAIL );
470 
471         if ( strEmail == null )
472         {
473             strEmail = user.getUserInfo( LuteceUser.HOME_INFO_ONLINE_EMAIL );
474         }
475 
476         return strEmail;
477     }
478 }