1 package org.itracker.web.util;
2
3 import org.apache.commons.lang.math.NumberUtils;
4 import org.apache.log4j.Logger;
5 import org.apache.struts.action.*;
6 import org.itracker.core.resources.ITrackerResources;
7 import org.itracker.model.*;
8 import org.itracker.model.util.IssueUtilities;
9 import org.itracker.model.util.UserUtilities;
10 import org.itracker.services.IssueService;
11 import org.itracker.services.ProjectService;
12 import org.itracker.web.ptos.IssuePTO;
13
14 import javax.servlet.http.HttpServletRequest;
15 import javax.servlet.http.HttpSession;
16 import java.util.*;
17
18 public class ListIssuesActionUtil {
19 private static final Logger log = Logger.getLogger(ListIssuesActionUtil.class);
20
21
22 public static final String LIST_ISSUES_PAGE_TITLE_KEY = "itracker.web.listissues.title";
23
24 public static final String ATT_NAME_PAGE_TITLE_KEY = "pageTitleKey";
25 public static final String ATT_NAME_PAGE_TITLE_ARG = "pageTitleArg";
26 public static final String ATT_NAME_HAS_ORDER_PARAM = "hasOrderParam";
27
28 public static final String ATT_NAME_ORDER_PARAM = "orderParam";
29
30 public static final String ATT_NAME_ISSUE_PTOS = "issuePTOs";
31 public static final String ATT_NAME_PROJECT = "project";
32 public static final String ATT_NAME_PROJCET_ID = "projectId";
33 public static final String ATT_NAME_HAS_ISSUES = "hasIssues";
34 public static final String ATT_NAME_HAS_VIEW_ALL = "hasViewAll";
35
36 public static final String ATT_NAME_UNASSIGNED = "itracker_web_generic_unassigned";
37
38 public static final String SES_ATT_NAME_CURRENT__USER = "currUser";
39 public static final String SES_ATT_NAME_PREFERENCES = "preferences";
40 public static final String PARAM_NAME_PROJECT_ID = "projectId";
41
42
43 public static final String PARAM_NAME_START = "start";
44 public static final String PARAM_NAME_ORDER = "order";
45
46 public static final String ORDER_KEY_ID = "id";
47 public static final String ORDER_KEY_SEVERITY = "sev";
48 public static final String ORDER_KEY_STATUS = "stat";
49 public static final String ORDER_KEY_LAST_MODIFIED = "lm";
50 public static final String ORDER_KEY_OWNER_AND_STATUS = "own";
51
52
53 public static final String RES_KEY_UNASSIGNED = "itracker.web.generic.unassigned";
54 public static final String RES_KEY_UNKNOWN = "itracker.web.generic.unknown";
55
56 public static final String FWD_LIST_ISSUES = "list_issues";
57
58
59
60 public static ActionForward init(Action action, ActionMessages messages, ActionMapping mapping, HttpServletRequest request) {
61
62 Locale locale = LoginUtilities.getCurrentLocale(request);
63
64 IssueService issueService = ServletContextUtils.getItrackerServices().getIssueService();
65 ProjectService projectService = ServletContextUtils.getItrackerServices().getProjectService();
66 User um = (User)request.getSession().getAttribute(ListIssuesActionUtil.SES_ATT_NAME_CURRENT__USER);
67 Integer currUserId = um.getId();
68 HttpSession session = request.getSession(true);
69 Map<Integer, Set<PermissionType>> userPermissions = RequestHelper.getUserPermissions(session);
70
71 UserPreferences userPrefs = (UserPreferences) request.getSession().getAttribute(ListIssuesActionUtil.SES_ATT_NAME_PREFERENCES);
72
73 Integer projectId = NumberUtils.createInteger(request.getParameter(ListIssuesActionUtil.PARAM_NAME_PROJECT_ID));
74 log.debug("execute: " + ListIssuesActionUtil.PARAM_NAME_PROJECT_ID + " was: " + projectId);
75
76 if (null == projectId) {
77 messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(
78 "itracker.web.error.invalidproject"));
79 return mapping.findForward("error");
80
81 }
82
83 int status = (userPrefs.getShowClosedOnIssueList() ? IssueUtilities.STATUS_END : IssueUtilities.STATUS_CLOSED);
84
85
86 Project project = projectService.getProject(projectId);
87 if (null == project) {
88 messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(
89 "itracker.web.error.invalidproject"));
90 return mapping.findForward("error");
91 }
92 log.debug("execute: projectModel_Name: " + project.getName());
93 List<Issue> listIssues = issueService.getIssuesByProjectId(projectId, status);
94 log.debug("execute: issues found for this project: " + listIssues.size());
95
96 List<IssuePTO> issuePTOs = new ArrayList<IssuePTO>();
97
98
99 boolean hasOrderParam = false;
100 String order = "";
101 String orderParam = request.getParameter(ListIssuesActionUtil.PARAM_NAME_ORDER);
102 if(orderParam == null || "".equals(orderParam)) {
103 order = userPrefs.getSortColumnOnIssueList();
104 orderParam = "";
105 } else {
106 hasOrderParam = true;
107 order = orderParam;
108 }
109
110 if(ListIssuesActionUtil.ORDER_KEY_ID.equals(order)) {
111 Collections.sort(listIssues, Issue.ID_COMPARATOR);
112 } else if(ListIssuesActionUtil.ORDER_KEY_SEVERITY.equals(order)) {
113 Collections.sort(listIssues, Issue.SEVERITY_COMPARATOR);
114 } else if(ListIssuesActionUtil.ORDER_KEY_STATUS.equals(order)) {
115 Collections.sort(listIssues, Issue.STATUS_COMPARATOR);
116 } else if(ListIssuesActionUtil.ORDER_KEY_LAST_MODIFIED.equals(order)) {
117 Collections.sort(listIssues, Collections.reverseOrder(
118 Issue.LAST_MODIFIED_DATE_COMPARATOR));
119 } else if(ListIssuesActionUtil.ORDER_KEY_OWNER_AND_STATUS.equals(order)) {
120 Collections.sort(listIssues, Issue.OWNER_AND_STATUS_COMPARATOR);
121 } else {
122 Collections.sort(listIssues, Issue.STATUS_COMPARATOR);
123 }
124
125 int start = 0;
126 String startString = request.getParameter(ListIssuesActionUtil.PARAM_NAME_START);
127 if(startString != null) {
128 try {
129 start = Integer.parseInt(startString);
130 } catch(NumberFormatException nfe) {
131 }
132 }
133 int numViewable = 0;
134 boolean hasIssues = false;
135 boolean hasViewAll = UserUtilities.hasPermission(userPermissions, project.getId(), PermissionType.ISSUE_VIEW_ALL);
136
137 if (!hasViewAll) {
138 if (null == userPermissions.get(projectId)) {
139 return mapping.findForward("unauthorized");
140 }
141 }
142
143 if(hasViewAll) {
144 numViewable = listIssues.size();
145 } else {
146 for (Issue listIssue : listIssues) {
147 if (IssueUtilities.canViewIssue(listIssue, currUserId, userPermissions)) {
148 numViewable++;
149 }
150 }
151 }
152 int row = 0;
153 int k = 0;
154 Iterator<Issue> issuesIt = listIssues.iterator();
155
156 Issue issue;
157 IssuePTO issuePTO;
158 String statusLocalizedString, severityLocalizedString, componentsSize;
159 while (issuesIt.hasNext()) {
160
161 issue = issuesIt.next();
162 issuePTO = new IssuePTO(issue);
163
164 statusLocalizedString=IssueUtilities.getStatusName(issue.getStatus(), locale);
165 severityLocalizedString = IssueUtilities.getSeverityName(issue.getSeverity(), locale) ;
166 if (issue.getComponents().size() == 0) {
167 componentsSize = ITrackerResources.getString(
168 ListIssuesActionUtil.RES_KEY_UNKNOWN, locale);
169 } else {
170 componentsSize = issue.getComponents().get(0).getName()
171 + (issue.getComponents().size() > 1 ? " (+)" : "");
172 }
173 issuePTO.setStatusLocalizedString(statusLocalizedString);
174 issuePTO.setSeverityLocalizedString(severityLocalizedString);
175 issuePTO.setComponentsSize(componentsSize);
176 if(issue.getOwner()==null) {
177 issuePTO.setUnassigned(true);
178 }
179
180 if(project.getStatus() == Status.ACTIVE && ! IssueUtilities.hasIssueNotification(issue, project, currUserId)) {
181 issuePTO.setUserHasIssueNotification(true);
182 }
183 if(project.getStatus() == Status.ACTIVE) {
184 if(IssueUtilities.canEditIssue(issue, currUserId, userPermissions)) {
185 issuePTO.setUserCanEdit(true);
186 }
187 }
188
189 if(! hasViewAll && ! IssueUtilities.canViewIssue(issue, currUserId, userPermissions)) {
190 continue;
191 }
192 hasIssues = true;
193 if(start > 0 && k < start) {
194 k++;
195 continue;
196 }
197 if(userPrefs.getNumItemsOnIssueList() > 0 && row >= userPrefs.getNumItemsOnIssueList()) {
198 break;
199 }
200 row++;
201
202 issuePTOs.add(issuePTO);
203 }
204
205
206 request.setAttribute("pagination", new Pagination(numViewable, start, userPrefs.getNumItemsOnIssueList()));
207 request.setAttribute(ListIssuesActionUtil.ATT_NAME_HAS_ORDER_PARAM, hasOrderParam);
208 request.setAttribute(ListIssuesActionUtil.ATT_NAME_ORDER_PARAM, orderParam);
209 request.setAttribute(ListIssuesActionUtil.ATT_NAME_ISSUE_PTOS, issuePTOs);
210 request.setAttribute(ListIssuesActionUtil.ATT_NAME_PROJECT, project);
211 request.setAttribute(ListIssuesActionUtil.ATT_NAME_PROJCET_ID, projectId);
212 request.setAttribute(ListIssuesActionUtil.ATT_NAME_HAS_ISSUES, hasIssues);
213 request.setAttribute(ListIssuesActionUtil.ATT_NAME_HAS_VIEW_ALL, hasViewAll);
214
215
216 request.setAttribute("rssFeed", "/servlets/issues/p" + project.getId());
217
218 request.setAttribute(ListIssuesActionUtil.ATT_NAME_UNASSIGNED, ITrackerResources.getString(ListIssuesActionUtil.RES_KEY_UNASSIGNED, locale));
219 String pageTitleArg = project.getName();
220 request.setAttribute(ListIssuesActionUtil.ATT_NAME_PAGE_TITLE_KEY, ListIssuesActionUtil.LIST_ISSUES_PAGE_TITLE_KEY);
221 request.setAttribute(ListIssuesActionUtil.ATT_NAME_PAGE_TITLE_ARG, pageTitleArg);
222 final Map<Integer, Set<PermissionType>> permissions = RequestHelper.getUserPermissions(session);
223 boolean canCreateIssue = false;
224 if(project.getStatus() == Status.ACTIVE && UserUtilities.hasPermission(permissions, project.getId(), PermissionType.ISSUE_EDIT_ALL)) {
225 canCreateIssue = true;
226 }
227 request.setAttribute("canCreateIssue", canCreateIssue);
228
229 return null;
230 }
231
232
233
234 public static class Pagination {
235 final private int total, start, perPage, pageCount, currentPage;
236 private Pagination(final int total, final int start, final int perPage) {
237 this.total = total;
238 this.start = start;
239 this.perPage = perPage;
240 pageCount = perPage>0?Double.valueOf(Math.ceil((double)total/perPage)).intValue():1;
241 currentPage = start>0?Double.valueOf(Math.ceil((double)start/perPage)).intValue()+1:1;
242 }
243
244 public int getTotal() {
245 return total;
246 }
247
248 public int getStart() {
249 return start;
250 }
251
252 public int getPerPage() {
253 return perPage;
254 }
255
256 public int getPageCount() {
257 return pageCount;
258 }
259
260 public int getCurrentPage() {
261 return currentPage;
262 }
263 }
264
265 }