ProjectServiceImpl.java
/*
 * This software was designed and created by Jason Carroll.
 * Copyright (c) 2002, 2003, 2004 Jason Carroll.
 * The author can be reached at jcarroll@cowsultants.com
 * ITracker website: http://www.cowsultants.com
 * ITracker forums: http://www.cowsultants.com/phpBB/index.php
 *
 * This program is free software; you can redistribute it and/or modify
 * it only under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */
package org.itracker.services.implementations;
import org.apache.log4j.Logger;
import org.itracker.model.*;
import org.itracker.model.util.IssueUtilities;
import org.itracker.persistence.dao.*;
import org.itracker.services.ProjectService;
import java.util.*;
public class ProjectServiceImpl implements ProjectService {
    //TODO: Cleanup this file, go through all issues, todos, etc.
    //TODO: Add Javadocs here: document this whole class.
    private static final Logger logger = Logger.getLogger(ProjectService.class);
    private ComponentDAO componentDAO;
    private CustomFieldDAO customFieldDAO;
    private ProjectDAO projectDAO;
    private ProjectScriptDAO projectScriptDAO;
    private UserDAO userDAO;
    private VersionDAO versionDAO;
    private IssueDAO issueDAO;
    public ProjectServiceImpl(ComponentDAO componentDAO,
                              CustomFieldDAO customFieldDAO, ProjectDAO projectDAO,
                              ProjectScriptDAO projectScriptDAO, UserDAO userDAO,
                              VersionDAO versionDAO, IssueDAO issueDAO) {
        this.componentDAO = componentDAO;
        this.customFieldDAO = customFieldDAO;
        this.projectDAO = projectDAO;
        this.projectScriptDAO = projectScriptDAO;
        this.userDAO = userDAO;
        this.versionDAO = versionDAO;
        this.issueDAO = issueDAO;
    }
    public Project getProject(Integer projectId) {
        Project project = getProjectDAO().findByPrimaryKey(projectId);
        return project;
    }
    public List<Project> getAllProjects() {
        return getProjectDAO().findAll();
    }
    public List<Project> getAllAvailableProjects() {
        List<Project> projects = getProjectDAO().findAllAvailable();
        return projects;
    }
    public List<Project> getListOfAllAvailableProjects() {
        return getAllAvailableProjects();
    }
    public Component updateProjectComponent(Component component) {
        getComponentDAO().saveOrUpdate(component);
        return component;
    }
    public Component addProjectComponent(Integer projectId, Component component) {
        Project project = getProjectDAO().findByPrimaryKey(projectId);
        component.setProject(project);
        project.getComponents().add(component);
        getComponentDAO().save(component);
        getProjectDAO().save(project);
        return component;
    }
    public boolean removeProjectComponent(Integer projectId, Integer componentId) {
        Component component = getComponentDAO().findById(componentId);
        if (component == null) {
            return false; //component doesn't exist
        }
        if (!component.getProject().getId().equals(projectId)) {
            return false;
        }
        getComponentDAO().delete(component);
        return true;
    }
    public Component getProjectComponent(Integer componentId) {
        Component component = getComponentDAO().findById(componentId);
        return component;
    }
    public Version addProjectVersion(Integer projectId, Version version) {
        version.setCreateDate(new Date());
        Project project = getProjectDAO().findByPrimaryKey(projectId);
        version.setProject(project);
        Collection<Version> versions = project.getVersions();
        versions.add(version);
        getVersionDAO().save(version);
        return version;
    }
    public boolean removeProjectVersion(Integer projectId, Integer versionId) {
        Version version = getVersionDAO().findByPrimaryKey(versionId);
        if (version == null) {
            return false; // version doesn't exist
        }
        if (!version.getProject().getId().equals(projectId)) {
            return false;
        }
        List<Issue> issues = getIssueDAO().findByTargetVersion(version.getId());
        Iterator<Issue> iterator = issues.iterator();
        while (iterator.hasNext()) {
            Issue issue = (Issue) iterator.next();
            issue.setTargetVersion(null);
            getIssueDAO().save(issue);
        }
        issues = getIssueDAO().findByVersion(version.getId());
        iterator = issues.iterator();
        while (iterator.hasNext()) {
            Issue issue = (Issue) iterator.next();
            if (issue.getVersions().remove(version)) {
                getIssueDAO().save(issue);
            }
        }
        getVersionDAO().delete(version);
        return true;
    }
    public Version updateProjectVersion(Version version) {
        getVersionDAO().saveOrUpdate(version);
        return version;
    }
    public Version getProjectVersion(Integer versionId) {
        Version version = getVersionDAO().findByPrimaryKey(versionId);
        return version;
    }
    public List<User> getProjectOwners(Integer projectId) {
        Project project = getProjectDAO().findByPrimaryKey(projectId);
        List<User> users = project.getOwners();
        return users;
    }
    public boolean setProjectOwners(Project project,
                                    Set<Integer> setOfNewOwnerIds) {
        if (null == project) {
            logger.warn("setProjectOwners, project was null");
            throw new IllegalArgumentException("Project must not be null.");
        }
        if (null == setOfNewOwnerIds) {
            setOfNewOwnerIds = new HashSet<Integer>(0);
        }
        List<User> owners = new ArrayList<User>(setOfNewOwnerIds.size());
        if (!setOfNewOwnerIds.isEmpty()) {
            for (Iterator<Integer> iterator = setOfNewOwnerIds.iterator(); iterator
                    .hasNext(); ) {
                Integer ownerId = iterator.next();
                User owner = getUserDAO().findByPrimaryKey(ownerId);
                owners.add(owner);
            }
        }
        project.setOwners(owners);
        return true;
    }
    public List<CustomField> getProjectFields(Integer projectId) {
        return getProjectFields(projectId, null);
    }
    /**
     * TODO: implement Locale-aware ProjectFields.
     */
    public List<CustomField> getProjectFields(Integer projectId, Locale locale) {
        Project project = projectDAO.findByPrimaryKey(projectId);
        List<CustomField> fields = project.getCustomFields();
        return fields;
    }
    public boolean setProjectFields(Project project,
                                    Set<Integer> setOfNewsFieldIds) {
        List<CustomField> fields;
        fields = project.getCustomFields();
        fields.clear();
        if (setOfNewsFieldIds != null && !setOfNewsFieldIds.isEmpty()) {
            for (Iterator<Integer> iterator = setOfNewsFieldIds.iterator(); iterator
                    .hasNext(); ) {
                Integer fieldId = iterator.next();
                CustomField field = customFieldDAO.findByPrimaryKey(fieldId);
                fields.add(field);
            }
        }
        return true;
    }
    public ProjectScript getProjectScript(Integer scriptId) {
        ProjectScript projectScript = this.projectScriptDAO
                .findByPrimaryKey(scriptId);
        return projectScript;
    }
    public List<ProjectScript> getProjectScripts() {
        List<ProjectScript> projectScripts = this.projectScriptDAO.findAll();
        return projectScripts;
    }
    public ProjectScript addProjectScript(Integer projectId,
                                          ProjectScript projectScript) {
        ProjectScript addprojectScript = new ProjectScript();
        addprojectScript.setId(projectScript.getId());
        addprojectScript.setFieldId(projectScript.getFieldId());
        addprojectScript.setFieldType(projectScript.getFieldType());
        addprojectScript.setPriority(projectScript.getPriority());
        addprojectScript.setProject(projectScript.getProject());
        addprojectScript.setScript(projectScript.getScript());
        this.projectScriptDAO.save(addprojectScript);
        return addprojectScript;
    }
    public boolean removeProjectScript(Integer projectId, Integer scriptId) {
        ProjectScript script = projectScriptDAO.findByPrimaryKey(scriptId);
        this.projectScriptDAO.delete(script);
        return true;
    }
    public ProjectScript updateProjectScript(ProjectScript projectScript) {
        ProjectScript editprojectScript = projectScriptDAO
                .findByPrimaryKey(projectScript.getId());
        editprojectScript.setId(projectScript.getId());
        editprojectScript.setFieldId(projectScript.getFieldId());
        editprojectScript.setPriority(projectScript.getPriority());
        editprojectScript.setProject(projectScript.getProject());
        editprojectScript.setScript(projectScript.getScript());
        this.projectScriptDAO.saveOrUpdate(editprojectScript);
        return editprojectScript;
    }
    public Long getTotalNumberIssuesByProject(Integer projectId) {
        return issueDAO.countByProject(projectId);
    }
    public Long countIssuesByVersion(Integer versionId) {
        return issueDAO.countByVersion(versionId);
    }
    public Long countIssuesByComponent(Integer componentId) {
        return issueDAO.countByComponent(componentId);
    }
    public Long[] getProjectStats(Integer projectId) {
        final Long[] issueStats = new Long[2];
        Long openIssuesCount = issueDAO.countByProjectAndLowerStatus(projectId,
                IssueUtilities.STATUS_RESOLVED);
        issueStats[0] = openIssuesCount;
        Long resolvedIssuesCount = issueDAO.countByProjectAndHigherStatus(
                projectId, IssueUtilities.STATUS_RESOLVED);
        issueStats[1] = resolvedIssuesCount;
        return issueStats;
    }
    //TODO: Decide if this code is really needed and document for what
    @SuppressWarnings("unused")
    private IssueDAO getIssueDAO() {
        return issueDAO;
    }
    private ProjectDAO getProjectDAO() {
        return projectDAO;
    }
    private ComponentDAO getComponentDAO() {
        return componentDAO;
    }
    private CustomFieldDAO getCustomFieldDAO() {
        return this.customFieldDAO;
    }
    private ProjectScriptDAO getProjectScriptDAO() {
        return this.projectScriptDAO;
    }
    private VersionDAO getVersionDAO() {
        return this.versionDAO;
    }
    private UserDAO getUserDAO() {
        return this.userDAO;
    }
    public List<CustomField> getListOfProjectFields(Integer projectId) {
        throw new UnsupportedOperationException();
    }
    public List<User> getListOfProjectOwners(Integer projectId) {
        throw new UnsupportedOperationException();
    }
    public Long getTotalNumberOpenIssuesByProject(Integer projectId) {
        return issueDAO.countByProjectAndLowerStatus(projectId,
                IssueUtilities.STATUS_RESOLVED);
    }
    public Long getTotalNumberResolvedIssuesByProject(Integer projectId) {
        return issueDAO.countByProjectAndHigherStatus(projectId,
                IssueUtilities.STATUS_RESOLVED);
    }
    public Date getLatestIssueUpdatedDateByProjectId(Integer projectId) {
        return issueDAO.latestModificationDate(projectId);
    }
    public Project createProject(Project project, Integer userId) {
        project.setId(null);
        User user = getUserDAO().findByPrimaryKey(userId);
        project.setOwners(Arrays.asList(new User[]{user}));
        getProjectDAO().save(project);
        return project;
    }
    public Project updateProject(Project project, Integer userId) {
        User user = getUserDAO().findByPrimaryKey(userId);
        getProjectDAO().saveOrUpdate(project);
        return project;
    }
    public Boolean isUniqueProjectName(String projectName,
                                       Integer updatedProjectId) {
        Project project = getProjectDAO().findByName(projectName);
        if (project != null) {
            // validate that the returned project is not the updated one.
            if (!project.getId().equals(updatedProjectId)) {
                return false;
            }
        }
        return true;
    }
}