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 org.apache.log4j.Logger;
23  import org.itracker.model.Issue;
24  import org.itracker.model.Notification;
25  import org.itracker.model.util.IssueUtilities;
26  import org.itracker.services.ConfigurationService;
27  import org.itracker.services.IssueService;
28  import org.itracker.services.NotificationService;
29  import org.itracker.web.util.ServletContextUtils;
30  import org.quartz.JobExecutionContext;
31  import org.quartz.JobExecutionException;
32  import org.springframework.transaction.annotation.Transactional;
33  
34  import java.util.*;
35  
36  /**
37   * This class can be used to send reminder emails to owners/admins
38   * that issues need their attention.
39   *
40   */
41  public class ReminderNotification extends BaseJob implements Runnable {
42  
43      public static final String DEFAULT_BASE_URL = "http://localhost:8080/itracker";
44      public static final int DEFAULT_ISSUE_AGE = 30;
45  
46      private final Logger logger;
47  
48      public ReminderNotification() {
49          this.logger = Logger.getLogger(getClass());
50      }
51  
52      @Override
53      @Transactional
54      public void run() {
55          this.performTask(new String[]{});
56      }
57  
58      @Override
59      public void execute(JobExecutionContext context) throws JobExecutionException {
60          super.execute(context);
61          this.performTask((String[]) context.get("args"));
62      }
63  
64      /**
65       * This method is called by the scheduler to send the reminder
66       * notifications.  The arguments can be used to configure which issues
67       * and projects are included in the notifications.  The args should
68       * include as the first parameter the base url of the server including
69       * the scheme, hostname, port, and context.  For example:
70       * <br>
71       * http://localhost:8080/itracker
72       * <br>
73       * If no other arguments are supplied it sends reminders to all
74       * owners/admins of unresolved issues in all projects that have not been
75       * modified in 30 days.  The second element of the array can be a number
76       * that represents the number of days to use to check the last modified
77       * date.  The third optional element is a number that represents the project
78       * id to limit the notifications to. A fourth optional argument is the severity
79       * to send the notification for.
80       *
81       * @param args optional arguments to configure the notification messages
82       */
83      public void performTask(String[] args) {
84          final List<Issue> issues;
85          final ConfigurationService configurationService = ServletContextUtils.getItrackerServices().getConfigurationService();
86  
87          String baseURL = configurationService.getSystemBaseURL();
88          int notificationDays = configurationService.getIntegerProperty("reminder_notification_days",
89                          DEFAULT_ISSUE_AGE);
90  
91          int projectId = -1;
92          int severity = -1;
93  
94          // Process arguments.
95          if (args != null) {
96              if (args.length > 0 && args[0] != null) {
97                  baseURL = args[0];
98              }
99  
100             if (null == baseURL) {
101                 baseURL = DEFAULT_BASE_URL;
102             }
103             if (args.length > 1) {
104                 try {
105                     notificationDays = Integer.parseInt(args[1]);
106                 } catch (NumberFormatException nfe) {
107                     logger.debug("Invalid issue age specified in ReminderNotification task.");
108                 }
109             }
110             if (args.length > 2) {
111                 try {
112                     projectId = Integer.parseInt(args[2]);
113                 } catch (NumberFormatException nfe) {
114                     logger.debug("Invalid projectId specified in ReminderNotification task.");
115                 }
116             }
117             if (args.length > 3) {
118                 try {
119                     severity = Integer.parseInt(args[3]);
120                 } catch (NumberFormatException nfe) {
121                     logger.debug("Invalid severity specified in ReminderNotification task.");
122                 }
123             }
124         }
125         if (notificationDays < 1) {
126             logger.info("Reminder notifications are disabled for project " + projectId );
127             return;
128         }
129         logger.debug("Reminder notifications being sent for project " + projectId + " with issues over " + notificationDays + " days old with severity " + severity + ".  Base URL = " + baseURL);
130 
131         try {
132             IssueService issueService = ServletContextUtils.getItrackerServices().getIssueService();
133             NotificationService notificationService = ServletContextUtils.getItrackerServices().getNotificationService();
134             GregorianCalendar cal = new GregorianCalendar();
135             cal.add(Calendar.DAY_OF_MONTH, 0 - notificationDays);
136             Date threshold = cal.getTime();
137 
138             if (projectId > 0) {
139                 issues = issueService.getIssuesByProjectId(projectId, IssueUtilities.STATUS_RESOLVED);
140             } else {
141                 issues = issueService.getIssuesWithStatusLessThan(IssueUtilities.STATUS_RESOLVED);
142             }
143             if (issues != null && issues.size() > 0) {
144                 for (Issue issue : issues) {
145                     if (severity >= 0 && issue.getSeverity() != severity) {
146                         continue;
147                     }
148                     if (issue.getLastModifiedDate() != null && issue.getLastModifiedDate().before(threshold)) {
149                         List<Notification> notifications = notificationService.getPrimaryIssueNotifications(issue);
150                         for (Notification notification : notifications) {
151                             if (notification.getUser().getEmail() != null
152                                     && notification.getUser().getEmail().indexOf('@') >= 0) {
153                                 if (logger.isDebugEnabled()) {
154                                     logger.debug("Sending reminder notification for issue " + issue.getId() + " to " + notification.getUser() + " users.");
155                                 }
156                                 notificationService.sendReminder(issue, notification.getUser(), baseURL, notificationDays);
157 
158                             }
159                         }
160                     }
161                 }
162             }
163         } catch (Exception e) {
164             logger.error("Error sending reminder notifications. Message: ", e);
165             throw new RuntimeException("failed to send reminder notifications.", e);
166         }
167     }
168 }