com.concursive.connect.web.modules.profile.utils.ProjectUtils.java Source code

Java tutorial

Introduction

Here is the source code for com.concursive.connect.web.modules.profile.utils.ProjectUtils.java

Source

/*
 * ConcourseConnect
 * Copyright 2009 Concursive Corporation
 * http://www.concursive.com
 *
 * This file is part of ConcourseConnect, an open source social business
 * software and community platform.
 *
 * Concursive ConcourseConnect is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License as published
 * by the Free Software Foundation, version 3 of the License.
 *
 * Under the terms of the GNU Affero General Public License you must release the
 * complete source code for any application that uses any part of ConcourseConnect
 * (system header files and libraries used by the operating system are excluded).
 * These terms must be included in any work that has ConcourseConnect components.
 * If you are developing and distributing open source applications under the
 * GNU Affero General Public License, then you are free to use ConcourseConnect
 * under the GNU Affero General Public License.
 *
 * If you are deploying a web site in which users interact with any portion of
 * ConcourseConnect over a network, the complete source code changes must be made
 * available.  For example, include a link to the source archive directly from
 * your web site.
 *
 * For OEMs, ISVs, SIs and VARs who distribute ConcourseConnect with their
 * products, and do not license and distribute their source code under the GNU
 * Affero General Public License, Concursive provides a flexible commercial
 * license.
 *
 * To anyone in doubt, we recommend the commercial license. Our commercial license
 * is competitively priced and will eliminate any confusion about how
 * ConcourseConnect can be used and distributed.
 *
 * ConcourseConnect 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 Affero General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with ConcourseConnect.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Attribution Notice: ConcourseConnect is an Original Work of software created
 * by Concursive Corporation
 */

package com.concursive.connect.web.modules.profile.utils;

import com.concursive.commons.db.DatabaseUtils;
import com.concursive.commons.phone.PhoneNumberBean;
import com.concursive.commons.phone.PhoneNumberUtils;
import com.concursive.commons.text.StringUtils;
import com.concursive.connect.Constants;
import com.concursive.connect.cache.utils.CacheUtils;
import com.concursive.connect.web.modules.blog.dao.BlogPostList;
import com.concursive.connect.web.modules.common.social.geotagging.utils.LocationBean;
import com.concursive.connect.web.modules.common.social.geotagging.utils.LocationUtils;
import com.concursive.connect.web.modules.common.social.tagging.dao.TagList;
import com.concursive.connect.web.modules.common.social.tagging.dao.TagLogList;
import com.concursive.connect.web.modules.discussion.dao.TopicList;
import com.concursive.connect.web.modules.documents.dao.FileItemList;
import com.concursive.connect.web.modules.issues.dao.TicketList;
import com.concursive.connect.web.modules.login.dao.User;
import com.concursive.connect.web.modules.login.utils.UserUtils;
import com.concursive.connect.web.modules.members.dao.TeamMember;
import com.concursive.connect.web.modules.members.dao.TeamMemberList;
import com.concursive.connect.web.modules.plans.dao.AssignmentList;
import com.concursive.connect.web.modules.profile.dao.Project;
import com.concursive.connect.web.modules.profile.dao.ProjectCategory;
import com.concursive.connect.web.modules.wiki.dao.WikiList;
import com.concursive.connect.web.utils.LookupList;
import com.concursive.connect.web.utils.PagedListInfo;
import net.sf.ehcache.Ehcache;
import net.sf.ehcache.Element;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.sql.*;
import java.util.Calendar;
import java.util.HashMap;

/**
 * Class to manipulate project objects
 *
 * @author matt rajkowski
 * @version $Id$
 * @created February 7, 2006
 */
public class ProjectUtils {

    private static Log LOG = LogFactory.getLog(ProjectUtils.class);

    public static int queryWhatsNewCount(Connection db, int userId) throws SQLException {
        int count = 0;
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DAY_OF_MONTH, -2);
        Timestamp alertRangeStart = new Timestamp(cal.getTimeInMillis());
        // Latest News
        BlogPostList newsList = new BlogPostList();
        newsList.setForUser(userId);
        newsList.setAlertRangeStart(alertRangeStart);
        newsList.setCurrentNews(Constants.TRUE);
        count += newsList.queryCount(db);
        // Latest Issues
        TopicList topicList = new TopicList();
        topicList.setForUser(userId);
        topicList.setAlertRangeStart(alertRangeStart);
        count += topicList.queryCount(db);
        // Latest Files
        FileItemList fileItemList = new FileItemList();
        fileItemList.setLinkModuleId(Constants.PROJECTS_FILES);
        fileItemList.setForProjectUser(userId);
        fileItemList.setAlertRangeStart(alertRangeStart);
        count += fileItemList.queryCount(db);
        // Latest Wikis
        WikiList wikiList = new WikiList();
        wikiList.setForUser(userId);
        wikiList.setAlertRangeStart(alertRangeStart);
        count += wikiList.queryCount(db);
        return count;
    }

    public static int queryWhatsAssignedCount(Connection db, int userId) throws SQLException {
        int count = 0;
        // Assignments
        AssignmentList assignmentList = new AssignmentList();
        assignmentList.setForProjectUser(userId);
        assignmentList.setAssignmentsForUser(userId);
        assignmentList.setIncompleteOnly(true);
        assignmentList.setOnlyIfRequirementOpen(true);
        assignmentList.setOnlyIfProjectOpen(true);
        count += assignmentList.queryCount(db);
        // Tickets
        TicketList ticketList = new TicketList();
        ticketList.setForProjectUser(userId);
        ticketList.setAssignedTo(userId);
        ticketList.setOnlyOpen(true);
        ticketList.setOnlyIfProjectOpen(true);
        count += ticketList.queryCount(db);
        return count;
    }

    public static int queryMyProjectCount(Connection db, int userId) throws SQLException {
        int count = 0;
        // How many projects does this user belong to?
        TeamMemberList teamMemberList = new TeamMemberList();
        teamMemberList.setUserId(userId);
        count += teamMemberList.queryCount(db);
        return count;
    }

    public static Project loadProject(int projectId) {
        if (projectId > -1) {
            Ehcache cache = CacheUtils.getCache(Constants.SYSTEM_PROJECT_CACHE);
            Element element = cache.get(projectId);
            return (Project) element.getObjectValue();
        } else {
            return null;
        }
    }

    public static Project loadProject(String uniqueId) {
        if (StringUtils.hasText(uniqueId)) {
            int projectId = retrieveProjectIdFromUniqueId(uniqueId);
            if (projectId > -1) {
                return loadProject(projectId);
            }
        }
        return null;
    }

    public static int retrieveProjectIdFromUniqueId(String uniqueId) {
        Ehcache cache = CacheUtils.getCache(Constants.SYSTEM_PROJECT_UNIQUE_ID_CACHE);
        Element element = cache.get(uniqueId);
        if (element.getObjectValue() != null) {
            return (Integer) element.getObjectValue();
        }
        return -1;
    }

    public static boolean hasAccess(int projectId, User thisUser, String permission) {
        // Get the project from cache
        Project thisProject = loadProject(projectId);
        // Check access to the system first
        if (thisUser == null || UserUtils.isUserDisabled(thisUser)) {
            if (thisUser == null) {
                LOG.debug("hasAccess: failed - user is null");
            } else {
                LOG.debug("hasAccess: failed - user is disabled");
            }
            return false;
        }
        // Allow admins in
        if (thisUser.getAccessAdmin()) {
            return true;
        }
        // Allow content editors in
        if (thisUser.hasContentEditorAccess(thisProject.getLanguageId()) && thisProject.getPortal()) {
            return true;
        }
        // Compare the project permissions
        int accessLevel = thisProject.getPermissions().getAccessLevel(permission);
        // The following returns a number... typically 10-100
        LookupList roleList = CacheUtils.getLookupList("lookup_project_role");
        int projectRoleId = roleList.getLevelFromId(accessLevel);
        if (accessLevel == -1 || projectRoleId == -1) {
            LOG.debug("hasAccess: failed - invalid role");
            return false;
        }
        // If the user is on the team, check their permission
        TeamMember teamMember = thisProject.getTeam().getTeamMember(thisUser.getId());
        if (teamMember != null) {
            // Check if on the team, fully added, and has the correct role
            if (teamMember.getStatus() == TeamMember.STATUS_ADDED && teamMember.getRoleId() <= projectRoleId) {
                // On the team and has the correct role
                return true;
            }
        }
        if (!thisProject.getApproved()) {
            // If the project isn't approved, and you're not a team member
            LOG.trace("hasAccess: failed - project is not approved");
            return false;
        }
        // If the permissions allow for participants, return true
        if (thisProject.getFeatures().getAllowParticipants() && thisUser.isLoggedIn()) {
            // This user is logged in, and the project allows participants
            if (TeamMember.PARTICIPANT <= projectRoleId) {
                return true;
            }
        }
        if (thisProject.getFeatures().getAllowGuests()) {
            // If the permissions allow for guests, return true
            if (TeamMember.GUEST <= projectRoleId) {
                return true;
            }
        }
        LOG.trace("hasAccess: failed - all access conditions failed: " + permission + " projectId: " + projectId
                + " userId: " + thisUser.getId());
        return false;
    }

    public static boolean hasPermissionAsTeamMember(int projectId, User thisUser, String permission) {
        if (thisUser == null || UserUtils.isUserDisabled(thisUser)) {
            if (thisUser == null) {
                LOG.debug("hasAccess: failed - user is null");
            } else {
                LOG.debug("hasAccess: failed - user is disabled");
            }
            return false;
        }

        // Get the project from cache
        Project thisProject = loadProject(projectId);

        int accessLevel = thisProject.getPermissions().getAccessLevel(permission);
        // The following returns a number... typically 10-100
        LookupList roleList = CacheUtils.getLookupList("lookup_project_role");
        int projectRoleId = roleList.getLevelFromId(accessLevel);
        if (accessLevel == -1 || projectRoleId == -1) {
            LOG.debug("hasAccess: failed - invalid role");
            return false;
        }
        // If the user is on the team, check their permission
        TeamMember teamMember = thisProject.getTeam().getTeamMember(thisUser.getId());
        if (teamMember != null) {
            // Check if on the team, fully added, and has the correct role
            if (teamMember.getStatus() == TeamMember.STATUS_ADDED && teamMember.getRoleId() <= projectRoleId) {
                // On the team and has the correct role
                return true;
            }
        }

        return false;
    }

    public static TeamMember retrieveTeamMember(int projectId, User thisUser) {
        // Get the project from cache
        Project thisProject = loadProject(projectId);
        // Try retrieving the team member
        TeamMember teamMember = thisProject.getTeam().getTeamMember(thisUser.getId());
        if (teamMember == null) {
            // Generate a temporary team member
            if (thisUser.getAccessAdmin()) {
                // If this is an administrator of the system, give them access
                teamMember = new TeamMember();
                teamMember.setProjectId(thisProject.getId());
                teamMember.setUserLevel(UserUtils.getUserLevel(TeamMember.PROJECT_ADMIN));
                teamMember.setRoleId(TeamMember.PROJECT_ADMIN);
                teamMember.setTemporaryAdmin(true);
            } else if (thisUser.hasContentEditorAccess(thisProject.getLanguageId()) && thisProject.getPortal()) {
                teamMember = new TeamMember();
                teamMember.setProjectId(thisProject.getId());
                teamMember.setUserLevel(UserUtils.getUserLevel(TeamMember.PROJECT_ADMIN));
                teamMember.setRoleId(TeamMember.PROJECT_ADMIN);
                teamMember.setTemporaryAdmin(true);
            } else if (!thisProject.getApproved()) {
                // If the project isn't approved, and you're not a team member
                return null;
                /*
                } else if (thisProject.getFeatures().getMembershipRequired()) {
                // If not a member, and membership is required
                return false;
                */
            } else if (thisProject.getFeatures().getAllowParticipants() && thisUser.isLoggedIn()) {
                // Create a participant because the project promotes registered users to Partcipant
                teamMember = new TeamMember();
                teamMember.setProjectId(thisProject.getId());
                teamMember.setUserLevel(UserUtils.getUserLevel(TeamMember.PARTICIPANT));
                teamMember.setRoleId(TeamMember.PARTICIPANT);
            } else if (thisProject.getFeatures().getAllowGuests()) {
                // Create a guest by default because the project allows guests
                teamMember = new TeamMember();
                teamMember.setProjectId(thisProject.getId());
                teamMember.setUserLevel(UserUtils.getUserLevel(TeamMember.GUEST));
                teamMember.setRoleId(TeamMember.GUEST);
            }
        }
        return teamMember;
    }

    /**
     * Accepts a project for the given user
     *
     * @param db        Description of the Parameter
     * @param projectId Description of the Parameter
     * @param userId    Description of the Parameter
     * @throws SQLException Description of the Exception
     */
    public static void accept(Connection db, int projectId, int userId) throws SQLException {
        PreparedStatement pst = db.prepareStatement("UPDATE project_team " + "SET status = ? "
                + "WHERE project_id = ? " + "AND user_id = ? " + "AND status = ? ");
        DatabaseUtils.setInt(pst, 1, TeamMember.STATUS_ADDED);
        pst.setInt(2, projectId);
        pst.setInt(3, userId);
        pst.setInt(4, TeamMember.STATUS_PENDING);
        pst.executeUpdate();
        pst.close();
        CacheUtils.invalidateValue(Constants.SYSTEM_PROJECT_CACHE, projectId);
    }

    /**
     * Rejects a project for the given user
     *
     * @param db        Description of the Parameter
     * @param projectId Description of the Parameter
     * @param userId    Description of the Parameter
     * @throws SQLException Description of the Exception
     */
    public static void reject(Connection db, int projectId, int userId) throws SQLException {
        // Remove the user...
        PreparedStatement pst = db.prepareStatement(
                "DELETE FROM project_team " + "WHERE project_id = ? " + "AND user_id = ? " + "AND status = ? ");
        pst.setInt(1, projectId);
        pst.setInt(2, userId);
        pst.setInt(3, TeamMember.STATUS_PENDING);
        pst.execute();
        pst.close();
        CacheUtils.invalidateValue(Constants.SYSTEM_PROJECT_CACHE, projectId);
    }

    public static void formatAddress(Project thisProject) {
        // format US addresses only
        if (thisProject.getPostalCode() == null
                || !StringUtils.hasAllowedOnly("0123456789-", thisProject.getPostalCode())
                || (thisProject.getPostalCode().length() != 5 && thisProject.getPostalCode().length() != 10)) {
            // not a us zip so do nothing
        } else {
            if ((!StringUtils.hasText(thisProject.getCountry()) || "UNITED STATES".equals(thisProject.getCountry()))
                    && StringUtils.hasText(thisProject.getPostalCode())
                    && (!StringUtils.hasText(thisProject.getCity())
                            || !StringUtils.hasText(thisProject.getState()))) {
                LocationBean location = LocationUtils.findLocationByZipCode(thisProject.getPostalCode());
                if (location != null) {
                    if (!StringUtils.hasText(thisProject.getCity())) {
                        thisProject.setCity(location.getCity());
                    }
                    if (!StringUtils.hasText(thisProject.getState())) {
                        thisProject.setState(location.getState());
                    }
                    if (!StringUtils.hasText(thisProject.getCountry())) {
                        thisProject.setCountry("UNITED STATES");
                    }
                    if (!StringUtils.hasText(thisProject.getAddress()) && !thisProject.isGeoCoded()) {
                        // Use the zip code default
                        thisProject.setLatitude(location.getLatitude());
                        thisProject.setLongitude(location.getLongitude());
                    }
                }
            }
        }
    }

    public static void formatPhoneNumbers(Project thisProject) {
        // business
        if (thisProject.getBusinessPhone() != null) {
            PhoneNumberBean phone = PhoneNumberUtils.format(thisProject.getBusinessPhone(),
                    thisProject.getBusinessPhoneExt());
            thisProject.setBusinessPhone(phone.getNumber());
            thisProject.setBusinessPhoneExt(phone.getExtension());
        }
        // business2
        if (thisProject.getBusiness2Phone() != null) {
            PhoneNumberBean phone = PhoneNumberUtils.format(thisProject.getBusiness2Phone(),
                    thisProject.getBusiness2PhoneExt());
            thisProject.setBusiness2Phone(phone.getNumber());
            thisProject.setBusiness2PhoneExt(phone.getExtension());
        }
        // businessFax
        if (thisProject.getBusinessFax() != null) {
            PhoneNumberBean phone = PhoneNumberUtils.format(thisProject.getBusinessFax(), null);
            thisProject.setBusinessFax(phone.getNumber());
        }
        // home
        if (thisProject.getHomePhone() != null) {
            PhoneNumberBean phone = PhoneNumberUtils.format(thisProject.getHomePhone(),
                    thisProject.getHomePhoneExt());
            thisProject.setHomePhone(phone.getNumber());
            thisProject.setHomePhoneExt(phone.getExtension());
        }
        // home2
        if (thisProject.getHome2Phone() != null) {
            PhoneNumberBean phone = PhoneNumberUtils.format(thisProject.getHome2Phone(),
                    thisProject.getHome2PhoneExt());
            thisProject.setHome2Phone(phone.getNumber());
            thisProject.setHome2PhoneExt(phone.getExtension());
        }
        // homeFax
        if (thisProject.getHomeFax() != null) {
            PhoneNumberBean phone = PhoneNumberUtils.format(thisProject.getHomeFax(), null);
            thisProject.setHomeFax(phone.getNumber());
        }
        // mobilePhone
        if (thisProject.getMobilePhone() != null) {
            PhoneNumberBean phone = PhoneNumberUtils.format(thisProject.getMobilePhone(), null);
            thisProject.setMobilePhone(phone.getNumber());
        }
        // pagerNumber
        if (thisProject.getPagerNumber() != null) {
            PhoneNumberBean phone = PhoneNumberUtils.format(thisProject.getPagerNumber(), null);
            thisProject.setPagerNumber(phone.getNumber());
        }
        // carPhone
        if (thisProject.getCarPhone() != null) {
            PhoneNumberBean phone = PhoneNumberUtils.format(thisProject.getCarPhone(), null);
            thisProject.setCarPhone(phone.getNumber());
        }
        // radioPhone
        if (thisProject.getRadioPhone() != null) {
            PhoneNumberBean phone = PhoneNumberUtils.format(thisProject.getRadioPhone(), null);
            thisProject.setRadioPhone(phone.getNumber());
        }
    }

    public static void formatWebAddress(Project thisProject) {
        if (thisProject.getWebPage() != null) {
            String page = thisProject.getWebPage().trim();
            if (page.length() == 0) {
                // turn blanks into null
                page = null;
            } else if (page.indexOf("://") == -1) {
                // prefix with a scheme
                page = "http://" + page;
            }
            thisProject.setWebPage(page);
        }
    }

    // TODO: the following really only work in the Western Hemisphere. Need to update to handle whole world coordinates.
    public static String formatLatitude(String latitude) {
        if (latitude == null || latitude.contains(".")) {
            return latitude;
        }
        if (latitude.startsWith("0")) {
            return (latitude.substring(1, 3) + "." + latitude.substring(3));
        }
        String thisLatitude;
        if (latitude.startsWith("-")) {
            // If it starts with a '-', put a decimal after the second character...
            // -36775005
            thisLatitude = "-" + latitude.substring(1, 3) + "." + latitude.substring(3);
        } else {
            // place the decimal after the second character...
            // 36775005
            thisLatitude = latitude.substring(0, 2) + "." + latitude.substring(2);
        }
        return thisLatitude;
    }

    public static String formatLongitude(String longitude) {
        if (longitude == null || longitude.contains(".")) {
            return longitude;
        }
        // Default for many importers...
        if (longitude.startsWith("0")) {
            return ("-" + longitude.substring(1, 3) + "." + longitude.substring(3));
        }

        // Assumptions:
        // The following fits standard DDMMSSAA formatting:
        // The following assume that a leading '-' is ignored.
        // If the string length is even, the first two characters are the degrees,
        // if the string length is odd, the first three characters are the degrees.
        // TODO: Do an actiua
        String tmpLongitude = longitude;
        if (tmpLongitude.startsWith("-")) {
            // Strip the minus...
            tmpLongitude = tmpLongitude.substring(1);
        }
        // Now process the value...
        String thisLongitude;
        if ((tmpLongitude.length() % 2) > 0) {
            // Odd string length, take the first three characters as degrees...
            thisLongitude = tmpLongitude.substring(0, 3) + "." + tmpLongitude.substring(3);
        } else {
            // Even string length, take the first two characters as degrees...
            thisLongitude = tmpLongitude.substring(0, 2) + "." + tmpLongitude.substring(2);
        }
        // Add the '-' back in..."
        if (longitude.startsWith("-")) {
            thisLongitude = "-" + thisLongitude;
        }
        return thisLongitude;
    }

    public static synchronized String updateUniqueId(Connection db, int projectId, String title)
            throws SQLException {
        if (projectId == -1) {
            throw new SQLException("ID was not specified");
        }
        if (title == null) {
            throw new SQLException("Title was not specified");
        }
        // reserve a unique text id for the project
        String uniqueId = ProjectUtils.generateUniqueId(title, projectId, db);
        PreparedStatement pst = db
                .prepareStatement("UPDATE projects " + "SET projecttextid = ? " + "WHERE project_id = ?");
        pst.setString(1, uniqueId);
        pst.setInt(2, projectId);
        pst.execute();
        pst.close();
        CacheUtils.invalidateValue(Constants.SYSTEM_PROJECT_CACHE, projectId);
        CacheUtils.invalidateValue(Constants.SYSTEM_PROJECT_UNIQUE_ID_CACHE, uniqueId);
        return uniqueId;
    }

    private static String generateUniqueId(String title, int projectId, Connection db) throws SQLException {
        // Title can look like...
        // Some Project Name
        // some-project-name
        // some-project-name-2

        // Format to allowed characters to get extension (some will be treated later)
        String allowed = "abcdefghijklmnopqrstuvwxyz1234567890-/& ";
        String nameToSearch = StringUtils.toAllowedOnly(allowed, title.trim().toLowerCase());
        if (!StringUtils.hasText(nameToSearch)) {
            nameToSearch = "listing";
        }

        // Break out any numbered extension: ex. name-5
        String originalExtension = null;
        int dotIndex = nameToSearch.lastIndexOf("-");
        if (dotIndex > -1 && dotIndex + 1 < nameToSearch.length()) {
            if (StringUtils.isNumber(nameToSearch.substring(dotIndex + 1))) {
                originalExtension = nameToSearch.substring(dotIndex);
                nameToSearch = nameToSearch.substring(0, dotIndex);
            }
        }

        // Convert spaces to - for url compliance and search engine readability
        nameToSearch = StringUtils.replace(nameToSearch, " ", "-");
        nameToSearch = StringUtils.replace(nameToSearch, "&", "and");
        nameToSearch = StringUtils.replace(nameToSearch, "/", "-");

        // See if there is a dupe in the database, and retrieve the latest value
        boolean originalExtensionExists = false;
        PreparedStatement pst = db.prepareStatement(
                "SELECT project_id, projecttextid " + "FROM projects " + "WHERE projecttextid LIKE ? ");
        pst.setString(1, nameToSearch + "%");
        ResultSet rs = pst.executeQuery();
        long value = 0;
        while (rs.next()) {
            long thisProjectId = rs.getLong("project_id");
            String thisTextId = rs.getString("projecttextid");
            // If it already owns this id, then keep it
            if (projectId > -1 && projectId == thisProjectId && nameToSearch.equals(thisTextId)) {
                return nameToSearch;
            }
            if (originalExtension != null) {
                if (thisTextId.equals(nameToSearch + originalExtension)) {
                    originalExtensionExists = true;
                }
            }
            // Only compare to this name exactly, or this named iteration
            if (thisTextId.equals(nameToSearch)) {
                if (1 > value) {
                    value = 1;
                }
            }

            if (thisTextId.startsWith(nameToSearch + "-")) {
                String foundExtensionValue = thisTextId.substring(thisTextId.lastIndexOf("-") + 1);
                if (StringUtils.isNumber(foundExtensionValue)) {
                    try {
                        long thisValue = Long.parseLong(foundExtensionValue);
                        if (thisValue > value) {
                            value = thisValue;
                        }
                    } catch (Exception e) {
                        // The extension is big... so add another extension
                        rs.close();
                        pst.close();
                        return generateUniqueId(nameToSearch + "-2", projectId, db);
                    }
                }
            }
        }
        if (originalExtension != null && !originalExtensionExists) {
            return (nameToSearch + originalExtension);
        }
        // Set this one accordingly
        if (value == 0) {
            return nameToSearch;
        } else {
            ++value;
            return (nameToSearch + "-" + value);
        }
    }

    public static String decodeLabel(Project project, String section) {
        if (section == null) {
            return null;
        }
        // Add items that do not match their section name
        HashMap<String, String> sectionMap = new HashMap<String, String>();
        sectionMap.put("issues", "Discussion");
        sectionMap.put("file", "Documents");
        sectionMap.put("requirements", "Plan");
        sectionMap.put("assignments", "Plan");
        int sep = section.indexOf("_");
        if (sep > -1) {
            section = section.substring(0, sep);
        }
        String label = sectionMap.get(section);
        if (label != null) {
            return project.getLabel(label);
        }
        return project.getLabel(String.valueOf(section.charAt(0)).toUpperCase() + section.substring(1));
        // TODO: use translation
        //String newText = prefs.getLabel("tabbedMenu.tab." + text, language);
    }

    public static ProjectCategory loadProjectCategory(int categoryId) {
        Ehcache cache = CacheUtils.getCache(Constants.SYSTEM_PROJECT_CATEGORY_LIST_CACHE);
        Element element = cache.get(categoryId);
        return (ProjectCategory) element.getObjectValue();
    }

    public static TagList loadProjectTags(Connection db, int projectId) throws SQLException {
        // Get popular tags for this project
        TagList popularTagList = new TagList();
        popularTagList.setTableName(Project.TABLE);
        popularTagList.setUniqueField(Project.PRIMARY_KEY);
        popularTagList.setLinkItemId(projectId);
        PagedListInfo tagListInfo = new PagedListInfo();
        tagListInfo.setColumnToSortBy("tag_count DESC, tag");
        tagListInfo.setItemsPerPage(10);
        popularTagList.setPagedListInfo(tagListInfo);
        popularTagList.buildList(db);
        return popularTagList;
    }

    public static TagLogList loadProjectTagsForUser(Connection db, int projectId, int userId) throws SQLException {
        // Get the user's tags for this project
        TagLogList tagLogList = new TagLogList();
        tagLogList.setTableName(Project.TABLE);
        tagLogList.setUniqueField(Project.PRIMARY_KEY);
        tagLogList.setUserId(userId);
        tagLogList.setLinkItemId(projectId);
        tagLogList.buildList(db);
        return tagLogList;
    }

    public static boolean datesDiffer(Timestamp a, Timestamp b) {
        if (a == null && b == null) {
            return false;
        }
        if (a != null && b == null) {
            return true;
        }
        if (a == null) {
            return true;
        }
        return !a.equals(b);
    }

    public static int retrieveWebcastIdFromProjectId(Connection db, int projectId) throws SQLException {
        int webcastId = -1;
        PreparedStatement pst = db
                .prepareStatement("SELECT webcast_id " + "FROM project_webcast " + "WHERE project_id = ? ");
        pst.setInt(1, projectId);
        ResultSet rs = pst.executeQuery();
        if (rs.next()) {
            webcastId = rs.getInt("webcast_id");
        }
        rs.close();
        pst.close();

        return webcastId;
    }
}