View Javadoc
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  	// TODO check for other occurences for this constants and maybe place somewhere else?
22  	public static final String LIST_ISSUES_PAGE_TITLE_KEY = "itracker.web.listissues.title";
23  	// request attribute names
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      // get the services
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      // get the request parameters
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      // get some values
83      int status = (userPrefs.getShowClosedOnIssueList() ? IssueUtilities.STATUS_END : IssueUtilities.STATUS_CLOSED);
84      
85      // do some service calls
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      // prepare PTOs
96      List<IssuePTO> issuePTOs = new ArrayList<IssuePTO>();
97      
98      // do some more order processing
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     // start copying from Models to PTOs
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     // populate the request$
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     * TODO temporary pagination helper
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 }