KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > za > org > coefficient > modules > issueTracker > IssueTracker


1 /*
2  * Coefficient - facilitates project based collaboration
3  * Copyright (C) 2003, Dylan Etkin, CSIR icomtek
4  * PO Box 395
5  * Pretoria 0001, RSA
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  */

19
20 package za.org.coefficient.modules.issueTracker;
21
22 import net.sf.hibernate.HibernateException;
23 import net.sf.hibernate.ObjectNotFoundException;
24 import net.sf.hibernate.Hibernate;
25 import net.sf.hibernate.Session;
26 import net.sf.hibernate.type.Type;
27
28 import org.apache.commons.fileupload.FileUploadException;
29
30 import za.org.coefficient.authentication.Role;
31 import za.org.coefficient.authentication.CoefficientUser;
32 import za.org.coefficient.core.Constants;
33 import za.org.coefficient.util.common.MailUtil;
34 import za.org.coefficient.util.common.BaseMultipartRequest;
35 import za.org.coefficient.util.common.UploadedFile;
36 import za.org.coefficient.util.common.HibernatePager;
37 import za.org.coefficient.util.common.InvokerFactory;
38 import net.sf.hibernate.util.HibernateUtil;
39 import za.org.coefficient.util.ejb.VelocityScreenUtil;
40 import za.org.coefficient.util.ejb.SecurityUtil;
41 import za.org.coefficient.interfaces.CoefficientContext;
42 import za.org.coefficient.modules.BaseProjectModule;
43 import za.org.coefficient.modules.issueTracker.DiscussionData;
44 import za.org.coefficient.modules.project.ProjectConstants;
45 import za.org.coefficient.modules.vote.VoteData;
46 import za.org.coefficient.modules.fileUpload.ProjectFolderItem;
47 import za.org.coefficient.modules.fileUpload.ProjectFolder;
48 import za.org.coefficient.modules.fileUpload.ProjectEntity;
49 import za.org.coefficient.modules.fileUpload.ProjectUpload;
50
51 import java.text.SimpleDateFormat JavaDoc;
52
53 import java.util.HashMap JavaDoc;
54 import java.util.List JavaDoc;
55 import java.util.ArrayList JavaDoc;
56 import java.util.Date JavaDoc;
57 import java.util.Arrays JavaDoc;
58 import java.util.Iterator JavaDoc;
59
60 import java.io.File JavaDoc;
61 import java.io.FileOutputStream JavaDoc;
62 import java.io.IOException JavaDoc;
63
64 /**
65  * @pojo2ejb.class
66  * name="IssueTracker"
67  * jndi-prefix="za/org/coefficient/project/"
68  * interface-extends="za.org.coefficient.interfaces.Module"
69  * interface-local-extends="za.org.coefficient.interfaces.ModuleLocal"
70  *
71  * @web.resource-env-ref
72  * name="za/org/coefficient/project/IssueTracker"
73  * type="za.org.coefficient.modules.issueTracker.IssueTracker"
74  * @web.resource-env-ref
75  * name="IssueTracker"
76  * type="za.org.coefficient.modules.issueTracker.IssueTracker"
77  */

78 public class IssueTracker extends BaseProjectModule {
79     //~ Static fields/initializers =============================================
80

81     public final static int PERCENT_COMPLETE_START = 0;
82     public final static int PERCENT_COMPLETE_FINISHED = 100;
83
84     public final static String JavaDoc LINK_DUPLICATES = "duplicates";
85     public final static String JavaDoc LINK_DUPLICATED_BY = "is duplicated by";
86     public final static String JavaDoc LINK_INCORPORATES = "incorporates";
87     public final static String JavaDoc LINK_PART_OF = "is part of";
88     public final static String JavaDoc LINK_RELATES_TO = "relates to";
89     public final static String JavaDoc LINK_RELATED_TO = "is related to";
90
91     public final static String JavaDoc STATUS_ASSIGNED = "Assigned";
92     public final static String JavaDoc STATUS_CLOSED = "Closed";
93     //public final static String STATUS_INPROGRESS = "In Progress";
94
public final static String JavaDoc STATUS_REOPENED = "Reopened";
95     //public final static String STATUS_RESOLVED = "Resolved";
96
public final static String JavaDoc STATUS_UNASSIGNED = "Unassigned";
97
98     public final static String JavaDoc PRIORITY_BLOCKER = "Blocker";
99     public final static String JavaDoc PRIORITY_CRITICAL = "Critical";
100     public final static String JavaDoc PRIORITY_MAJOR = "Major";
101     public final static String JavaDoc PRIORITY_MINOR = "Minor";
102     public final static String JavaDoc PRIORITY_TRIVIAL = "Trivial";
103     
104     public final static String JavaDoc TYPE_BUG = "Bug";
105     public final static String JavaDoc TYPE_NEWFEATURE = "New Feature";
106     public final static String JavaDoc TYPE_TASK = "Task";
107     public final static String JavaDoc TYPE_IMPROVEMENT = "Improvement";
108     public final static String JavaDoc TYPE_PATCH = "Patch";
109
110     public final static String JavaDoc RESOLUTION_FIXED = "Fixed";
111     public final static String JavaDoc RESOLUTION_WONT_FIX = "Won't fix";
112     public final static String JavaDoc RESOLUTION_DUPLICATE = "Duplicate";
113     public final static String JavaDoc RESOLUTION_INCOMPLETE = "Need more information";
114     public final static String JavaDoc RESOLUTION_CANNOT_REPRODUCE = "Cannot reproduce";
115     public final static String JavaDoc RESOLUTION_REJECTED = "Rejected";
116     public final static String JavaDoc RESOLUTION_UNRESOLVED = "Unresolved";
117
118     private static ArrayList JavaDoc ISSUE_TYPES = new ArrayList JavaDoc();
119     private static ArrayList JavaDoc ISSUE_PRIORITIES = new ArrayList JavaDoc();
120     private static ArrayList JavaDoc ISSUE_STATUSES = new ArrayList JavaDoc();
121     private static ArrayList JavaDoc ISSUE_RESOLUTIONS = new ArrayList JavaDoc();
122     private static ArrayList JavaDoc ISSUE_LINKS = new ArrayList JavaDoc();
123
124     private static final String JavaDoc CURRENT_FILTER = "__current_filter__23";
125     private static final String JavaDoc ISSUE_PAGER = "__issue_pager_sess__";
126
127     private static final int SIZEKB = 1024;
128     private static final int SIZEMB = 1024 * SIZEKB;
129
130     private static final String JavaDoc MESSAGE_1 = "You have been emailed this because you have expressed interest in watching this issue. To remove the watch you should login to the issue tracker and click unwatch. <br>Key: ";
131     private static final String JavaDoc MESSAGE_2 = "<br>Subject: ";
132     private static final String JavaDoc SUBJECT =
133         Constants.CFG_SITENAME + " Issue Tracker [Watching] Issue Key: ";
134
135     private static final String JavaDoc ISSUE_DATA = "__issue_data_holder__";
136     private static final String JavaDoc ISSUE_DATAS = "__issues_data_holder__";
137
138     static {
139         try {
140             HibernateUtil.configureHibernateForClasses(new Class JavaDoc [] {IssueData.class, VoteData.class, DiscussionData.class, ProjectFolderItem.class, ProjectFolder.class, ProjectEntity.class, ProjectUpload.class, SearchFilter.class});
141         } catch (HibernateException he) {
142             he.printStackTrace();
143         }
144
145         // setup the ISSUE_TYPES
146
ISSUE_TYPES.add(TYPE_BUG);
147         ISSUE_TYPES.add(TYPE_NEWFEATURE);
148         ISSUE_TYPES.add(TYPE_TASK);
149         ISSUE_TYPES.add(TYPE_IMPROVEMENT);
150         ISSUE_TYPES.add(TYPE_PATCH);
151
152         ISSUE_PRIORITIES.add(PRIORITY_BLOCKER);
153         ISSUE_PRIORITIES.add(PRIORITY_CRITICAL);
154         ISSUE_PRIORITIES.add(PRIORITY_MAJOR);
155         ISSUE_PRIORITIES.add(PRIORITY_MINOR);
156         ISSUE_PRIORITIES.add(PRIORITY_TRIVIAL);
157
158         ISSUE_STATUSES.add(STATUS_UNASSIGNED);
159         ISSUE_STATUSES.add(STATUS_ASSIGNED);
160         //ISSUE_STATUSES.add(STATUS_INPROGRESS);
161
ISSUE_STATUSES.add(STATUS_CLOSED);
162         ISSUE_STATUSES.add(STATUS_REOPENED);
163         //ISSUE_STATUSES.add(STATUS_RESOLVED);
164

165         ISSUE_RESOLUTIONS.add(RESOLUTION_UNRESOLVED);
166         ISSUE_RESOLUTIONS.add(RESOLUTION_WONT_FIX);
167         ISSUE_RESOLUTIONS.add(RESOLUTION_DUPLICATE);
168         ISSUE_RESOLUTIONS.add(RESOLUTION_INCOMPLETE);
169         ISSUE_RESOLUTIONS.add(RESOLUTION_CANNOT_REPRODUCE);
170         ISSUE_RESOLUTIONS.add(RESOLUTION_FIXED);
171         ISSUE_RESOLUTIONS.add(RESOLUTION_REJECTED);
172
173         ISSUE_LINKS.add(LINK_DUPLICATES);
174         ISSUE_LINKS.add(LINK_INCORPORATES);
175         ISSUE_LINKS.add(LINK_PART_OF);
176         ISSUE_LINKS.add(LINK_RELATES_TO);
177     }
178
179     //~ Methods ================================================================
180

181     public String JavaDoc getMainMethod() {
182         return "entry";
183     }
184
185     public String JavaDoc getModuleDescription() {
186         return "Allows for display of issues for a project";
187     }
188
189     public String JavaDoc getModuleDisplayName() {
190         return "Issue Tracker";
191     }
192
193     public String JavaDoc canExecuteForRole(CoefficientContext ctx, String JavaDoc methodName,
194         Role usersHighestRole) {
195         if (usersHighestRole.getRoleValue() == SecurityUtil.GUEST_ROLE_VAL &&
196             (methodName.equals("createIssue") ||
197              methodName.equals("setWatch") ||
198              methodName.equals("comment") ||
199              methodName.equals("saveComment") ||
200              methodName.equals("attatchFile") ||
201              methodName.equals("saveUpload") ||
202              methodName.equals("voteForIssue") ||
203              methodName.equals("unvoteForIssue") ||
204              methodName.equals("saveFilterPrompt") ||
205              methodName.equals("saveFilter") ||
206              methodName.equals("deleteFilter") ||
207              methodName.equals("saveIssue"))) {
208             return "You must be logged in to perform this operation";
209         } else if (usersHighestRole.getRoleValue() >
210                    SecurityUtil.PROJECT_MEMBER_ROLE_VAL &&
211                    (methodName.equals("changeStatus") ||
212                     methodName.equals("resolveIssuePrompt") ||
213                     methodName.equals("resolveIssue") ||
214                     methodName.equals("deleteAttatchment") ||
215                     methodName.equals("deleteAttatchment") )) {
216             return "You must be at least a project member to perform this operation";
217         } else {
218             return null;
219         }
220     }
221
222     public String JavaDoc displayUsersData(CoefficientUser user) {
223         HashMap JavaDoc map = new HashMap JavaDoc();
224         try {
225             List JavaDoc assignedIssues =
226                 HibernateUtil.find("select issue from " + IssueData.class.getName()
227                                    + " as issue where issue.assignedTo.id = ? "
228                                    + " and (issue.status = ? or issue.status = ?) "
229                                    + "order by issue.project.name, issue.priority, issue.id",
230                                    new Object JavaDoc[]{user.getId(), "Assigned", "Reopened"}
231                                    , new Type[]{Hibernate.LONG, Hibernate.STRING,
232                                                 Hibernate.STRING});
233             List JavaDoc reportedIssues =
234                 HibernateUtil.find("select issue from " + IssueData.class.getName()
235                                    +" as issue where issue.author.id = ? "
236                                    + "and (issue.status = ? or issue.status = ? ) "
237                                    + "order by issue.project.name, issue.priority, issue.id",
238                                    new Object JavaDoc[]{user.getId(), "Assigned", "Reopened"}
239                                    , new Type[]{Hibernate.LONG, Hibernate.STRING,
240                                                 Hibernate.STRING});
241             map.put("reportedIssues", reportedIssues);
242             map.put("assignedIssues", assignedIssues);
243             map.put("user", user);
244             map.put("encoder", new URLEncoder());
245         } catch (HibernateException he) {
246             he.printStackTrace();
247         }
248
249         StringBuffer JavaDoc sb =
250             VelocityScreenUtil.getProcessedScreen("usersDataSummary.vm", map);
251
252         return sb.toString();
253     }
254
255     /**
256      * TODO: implement this
257      */

258     public CoefficientContext deleteAllForProject(CoefficientContext ctx) {
259         return ctx;
260     }
261
262     public CoefficientContext entry(CoefficientContext ctx) {
263         if(ctx.getCurrentUser() == null) {
264             ctx.setForward("IssueTracker", "viewIssueFilters");
265         } else {
266             HashMap JavaDoc params = new HashMap JavaDoc();
267             params.put("assigneeSelect", "issue_current_user");
268             params.put("Assigned", "true");
269             params.put("Reopened", "true");
270             ctx.setForward("IssueTracker", "filterIssues", params);
271         }
272         return ctx;
273     }
274
275     public String JavaDoc getSummaryForProject(CoefficientContext ctx)
276         throws HibernateException
277     {
278         HashMap JavaDoc map = new HashMap JavaDoc();
279         Session sess = HibernateUtil.getSession();
280         map.put("issueCnt", ((Integer JavaDoc)sess.iterate("select count(*) from "
281             + IssueData.class.getName()
282             + " as issData where issData.project.id = ?",
283             ctx.getProject().getId(), Hibernate.LONG).next()));
284         map.put("projectName", ProjectConstants.PROJECT_NAME);
285         // TODO: remove this when the hibernate util is all fixed up, this won't
286
// be needed.
287
HibernateUtil.finalizeSession();
288         StringBuffer JavaDoc sb = VelocityScreenUtil
289             .getProcessedScreen("getSummaryForProject.vm", map);
290         return sb.toString();
291     }
292
293     /**
294      * This method is required as this is a project module.
295      */

296     public CoefficientContext showSummaryForProject(CoefficientContext ctx)
297         throws HibernateException
298     {
299         HashMap JavaDoc map = new HashMap JavaDoc();
300         map.put("content", getSummaryForProject(ctx));
301         map.put("user", ctx.getCurrentUser());
302         StringBuffer JavaDoc sb = VelocityScreenUtil
303             .getProcessedScreen("showSummaryForProject.vm", map);
304         ctx.setModuleContent(sb.toString(), getModuleDisplayName());
305         return ctx;
306     }
307
308     public CoefficientContext viewIssueFilters(CoefficientContext ctx)
309         throws HibernateException {
310         HashMap JavaDoc map = new HashMap JavaDoc();
311         Long JavaDoc projectId = ctx.getProject().getId();
312                 
313         if (ctx.getCurrentUser() != null) {
314             Long JavaDoc userId = ctx.getCurrentUser().getId();
315             List JavaDoc myFilters = getMyFilters(projectId, userId);
316             map.put("myFilters", myFilters);
317             map.put("myFiltersCount", getMyFiltersCount(myFilters));
318             map.put("reportedByMe", getReportedByMeCount(projectId, userId));
319             map.put("assignedToMe", getAssignedToMeCount(projectId, userId));
320         }
321
322         map.put("statuses", getStatusesCount(projectId));
323         map.put("priorities", getPrioritiesCount(projectId));
324         map.put("types", getTypesCount(projectId));
325         map.put("all", getAllCount(projectId));
326         map.put("open", getOpenCount(projectId));
327         map.put("new", getNewCount(projectId));
328         map.put("user", ctx.getCurrentUser());
329         
330         if(ctx.getSessionAttribute(CURRENT_FILTER) != null) {
331             map.put("filter", new Boolean JavaDoc(true));
332         }
333         
334         StringBuffer JavaDoc sb = VelocityScreenUtil
335             .getProcessedScreen("viewSummaries.vm", map);
336         ctx.setModuleContent(sb.toString(), getModuleDisplayName());
337         return ctx;
338     }
339
340     public CoefficientContext createIssue(CoefficientContext ctx) throws HibernateException {
341         String JavaDoc type = ctx.getParameter("type");
342         HashMap JavaDoc map = new HashMap JavaDoc();
343         map.put("project", ctx.getProject());
344         map.put("user", ctx.getCurrentUser());
345         if (type == null) {
346             map.put("types", ISSUE_TYPES);
347             if(ctx.getSessionAttribute(CURRENT_FILTER) != null) {
348                 map.put("filter", new Boolean JavaDoc(true));
349             }
350             // Prompt for type
351
StringBuffer JavaDoc sb = VelocityScreenUtil
352                 .getProcessedScreen("createIssueTypePrompt.vm", map);
353             ctx.setModuleContent(sb.toString(), getModuleDisplayName());
354         } else {
355             Long JavaDoc issueId = ctx.getParameterAsLong("issueId", -1);
356             if(issueId.longValue() != -1) {
357                 map.put("issue", HibernateUtil.load(IssueData.class, issueId));
358             }
359             map.put("type", type);
360             map.put("priorities", ISSUE_PRIORITIES);
361             ArrayList JavaDoc versions = new ArrayList JavaDoc();
362             versions.addAll(ctx.getProject().getVersions());
363             map.put("versions", versions);
364             map.put("assignees", ctx.getProject().getMembers());
365             map.put("components", ctx.getProject().getComponents());
366
367             Role highestRole = SecurityUtil
368                 .getHighestRoleForUser(ctx.getCurrentUser(),ctx.getProject());
369             if (highestRole.getRoleValue() <= SecurityUtil.PROJECT_MEMBER_ROLE_VAL) {
370                 map.put("canAssign", new Boolean JavaDoc (true));
371             }
372             
373             if(ctx.getSessionAttribute(CURRENT_FILTER) != null) {
374                 map.put("filter", new Boolean JavaDoc(true));
375             }
376
377             // Prompt for other information
378
StringBuffer JavaDoc sb = VelocityScreenUtil
379                 .getProcessedScreen("issueEditCreate.vm", map);
380             ctx.setModuleContent(sb.toString(), getModuleDisplayName());
381         }
382         return ctx;
383     }
384
385     public CoefficientContext saveIssue(CoefficientContext ctx) throws HibernateException {
386         Role maxReadRole = SecurityUtil
387             .getRoleForValue(SecurityUtil.GUEST_ROLE_VAL);
388         Role maxWriteRole =
389             SecurityUtil.getRoleForValue(SecurityUtil.SITE_MEMBER_ROLE_VAL);
390
391         if(!"".equals(ctx.getParameter("summary", "").trim()) &&
392            !"".equals(ctx.getParameter("description", "").trim())) {
393
394             IssueData issue = null;
395             Long JavaDoc issueId = ctx.getParameterAsLong("issueId", -1);
396             if(issueId.longValue() != -1) {
397                 issue = (IssueData)HibernateUtil.load(IssueData.class, issueId);
398                 HibernateUtil.evict(issue);
399             } else {
400                 issue = new IssueData();
401             }
402             issue.setType(ctx.getParameter("type"));
403             issue.setSummary(ctx.getParameter("summary"));
404             issue.setEnvironment(ctx.getParameter("environment"));
405             issue.setPriority(ctx.getParameter("priority"));
406             if("Task".equals(issue.getType())) {
407                 issue.setTaskStartDate(ctx.getParameterAsDate("taskStartDate"));
408                 issue.setTaskEndDate(ctx.getParameterAsDate("taskEndDate"));
409             }
410             
411             Long JavaDoc assigneeId = ctx.getParameterAsLong("assignedToId", -1);
412             if (assigneeId.longValue() > -1) {
413                 issue.setStatus(STATUS_ASSIGNED);
414                 issue.setAssignedTo((CoefficientUser)HibernateUtil
415                                     .load(CoefficientUser.class, assigneeId));
416             } else {
417                 issue.setStatus(STATUS_UNASSIGNED);
418                 issue.setAssignedTo(null);
419             }
420
421             String JavaDoc [] affectedVersions = ctx.getParameterValues("versions");
422             List JavaDoc affectVer = null;
423             if(affectedVersions.length == 0) {
424                 affectVer = new ArrayList JavaDoc();
425                 affectVer.add("unknown");
426             } else {
427                 affectVer = Arrays.asList(affectedVersions);
428             }
429             issue.setAffectedVersions(affectVer);
430             
431             String JavaDoc [] components = ctx.getParameterValues("comps");
432             List JavaDoc comps = null;
433             if(components.length == 0) {
434                 comps = new ArrayList JavaDoc();
435                 comps.add("unknown");
436             } else {
437                 comps = Arrays.asList(components);
438             }
439             issue.setIssueComponents(comps);
440
441             if(issueId.longValue() == -1) {
442                 issue.setAuthor(ctx.getCurrentUser());
443                 issue.setProject(ctx.getProject());
444
445                 DiscussionData discussion = new DiscussionData();
446                 discussion.setUser(ctx.getCurrentUser());
447                 discussion.setComments(ctx.getParameter("description"));
448                 discussion.setSubject(ctx.getParameter("summary"));
449                 discussion.setMaxReadRole(maxReadRole);
450                 discussion.setMaxWriteRole(maxWriteRole);
451                 discussion.setType("discussion");
452                 discussion.setProject(ctx.getProject());
453                 HibernateUtil.save(discussion);
454                 issue.setDiscussion(discussion);
455             
456             
457                 VoteData vote = new VoteData();
458                 vote.setMinimumRole(maxWriteRole);
459                 vote.setStatus(new Boolean JavaDoc(true));
460                 vote.setSequence(new Long JavaDoc(1));
461                 vote.setName("Issue Vote");
462                 vote.setStartDate(new Date JavaDoc(System.currentTimeMillis()));
463                 vote.setEndDate(new Date JavaDoc(System.currentTimeMillis()));
464                 vote.setPerson(ctx.getCurrentUser().getFullName());
465                 vote.setQuestion("Vote for this issue if it is important to you");
466                 vote.getAnswers().add("Yes");
467                 vote.getCounts().add(new Long JavaDoc(0));
468                 HibernateUtil.save(vote);
469                 issue.setVote(vote);
470             
471                 ProjectFolderItem pfi = new ProjectFolderItem();
472                 pfi.setMaxReadRole(maxReadRole);
473                 pfi.setMaxWriteRole(maxWriteRole);
474                 pfi.setName(ctx.getParameter("summary"));
475                 pfi.setUserComment("Used to hold uploads for this issue");
476                 HibernateUtil.save(pfi);
477                 issue.setUploads(pfi);
478             
479                 issue.setResolution(RESOLUTION_UNRESOLVED);
480             } else {
481                 issue.setPercentComplete(ctx.getParameterAsInt("percentComplete", 0));
482                 issue.getDiscussion()
483                     .setComments(ctx.getParameter("description"));
484                 issue.getDiscussion().setSubject(ctx.getParameter("summary"));
485
486                 // Alert the watchers of any changes to the issue
487
StringBuffer JavaDoc message = new StringBuffer JavaDoc("The affected versions are now:");
488                 for(Iterator JavaDoc it = issue.getAffectedVersions().iterator(); it.hasNext();) {
489                     String JavaDoc version = (String JavaDoc)it.next();
490                     message.append("<br>"+version);
491                 }
492                 if(issue.getAffectedVersions().size() == 0) {
493                     message.append("none");
494                 }
495
496                 StringBuffer JavaDoc compMessage = new StringBuffer JavaDoc("The components are now:");
497                 for (Iterator JavaDoc it = issue.getIssueComponents().iterator(); it.hasNext();) {
498                     String JavaDoc component = (String JavaDoc)it.next();
499                     compMessage.append("<br>" + component);
500                 }
501                 if(issue.getIssueComponents().size() == 0) {
502                     compMessage.append("none");
503                 }
504
505                 emailWatchers(issue, "This issue has been updated.", "The priority is now: "
506                               + issue.getPriority() + "<br>The issue is assigned to: "
507                               + ((issue.getAssignedTo() != null) ?
508                                  issue.getAssignedTo().getFullName() : "unassigned" )
509                               + "<br>" + message.toString() + "<br>" + compMessage.toString());
510             }
511
512             String JavaDoc comment = ctx.getParameter("comment", "");
513             
514             HibernateUtil.saveOrUpdate(issue);
515             ctx.setSessionAttribute(ISSUE_DATA, issue);
516             HashMap JavaDoc params = new HashMap JavaDoc();
517             params.put("id", issue.getId());
518             if(issueId.longValue() == -1 || comment.trim().equals("")) {
519                 ctx.setForward("IssueTracker", "viewIssue", params);
520             } else {
521                 params.put("comment", comment);
522                 ctx.setForward("IssueTracker", "saveComment", params);
523             }
524         } else {
525             ctx.setError("You must provide a summary and a description to create an issue");
526         }
527         return ctx;
528     }
529
530     public CoefficientContext viewIssue(CoefficientContext ctx) throws HibernateException {
531         HashMap JavaDoc map = new HashMap JavaDoc();
532         map.put("project", ctx.getProject());
533         if (ctx.getCurrentUser() != null) {
534             map.put("user", ctx.getCurrentUser());
535         }
536         Role highestRole = SecurityUtil.getHighestRoleForUser(ctx.getCurrentUser(),
537                                                               ctx.getProject());
538         if (highestRole.getRoleValue() <= SecurityUtil.PROJECT_MEMBER_ROLE_VAL) {
539             map.put("editable", new Boolean JavaDoc(true));
540         }
541         map.put("dateFormat", new SimpleDateFormat JavaDoc(Constants.SYSTEM_DATE_FORMAT));
542         Long JavaDoc issueId = ctx.getParameterAsLong("id", -1);
543         if (issueId.longValue() > -1) {
544             IssueData issue =
545                 (IssueData)HibernateUtil.load(IssueData.class, issueId);
546
547             // get uploads for issue
548
List JavaDoc uploads =
549                 HibernateUtil.find("FROM " + ProjectUpload.class.getName()
550                              + " as upload WHERE "
551                              + "upload.folderItem.ID = ? ORDER BY upload.ID DESC",
552                              issue.getUploads().getID(), Hibernate.LONG);
553             map.put("uploads", uploads);
554             map.put("issue", issue);
555             if(ctx.getSessionAttribute(ISSUE_PAGER) != null) {
556                 map.put("pager", new Boolean JavaDoc(true));
557             }
558             map.put("encoder", new URLEncoder());
559
560             ctx.setSessionAttribute(ISSUE_DATA, issue);
561             
562             StringBuffer JavaDoc sb = VelocityScreenUtil
563                 .getProcessedScreen("viewIssue.vm", map);
564             ctx.setModuleContent(sb.toString(), getModuleDisplayName());
565         } else {
566             ctx.setError("You must select an issue to view");
567         }
568         return ctx;
569     }
570
571     public CoefficientContext viewIssueComments(CoefficientContext ctx) {
572         IssueData issue = (IssueData)ctx.getSessionAttribute(ISSUE_DATA);
573         if(issue != null) {
574             HashMap JavaDoc map = new HashMap JavaDoc();
575             map.put("issue", issue);
576             map.put("encoder", new URLEncoder());
577             if (ctx.getCurrentUser() != null) {
578                 map.put("user", ctx.getCurrentUser());
579             }
580             StringBuffer JavaDoc sb = VelocityScreenUtil
581                 .getProcessedScreen("viewIssueComments.vm", map);
582             ctx.setModuleContent(sb.toString(), getModuleDisplayName());
583         } else {
584             ctx.setError("You must select an issue to view its comments");
585         }
586         return ctx;
587     }
588
589     public CoefficientContext setWatch(CoefficientContext ctx) throws HibernateException {
590         Long JavaDoc userId = ctx.getParameterAsLong("userId", -1);
591         Long JavaDoc issueId = ctx.getParameterAsLong("issueId", -1);
592         boolean add = ctx.getParameterAsBoolean("add");
593         IssueData issue = (IssueData)ctx.getSessionAttribute(ISSUE_DATA);
594         if (userId.longValue() > -1 && issue != null) {
595             CoefficientUser user =
596                 (CoefficientUser)HibernateUtil.load(CoefficientUser.class, userId);
597             if (add) {
598                 issue.addWatcher(user);
599             } else {
600                 issue.removeWatcher(user);
601             }
602             HibernateUtil.saveOrUpdate(issue);
603             HashMap JavaDoc params = new HashMap JavaDoc();
604             params.put("id", issueId);
605             emailWatchers(issue, "A user is " + ((add) ? "" : "not" ) + "watching this issue", "A watch has been set on this issue by " + ctx.getCurrentUser().getFullName());
606             ctx.setForward("IssueTracker", "viewIssue", params);
607         } else {
608             ctx.setError("You must provide both a userId and issue to modify a watch");
609         }
610         return ctx;
611     }
612
613     public CoefficientContext comment(CoefficientContext ctx) throws HibernateException {
614         HashMap JavaDoc map = new HashMap JavaDoc();
615         IssueData issue = (IssueData)ctx.getSessionAttribute(ISSUE_DATA);
616         map.put("user", ctx.getCurrentUser());
617         if (issue != null) {
618             map.put("issue", issue);
619             StringBuffer JavaDoc sb = VelocityScreenUtil
620                 .getProcessedScreen("addComment.vm", map);
621             ctx.setModuleContent(sb.toString(), getModuleDisplayName());
622         } else {
623             ctx.setError("You must select an issue to add a comment to");
624         }
625         return ctx;
626     }
627
628     public CoefficientContext saveComment(CoefficientContext ctx) throws HibernateException {
629         Long JavaDoc issueId = ctx.getParameterAsLong("id", -1);
630         IssueData issue = (IssueData)ctx.getSessionAttribute(ISSUE_DATA);
631         if (issue != null) {
632             Role maxReadRole = SecurityUtil
633                 .getRoleForValue(SecurityUtil.GUEST_ROLE_VAL);
634             Role maxWriteRole =
635                 SecurityUtil.getRoleForValue(SecurityUtil.SITE_MEMBER_ROLE_VAL);
636             DiscussionData reply = new DiscussionData();
637             reply.setUser(ctx.getCurrentUser());
638             reply.setComments(ctx.getParameter("comment"));
639             reply.setSubject("ISSUE_TRACKER REPLY");
640             reply.setMaxReadRole(maxReadRole);
641             reply.setMaxWriteRole(maxWriteRole);
642             reply.setType("discussion");
643             reply.setProject(ctx.getProject());
644             reply.setParent(issue.getDiscussion());
645             HibernateUtil.save(reply);
646             issue.getDiscussion().addChild(reply);
647             HibernateUtil.saveOrUpdate(issue.getDiscussion());
648                 
649             HashMap JavaDoc params = new HashMap JavaDoc();
650             params.put("id", issueId);
651             emailWatchers(issue, "A comment has been added",
652                           "The following comment has been added to this issue:<br>" + reply.getComments());
653             ctx.setForward("IssueTracker", "viewIssue", params);
654         } else {
655             ctx.setError("You must select an issue to add a comment to");
656         }
657         return ctx;
658     }
659
660     public CoefficientContext attatchFile(CoefficientContext ctx) throws HibernateException {
661         IssueData issue = (IssueData)ctx.getSessionAttribute(ISSUE_DATA);
662         if (issue != null) {
663             HashMap JavaDoc map = new HashMap JavaDoc();
664             map.put("user", ctx.getCurrentUser());
665             map.put("issue", issue);
666             map.put("maxSize", getSizeString(Integer
667                                              .parseInt(Constants
668                                                        .MAX_FILE_UPLOAD_SIZE_BYTES)));
669             StringBuffer JavaDoc sb = VelocityScreenUtil
670                 .getProcessedScreen("attatchFile.vm", map);
671             ctx.setModuleContent(sb.toString(), getModuleDisplayName());
672         } else {
673             ctx.setError("You must supply an issue to attatch a file to");
674         }
675         return ctx;
676     }
677
678     public CoefficientContext saveUpload(CoefficientContext ctx) throws HibernateException {
679         IssueData issue = (IssueData)ctx.getSessionAttribute(ISSUE_DATA);
680         if (issue != null) {
681             String JavaDoc comment = saveFile(ctx, issue.getUploads());
682             HashMap JavaDoc params = new HashMap JavaDoc();
683             params.put("id", issue.getId());
684             if (!comment.equals("")) {
685                 params.put("comment", comment);
686                 ctx.setForward("IssueTracker", "saveComment", params);
687             } else {
688                 ctx.setForward("IssueTracker", "viewIssue", params);
689             }
690             emailWatchers(issue, "An attatchment has been added", "An attatchment has been added by " + ctx.getCurrentUser().getFullName() + "with the comment: "+ comment + "<br>");
691         } else {
692             ctx.setError("You must supply an issue to attatch a file to");
693         }
694         return ctx;
695     }
696
697     public CoefficientContext voteForIssue(CoefficientContext ctx) throws HibernateException {
698         IssueData issue = (IssueData)ctx.getSessionAttribute(ISSUE_DATA);
699         if (issue != null) {
700             VoteData vote = issue.getVote();
701             vote.getVoters().add(ctx.getCurrentUser().getUserName());
702             vote.getCounts().set(0, new Long JavaDoc(((Long JavaDoc)vote.getCounts().get(0))
703                                              .longValue() + 1));
704             HibernateUtil.saveOrUpdate(vote);
705             HashMap JavaDoc params = new HashMap JavaDoc();
706             params.put("id", issue.getId());
707             emailWatchers(issue, "A vote has been cast for this issue", "A vote has been cast in favor of this issue by " + ctx.getCurrentUser().getFullName());
708             ctx.setForward("IssueTracker", "viewIssue", params);
709         } else {
710             ctx.setError("You must supply an issue to vote on");
711         }
712         return ctx;
713     }
714
715     public CoefficientContext unvoteForIssue(CoefficientContext ctx) throws HibernateException {
716         IssueData issue = (IssueData)ctx.getSessionAttribute(ISSUE_DATA);
717         if (issue != null) {
718             VoteData vote = issue.getVote();
719             int idx = vote.getVoters().indexOf(ctx.getCurrentUser().getUserName());
720             if (idx > -1) {
721                 vote.getVoters().remove(idx);
722                 vote.getCounts().set(0, new Long JavaDoc(((Long JavaDoc)vote.getCounts().get(0))
723                                                  .longValue() - 1));
724                 HibernateUtil.saveOrUpdate(vote);
725                 emailWatchers(issue, "A vote has been uncast for this issue", "A vote has been uncast for this issue by " + ctx.getCurrentUser().getFullName());
726             }
727             HashMap JavaDoc params = new HashMap JavaDoc();
728             params.put("id", issue.getId());
729             ctx.setForward("IssueTracker", "viewIssue", params);
730         } else {
731             ctx.setError("You must supply an issue to vote on");
732         }
733         return ctx;
734     }
735
736     public CoefficientContext findIssues(CoefficientContext ctx) throws HibernateException {
737         HashMap JavaDoc map = new HashMap JavaDoc();
738         if(ctx.getParameter("advanced") != null &&
739            !ctx.getParameter("advanced").trim().equals("")) {
740             map.put("advanced", new Boolean JavaDoc(true));
741         }
742         map.put("user", ctx.getCurrentUser());
743         map.put("issues", HibernateUtil.findAll(IssueData.class));
744         map.put("project", ctx.getProject());
745         map.put("priorities", ISSUE_PRIORITIES);
746         map.put("statuses", ISSUE_STATUSES);
747         map.put("resolutions", ISSUE_RESOLUTIONS);
748         map.put("types", ISSUE_TYPES);
749         map.put("hour", new Long JavaDoc(3600000L));
750         map.put("day", new Long JavaDoc(86400000L));
751         map.put("week", new Long JavaDoc(604800000L));
752         map.put("month", new Long JavaDoc(2592000000L));
753
754         if(ctx.getSessionAttribute(CURRENT_FILTER) != null) {
755             map.put("filter", new Boolean JavaDoc(true));
756         }
757         map.put("encoder", new URLEncoder());
758
759         StringBuffer JavaDoc sb = VelocityScreenUtil
760             .getProcessedScreen("searchIssues.vm", map);
761         ctx.setModuleContent(sb.toString(), getModuleDisplayName());
762         return ctx;
763     }
764
765     public CoefficientContext saveFilterPrompt(CoefficientContext ctx) throws Exception JavaDoc {
766         SearchFilter filter =
767             (SearchFilter)ctx.getSessionAttribute(CURRENT_FILTER);
768         if (filter == null) {
769             ctx.setError("You must have a current filter to save");
770         } else {
771             HashMap JavaDoc map = new HashMap JavaDoc();
772             map.put("user", ctx.getCurrentUser());
773             map.put("filter", filter);
774             map.put("week", new Long JavaDoc(2592000000L));
775             map.put("priorities", ISSUE_PRIORITIES);
776             map.put("statuses", ISSUE_STATUSES);
777             map.put("resolutions", ISSUE_RESOLUTIONS);
778             map.put("types", ISSUE_TYPES);
779             StringBuffer JavaDoc sb = VelocityScreenUtil
780                 .getProcessedScreen("saveSearchPrompt.vm", map);
781             ctx.setModuleContent(sb.toString(), getModuleDisplayName());
782         }
783         return ctx;
784     }
785
786     public CoefficientContext saveFilter(CoefficientContext ctx) throws Exception JavaDoc {
787         SearchFilter filter =
788             (SearchFilter)ctx.getSessionAttribute(CURRENT_FILTER);
789         if (filter == null) {
790             ctx.setError("You must have a current filter to save");
791         } else {
792             if(!ctx.getParameter("name", "").trim().equals("")) {
793                 filter.setName(ctx.getParameter("name"));
794                 filter.setFilterDescription(ctx.getParameter("description", ""));
795                 filter.setFilterAuthor(ctx.getCurrentUser());
796                 HibernateUtil.saveOrUpdate(filter);
797                 ctx.removeSessionAttribute(CURRENT_FILTER);
798                 ctx.setForward("IssueTracker", "viewIssueFilters");
799             } else {
800                 ctx.setError("You must provide a name for the filter");
801             }
802         }
803         return ctx;
804     }
805
806     public CoefficientContext deleteFilter(CoefficientContext ctx) throws Exception JavaDoc {
807         Long JavaDoc filterId = ctx.getParameterAsLong("filterId", -1);
808         if (filterId.longValue() > -1) {
809             SearchFilter filter =
810                 (SearchFilter)HibernateUtil.load(SearchFilter.class, filterId);
811             if(filter != null && filter.getAuthor().equals(ctx.getCurrentUser())) {
812                 HibernateUtil.delete(filter);
813                 ctx.setForward("IssueTracker", "viewIssueFilters");
814             } else {
815                 ctx.setError("You must be the author to delete this filter");
816             }
817         } else {
818             ctx.setError("You must supply a filter to delete");
819         }
820         return ctx;
821     }
822
823     public CoefficientContext changeStatus(CoefficientContext ctx) throws Exception JavaDoc {
824         IssueData issue = (IssueData)ctx.getSessionAttribute(ISSUE_DATA);
825         String JavaDoc status = ctx.getParameter("status", "");
826         if (issue != null && !status.equals("")) {
827             issue.setStatus(status);
828             HibernateUtil.saveOrUpdate(issue);
829             HashMap JavaDoc params = new HashMap JavaDoc();
830             params.put("id", issue.getId());
831             ctx.setForward("IssueTracker", "viewIssue", params);
832             emailWatchers(issue, "This issues status has been changed", "This issues status has been changed to " + issue.getStatus());
833         } else {
834             ctx.setError("You must provide an issue and a status to change status on.");
835         }
836         return ctx;
837     }
838
839     public CoefficientContext resolveIssuePrompt(CoefficientContext ctx) throws Exception JavaDoc {
840         IssueData issue = (IssueData)ctx.getSessionAttribute(ISSUE_DATA);
841         if (issue != null) {
842             HashMap JavaDoc map = new HashMap JavaDoc();
843             map.put("issueId", issue.getId());
844             map.put("resolutions", ISSUE_RESOLUTIONS);
845             map.put("user", ctx.getCurrentUser());
846             ArrayList JavaDoc versions = new ArrayList JavaDoc();
847             versions.addAll(ctx.getProject().getVersions());
848             map.put("versions", versions);
849             StringBuffer JavaDoc sb = VelocityScreenUtil
850                 .getProcessedScreen("resolveIssue.vm", map);
851             ctx.setModuleContent(sb.toString(), getModuleDisplayName());
852         } else {
853             ctx.setError("You must provide an issue to resolve");
854         }
855         return ctx;
856     }
857
858     public CoefficientContext resolveIssue(CoefficientContext ctx) throws Exception JavaDoc {
859         IssueData issue = (IssueData)ctx.getSessionAttribute(ISSUE_DATA);
860         String JavaDoc resolution = ctx.getParameter("resolution", "");
861         boolean reopen = ctx.getParameterAsBoolean("reopen");
862         if (issue != null) {
863             if (reopen) {
864                 issue.setResolution(RESOLUTION_UNRESOLVED);
865                 issue.setStatus(STATUS_REOPENED);
866                 issue.setCompleted(false);
867             } else if (!resolution.equals("")) {
868                 issue.setStatus(STATUS_CLOSED);
869                 if (RESOLUTION_FIXED.equals(resolution)) {
870                     issue.setResolution(RESOLUTION_FIXED);
871                     issue.setPercentComplete(PERCENT_COMPLETE_FINISHED);
872                 } else {
873                     issue.setResolution(resolution);
874                 }
875                 // Check for fix versions
876
String JavaDoc [] fixVersions = ctx.getParameterValues("fixVersions");
877                 issue.setFixVersions(Arrays.asList(fixVersions));
878                 
879                 issue.setCompleted(true);
880             } else {
881                 ctx.setError("You must provide a resolution for this issue");
882             }
883
884             if (!ctx.isError()) {
885                 HibernateUtil.saveOrUpdate(issue);
886
887                 String JavaDoc comment = ctx.getParameter("comment", "");
888                 HashMap JavaDoc params = new HashMap JavaDoc();
889                 params.put("id", issue.getId());
890                 if (!comment.equals("")) {
891                     params.put("comment", comment);
892                     ctx.setForward("IssueTracker", "saveComment", params);
893                 } else {
894                     params.put("id", issue.getId());
895                     ctx.setForward("IssueTracker", "viewIssue", params);
896                 }
897                 emailWatchers(issue, "This issue has been resolved", "This issue has been resolved as " + issue.getResolution());
898             }
899         } else {
900             ctx.setError("You must provide an issue to resolve");
901         }
902         return ctx;
903     }
904
905     public CoefficientContext deleteAttatchment(CoefficientContext ctx) throws Exception JavaDoc {
906         IssueData issue = (IssueData)ctx.getSessionAttribute(ISSUE_DATA);
907         if (issue != null) {
908             InvokerFactory.getInvoker()
909                 .invokeMethodOnModule("FileUpload", "deleteFile",
910                                       new Object JavaDoc[]{ctx, ctx.getProject()});
911             HashMap JavaDoc params = new HashMap JavaDoc();
912             params.put("id", issue.getId());
913             ctx.setForward("IssueTracker", "viewIssue", params);
914             emailWatchers(issue, "This issue has had an attatchment deleted",
915                           "This issue has had an attatchment deleted");
916         } else {
917             ctx.setError("You must select an issue to delete an attatchment from");
918         }
919         return ctx;
920     }
921
922     public CoefficientContext linkIssuePrompt(CoefficientContext ctx) throws HibernateException {
923         IssueData issue = (IssueData)ctx.getSessionAttribute(ISSUE_DATA);
924         if (issue == null) {
925             ctx.setError("You must select an issue to link");
926         } else {
927             HashMap JavaDoc map = new HashMap JavaDoc();
928             map.put("issue", issue);
929             map.put("links", ISSUE_LINKS);
930             map.put("user", ctx.getCurrentUser());
931             StringBuffer JavaDoc sb = VelocityScreenUtil
932                 .getProcessedScreen("linkIssue.vm", map);
933             ctx.setModuleContent(sb.toString(), getModuleDisplayName());
934         }
935         return ctx;
936     }
937
938     public CoefficientContext linkIssue(CoefficientContext ctx) throws HibernateException {
939         IssueData issue = (IssueData)ctx.getSessionAttribute(ISSUE_DATA);
940         boolean remove = ctx.getParameterAsBoolean("remove");
941         if (issue == null) {
942             ctx.setError("You must select an issue to link/unlink");
943         } else {
944             Long JavaDoc otherIssueId = ctx.getParameterAsLong("issueId", -1);
945             String JavaDoc linkType = ctx.getParameter("linkType");
946             if (otherIssueId.longValue() > -1 && linkType != null) {
947                 if(issue.getId().equals(otherIssueId)) {
948                     ctx.setError("You cannot link an issue to itself");
949                 } else {
950                     try {
951                         IssueData otherIssue =
952                             (IssueData)HibernateUtil.load(IssueData.class, otherIssueId);
953                         if(LINK_DUPLICATES.equals(linkType)) {
954                             if (remove) {
955                                 otherIssue.removeDuplicatedBy(issue.getId());
956                                 issue.removeDuplicates(otherIssue.getId());
957                             } else {
958                                 otherIssue.addDuplicatedBy(issue.getId(),
959                                                            issue.getSummary());
960                                 issue.addDuplicates(otherIssue.getId(),
961                                                     otherIssue.getSummary());
962                             }
963                         } else if (LINK_DUPLICATED_BY.equals(linkType)) {
964                             if(remove) {
965                                 otherIssue.removeDuplicates(issue.getId());
966                                 issue.removeDuplicatedBy(otherIssue.getId());
967                             } else {
968                                 otherIssue.addDuplicates(issue.getId(),
969                                                          issue.getSummary());
970                                 issue.addDuplicatedBy(otherIssue.getId(),
971                                                       otherIssue.getSummary());
972                             }
973                         } else if (LINK_INCORPORATES.equals(linkType)) {
974                             if(remove) {
975                                 otherIssue.removePartOf(issue.getId());
976                                 issue.removeIncorporates(otherIssue.getId());
977                             } else {
978                                 otherIssue.addPartOf(issue.getId(),
979                                                      issue.getSummary());
980                                 issue.addIncorporates(otherIssue.getId(),
981                                                       otherIssue.getSummary());
982                             }
983                         } else if (LINK_PART_OF.equals(linkType)) {
984                             if(remove) {
985                                 otherIssue.removeIncorporates(issue.getId());
986                                 issue.removePartOf(otherIssue.getId());
987                             } else {
988                                 otherIssue.addIncorporates(issue.getId(),
989                                                            issue.getSummary());
990                                 issue.addPartOf(otherIssue.getId(),
991                                                 otherIssue.getSummary());
992                             }
993                         } else if (LINK_RELATES_TO.equals(linkType)) {
994                             if(remove) {
995                                 otherIssue.removeRelatedTo(issue.getId());
996                                 issue.removeRelatesTo(otherIssue.getId());
997                             } else {
998                                 otherIssue.addRelatedTo(issue.getId(),
999                                                         issue.getSummary());
1000                                issue.addRelatesTo(otherIssue.getId(),
1001                                                   otherIssue.getSummary());
1002                            }
1003                        } else if (LINK_RELATED_TO.equals(linkType)) {
1004                            if(remove) {
1005                                otherIssue.removeRelatesTo(issue.getId());
1006                                issue.removeRelatedTo(otherIssue.getId());
1007                            } else {
1008                                otherIssue.addRelatesTo(issue.getId(),
1009                                                        issue.getSummary());
1010                                issue.addRelatedTo(otherIssue.getId(),
1011                                                   otherIssue.getSummary());
1012                            }
1013                        }
1014                        HibernateUtil.saveOrUpdate(issue);
1015                        HibernateUtil.saveOrUpdate(otherIssue);
1016                        String JavaDoc comment = ctx.getParameter("comment", "");
1017                        HashMap JavaDoc params = new HashMap JavaDoc();
1018                        params.put("id", issue.getId());
1019                        if (!comment.equals("")) {
1020                            params.put("comment", comment);
1021                            ctx.setForward("IssueTracker", "saveComment", params);
1022                        } else {
1023                            ctx.setForward("IssueTracker", "viewIssue", params);
1024                        }
1025                        String JavaDoc op = null;
1026                        if(remove) {
1027                            op = "unlinked";
1028                        } else {
1029                            op = "linked";
1030                        }
1031                        emailWatchers(issue, "This issue has been " + op,
1032                                      "This issue has been "+ op +" and " + linkType
1033                                      + " issue "+otherIssue.getId());
1034                    } catch (ObjectNotFoundException onfe) {
1035                        ctx.setError("The issue with id, "+ otherIssueId +
1036                                     " does not exist");
1037                    }
1038                }
1039            } else {
1040                ctx.setError("You must select another issue and a link type to link/unlink this issue to.");
1041            }
1042        }
1043        return ctx;
1044    }
1045
1046
1047    public CoefficientContext filterIssues(CoefficientContext ctx) throws Exception JavaDoc {
1048        // Populate a filter object or look it up if an id is passed
1049
boolean clearResults = ctx.getParameterAsBoolean("clearResults");
1050        Long JavaDoc filterId = ctx.getParameterAsLong("filterId", -1);
1051        SearchFilter filter = null;
1052        HibernatePager hp = null;
1053        HashMap JavaDoc map = new HashMap JavaDoc();
1054
1055        if (ctx.getParameter("next") != null) {
1056            hp = (HibernatePager) ctx.getSessionAttribute(ISSUE_PAGER);
1057            if (hp == null) {
1058                ctx.setError("Invalid operation");
1059            } else {
1060                hp.next();
1061            }
1062            filter = (SearchFilter)ctx.getSessionAttribute(CURRENT_FILTER);
1063        } else if (ctx.getParameter("previous") != null) {
1064            hp = (HibernatePager) ctx.getSessionAttribute(ISSUE_PAGER);
1065            if (hp == null) {
1066                ctx.setError("Invalid operation");
1067            } else {
1068                hp.previous();
1069            }
1070            filter = (SearchFilter)ctx.getSessionAttribute(CURRENT_FILTER);
1071        } else if (ctx.getParameter("page") != null) {
1072            hp = (HibernatePager) ctx.getSessionAttribute(ISSUE_PAGER);
1073            if (hp == null) {
1074                ctx.setError("pager does not exist");
1075            } else {
1076                hp.goToPage(ctx.getParameterAsInteger("page").intValue());
1077            }
1078            filter = (SearchFilter)ctx.getSessionAttribute(CURRENT_FILTER);
1079        } else if (ctx.getParameterAsBoolean("view")) {
1080            filter = (SearchFilter)ctx.getSessionAttribute(CURRENT_FILTER);
1081            hp = (HibernatePager) ctx.getSessionAttribute(ISSUE_PAGER);
1082            // Make sure we refresh the search on the page we were on
1083
hp.goToPage(hp.getCurrentPageNumber());
1084        } else {
1085            if (filterId.longValue() > -1) {
1086                filter = (SearchFilter)HibernateUtil.load(SearchFilter.class,
1087                                                          filterId);
1088            } else {
1089                filter = new SearchFilter();
1090                filter.setProject(ctx.getProject());
1091                filter.setFilterAuthor(ctx.getCurrentUser());
1092                filter.setSearchText(ctx.getParameter("query", ""));
1093                filter.setSummary(ctx.getParameterAsBoolean("summary"));
1094                filter.setDescription(ctx.getParameterAsBoolean("description"));
1095                filter.setComments(ctx.getParameterAsBoolean("comments"));
1096                filter.setEnvironment(ctx.getParameterAsBoolean("environment"));
1097                
1098                ArrayList JavaDoc types = new ArrayList JavaDoc();
1099                for(Iterator JavaDoc it = ISSUE_TYPES.iterator(); it.hasNext();) {
1100                    String JavaDoc type = (String JavaDoc)it.next();
1101                    if(ctx.getParameterAsBoolean(type)) {
1102                        types.add(type);
1103                    }
1104                }
1105
1106                ArrayList JavaDoc statuses = new ArrayList JavaDoc();
1107                for(Iterator JavaDoc it = ISSUE_STATUSES.iterator(); it.hasNext();) {
1108                    String JavaDoc status = (String JavaDoc)it.next();
1109                    if(ctx.getParameterAsBoolean(status)) {
1110                        statuses.add(status);
1111                    }
1112                }
1113
1114                ArrayList JavaDoc resolutions = new ArrayList JavaDoc();
1115                for(Iterator JavaDoc it = ISSUE_RESOLUTIONS.iterator(); it.hasNext();) {
1116                    String JavaDoc res = (String JavaDoc)it.next();
1117                    if(ctx.getParameterAsBoolean(res)) {
1118                        resolutions.add(res);
1119                    }
1120                }
1121
1122                ArrayList JavaDoc priorities = new ArrayList JavaDoc();
1123                for(Iterator JavaDoc it = ISSUE_PRIORITIES.iterator(); it.hasNext();) {
1124                    String JavaDoc pri = (String JavaDoc)it.next();
1125                    if(ctx.getParameterAsBoolean(pri)) {
1126                        priorities.add(pri);
1127                    }
1128                }
1129
1130                filter.setTypes(types);
1131                filter.setStatuses(statuses);
1132                filter.setResolutions(resolutions);
1133                filter.setPriorities(priorities);
1134                
1135                String JavaDoc reporterSelect = ctx.getParameter("reporterSelect", "");
1136                if ("issue_no_reporter".equals(reporterSelect)) {
1137                    filter.setAuthor(null);
1138                } else if ("issue_current_user".equals(reporterSelect)) {
1139                    filter.setAuthor(ctx.getCurrentUser());
1140                } else if ("specificuser".equals(reporterSelect)) {
1141                    String JavaDoc userName = ctx.getParameter("reporter", "");
1142                    CoefficientUser user =
1143                        (CoefficientUser)InvokerFactory.getInvoker()
1144                        .invokeMethodOnModule("UserAdmin", "findUserForName",
1145                                              new Object JavaDoc[] {userName});
1146                    filter.setAuthor(user);
1147                } else if ("specificgroup".equals(reporterSelect)) {
1148                    String JavaDoc roleName = ctx.getParameter("reporter", "");
1149                    Role role = SecurityUtil.getRoleForDescription(roleName);
1150                    filter.setAuthorRole(role);
1151                }
1152                
1153                String JavaDoc assigneeSelect = ctx.getParameter("assigneeSelect", "");
1154                if ("unassigned".equals(assigneeSelect)) {
1155                    filter.setAssignedTo(null);
1156                } else if ("issue_current_user".equals(assigneeSelect)) {
1157                    filter.setAssignedTo(ctx.getCurrentUser());
1158                } else if ("specificuser".equals(assigneeSelect)) {
1159                    String JavaDoc userName = ctx.getParameter("assignee", "");
1160                    CoefficientUser user =
1161                        (CoefficientUser)InvokerFactory.getInvoker()
1162                        .invokeMethodOnModule("UserAdmin", "findUserForName",
1163                                              new Object JavaDoc[] {userName});
1164                    filter.setAssignedTo(user);
1165                } else if ("specificgroup".equals(assigneeSelect)) {
1166                    String JavaDoc roleName = ctx.getParameter("assignee", "");
1167                    Role role = SecurityUtil.getRoleForDescription(roleName);
1168                    filter.setAssignedToRole(role);
1169                }
1170
1171                // Get time and date fields
1172
filter.setCreatedAfter(ctx.getParameterAsDate("createdAfter"));
1173                filter.setCreatedBefore(ctx.getParameterAsDate("createdBefore"));
1174                filter.setCreatedInPrevious(ctx.getParameterAsLong("createdInPrevious"));
1175                filter.setUpdatedAfter(ctx.getParameterAsDate("updatedAfter"));
1176                filter.setUpdatedBefore(ctx.getParameterAsDate("updatedBefore"));
1177                filter.setUpdatedInPrevious(ctx.getParameterAsLong("updatedInPrevious"));
1178
1179            }
1180            ctx.setSessionAttribute(CURRENT_FILTER, filter);
1181            hp = new HibernatePager(filter.getQuery(), filter.getQueryObjects(),
1182                                    Constants.MAX_ELEMENTS_PER_PAGE);
1183        }
1184        ctx.setSessionAttribute(ISSUE_PAGER, hp);
1185        if(clearResults) {
1186            map.put("pager", null);
1187            ctx.setSessionAttribute(ISSUE_PAGER, null);
1188        } else {
1189            map.put("pager", hp);
1190        }
1191        map.put("user", ctx.getCurrentUser());
1192        map.put("filter", filter);
1193        map.put("project", ctx.getProject());
1194        map.put("priorities", ISSUE_PRIORITIES);
1195        map.put("statuses", ISSUE_STATUSES);
1196        map.put("resolutions", ISSUE_RESOLUTIONS);
1197        map.put("types", ISSUE_TYPES);
1198        map.put("hour", new Long JavaDoc(3600000L));
1199        map.put("day", new Long JavaDoc(86400000L));
1200        map.put("week", new Long JavaDoc(604800000L));
1201        map.put("month", new Long JavaDoc(2592000000L));
1202        map.put("encoder", new URLEncoder());
1203        StringBuffer JavaDoc sb = VelocityScreenUtil
1204            .getProcessedScreen("searchIssues.vm", map);
1205        ctx.setModuleContent(sb.toString(), getModuleDisplayName());
1206        return ctx;
1207    }
1208
1209    /**
1210     * Workflow evalutation method.
1211     */

1212    public boolean isIssueCompleted(CoefficientContext ctx) throws HibernateException {
1213        Object JavaDoc [] vals = new Object JavaDoc [] {ctx.getProject().getId(), new Boolean JavaDoc(true),
1214                                        ctx.getParameter("issueSummary")};
1215        Type [] types = new Type [] {Hibernate.LONG, Hibernate.BOOLEAN,
1216                                     Hibernate.STRING};
1217        Session sess = HibernateUtil.getSession();
1218        Integer JavaDoc retVal =
1219            (Integer JavaDoc)sess.iterate("select count(issue) from "
1220                                           + IssueData.class.getName()
1221                                           + " as issue where "
1222                                           + "issue.project.id = ? and "
1223                                           + "issue.completed = ? and issue.summary = ?",
1224                                           vals, types).next();
1225        // TODO: remove this when the hibernate util is all fixed up, this won't
1226
// be needed.
1227
HibernateUtil.finalizeSession();
1228        return retVal.intValue() == 1;
1229    }
1230
1231    public CoefficientContext deleteIssueWithSummary(CoefficientContext ctx)
1232        throws HibernateException
1233    {
1234        String JavaDoc summary = ctx.getParameter("summary");
1235        HibernateUtil.delete("FROM " + IssueData.class.getName() +
1236                             " as issue where issue.summary = ? and issue.project.id = ?",
1237                             new Object JavaDoc[]{summary, ctx.getProject().getId()},
1238                             new Type[]{Hibernate.STRING, Hibernate.LONG});
1239        return ctx;
1240    }
1241
1242    private void emailWatchers(IssueData issue, String JavaDoc subject, String JavaDoc message) {
1243        for (Iterator JavaDoc it = issue.getWatchers().iterator(); it.hasNext(); ) {
1244            CoefficientUser user = (CoefficientUser)it.next();
1245            MailUtil.sendEmail(MESSAGE_1 + issue.getId() + MESSAGE_2
1246                               + issue.getSummary() + "<br>" + message,
1247                               SUBJECT + issue.getId() + " - " + subject,
1248                               user.getEmail(), null);
1249        }
1250    }
1251
1252    private String JavaDoc saveFile(CoefficientContext ctx, ProjectFolderItem item)
1253        throws HibernateException
1254    {
1255        String JavaDoc retVal = "";
1256
1257            BaseMultipartRequest request = null;
1258            try {
1259                request = ctx.getMultipartRequest();
1260            } catch (FileUploadException fe) {
1261                ctx.setError("Error getting mutlipart request - file cannot be uploaded!");
1262                return "";
1263            }
1264            retVal = request.getParameter("comment");
1265            ProjectUpload upload = new ProjectUpload();
1266            UploadedFile file = null;
1267            try {
1268                file = request.getFileParameter("file");
1269            } catch (FileUploadException fue) {
1270                ctx.setError("Error uploading file!");
1271                return "";
1272            }
1273            byte[] content = file.getContent();
1274            if (content.length == 0) {
1275                ctx.setError("Empty file!");
1276                return "";
1277            }
1278            upload.setFileSize(content.length);
1279            upload.setFolderItem(item);
1280            upload.setUserComment("no comment");
1281            upload.setMimeType(file.getContentType());
1282            upload.setCoefficientUser(ctx.getCurrentUser());
1283            upload.setVersion(1.0);
1284            upload.setFilename(file.getFilename());
1285            
1286            HibernateUtil.save(upload);
1287            
1288            try {
1289                if (Constants.FILEUPLOAD_SAVE_PATH.compareTo("?") == 0) {
1290                    ctx.setError("The server is not properly configured for file uploads! The path to save files to has not been specified! Contact site administrator.");
1291                    return "";
1292                }
1293                File diskFile =
1294                    new File(Constants.FILEUPLOAD_SAVE_PATH
1295                             + upload.getID() + ".up");
1296                File pathFile = new File(Constants.FILEUPLOAD_SAVE_PATH);
1297                
1298                if (!(pathFile.exists() || pathFile.mkdirs())
1299                    || (!diskFile.createNewFile())) {
1300                    ctx.setError("Could not create the file on the server! Contact site administrator.");
1301                    return "";
1302                }
1303                FileOutputStream JavaDoc out = new FileOutputStream JavaDoc(diskFile);
1304                out.write(content);
1305                out.flush();
1306                out.close();
1307            } catch (IOException JavaDoc e) {
1308                e.printStackTrace();
1309                ctx.setError("Unable to save file to disk! Contact site administrator.");
1310                return "";
1311            }
1312        return retVal;
1313    }
1314
1315    /**
1316     * To get a string describing the size of a file
1317     */

1318    private String JavaDoc getSizeString(int fileSize) {
1319        String JavaDoc size;
1320        if (fileSize >= SIZEMB) {
1321            size = "" + ((float) fileSize / (float) SIZEMB);
1322
1323            return trimToOneDecimalPlace(size) + " MB";
1324        } else if (fileSize >= SIZEKB) {
1325            size = "" + ((float) fileSize / (float) SIZEKB);
1326
1327            return trimToOneDecimalPlace(size) + " kb";
1328        } else {
1329            return fileSize + " bytes";
1330        }
1331    }
1332
1333    private String JavaDoc trimToOneDecimalPlace(String JavaDoc floatString) {
1334        int pos = floatString.lastIndexOf(".");
1335
1336        return floatString.substring(0, pos + 2);
1337    }
1338
1339    private Type [] getHibernateTypesForObjects(Object JavaDoc [] objects) {
1340        Type [] results = new Type[objects.length];
1341        for(int i = 0; i < objects.length; i++) {
1342            if(objects[i] instanceof String JavaDoc) {
1343                results[i] = Hibernate.STRING;
1344            } else if(objects[i] instanceof Boolean JavaDoc) {
1345                results[i] = Hibernate.BOOLEAN;
1346            } else if(objects[i] instanceof Long JavaDoc) {
1347                results[i] = Hibernate.LONG;
1348            } else if(objects[i] instanceof Date JavaDoc) {
1349                results[i] = Hibernate.DATE;
1350            } else {
1351                results[i] = Hibernate.OBJECT;
1352            }
1353        }
1354        return results;
1355    }
1356
1357    private HashMap JavaDoc getStatusesCount(Long JavaDoc projectId)
1358        throws HibernateException
1359    {
1360        Type [] types = new Type [] {Hibernate.LONG, Hibernate.STRING};
1361        Object JavaDoc [] objs = new Object JavaDoc[2];
1362        objs[0] = projectId;
1363        
1364        // get status counts
1365
HashMap JavaDoc statuses = new HashMap JavaDoc();
1366        Session sess = HibernateUtil.getSession();
1367        for (Iterator JavaDoc it = ISSUE_STATUSES.iterator(); it.hasNext();) {
1368            objs[1] = (String JavaDoc)it.next();
1369            statuses.put(objs[1], sess.iterate("select count(*) FROM "
1370                                               + IssueData.class.getName()
1371                                               +" as iss where iss.project.id = ? and iss.status = ?", objs, types).next());
1372        }
1373        // TODO: remove this when the hibernate util is all fixed up, this won't
1374
// be needed.
1375
HibernateUtil.finalizeSession();
1376        return statuses;
1377    }
1378
1379    private HashMap JavaDoc getPrioritiesCount(Long JavaDoc projectId)
1380        throws HibernateException
1381    {
1382        Type [] types = new Type [] {Hibernate.LONG, Hibernate.STRING, Hibernate.STRING};
1383        Object JavaDoc [] objs = new Object JavaDoc[3];
1384        objs[0] = projectId;
1385        objs[1] = "Closed";
1386        // get priority counts
1387
HashMap JavaDoc priorities = new HashMap JavaDoc();
1388        Session sess = HibernateUtil.getSession();
1389        for (Iterator JavaDoc it = ISSUE_PRIORITIES.iterator(); it.hasNext();) {
1390            objs[2] = (String JavaDoc)it.next();
1391            priorities.put(objs[2], sess.iterate("select count(*) FROM "
1392                                                 + IssueData.class.getName()
1393                                                 +" as iss where iss.project.id = ? and iss.status != ? and iss.priority = ?", objs, types).next());
1394        }
1395        // TODO: remove this when the hibernate util is all fixed up, this won't
1396
// be needed.
1397
HibernateUtil.finalizeSession();
1398        return priorities;
1399    }
1400
1401    private HashMap JavaDoc getTypesCount(Long JavaDoc projectId) throws HibernateException {
1402        Type [] types = new Type [] {Hibernate.LONG, Hibernate.STRING};
1403        Object JavaDoc [] objs = new Object JavaDoc[2];
1404        objs[0] = projectId;
1405        // get type counts
1406
HashMap JavaDoc issTypes = new HashMap JavaDoc();
1407        Session sess = HibernateUtil.getSession();
1408        for (Iterator JavaDoc it = ISSUE_TYPES.iterator(); it.hasNext();) {
1409            objs[1] = (String JavaDoc)it.next();
1410            issTypes.put(objs[1], sess.iterate("select count(*) FROM "
1411                                            + IssueData.class.getName()
1412                                            + " as iss where iss.project.id = ? and iss.type = ?", objs, types).next());
1413        }
1414        // TODO: remove this when the hibernate util is all fixed up, this won't
1415
// be needed.
1416
HibernateUtil.finalizeSession();
1417        return issTypes;
1418    }
1419
1420    private Integer JavaDoc getReportedByMeCount(Long JavaDoc projectId, Long JavaDoc userId)
1421        throws HibernateException
1422    {
1423        Session sess = HibernateUtil.getSession();
1424        Integer JavaDoc retVal =
1425            (Integer JavaDoc)sess.iterate("select count(*) FROM "+ IssueData.class.getName()
1426                                           + " as iss where iss.project.id = ? and iss.author.id = ? ",
1427                                           new Object JavaDoc[]{projectId, userId},
1428                                           new Type[]{Hibernate.LONG, Hibernate.LONG}).next();
1429        // TODO: remove this when the hibernate util is all fixed up, this won't
1430
// be needed.
1431
HibernateUtil.finalizeSession();
1432        return retVal;
1433    }
1434    
1435    private Integer JavaDoc getAssignedToMeCount(Long JavaDoc projectId, Long JavaDoc userId)
1436        throws HibernateException
1437    {
1438        Session sess = HibernateUtil.getSession();
1439        Integer JavaDoc retVal = (Integer JavaDoc)sess.iterate("select count(*) FROM "+ IssueData.class.getName()
1440                            + " as iss where iss.project.id = ? and iss.assignedTo.id = ? ",
1441                            new Object JavaDoc[]{projectId, userId},
1442                            new Type[]{Hibernate.LONG, Hibernate.LONG}).next();
1443        // TODO: remove this when the hibernate util is all fixed up, this won't
1444
// be needed.
1445
HibernateUtil.finalizeSession();
1446        return retVal;
1447    }
1448
1449    private Integer JavaDoc getAllCount(Long JavaDoc projectId) throws HibernateException {
1450        Session sess = HibernateUtil.getSession();
1451        Integer JavaDoc retVal = (Integer JavaDoc)sess.iterate("select count(*) FROM "+ IssueData.class.getName()
1452                            + " as iss where iss.project.id = ?",
1453                            projectId, Hibernate.LONG).next();
1454        // TODO: remove this when the hibernate util is all fixed up, this won't
1455
// be needed.
1456
HibernateUtil.finalizeSession();
1457        return retVal;
1458    }
1459
1460    private Integer JavaDoc getOpenCount(Long JavaDoc projectId) throws HibernateException {
1461        Session sess = HibernateUtil.getSession();
1462        Integer JavaDoc retVal = (Integer JavaDoc)sess.iterate("select count(*) FROM "+ IssueData.class.getName()
1463                            + " as iss where iss.project.id = ? and iss.resolution = ?",
1464                            new Object JavaDoc[]{projectId, "Unresolved"},
1465                            new Type[]{Hibernate.LONG, Hibernate.STRING}).next();
1466        // TODO: remove this when the hibernate util is all fixed up, this won't
1467
// be needed.
1468
HibernateUtil.finalizeSession();
1469        return retVal;
1470    }
1471
1472    private Integer JavaDoc getNewCount(Long JavaDoc projectId) throws HibernateException {
1473        long currTime = System.currentTimeMillis();
1474        Date JavaDoc beforeDate = new Date JavaDoc(currTime - 604800000);
1475        Date JavaDoc currentDate = new Date JavaDoc(currTime);
1476        Session sess = HibernateUtil.getSession();
1477        Integer JavaDoc retVal = (Integer JavaDoc)sess.iterate("select count(*) FROM "+ IssueData.class.getName()
1478                            + " as iss where iss.project.id = ? and iss.createDate between ? and ? ",
1479                            new Object JavaDoc[]{projectId, beforeDate, currentDate},
1480                            new Type[]{Hibernate.LONG, Hibernate.DATE, Hibernate.DATE}).next();
1481        // TODO: remove this when the hibernate util is all fixed up, this won't
1482
// be needed.
1483
HibernateUtil.finalizeSession();
1484        return retVal;
1485    }
1486
1487    private List JavaDoc getMyFilters(Long JavaDoc projectId, Long JavaDoc userId)
1488        throws HibernateException
1489    {
1490        List JavaDoc myFilters = null;
1491        Type [] types = new Type [] {Hibernate.LONG, Hibernate.LONG};
1492        Object JavaDoc [] objs = new Object JavaDoc[2];
1493        objs[0] = projectId;
1494        objs[1] = userId;
1495        myFilters = HibernateUtil.find("FROM " + SearchFilter.class.getName()
1496                              +" as sf where sf.project.id = ? and sf.filterAuthor.id = ?",
1497                              objs, types);
1498        return myFilters;
1499    }
1500
1501    private HashMap JavaDoc getMyFiltersCount(List JavaDoc myFilters)
1502        throws HibernateException
1503    {
1504        HashMap JavaDoc myFiltersCount = new HashMap JavaDoc();
1505        if(myFilters != null) {
1506            Session sess = HibernateUtil.getSession();
1507            for(Iterator JavaDoc it = myFilters.iterator(); it.hasNext(); ) {
1508                SearchFilter filter = (SearchFilter)it.next();
1509                String JavaDoc query = filter.getQuery();
1510                int idx = query.indexOf("order by");
1511                String JavaDoc temp = null;
1512                if (idx != -1) {
1513                    temp = query.substring(0, query.indexOf("order by"));
1514                } else {
1515                    temp = query;
1516                }
1517                temp = temp.replaceFirst("[Ff][Rr][Oo][Mm]", "from");
1518                String JavaDoc countQuery =
1519                    "select count(*) "
1520                    + temp.substring(temp.indexOf("from"), temp.length());
1521                myFiltersCount.put(filter.getName(),
1522                                   sess.iterate(countQuery, filter.getQueryObjects(),
1523                                                getHibernateTypesForObjects(filter.getQueryObjects())).next());
1524            }
1525            // TODO: remove this when the hibernate util is all fixed up, this won't
1526
// be needed.
1527
HibernateUtil.finalizeSession();
1528        }
1529        return myFiltersCount;
1530    }
1531
1532}
1533
Popular Tags