View Javadoc

1   /*
2    * This software was designed and created by Jason Carroll.
3    * Copyright (c) 2002, 2003, 2004 Jason Carroll.
4    * The author can be reached at jcarroll@cowsultants.com
5    * ITracker website: http://www.cowsultants.com
6    * ITracker forums: http://www.cowsultants.com/phpBB/index.php
7    *
8    * This program is free software; you can redistribute it and/or modify
9    * it only under the terms of the GNU General Public License as published by
10   * the Free Software Foundation; either version 2 of the License, or
11   * (at your option) any later version.
12   *
13   * This program is distributed in the hope that it will be useful,
14   * but WITHOUT ANY WARRANTY; without even the implied warranty of
15   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   * GNU General Public License for more details.
17   */
18  
19  package org.itracker.services.implementations;
20  
21  import java.util.ArrayList;
22  import java.util.Arrays;
23  import java.util.Collection;
24  import java.util.Date;
25  import java.util.HashSet;
26  import java.util.Iterator;
27  import java.util.List;
28  import java.util.Locale;
29  import java.util.Set;
30  
31  import org.apache.log4j.Logger;
32  import org.itracker.model.Component;
33  import org.itracker.model.CustomField;
34  import org.itracker.model.Issue;
35  import org.itracker.model.Project;
36  import org.itracker.model.ProjectScript;
37  import org.itracker.model.User;
38  import org.itracker.model.Version;
39  import org.itracker.persistence.dao.ComponentDAO;
40  import org.itracker.persistence.dao.CustomFieldDAO;
41  import org.itracker.persistence.dao.IssueDAO;
42  import org.itracker.persistence.dao.ProjectDAO;
43  import org.itracker.persistence.dao.ProjectScriptDAO;
44  import org.itracker.persistence.dao.UserDAO;
45  import org.itracker.persistence.dao.VersionDAO;
46  import org.itracker.services.ProjectService;
47  import org.itracker.services.util.IssueUtilities;
48  
49  public class ProjectServiceImpl implements ProjectService {
50  
51  	//TODO: Cleanup this file, go through all issues, todos, etc.
52  	//TODO: Add Javadocs here: document this whole class.
53  	
54  	private static final Logger logger = Logger.getLogger(ProjectService.class);
55  	
56  	private ComponentDAO componentDAO;
57  	private CustomFieldDAO customFieldDAO;
58  	private ProjectDAO projectDAO;
59  	private ProjectScriptDAO projectScriptDAO;
60  	private UserDAO userDAO;
61  	private VersionDAO versionDAO;
62  	private IssueDAO issueDAO;
63  
64  	public ProjectServiceImpl(ComponentDAO componentDAO,
65  			CustomFieldDAO customFieldDAO, ProjectDAO projectDAO,
66  			ProjectScriptDAO projectScriptDAO, UserDAO userDAO,
67  			VersionDAO versionDAO, IssueDAO issueDAO) {
68  		this.componentDAO = componentDAO;
69  		this.customFieldDAO = customFieldDAO;
70  		this.projectDAO = projectDAO;
71  		this.projectScriptDAO = projectScriptDAO;
72  		this.userDAO = userDAO;
73  		this.versionDAO = versionDAO;
74  		this.issueDAO = issueDAO;
75  	}
76  
77  	public Project getProject(Integer projectId) {
78  		Project project = projectDAO.findByPrimaryKey(projectId);
79  		return project;
80  	}
81  
82  	public List<Project> getAllProjects() {
83  		return projectDAO.findAll();
84  	}
85  
86  	public List<Project> getAllAvailableProjects() {
87  		List<Project> projects = projectDAO.findAllAvailable();
88  		return projects;
89  	}
90  
91  	public List<Project> getListOfAllAvailableProjects() {
92  		return getAllAvailableProjects();
93  	}
94  
95  	public Component updateProjectComponent(Component component) {
96  //		component.setLastModifiedDate(new Date());
97  		componentDAO.saveOrUpdate(component);
98  		return component;
99  	}
100 
101 	public Component addProjectComponent(Integer projectId, Component component) {
102 		Project project = projectDAO.findByPrimaryKey(projectId);
103 
104 		component.setCreateDate(new Date());
105 		component.setProject(project);
106 
107 		List<Component> components = project.getComponents();
108 		components.add(component);
109 
110 		componentDAO.save(component);
111 
112 		return component;
113 	}
114 
115 	public boolean removeProjectComponent(Integer projectId, Integer componentId) {
116 
117 		Component component = componentDAO.findById(componentId);
118 		if(component == null) {
119 			return false; //component doesn't exist
120 		}
121 		
122 		if(!component.getProject().getId().equals(projectId)) {
123 			//throw new ProjectException("the component doesn't belong to the project specified");
124 			return false;
125 		}
126 		
127 		componentDAO.delete(component);
128 
129 		return true;
130 
131 	}
132 
133 	public Component getProjectComponent(Integer componentId) {
134 
135 		Component component = componentDAO.findById(componentId);
136 
137 		return component;
138 
139 	}
140 
141 	public Version addProjectVersion(Integer projectId, Version version) {
142 		version.setCreateDate(new Date());
143 
144 		Project project = projectDAO.findByPrimaryKey(projectId);
145 		version.setProject(project);
146 
147 		Collection<Version> versions = project.getVersions();
148 		versions.add(version);
149 		versionDAO.save(version);
150 
151 		return version;
152 
153 	}
154 
155 	public boolean removeProjectVersion(Integer projectId, Integer versionId) {
156 
157 		Version version = versionDAO.findByPrimaryKey(versionId);
158 		if (version == null) {
159 			return false; // version doesn't exist
160 		}
161 
162 		if (!version.getProject().getId().equals(projectId)) {
163 			// throw new
164 			// ProjectException("the component doesn't belong to the project specified");
165 			return false;
166 		}
167 
168 		List<Issue> issues = issueDAO.findByTargetVersion(version.getId());
169 		Iterator<Issue> iterator = issues.iterator();
170 		while (iterator.hasNext()) {
171 			Issue issue = (Issue) iterator.next();
172 			issue.setTargetVersion(null);
173 			issueDAO.save(issue);
174 		}
175 
176 		issues = issueDAO.findByVersion(version.getId());
177 		iterator = issues.iterator();
178 		while (iterator.hasNext()) {
179 			Issue issue = (Issue) iterator.next();
180 			if (issue.getVersions().remove(version)) {
181 				issueDAO.save(issue);
182 			}
183 		}
184 
185 		versionDAO.delete(version);
186 		return true;
187 	}
188 
189 	public Version updateProjectVersion(Version version) {
190 		versionDAO.saveOrUpdate(version);
191 		return version;
192 	}
193 
194 	public Version getProjectVersion(Integer versionId) {
195 		Version version = versionDAO.findByPrimaryKey(versionId);
196 
197 		return version;
198 
199 	}
200 
201 	public List<User> getProjectOwners(Integer projectId) {
202 		Project project = projectDAO.findByPrimaryKey(projectId);
203 		List<User> users = project.getOwners();
204 		return users;
205 	}
206 
207 	public boolean setProjectOwners(Project project,
208 			Set<Integer> setOfNewOwnerIds) {
209 		if (null == project) {
210 			logger.warn("setProjectOwners, project was null");
211 			throw new IllegalArgumentException("Project must not be null.");
212 		}
213 		if (null == setOfNewOwnerIds) {
214 			setOfNewOwnerIds = new HashSet<Integer>(0);
215 		}
216 		
217 		List<User> owners = new ArrayList<User>(setOfNewOwnerIds.size());
218 		if (!setOfNewOwnerIds.isEmpty()) {
219 
220 			for (Iterator<Integer> iterator = setOfNewOwnerIds.iterator(); iterator
221 					.hasNext();) {
222 				Integer ownerId = iterator.next();
223 				User owner = userDAO.findByPrimaryKey(ownerId);
224 				owners.add(owner);
225 			}
226 		}
227 		project.setOwners(owners);
228 		
229 		return true;
230 	}
231 
232 	public List<CustomField> getProjectFields(Integer projectId) {
233 		return getProjectFields(projectId, null);
234 	}
235 
236 	/**
237 	 * TODO: implement Locale-aware ProjectFields.
238 	 */
239 	public List<CustomField> getProjectFields(Integer projectId, Locale locale) {
240 
241 		Project project = projectDAO.findByPrimaryKey(projectId);
242 		List<CustomField> fields = project.getCustomFields();
243 
244 		return fields;
245 	}
246 
247 	public boolean setProjectFields(Project project,
248 			Set<Integer> setOfNewsFieldIds)  {
249 		List<CustomField> fields;
250 		fields = project.getCustomFields();
251 		fields.clear();
252 
253 		if (setOfNewsFieldIds != null && !setOfNewsFieldIds.isEmpty()) {
254 			for (Iterator<Integer> iterator = setOfNewsFieldIds.iterator(); iterator
255 					.hasNext();) {
256 				Integer fieldId = iterator.next();
257 				CustomField field = customFieldDAO.findByPrimaryKey(fieldId);
258 				fields.add(field);
259 			}
260 		}
261 		return true;
262 	}
263 
264 	public ProjectScript getProjectScript(Integer scriptId) {
265 		ProjectScript projectScript = this.projectScriptDAO
266 				.findByPrimaryKey(scriptId);
267 		return projectScript;
268 
269 	}
270 
271 	public List<ProjectScript> getProjectScripts() {
272 		List<ProjectScript> projectScripts = this.projectScriptDAO.findAll();
273 		return projectScripts;
274 	}
275 
276 	public ProjectScript addProjectScript(Integer projectId,
277 			ProjectScript projectScript) {
278 		ProjectScript addprojectScript = new ProjectScript();
279 		addprojectScript.setId(projectScript.getId());
280 		addprojectScript.setFieldId(projectScript.getFieldId());
281 		addprojectScript.setPriority(projectScript.getPriority());
282 		addprojectScript.setProject(projectScript.getProject());
283 		addprojectScript.setScript(projectScript.getScript());
284 //		addprojectScript.setCreateDate(new Date());
285 //		addprojectScript.setLastModifiedDate(addprojectScript.getCreateDate());
286 		this.projectScriptDAO.save(addprojectScript);
287 
288 		return addprojectScript;
289 
290 	}
291 
292 	public boolean removeProjectScript(Integer projectId, Integer scriptId) {
293 		// Project project = projectDAO.findByPrimaryKey(projectId);
294 		ProjectScript script = projectScriptDAO.findByPrimaryKey(scriptId);
295 		this.projectScriptDAO.delete(script);
296 		// TODO: check this: why is this comment "script.remove()" there? Which
297 		// type is expected in Collection<T> scripts?
298 		// (WorkflowsScript? ProjectScript? Do you understand this? - I would
299 		// say ProjectScript)
300 		// Collection<ProjectScript> scripts = project.getScripts();
301 		// scripts.remove(script);
302 
303 		// script.remove();
304 
305 		return true;
306 
307 	}
308 
309 	public ProjectScript updateProjectScript(ProjectScript projectScript) {
310 		ProjectScript editprojectScript = projectScriptDAO
311 				.findByPrimaryKey(projectScript.getId());
312 		editprojectScript.setId(projectScript.getId());
313 		editprojectScript.setFieldId(projectScript.getFieldId());
314 		editprojectScript.setPriority(projectScript.getPriority());
315 		editprojectScript.setProject(projectScript.getProject());
316 		editprojectScript.setScript(projectScript.getScript());
317 		// editprojectScript.setCreateDate(projectScript.getCreateDate());
318 //		editprojectScript.setLastModifiedDate(new Date());
319 
320 		this.projectScriptDAO.saveOrUpdate(editprojectScript);
321 
322 		return editprojectScript;
323 	}
324 
325 	public Long getTotalNumberIssuesByProject(Integer projectId) {
326 		return issueDAO.countByProject(projectId);
327 	}
328 
329 	public Long countIssuesByVersion(Integer versionId) {
330 		return issueDAO.countByVersion(versionId);
331 
332 	}
333 
334 	public Long countIssuesByComponent(Integer componentId) {
335 		return issueDAO.countByComponent(componentId);
336 	}
337 
338 	public Long[] getProjectStats(Integer projectId) {
339 		final Long[] issueStats = new Long[2];
340 
341 		Long openIssuesCount = issueDAO.countByProjectAndLowerStatus(projectId,
342 				IssueUtilities.STATUS_RESOLVED);
343 
344 		issueStats[0] = openIssuesCount;
345 
346 		Long resolvedIssuesCount = issueDAO.countByProjectAndHigherStatus(
347 				projectId, IssueUtilities.STATUS_RESOLVED);
348 		issueStats[1] = resolvedIssuesCount;
349 
350 		return issueStats;
351 	}
352 
353 	//TODO: Decide if this code is really needed and document for what
354 	@SuppressWarnings("unused")
355 	private IssueDAO getIssueDAO() {
356 		return issueDAO;
357 	}
358 
359 	private ProjectDAO getProjectDAO() {
360 		return projectDAO;
361 	}
362 
363 	//TODO: Decide if this code is really needed and document for what
364 	@SuppressWarnings("unused")
365 	private ComponentDAO getComponentDAO() {
366 		return componentDAO;
367 	}
368 
369 	//TODO: Decide if this code is really needed and document for what
370 	@SuppressWarnings("unused")
371 	private CustomFieldDAO getCustomFieldDAO() {
372 		return this.customFieldDAO;
373 	}
374 	
375 	//TODO: Decide if this code is really needed and document for what
376 	@SuppressWarnings("unused")
377 	private ProjectScriptDAO getProjectScriptDAO() {
378 		return this.projectScriptDAO;
379 	}
380 	
381 	//TODO: Decide if this code is really needed and document for what
382 	@SuppressWarnings("unused")
383 	private VersionDAO getVersionDAO() {
384 		return this.versionDAO;
385 	}
386 
387 	private UserDAO getUserDAO() {
388 		return this.userDAO;
389 	}
390 
391 	public List<CustomField> getListOfProjectFields(Integer projectId) {
392 		throw new UnsupportedOperationException();
393 	}
394 
395 	public List<User> getListOfProjectOwners(Integer projectId) {
396 		throw new UnsupportedOperationException();
397 	}
398 
399 	public Long getTotalNumberOpenIssuesByProject(Integer projectId) {
400 		return issueDAO.countByProjectAndLowerStatus(projectId,
401 				IssueUtilities.STATUS_RESOLVED);
402 	}
403 
404 	public Long getTotalNumberResolvedIssuesByProject(Integer projectId) {
405 		return issueDAO.countByProjectAndHigherStatus(projectId,
406 				IssueUtilities.STATUS_RESOLVED);
407 	}
408 	
409 	public Date getLatestIssueUpdatedDateByProjectId(Integer projectId) {
410 		return issueDAO.latestModificationDate(projectId);	
411 	}
412 	
413 	public Project createProject(Project project, Integer userId) {
414 		User user = getUserDAO().findByPrimaryKey(userId);
415 		project.setOwners(Arrays.asList(new User[]{ user }));
416 		getProjectDAO().save(project);
417 
418 		return project;
419 	}
420 	public Project updateProject(Project project, Integer userId) {
421 		User user = getUserDAO().findByPrimaryKey(userId);
422 
423 		getProjectDAO().saveOrUpdate(project);
424 		
425 		return project;
426 	}
427 	
428 	public Boolean isUniqueProjectName(String projectName,
429 			Integer updatedProjectId) {
430 		Project project = getProjectDAO().findByName(projectName);
431 		if (project != null) {
432 			// validate that the returned project is not the updated one.
433 			if (!project.getId().equals(updatedProjectId)) {
434 				return false;
435 			}
436 		}
437 		return true;
438 	}
439 }