View Javadoc

1   /*
2    * This software was designed and created by Jason Carroll.
3    * Copyright (c) 2002, 2003, 2004 Jason Carroll.
4    * The author can be reached at jcarroll@cowsultants.com
5    * ITracker website: http://www.cowsultants.com
6    * ITracker forums: http://www.cowsultants.com/phpBB/index.php
7    *
8    * This program is free software; you can redistribute it and/or modify
9    * it only under the terms of the GNU General Public License as published by
10   * the Free Software Foundation; either version 2 of the License, or
11   * (at your option) any later version.
12   *
13   * This program is distributed in the hope that it will be useful,
14   * but WITHOUT ANY WARRANTY; without even the implied warranty of
15   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   * GNU General Public License for more details.
17   */
18  
19  package org.itracker.web.scheduler.tasks;
20  
21  
22  import java.util.ArrayList;
23  import java.util.Calendar;
24  import java.util.Date;
25  import java.util.GregorianCalendar;
26  import java.util.HashSet;
27  import java.util.List;
28  
29  import javax.mail.internet.InternetAddress;
30  
31  import org.apache.log4j.Logger;
32  import org.itracker.model.Issue;
33  import org.itracker.model.Notification;
34  import org.itracker.model.Notification.Type;
35  import org.itracker.services.ConfigurationService;
36  import org.itracker.services.IssueService;
37  import org.itracker.services.NotificationService;
38  import org.itracker.services.util.IssueUtilities;
39  import org.itracker.web.util.ServletContextUtils;
40  
41  /**
42    * This class can be used to send reminder emails to owners/admins
43    * that issues need their attention.
44    * @see SchedulableTask
45    */
46  public class ReminderNotification extends BaseJob {
47      
48      public static final String DEFAULT_BASE_URL = "http://localhost:8080/itracker";
49      public static final int DEFAULT_ISSUE_AGE = 30;
50  
51      private final Logger logger;
52      
53      public ReminderNotification() {
54          this.logger = Logger.getLogger(getClass());
55      }
56  
57      /**
58        * This method is called by the scheduler to send the reminder
59        * notifications.  The arguments can be used to configure which issues
60        * and projects are included in the notifications.  The args should
61        * include as the first parameter the base url of the server including
62        * the scheme, hostname, port, and context.  For example:
63        * <br>
64        * http://localhost:8080/itracker
65        * <br>
66        * If no other arguments are supplied it sends reminders to all
67        * owners/admins of unresolved issues in all projects that have not been
68        * modified in 30 days.  The second element of the array can be a number
69        * that represents the number of days to use to check the last modified
70        * date.  The third optional element is a number that represents the project
71        * id to limit the notifications to. A fourth optional argument is the severity
72        * to send the notification for.
73        * @param args optional arguments to configure the notification messages
74        * @see SchedulableTask#performTask
75        */
76      public void performTask(String[] args) {
77          List<Issue> issues;
78          String baseURL = DEFAULT_BASE_URL;
79          int issueAge = DEFAULT_ISSUE_AGE;
80          int projectId = -1;
81          int severity = -1;
82          ConfigurationService configurationService = ServletContextUtils.getItrackerServices().getConfigurationService();
83  
84          // Process arguments.
85          if(args != null) {
86              if(args.length > 0 && args[0] != null) {
87                  baseURL = args[0];
88              }
89              
90              if (null == baseURL) {
91              	baseURL = configurationService.getSystemBaseURL();
92              }
93              if(args.length > 1) {
94                  try {
95                      issueAge = Integer.parseInt(args[1]);
96                  } catch(NumberFormatException nfe) {
97                      logger.debug("Invalid issue age specified in ReminderNotification task.");
98                  }
99              }
100             if(args.length > 2) {
101                 try {
102                     projectId = Integer.parseInt(args[2]);
103                 } catch(NumberFormatException nfe) {
104                     logger.debug("Invalid projectId specified in ReminderNotification task.");
105                 }
106             }
107             if(args.length > 3) {
108                 try {
109                     severity = Integer.parseInt(args[3]);
110                 } catch(NumberFormatException nfe) {
111                     logger.debug("Invalid severity specified in ReminderNotification task.");
112                 }
113             }
114         }
115         logger.debug("Reminder Notifications being sent for project " + projectId + " with issues over " + issueAge + " days old with severity " + severity + ".  Base URL = " + baseURL);
116 
117         try {
118             IssueService issueService = ServletContextUtils.getItrackerServices().getIssueService();
119             NotificationService notificationService = ServletContextUtils.getItrackerServices().getNotificationService();
120             GregorianCalendar cal = new GregorianCalendar();
121             cal.add(Calendar.DAY_OF_MONTH, 0 - issueAge);
122             Date oldDate = cal.getTime();
123             Date currentDate = new Date();
124 
125             if(projectId > 0) {
126                 issues = issueService.getIssuesByProjectId(projectId, IssueUtilities.STATUS_RESOLVED);
127             } else {
128                 issues = issueService.getIssuesWithStatusLessThan(IssueUtilities.STATUS_RESOLVED);
129             }
130             if(issues != null && issues.size() > 0) {
131                 for(int i = 0; i < issues.size(); i++) {
132                     if(severity >= 0 && issues.get(i).getSeverity() != severity) {
133                         continue;
134                     }
135                     if(issues.get(i).getLastModifiedDate() != null && issues.get(i).getLastModifiedDate().before(oldDate)) {
136                         HashSet<InternetAddress> addresses = new HashSet<InternetAddress>();
137                         long numMillis = currentDate.getTime() - issues.get(i).getLastModifiedDate().getTime();
138                         int numDays = (int) (numMillis / (24 * 60 * 60 * 1000));
139 
140                         List<Notification> notifications = notificationService.getPrimaryIssueNotifications(issues.get(i));
141                         for(int j = 0; j < notifications.size(); j++) {
142                             if(notifications.get(j).getUser().getEmail() != null 
143                                     && notifications.get(j).getUser().getEmail().indexOf('@') >= 0) {
144                                 addresses.add(notifications.get(j).getUser().getEmailAddress());
145                             }
146                         }
147                         InternetAddress[] addressesArray = new ArrayList<InternetAddress>(addresses).toArray(new InternetAddress[]{});
148                         
149                         if (logger.isDebugEnabled()) {
150                         	logger.debug("Sending reminder notification for issue " + issues.get(i).getId() + " to " + addressesArray.length + " users.");
151                         }
152                         notificationService.sendNotification(issues.get(i), Type.ISSUE_REMINDER, baseURL, addressesArray, numDays);
153 
154                     }
155                 }
156             }
157         } catch(Exception e) {
158             logger.error("Error sending reminder notifications. Message: ", e);
159             throw new RuntimeException("failed to send reminder notifications.", e);
160         }
161     }
162 }