head	1.58;
access;
symbols
	TIGRIS_0_9_2_4:1.48
	TIGRIS_0_9_2_3:1.48
	HELM_PEER_PORT_BRANCH:1.57.0.2
	TURBINE_PEER:1.57
	TIGRIS_0_9_2_1:1.57
	TIGRIS_0_9_2:1.48.0.2
	TIGRIS_0_9_0:1.37.0.2
	TIGRIS_0_8_4:1.32.0.2
	NEWHELM:1.1.1.1
	TIGRIS_NOV_12_2000:1.1.1
	OLDHELM:1.8.0.2
	TIGRIS_NOV_11_2000:1.8
	TIGRIS_SEP_13_2000:1.5.0.2
	TIGRIS_BASELINE:1.6;
locks; strict;
comment	@# @;


1.58
date	2001.02.21.03.23.56;	author edk;	state dead;
branches;
next	1.57;

1.57
date	2001.01.26.18.29.00;	author edk;	state Exp;
branches
	1.57.2.1;
next	1.56;

1.56
date	2001.01.26.05.24.05;	author edk;	state dead;
branches;
next	1.55;

1.55
date	2001.01.25.02.53.24;	author leonardr;	state Exp;
branches;
next	1.54;

1.54
date	2001.01.25.01.42.10;	author leonardr;	state Exp;
branches;
next	1.53;

1.53
date	2001.01.25.01.38.06;	author leonardr;	state Exp;
branches;
next	1.52;

1.52
date	2001.01.24.22.24.36;	author leonardr;	state Exp;
branches;
next	1.51;

1.51
date	2001.01.24.21.41.48;	author leonardr;	state Exp;
branches;
next	1.50;

1.50
date	2001.01.24.20.42.46;	author dlr;	state Exp;
branches;
next	1.49;

1.49
date	2001.01.24.02.41.32;	author davidp;	state Exp;
branches;
next	1.48;

1.48
date	2001.01.17.22.07.33;	author leonardr;	state Exp;
branches;
next	1.47;

1.47
date	2001.01.05.01.46.24;	author dlr;	state Exp;
branches;
next	1.46;

1.46
date	2001.01.05.01.10.55;	author dlr;	state Exp;
branches;
next	1.45;

1.45
date	2000.12.29.23.00.48;	author dlr;	state Exp;
branches;
next	1.44;

1.44
date	2000.12.29.21.38.58;	author dlr;	state Exp;
branches;
next	1.43;

1.43
date	2000.12.29.20.17.11;	author dlr;	state Exp;
branches;
next	1.42;

1.42
date	2000.12.29.19.58.32;	author dlr;	state Exp;
branches;
next	1.41;

1.41
date	2000.12.29.17.11.52;	author leonardr;	state Exp;
branches;
next	1.40;

1.40
date	2000.12.29.02.35.14;	author dlr;	state Exp;
branches;
next	1.39;

1.39
date	2000.12.27.23.12.34;	author leonardr;	state Exp;
branches;
next	1.38;

1.38
date	2000.12.22.03.02.04;	author dlr;	state Exp;
branches;
next	1.37;

1.37
date	2000.12.20.18.39.55;	author leonardr;	state Exp;
branches;
next	1.36;

1.36
date	2000.12.07.06.32.14;	author dlr;	state Exp;
branches;
next	1.35;

1.35
date	2000.12.07.04.09.48;	author dlr;	state Exp;
branches;
next	1.34;

1.34
date	2000.12.07.03.55.35;	author dlr;	state Exp;
branches;
next	1.33;

1.33
date	2000.12.04.20.01.42;	author leonardr;	state Exp;
branches;
next	1.32;

1.32
date	2000.12.01.12.52.03;	author edk;	state Exp;
branches
	1.32.2.1;
next	1.31;

1.31
date	2000.11.29.23.57.50;	author leonardr;	state Exp;
branches;
next	1.30;

1.30
date	2000.11.29.19.59.33;	author leonardr;	state Exp;
branches;
next	1.29;

1.29
date	2000.11.23.06.24.43;	author dlr;	state Exp;
branches;
next	1.28;

1.28
date	2000.11.23.06.21.25;	author dlr;	state Exp;
branches;
next	1.27;

1.27
date	2000.11.21.23.32.49;	author leonardr;	state Exp;
branches;
next	1.26;

1.26
date	2000.11.20.20.07.32;	author leonardr;	state Exp;
branches;
next	1.25;

1.25
date	2000.11.17.21.49.37;	author leonardr;	state Exp;
branches;
next	1.24;

1.24
date	2000.11.17.20.14.30;	author dlr;	state Exp;
branches;
next	1.23;

1.23
date	2000.11.17.18.44.32;	author leonardr;	state Exp;
branches;
next	1.22;

1.22
date	2000.11.17.02.18.30;	author leonardr;	state Exp;
branches;
next	1.21;

1.21
date	2000.11.17.00.29.21;	author leonardr;	state Exp;
branches;
next	1.20;

1.20
date	2000.11.17.00.00.01;	author elicia;	state Exp;
branches;
next	1.19;

1.19
date	2000.11.16.01.12.27;	author leonardr;	state Exp;
branches;
next	1.18;

1.18
date	2000.11.15.23.52.16;	author elicia;	state Exp;
branches;
next	1.17;

1.17
date	2000.11.15.19.39.16;	author leonardr;	state Exp;
branches;
next	1.16;

1.16
date	2000.11.15.18.49.04;	author leonardr;	state Exp;
branches;
next	1.15;

1.15
date	2000.11.15.00.34.13;	author dlr;	state Exp;
branches;
next	1.14;

1.14
date	2000.11.14.23.07.57;	author elicia;	state Exp;
branches;
next	1.13;

1.13
date	2000.11.14.20.33.53;	author dlr;	state Exp;
branches;
next	1.12;

1.12
date	2000.11.14.20.31.31;	author dlr;	state Exp;
branches;
next	1.11;

1.11
date	2000.11.13.22.39.51;	author leonardr;	state Exp;
branches;
next	1.10;

1.10
date	2000.11.12.23.17.34;	author dlr;	state Exp;
branches;
next	1.9;

1.9
date	2000.11.12.22.57.31;	author dlr;	state Exp;
branches;
next	1.8;

1.8
date	2000.10.03.21.34.56;	author leonardr;	state Exp;
branches;
next	1.7;

1.7
date	2000.09.29.19.55.46;	author dlr;	state Exp;
branches;
next	1.6;

1.6
date	2000.09.21.19.44.07;	author kmaples;	state Exp;
branches;
next	1.5;

1.5
date	2000.09.20.03.13.16;	author brian;	state Exp;
branches;
next	1.4;

1.4
date	2000.04.18.00.10.34;	author jrobbins;	state Exp;
branches;
next	1.3;

1.3
date	2000.02.03.04.21.32;	author jrobbins;	state Exp;
branches;
next	1.2;

1.2
date	2000.01.31.02.41.53;	author jrobbins;	state Exp;
branches;
next	1.1;

1.1
date	2000.01.30.01.59.38;	author jrobbins;	state Exp;
branches
	1.1.1.1;
next	;

1.1.1.1
date	2000.11.12.21.15.06;	author dlr;	state Exp;
branches;
next	;

1.32.2.1
date	2000.12.05.06.34.16;	author jrobbins;	state Exp;
branches;
next	;

1.57.2.1
date	2001.01.28.01.02.17;	author dlr;	state dead;
branches;
next	;


desc
@@


1.58
log
@delete stuff from the head which is obsolete in the branch (more changes
are still needed for a clean compile)
@
text
@/* ================================================================
 * Copyright (c) 2000 CollabNet.  All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 * 
 * 1. Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 * 
 * 2. Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * 
 * 3. The end-user documentation included with the redistribution, if
 * any, must include the following acknowlegement: "This product includes
 * software developed by CollabNet (http://www.collab.net/)."
 * Alternately, this acknowlegement may appear in the software itself, if
 * and wherever such third-party acknowlegements normally appear.
 * 
 * 4. The hosted project names must not be used to endorse or promote
 * products derived from this software without prior written
 * permission. For written permission, please contact info@@collab.net.
 * 
 * 5. Products derived from this software may not use the "Tigris" name
 * nor may "Tigris" appear in their names without prior written
 * permission of CollabNet.
 * 
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL COLLABNET OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * ====================================================================
 * 
 * This software consists of voluntary contributions made by many
 * individuals on behalf of CollabNet.
 */


package org.tigris.helm.database;

import java.sql.*;
import java.util.*;

import org.webmacro.util.Log;

import com.workingdogs.village.*;

import org.apache.turbine.services.db.*;
import org.apache.turbine.util.db.pool.*;

import org.joist.util.*;
import org.joist.database.*;

import org.tigris.helm.DoesNotExist;
import org.tigris.helm.AlreadyExists;
import org.tigris.helm.database.*;
import org.tigris.helm.security.*;
import org.tigris.helm.tool.*;
import org.tigris.helm.project.*;
import org.tigris.helm.domain.ProjectGroup;

/**
 * This class deals with projects, and manages the proper database
 * activities related to their creation and deletion, ensuring
 * database integrity.
 *
 * @@author <a href="mailto:akosut@@leland.stanford.edu">Alexi Kosut</a>
 * @@author <a href="mailto:jrobbins@@collab.net">Jason Robbins</a>
 * @@author <a href="mailto:leonardr@@collab.net">Leonard Richardson</a>
 * @@author <a href="mailto:dlr@@collab.net">Daniel Rall</a>
 */
public class ProjectManager extends TableManager
{
    /**
     * The name of the database table that this <code>TableManager</code> 
     * manages.
     */
    public static final String TABLE_NAME = "HELM_PROJECT";

    /**
     * The primary database key field.
     */
    public static final String PROJECT_ID = "PROJECT_ID";

    /**
     * The domain field.
     */
    public static final String PROJECT_DOMAIN_ID = "DOMAIN_ID";

    /**
     * The name field.
     */
    public static final String PROJECT_NAME = "NAME";

    /**
     * The license field.
     */
    public static final String PROJECT_LICENSE = "LICENSE";

    /**
     * The short description field.
     */
    public static final String PROJECT_SHORT_DESCRIPTION = "SHORT_DESCRIPTION";

    /**
     * The long description field.
     */
    public static final String PROJECT_LONG_DESCRIPTION = "LONG_DESCRIPTION";

    /**
     * The flag field to use the project index file instead of the description.
     */
    public static final String USE_INDEX = "USE_INDEX";

    /**
     * The project profile
     */
    public static final String PROJECT_PROFILE = "PROFILE";

    /**
     * The project type.
     */
    public static final String PROJECT_TYPE = "TYPE";

    /**
     * The project status field.
     */
    public static final String PROJECT_STATUS = "STATUS";

    /**
     * The category ID field.
     */
    public static final String PROJECT_CATEGORY_ID = "CATEGORY_ID";

    /**
     * The alias URL field.
     */
    public static final String PROJECT_ALIAS_URL = "ALIAS_URL";

    /**
     * The member policy field.
     */
    public static final String PROJECT_MEMBER_POLICY = "MEMBER_POLICY";

    /**
     * The user ID of the user who proposed this project.
     */
    public static final String PROJECT_PROPOSED_BY = "PROPOSED_BY";

    /**
     * The user ID of the user who approved this project.
     */
    public static final String PROJECT_APPROVED_BY = "APPROVED_BY";

    /**
     * The proprietariness field.
     */
    public static final String PROJECT_IS_PROPRIETARY = "IS_PROPRIETARY";

    /**
     * ID of the skin this project is using.
     */
    public static final String SKIN_ID = "SKIN_ID";

    /**
     * The special name of projects which represent all public
     * projects in a domain.  
     */
    public static final String DOMAIN_PUBLIC_PROJECT_NAME = 
        "*All public projects in domain";

    /**
     * The special name of projects which represent all projects in a
     * domain.
     */
    public static final String DOMAIN_PROJECT_NAME =
        "*All projects in domain";

    /**
     * The keyword designating a domain project in the type field.
     */
    public static final String DOMAIN_PROJECT_TYPE = "domain";

    /**
     * The special name of the project representing all projects on
     * the host.  
     */
    public static final String HOST_PROJECT_NAME = 
        "**All projects on host";

    /**
     * The keyword designating the host project in the type field.
     */
    public static final String HOST_PROJECT_TYPE = "host";

    /**
     * SQL statement used to lock the tables used in the initializer.
     */
    private static final String LOCK_TABLES = "lock tables " + 
        "HELM_DOMAIN read, " +
        "HELM_PROJECT read";

    /**
     * The keyword designating a base project in the type field.
     */
    public static final String BASE_PROJECT_TYPE = "base";

    /**
     * The keyword designating a category project in the type field.
     */
    public static final String CATEGORY_PROJECT_TYPE = "category";

    /**
     * SQL statement used to unlock the tables used in the initializer.
     */
    private static final String UNLOCK_TABLES = "unlock tables";

    /**
     * Project ID for the special host project, set at class loading time.
     */
    private static String hostProjectID;

    /**
     * A mapping of domain names to special project IDs, populated
     * at class loading time.
     */
    private static Hashtable projectIDForDomain;

    /**
     * A mapping of domain names to project IDs representing the
     * public projects in the domain, populated at class loading time.  
     */
    private static Hashtable publicProjectIDForDomain;

    /**
     * A general-purpose DataManager
     */
    private DataManager dMgr;

    /**
     * Open the log file.
     */
    private static Log log = new Log("projMgr", "ProjectManager");

    /**
     * Whether to log debugging information.
     */
    private static boolean debug = true;
    
    static
    {
        String action = "Static initialization of ProjectManager: ";
        
        projectIDForDomain = new Hashtable();
        publicProjectIDForDomain = new Hashtable();

        DBConnection dbConn = null;
        Connection connection = null;
        DataManager dMgr = new DataManager();
        DomainManager domMgr = (DomainManager)dMgr
            .getManager("org.tigris.helm.database.DomainManager");

        TableDataSet projects = null;
        DataSet domains = null;
        // Get a connection from the Turbine connection pool.
        try 
        {
            dbConn = TurbineDB.getConnection();
            connection = dbConn.getConnection();

            Statement stmt = null;        
            try
            {
                // Grab a light weight database lock.
                stmt = connection.createStatement();
                stmt.executeUpdate(LOCK_TABLES);
            }
            catch (Exception e)
            {
                log.info("Table locking/unlocking error in static " +
                          "initializer: " + e.getMessage());
                throw new RuntimeException(e.getMessage());
            }

            Hashtable domainNameForID = new Hashtable();
            // Get the project ID for the special hostwide project.
            // TODO: This is generally useful--it should be static member of 
            // DomainManager.
            try
            {
                projects = new TableDataSet(connection, TABLE_NAME);
                projects.where("name=" + escapeAndQuoteSQL(HOST_PROJECT_NAME));
                projects.fetchRecords();
                if (projects.size() > 0)
                {
                    hostProjectID = projects.getRecord(0)
                        .getValue(PROJECT_ID).asString();
                }
                else
                {
                    throw new Exception ("Could not obtain hostProjectID");
                }
            }
            finally
            {
                if (projects != null) projects.close();
            }

            //Get a list of domains. Map the domain name to its ID
            //for later.
            domains = domMgr.listDomains(connection);
            int domainNum = domains.size();
            for (int i = 0; i < domainNum; i++)
            {
                Record domain = domains.getRecord(i);
                String domainID = domain.getValue(DomainManager.DOMAIN_ID)
                    .asString();
                String domainName = domain.getValue(DomainManager.DOMAIN_NAME)
                    .asString();
                domainNameForID.put(domainID, domainName);
            }

            String query = null;
            //Get the project IDs of all the special domain-wide projects.
            try
            {
                projects = new TableDataSet(connection, TABLE_NAME);
                query = PROJECT_NAME + "=" + 
                    escapeAndQuoteSQL(DOMAIN_PROJECT_NAME);
                projects.where(query);
                projects.fetchRecords();
                for (int i = 0; i < projects.size(); i++)
                {
                    Record project = projects.getRecord(i);
                    String projectID = project.getValue(PROJECT_ID).asString();
                    String domainID = 
                        project.getValue(PROJECT_DOMAIN_ID).asString();
                    projectIDForDomain.put(domainID, projectID);
                }
            }
            finally
            {
                if (projects != null) projects.close();
            }

            //Get the project IDs of all the special public project groups.
            //This stuff should go into a method since it's almost the same
            //as the stuff above.
            query = PROJECT_NAME + "=" +
                escapeAndQuoteSQL(DOMAIN_PUBLIC_PROJECT_NAME);
            try
            {
                projects = new TableDataSet(connection, TABLE_NAME);
                projects.where(query);
                projects.fetchRecords();
                for (int i = 0; i < projects.size(); i++)
                {
                    Record project = projects.getRecord(i);
                    String projectID = project.getValue(PROJECT_ID).asString();
                    String domainID = 
                        project.getValue(PROJECT_DOMAIN_ID).asString();
                    publicProjectIDForDomain.put(domainID, projectID);
                }
            }
            finally
            {
                if (projects != null) projects.close();
            }

            if (stmt != null)
            {
                // Unlock the database tables.
                stmt.executeUpdate(UNLOCK_TABLES);
                stmt.close();
            }
        }
        catch (Exception e)
        {
            log.exception(e);
            if (debug) log.debug(action + e.getMessage());
            throw new RuntimeException(e.getMessage());
        }
        finally
        {
            try 
            {
                if (projects != null) projects.close();
                if (domains != null) domains.close();
                TurbineDB.releaseConnection(dbConn);
            }
            catch (Exception e)
            {
                if (debug) log.error(action + e.getMessage());
                log.exception(e);
                throw new RuntimeException(e.getMessage());
            }
        }
    }
    
    /**
     * Creates a new instance.
     *
     * @@param dataMgr The associated <code>DataManager</code>.
     */
    public ProjectManager(DataManager dataMgr)
    {
        super(dataMgr);
        dMgr = dataMgr;
    }

    /**
     * Returns the host project ID
     *
     * @@return The ID of the special host project.
     */
    public String getHostProjectID()
    {
        return hostProjectID;
    }

    /**
     * Returns the domain project ID for the specified domain.
     *
     * @@param domainID The ID of the domain.
     * @@return         The ID of the special domain project.
     */
    public String getDomainProjectID(String domainID)
    {
        return (String)projectIDForDomain.get(domainID);
    }

    /**
     * Returns the "public projects" project ID for the specified domain.
     *
     * @@param domainID The ID of the domain.
     * @@return         The ID of the special domain project.
     */
    public String getPublicDomainProjectID(String domainID)
    {
        return (String)publicProjectIDForDomain.get(domainID);
    }

    /**
     * Checks whether a project has been approved.
     *
     * @@param connection A database connection.
     * @@param projectID The project ID to check.
     * @@return     Whether the project has been approved.
     *
     */
    public boolean isApproved(Connection connection, String projectID)
        throws SQLException, DataSetException, JoistDatabaseException
    {
        Record r = getProjectForID(connection, projectID);
        String approvedBy = r.getValue(PROJECT_APPROVED_BY).asString();
        log.info("Approved by " + approvedBy);
        UserUserGroupManager usrGrpMgr = (UserUserGroupManager)
            dMgr.getManager("org.tigris.helm.database.UserUserGroupManager");
        return(!approvedBy.equals(usrGrpMgr.getNobodyUserID(connection)));
    }

    /**
     * Checks whether a project name already exists in the given domain.
     */
    public boolean assertProjectNonexistance(Connection connection, 
                                             String domainID, String name)
        throws AlreadyExists, SQLException, DataSetException
    {
        boolean alreadyExists = false;
	
        Record project = getProjectForName(connection, domainID, name);
        if (project != null)
        {
	   alreadyExists = true;
        }
	 return alreadyExists;
    }


    ////////////////////////////////////////////////////////////////
    // Project addition
    ////////////////////////////////////////////////////////////////

    /**
     * Adds a project.
     *
     * @@param connection        The JDBC database connection to use.
     * @@param domainID          ID of Domain in which the project resides.
     * @@param name              Name of the project.
     * @@param license           License of the project.
     * @@param shortDescription  A short description of the project.
     * @@param longDescription   A long description of the project.
     * @@param useIndex          Whether to use the index file contents for the
     *                          long description.
     * @@param aliasURL          URL to use as alias, if any.
     * @@param proposedBy        User who proposed the project.
     * @@param approvedBy        User who approved the project, if any.
     * @@return                  The database record for the project.
     *
     * @@exception SQLException
     * @@exception DataSetException 
     * @@exception UpdateException
     */
    public Record addProject (Connection connection,
                              ProjectProfile profile,
                              String domainID,
                              String name, 
                              String license,
                              String shortDescription,
                              String longDescription,
                              String useIndex,
                              String status,
                              String aliasURL,
                              String proposedBy,
                              String approvedBy)
        throws SQLException, DataSetException, JoistDatabaseException, 
               DoesNotExist, AlreadyExists
    {
        
        return updateProject(connection, 
                             null,             //projectID
                             profile,          //profile
                             domainID,         //domainID
                             name,             //name
                             license,          //license
                             shortDescription, //shortDescription
                             longDescription,  //longDescription
                             useIndex,         //useIndex
                             status,           //status
                             aliasURL,         //aliasURL
                             proposedBy,       //proposedBy
                             approvedBy        //approvedBy
                             );
    }


    ////////////////////////////////////////////////////////////////
    // Project manipulation
    ////////////////////////////////////////////////////////////////

    /**
     * Approves the project in the name of the given userID.
     *
     * @@param connection  The JDBC database connection to use.
     * @@param projectID   The project to approve.
     * @@param userID      The user approving the project.
     * @@return  The system-assigned project ID for the project.
     *
     * @@exception SQLException
     * @@exception DataSetException 
     */
    public void approveProject(Connection connection,
                               String projectID,
                               String userID)
        throws SQLException, DataSetException, JoistDatabaseException
    {
        Record project = getProjectForID(connection, projectID);
        project.setValue(PROJECT_APPROVED_BY, userID);
        String status = project.getValue(PROJECT_STATUS).asString();
        String license = project.getValue(PROJECT_LICENSE).asString();
        String domainID = project.getValue(PROJECT_DOMAIN_ID).asString();
        project.save();
    }

    /**
     * Updates a project's info.
     * This is public version of the private updateProject.  Used
     * by, eg., ProjectEdit  to update project info.
     * <p>
     * Pass nulls for all args you do not want to change.
     *
     * @@param connection        The JDBC database connection to use.
     * @@param projectID         The database key of the project to update.
     * @@param profile           Profile of the project to be created.
     * @@param domainID          ID of domain in which the project resides.
     * @@param name              Name of the project.
     * @@param license           License of the project.
     * @@param shortDescription  A short description of the project.
     * @@param longDescription   A long description of the project.
     * @@param useIndex          Whether to use the index file contents for the
     *                          long description.
     * @@param status            Status of the project.
     * @@param categoryID        Category ID of this project
     * @@param aliasURL          Project URL
     *
     * @@exception SQLException
     * @@exception DataSetException 
     * @@exception JoistDatabaseException
     */
    public void updateProjectInfo(Connection connection,
                                  String projectID,
                                  String license,
                                  String shortDescription,
                                  String longDescription,
                                  String useIndex,
                                  String status, 
                                  String aliasURL
                                  )
        throws SQLException, DataSetException, JoistDatabaseException,
               DoesNotExist
    {
        updateProject(connection,
                      projectID,        //projectID
                      null,             //profile
                      null,             //domainID
                      null,             //name
                      license,          //license
                      shortDescription, //shortDescription
                      longDescription,  //longDescription
                      useIndex,         //useIndex
                      status,           //status
                      aliasURL,         //aliasURL
                      null,             //proposedBy
                      null              //approvedBy
                      );
    }
   
    /**
     * Updates an existing project or adds a new project to the database 
     * (depending on whether given a <code>projectID</code> or not).
     *
     * Note: This method only changes the database. It does not
     * run scripts.
     *
     * @@param connection        The JDBC database connection to use.
     * @@param projectID         The database key of the project to update 
     *                            (or null, in which case a new project is 
     *                            created).
     * @@param profile           Profile of a new project (immutable).
     * @@param domainID          ID of domain in which the project resides.
     * @@param name              Name of the project.
     * @@param license           License of the project.
     * @@param shortDescription  A short description of the project.
     * @@param longDescription   A longer description of the project.
     * @@param useIndex          Whether to use the index file contents for the
     *                          long description.
     * @@param status            Status of the project.
     * @@param aliasURL          Project URL
     * @@param proposedBy        ID of user who proposed project.
     * @@param approvedBy        ID of user who approved project.
     *
     * @@return  The system-assigned project ID for the project.
     *
     * @@exception SQLException
     * @@exception DataSetException 
     */
    private Record updateProject (Connection connection,
                                  String projectID, 
                                  ProjectProfile profile,
                                  String domainID,
                                  String name, 
                                  String license,
                                  String shortDescription,
                                  String longDescription,
                                  String useIndex,
                                  String status,
                                  String aliasURL,
                                  String proposedBy,
                                  String approvedBy)
        throws SQLException, DataSetException, JoistDatabaseException,
               DoesNotExist
    {
        Record project = null;
        TableDataSet projects = null;
        String action = null;
        
        if (projectID == null)
        {
            action = "Adding Project";
        } else {
            action = "Updating Project";
            profile = null; //Immutable.
        }

        try
        {
            projects = new TableDataSet(connection, TABLE_NAME, 
                                        new KeyDef().addAttrib(PROJECT_ID));

            if (projectID != null)
            {
                // Updating an existing project; get it.
                projects.where(PROJECT_ID + '=' + projectID);                
                projects.fetchRecords(1);
                if (debug) log.debug("Getting Record for existing project");
                project = projects.getRecord(0);
            }
            else
            {
                // Adding a new project.
                if (debug) log.debug("Adding Record for new project");
                project = projects.addRecord();
            }

            // Do update.
            if (domainID != null) project.setValue(PROJECT_DOMAIN_ID, 
                                                   domainID);

            if (name != null) project.setValue(PROJECT_NAME, name);

            if (profile != null) 
            {
                project.setValue(PROJECT_PROFILE, profile.getKey());
                project.setValue(PROJECT_TYPE, profile.getType());
            }

            if (shortDescription != null) 
                project.setValue(PROJECT_SHORT_DESCRIPTION, shortDescription);

            if (longDescription != null) 
                project.setValue(PROJECT_LONG_DESCRIPTION, longDescription);

            if (useIndex != null)
                project.setValue(USE_INDEX, useIndex);

            if (status != null) 
                project.setValue(PROJECT_STATUS, status);

            if (aliasURL != null)
                project.setValue(PROJECT_ALIAS_URL, aliasURL);

            if (proposedBy != null)
                project.setValue(PROJECT_PROPOSED_BY, proposedBy);

            if (approvedBy != null)
                project.setValue(PROJECT_APPROVED_BY, approvedBy);

            project.save();
            if (projectID == null)
            {
                // NOTE: There is no way to refresh a Village Record which has
                // been created using TableDataSet.addRecord().
                projectID = getLastInsertedID(connection).toString();
                project.setValue(PROJECT_ID, projectID);
            }

            if (license != null) 
            { 
                project = setLicense(connection, projectID,  license);
            }
        }
        catch (DataSetException e)
        {
            log.exception(e);
            if (debug) log.debug(action + ": " + e.getMessage());
            throw e;
        }
        catch (SQLException e)
        {
            log.exception(e);
            if (debug) log.debug(action + ": " + e.getMessage());
            throw e;
        }
        finally
        {
            registerToClose(projects);
        }
        
        return project;
    }

    public Record setLicense (Connection connection, String projectID, 
                              String license)
        throws SQLException, DataSetException, JoistDatabaseException,
               DoesNotExist
    {
        //Get the project.
        Record project = getProjectForID(connection, projectID);

        //Get the old license--see if it's proprietary.
        String oldLicense = project.getValue(PROJECT_LICENSE).asString();
        if (oldLicense != null && oldLicense.equals(license))
        {
            return project;
        }
        boolean wasProprietary = Licenses.isProprietary(oldLicense);
        boolean isProprietary = Licenses.isProprietary(license);

        boolean approved = isApproved(connection, projectID);

        /*
         * Approved non-proprietary projects can't go proprietary.
         */
        if (approved && isProprietary && !wasProprietary)
        {
            return project;
        }

        //Set the new license.
        project.setValue(PROJECT_LICENSE, license);
        project.save();

        //If we are approved, change appropriate groups.
        if (approved)
        {
            ProjectProjectGroupManager prjGrpMgr = (ProjectProjectGroupManager)
                dMgr.getManager
                ("org.tigris.helm.database.ProjectProjectGroupManager");
            
            String domainID = project.getValue(PROJECT_DOMAIN_ID).asString();
            
            Project p = new Project(connection, dMgr, projectID);

            //If we used not to be proprietary and now we are, remove
            //this project from the public projects list.
            if ((!wasProprietary || oldLicense == null) && isProprietary)
            {
                log.info("Removing project from public group.");
                ProjectGroup.removeFromPublicGroup(connection, dMgr, p, domainID);
            }
            
            //If we used to be proprietary and now we're not, add this project
            //to the public projects list.
            if ((wasProprietary || oldLicense == null) && !isProprietary)
            {
                log.info("Adding project to public group.");
                ProjectGroup.addToPublicGroup(connection, dMgr, p, domainID);
            }
        }

        return project;
    }

    ////////////////////////////////////////////////////////////////
    // Project deletion
    ////////////////////////////////////////////////////////////////

    /**
     * Deletes an existing project from the database
     *
     * @@param      connection    the JDBC database connection
     * @@param      projectID       the ID of the project to delete
     * @@exception SQLException
     */
    public void  deleteProject (Connection connection, String projectID)
        throws SQLException, DataSetException, JoistDatabaseException
    {
        String action = "Deleting Project";

        Record project = getProjectForID(connection, projectID);
        if (project != null)
        {
            project.markToBeDeleted();
            project.save();
        }
    }

    ////////////////////////////////////////////////////////////////
    // Project retrieval
    ////////////////////////////////////////////////////////////////

    /**
     * Gets a project name for a project ID.
     *
     * @@param    connection    A JDBC database connection
     * @@param    projectID       The projectID to obtain 
     * @@return     a String
     * @@exception    SQLException
     * @@exception    DataSetException
     */
    public String getProjectName (Connection connection, String projectID)
        throws SQLException, DataSetException, JoistDatabaseException
    {
        Record project = getProjectForID(connection, projectID);
        if (project != null)
        {
            return project.getValue(PROJECT_NAME).asString();
        }
        else
        {
            throw new JoistDatabaseException("No such project: " + projectID);
        }
    }

    /**
     * Retrieves the ID for a project with known name and domain
     *
     * @@param    connection    A JDBC database connection
     * @@param    domainId      Domain in which the project resides
     * @@param    projectName   The project name to identify
     * @@return     a String
     * @@exception    SQLException
     * @@exception    DataSetException
     */
    public String getProjectID (Connection connection, String domainID, 
                                String name)
        throws SQLException, DataSetException, JoistDatabaseException
    {
        Record project = getProjectForName(connection, domainID, name);
        if (project != null)
        {
            return project.getValue(PROJECT_ID).asString();
        }
        else
        {
            throw new JoistDatabaseException("Invalid domain/project: " + 
                                             domainID + '/' + name);
        }
    }
    
    /**
     * Given a projectID, find the associated domain name.
     *
     * @@param connection   A JDBC database connection
     * @@param projectID    The projectID whose domain will be found
     * @@return a String
     * @@exception DataSetException
     */
    public String getProjectDomain (Connection connection, String projectID)
        throws DataSetException, SQLException
    {
        Record project = getProjectForID(connection, projectID);
        String domainID;
        if (project != null)
            domainID = project.getValue(PROJECT_DOMAIN_ID).asString();
        else
            throw new DataSetException("bad projectID (no record): " + 
                    projectID);

        DomainManager domMgr = (DomainManager)dMgr
            .getManager("org.tigris.helm.database.DomainManager");
        try {
            return domMgr.getDomainName(domainID);
        } catch (JoistDatabaseException e) {
            log.exception(e);
            if (debug) log.debug("JoistDatabaseException in getProjectDomain");
            throw new DataSetException(e.getMessage());
        }
    }

    /**
     * Retrieves a Record containing the project specified by domain and name.
     *
     * @@param  connection    A JDBC database connection
     * @@param  domainID      Domain of the project to be retrieved
     * @@param  name          Name of the project to be retrieved
     * @@return The request project's data.
     * @@exception    SQLException
     * @@exception    DataSetException
     */
    public Record getProjectForName(Connection connection, String domainID, 
                                    String name)
        throws SQLException, DataSetException
    {
        Record project = null;
        DataSet projects = getProjects(null,           //order
                                       connection,     //connection
                                       null,           //projectID
                                       null,           //profile
                                       null,           //type
                                       domainID,       //domainID
                                       name,           //name
                                       null,           //aliasURL
                                       null,           //license
                                       null,           //shortDescription
                                       null,           //longDescription
                                       null,           //status
                                       null            //approvedBy
                                       );
        if (projects != null && projects.containsRecord(0))
        {
            project = projects.getRecord(0);
        }
        return project;
    }

    /**
     * Retrieves a DataSet containing the project specified by ID
     *
     * @@param  connection    A JDBC database connection
     * @@param  domainID      ID of the project to be retrieved
     * @@return The requested project's record.
     * @@exception    SQLException
     * @@exception    DataSetException
     */
    public Record getProjectForID(Connection connection, String projectID)
        throws SQLException, DataSetException
    {
        Record project = null;
        DataSet projects = getProjects(null,           //order
                                       connection,     //connection
                                       projectID,      //projectID
                                       null,           //profile
                                       null,           //type
                                       null,           //domainID
                                       null,           //name
                                       null,           //aliasURL
                                       null,           //license
                                       null,           //shortDescription
                                       null,           //longDescription
                                       null,           //status
                                       null            //approvedBy
                                       );
        if (projects != null && projects.containsRecord(0))
        {
            project = projects.getRecord(0);
        }
        return project;
    }
        
    /**
     * Retrieves a project from domain and alias URL.
     *
     * @@param    conn     The JDBC database connection use to.
     * @@param    domainID The ID of the domain (or <code>null</code>).
     * @@param    aliasURL The project alias URL.
     * @@return            The project for an alias URL.
     *
     * @@exception SQLException
     * @@exception DataSetException
     * @@exception JoistDatabaseException
     */
    // TODO: is domainID needed here? JER
    public Record getProjectForAliasURL (Connection conn, String domainID, 
                                         String aliasURL)
        throws SQLException, DataSetException, JoistDatabaseException
    {
        Record project = null;
        if (aliasURL != null && aliasURL.length() > 0)
        {
            TableDataSet projects = null;
            projects.where(buildWhereClause(null,      //projectID
                                            null,      //profile
                                            null,      //type
                                            domainID,  //domainID
                                            null,      //name
                                            aliasURL,  //aliasURL
                                            null,      //license
                                            null,      //shortDescription
                                            null,      //longDescription
                                            null,      //status
                                            null       //approvedBy
                                            ));
            try
            {
                projects = new TableDataSet(conn, TABLE_NAME);
                projects.fetchRecords();
                if (projects.size() > 1)
                {
                    throw new JoistDatabaseException("Duplicate alias URL for "
                                                     + "domain: " + aliasURL + 
                                                     " for " +domainID);
                }
                project = projects.getRecord(0);
            }
            finally
            {
                registerToClose(projects);
            }
        }
        return project;
    }

    /**
     * Retrieves a DataSet containing all regular projects for a domain.
     *
     * @@param  connection    A JDBC database connection.
     * @@param  domainID      The domain for which to get projects.
     * @@return a DataSet
     * @@exception    SQLException
     * @@exception DataSetException 
     */
    public DataSet getProjectsForDomain (Connection connection, 
                                         String domainID)
        throws SQLException, DataSetException
    {
        return getProjectsForDomainType(connection, domainID, 
                                        ProjectType.REGULAR);
    }

    public String getProjectsQuery()
    {
        return "SELECT * FROM " + TABLE_NAME;
    }

    public String getProjectsForDomainQuery(String domainID)
    {
        Criterion c = new Criterion(PROJECT_TYPE, ProjectType.REGULAR);
        c.and(new Criterion(PROJECT_DOMAIN_ID, domainID));
        String query = getProjectsQuery() + " WHERE " + c.toString();
        return query;
    }

    public String getProjectsNotInGroupQuery(String domainID, String groupID)
    {
        Criterion c = new Criterion(PROJECT_TYPE, ProjectType.REGULAR);
        c.and(new Criterion(PROJECT_DOMAIN_ID, domainID));
        c.and(new Criterion(ProjectProjectGroupManager.PROJECT_GROUP_ID,
                            Criterion.DOES_NOT_MATCH, groupID));
        
        String otherTable = ProjectProjectGroupManager.TABLE_NAME;
        StringBuffer q = new StringBuffer();
        q.append("SELECT ").append(TABLE_NAME).append(".* FROM ")
            .append(TABLE_NAME).append(", ").append(otherTable)
            .append(" WHERE ").append(TABLE_NAME).append('.').append(PROJECT_ID)
            .append('=').append(otherTable).append('.')
            .append(ProjectProjectGroupManager.PROJECT_ID).append(" AND ");
        q.append(c.toString());
                
        log.info("Project query: " + q.toString());
        return q.toString();
    }

    /**
     * Retrieves a DataSet containing all category projects for a domain.
     *
     * @@param  connection    A JDBC database connection.
     * @@param  domainID      The domain for which to get categories.
     * @@return a DataSet
     * @@exception    SQLException
     * @@exception DataSetException 
     */
    public DataSet getCategoriesForDomain (Connection connection, 
                                         String domainID)
        throws SQLException, DataSetException
    {
        return getProjectsForDomainType(connection, domainID, 
                                        ProjectType.CATEGORY);
    }

    /**
     * Retrieves a DataSet containing all projects for a domain and
     * a given type.
     *
     * @@param  connection    A JDBC database connection.
     * @@param  domainID      The domain for which to get projects.
     * @@param  type          The type of project to get.
     * @@return a DataSet
     * @@exception    SQLException
     * @@exception DataSetException 
     */
    public DataSet getProjectsForDomainType (Connection connection, 
                                             String domainID,
                                             String type)
        throws SQLException, DataSetException
    {
        return getProjects(PROJECT_NAME,           //order
                           connection,     //connection
                           null,           //projectID
                           null,           //profile
                           type,           //type
                           domainID,       //domainID
                           null,           //name
                           null,           //aliasURL
                           null,           //license
                           null,           //shortDescription
                           null,           //longDescription
                           null,           //status
                           null            //approvedBy
                           );
    }        

    /**
     * Retrieves a DataSet containing all projects on the site.
     *
     * @@param  connection    A JDBC database connection.
     * @@return a DataSet
     * @@exception    SQLException
     * @@exception DataSetException 
     */
    public DataSet getAllProjects (Connection connection)
        throws SQLException, DataSetException
    {
        return getProjects(PROJECT_NAME,           //order
                           connection,     //connection
                           null,           //projectID
                           null,           //profile
                           null,           //type
                           null,           //domainID
                           null,           //name
                           null,           //aliasURL
                           null,           //license
                           null,           //shortDescription
                           null,           //longDescription
                           null,           //status
                           null            //approvedBy
                           );
    }

    /**
     * Retrieves a DataSet containing all projects belonging to a
     * given category.
     *
     * @@param  connection    A JDBC database connection.
     * @@param  categoryID    The ID of the category to filter.
     * @@return a DataSet
     * @@exception    SQLException
     * @@exception DataSetException 
     */
    public DataSet getProjectsForCategory (Connection connection, 
                                           String categoryID)
        throws SQLException, DataSetException
    {
        String action = "Getting Projects for Domain Category: ";
        QueryDataSet projects = null;

        ProjectProjectGroupManager prjGrpMgr = (ProjectProjectGroupManager)
            dMgr.getManager("org.tigris.helm.database.ProjectProjectGroupManager");

        try
        {
            String otherTable = prjGrpMgr.TABLE_NAME;
            String otherProjectID = otherTable + "." + prjGrpMgr.joinBaseField;
            String otherCategoryID = otherTable + "." + prjGrpMgr.joinCompositeField;
            String projectID = TABLE_NAME + "." + PROJECT_ID;

            StringBuffer q = new StringBuffer();
            q.append("select ").append(TABLE_NAME).append(".* from ")
                .append(TABLE_NAME).append(", ").append(otherTable);
            q.append(" where ").append(projectID)
                .append("=").append(otherProjectID);
            q.append(" and ").append(otherCategoryID)
                .append("=").append(categoryID);

            projects = new QueryDataSet(connection, q.toString());

            projects.fetchRecords();
            
        }
        catch (DataSetException e)
        {
            log.exception(e);
            if (debug) log.debug(action + e.getMessage());
            throw e;
        }
        catch (SQLException e)
        {
            log.exception(e);
            if (debug) log.debug(action + e.getMessage());
            throw e;
        }
        finally
        {
            registerToClose(projects);
        }
        return projects;        
    }        

    /**
     * Retrieves a DataSet containing all categories belonging to a
     * given project.
     *
     * @@param  connection   A JDBC database connection.
     * @@param  projectID    The ID of the project for which to 
     *                       obtain categories.
     * @@return a DataSet
     * @@exception SQLException
     * @@exception DataSetException 
     */
    public DataSet getCategoriesForProject (Connection connection, 
                                           String projectID)
        throws SQLException, DataSetException
    {
        String action = "Getting Categories for Project: ";
        QueryDataSet categories = null;
        
        ProjectProjectGroupManager prjGrpMgr = (ProjectProjectGroupManager)
            dMgr.getManager("org.tigris.helm.database.ProjectProjectGroupManager");

	PreparedStatement stmt = null;        
        try
        {
            String groupTable = prjGrpMgr.TABLE_NAME;
            String groupProjectIDField = groupTable + "." + 
                prjGrpMgr.joinBaseField;
            String groupCategoryIDField = groupTable + "." + 
                prjGrpMgr.joinCompositeField;
            String projectIDField = TABLE_NAME + "." + 
                PROJECT_ID;
            String projectTypeField = TABLE_NAME + "." + 
                PROJECT_TYPE;

            StringBuffer q = new StringBuffer();
            q.append("select ").append(TABLE_NAME).append(".* from ")
                .append(TABLE_NAME).append(", ").append(groupTable);
            q.append(" where ").append(projectTypeField).append("='")
                .append(ProjectType.CATEGORY).append("'");
            q.append(" and ").append(groupProjectIDField).append("=")
                .append(projectID);
            q.append(" and ").append(projectIDField).append("=")
                .append(groupCategoryIDField);

            categories = new QueryDataSet(connection, q.toString());

            categories.fetchRecords();
            
        }
        catch (DataSetException e)
        {
            log.exception(e);
            if (debug) log.debug(action + e.getMessage());
            throw e;
        }
        catch (SQLException e)
        {
            log.exception(e);
            if (debug) log.debug(action + e.getMessage());
            throw e;
        }
        finally
        {
            registerToClose(categories);
        }
        return categories;        
    }        

    /**
     * Retrieves a DataSet containing unapproved projects for a domain.
     *
     * @@param  connection    A JDBC database connection.
     * @@param  domainID      The domain for which to get projects.
     * @@return a DataSet
     * @@exception    SQLException
     * @@exception DataSetException 
     */
    public DataSet getUnapprovedProjectsForDomain (Connection connection, 
                                                   String domainID)
        throws SQLException, DataSetException
    {
	// Get the userID for user "**Nobody"
	DataManager dMgr = getDataManager();
	UserManager uMgr =
	    (UserManager) dMgr.getManager("org.joist.database.UserManager");
	String nobodyUserID = null;
	try {
	    Record userRcd = uMgr.getUserForLoginID(connection, "**Nobody");
	    nobodyUserID = userRcd.getValue("userID").asString();
	}
	catch (JoistDatabaseException e) {
	    String message =
		"JoistDatabase problem in getUnapprovedProjectsForDomain: " +
		e.getMessage();
            if (debug) log.debug(message);
            throw new DataSetException(message);
	}
	catch (SQLException e) {
            if (debug) log.debug(
		"SQL problem in getUnapprovedProjectsForDomain: "
		+ e.getMessage());
            log.exception(e);
            throw e;
	}
        
	// Now look up the unapproved projects (i.e., APPROVED_BY "**Nobody")
        return getProjectsInDomainApprovedByUser (connection, domainID, 
                                                  nobodyUserID);
    }        

    /**
     * Retrieves a DataSet containing projects approved by a particular
     * user.
     *
     * @@param  connection    A JDBC database connection.
     * @@param  domainID      The domain for which to get projects.
     * @@return a DataSet
     * @@exception    SQLException
     * @@exception DataSetException 
     */
    public DataSet getProjectsInDomainApprovedByUser (Connection connection, 
                                                      String domainID,
                                                      String userID)
        throws SQLException, DataSetException
    {
        
        return getProjects(PROJECT_NAME,           //order
                           connection,     //connection
                           null,           //projectID
                           null,           //profile
                           null,           //type
                           domainID,       //domainID
                           null,           //name
                           null,           //aliasURL
                           null,           //license
                           null,           //shortDescription
                           null,           //longDescription
                           null,           //status
                           userID          //approvedBy
                           );
    }
       
    /**
     *  Retrieves projects by any of their fields
     *
     * @@param   connection        A JDBC database connection
     * @@param   projectID         A project ID
     * @@param   profile           A project profile
     * @@param   type              A project type
     * @@param   domainID          A project ID 
     * @@param   name              A project name
     * @@param   aliasURL          An alias URL
     * @@param   license           A license
     * @@param   shortDescription  A short description
     * @@param   longDescription   A long description
     * @@param   approvedBy        A user ID
     * @@return     a DataSet
     * @@exception    SQLException
     * @@exception    DataSetException
     */
    private TableDataSet getProjects(String order,
                                     Connection connection,
                                     String projectID,
                                     ProjectProfile profile,
                                     String type,
                                     String domainID,
                                     String name,
                                     String aliasURL,
                                     String license,
                                     String shortDescription,
                                     String longDescription,
                                     String status,
                                     String approvedBy)
        throws SQLException, DataSetException
    {
        String action = "Getting Projects: ";
        TableDataSet projects = null;

        try
        {
            projects = new TableDataSet(connection, TABLE_NAME, 
                                        new KeyDef().addAttrib(PROJECT_ID));
            projects.where(buildWhereClause(projectID,        //projectID
                                            profile,          //profile
                                            type,             //type
                                            domainID,         //domainID
                                            name,             //name
                                            aliasURL,         //aliasURL
                                            license,          //license
                                            shortDescription, //shortDescription
                                            longDescription,  //longDescription
                                            status,           //status
                                            approvedBy        //approvedBy
                                            ));
            if (order != null)
            {
                projects.order(order);
            }
            projects.fetchRecords();
        }
        catch (DataSetException e)
        {
            log.exception(e);
            if (debug) log.debug(action + e.getMessage());
            throw e;
        }
        catch (SQLException e)
        {
            log.exception(e);
            if (debug) log.debug(action + e.getMessage());
            throw e;
        }
        finally
        {
            registerToClose(projects);
        }
        return projects;
    }
    
    /**
     * Creates a SQL <code>where</code> clause.
     */
    protected static String buildWhereClause (String projectID, 
                                              ProjectProfile profile,
                                              String type,
                                              String domainID,
                                              String name,
                                              String aliasURL,
                                              String license,
                                              String shortDescription,
                                              String longDescription,
                                              String status,
                                              String approvedBy
                                              )
    {
        StringBuffer whereClause = new StringBuffer();
        
        boolean firstclause = true;

        if (projectID != null)
        {
            whereClause.append(PROJECT_ID).append('=').append(projectID);
            firstclause = false;
        }

        if (profile != null)
        {
            if (!firstclause)
            {
                whereClause.append(" AND ");
            }
            whereClause.append(PROJECT_PROFILE).append('=');
            whereClause.append(escapeAndQuoteSQL(profile.getKey()));
            firstclause = false;
        }

        if (type != null)
        {
            if (!firstclause)
            {
                whereClause.append(" AND ");
            }
            whereClause.append(PROJECT_TYPE).append('=');
            whereClause.append(escapeAndQuoteSQL(type));
            firstclause = false;
        }

        if (domainID != null)
        {
            if (!firstclause)
            {
                whereClause.append(" AND ");
            }
            firstclause = false;
            whereClause.append(PROJECT_DOMAIN_ID).append('=').append(domainID);
        }

        if (name != null)
        {
            if (!firstclause)
            {
                whereClause.append(" AND ");
            }
            firstclause = false;
            whereClause.append("LOWER(").append(PROJECT_NAME)
                .append(")=LOWER(").append(escapeAndQuoteSQL(name))
                .append(')');
        }

        if (aliasURL != null)
        {
            if (!firstclause)
            {
                whereClause.append(" AND ");
            }
            firstclause = false;
            whereClause.append(PROJECT_ALIAS_URL).append('=')
                .append(escapeAndQuoteSQL(aliasURL));
        }

        if (license != null)
        {
            if (!firstclause)
            {
                whereClause.append(" AND ");
            }
            firstclause = false;
            whereClause.append(PROJECT_LICENSE).append('=')
                .append(escapeAndQuoteSQL(license));
        }

        if (shortDescription != null)
        {
            if (!firstclause)
            {
                whereClause.append(" AND ");
            }
            firstclause = false;
            whereClause.append(PROJECT_SHORT_DESCRIPTION).append(" LIKE ")
                .append(escapeAndQuoteSQL("*" + shortDescription + "*"));
        }
        
        if (longDescription != null)
        {
            if (!firstclause)
            {
                whereClause.append(" AND ");
            }
            firstclause = false;
            whereClause.append(PROJECT_LONG_DESCRIPTION).append(" LIKE ")
                .append(escapeAndQuoteSQL("*" + longDescription + "*"));
        }

        if (status != null)
        {
            if (!firstclause)
            {
                whereClause.append(" AND ");
            }
            firstclause = false;
            status = escapeAndQuoteSQL(status);
            whereClause.append(PROJECT_STATUS).append('=');
            whereClause.append(status);
        }

        if (approvedBy != null)
        {
            if (!firstclause)
            {
                whereClause.append(" AND ");
            }
            firstclause = false;
            whereClause.append(PROJECT_APPROVED_BY).append('=')
		.append(approvedBy);
        }

        return whereClause.toString();
    }
}
@


1.57
log
@readding all the files as part of the process of returning to the way
things were as of tuesday
@
text
@@


1.57.2.1
log
@Porting to the Turbine Peer system.  -dlr and leonardr
@
text
@@


1.56
log
@revert this stuff to its state as of 2001/01/24 12:42:00 GMT -- with
the following exceptions, which have some different modifications so
they'll work with changes which have happened in joist:

ProjectNewsEdit.java
SkinManager.java
SkinStyleElementValueManager.java
StyleElementManager.java
StyleManager.java

it compiles.  i dunno if it works, though.
@
text
@d310 1
a310 1
                    throw new Exception("Could not obtain hostProjectID");
d408 1
a408 1

d416 1
a416 1
        super(dataMgr, new KeyDef().addAttrib(PROJECT_ID));
a419 33
    public String getProjectsQuery()
    {
        return "SELECT * FROM " + TABLE_NAME;
    }

    public String getProjectsForDomainQuery(String domainID)
    {
        Criterion c = new Criterion(PROJECT_TYPE, ProjectType.REGULAR);
        c.and(new Criterion(PROJECT_DOMAIN_ID, domainID));
        String query = getProjectsQuery() + " WHERE " + c.toString();
        return query;
    }

    public String getProjectsNotInGroupQuery(String domainID, String groupID)
    {
        Criterion c = new Criterion(PROJECT_TYPE, ProjectType.REGULAR);
        c.and(new Criterion(PROJECT_DOMAIN_ID, domainID));
        c.and(new Criterion(ProjectProjectGroupManager.PROJECT_GROUP_ID,
                            Criterion.DOES_NOT_MATCH, groupID));
        
        String otherTable = ProjectProjectGroupManager.TABLE_NAME;
        StringBuffer q = new StringBuffer();
        q.append("SELECT ").append(TABLE_NAME).append(".* FROM ")
            .append(TABLE_NAME).append(", ").append(otherTable)
            .append(" WHERE ").append(TABLE_NAME).append('.').append(PROJECT_ID)
            .append('=').append(otherTable).append('.')
            .append(ProjectProjectGroupManager.PROJECT_ID).append(" AND ");
        q.append(c.toString());
                
        log.info("Project query: " + q.toString());
        return q.toString();
    }

d455 1
d460 2
a461 2
    public boolean isApproved(String projectID)
        throws DBException
d463 6
a468 20
        boolean approved = false;
        String approvedBy = null;
        try {
            Record r = getProjectForID(projectID);
            approvedBy = r.getValue(PROJECT_APPROVED_BY).asString();
        } catch (DataSetException e) {
            throw new DBException(e);
        } catch (SQLException e) {
            throw new DBException(e);
        }

        UserManager uMgr = (UserManager)dMgr.getManager
            ("org.tigris.helm.database.UserManager");
        String nobodyUserID = uMgr.getNobodyUserID();
        if (approvedBy != null && !approvedBy.equals(nobody))
        {
            approved = true;
        }

        return approved;
d474 7
a480 4
    public void assertProjectNonexistance(String domainID, String name)
        throws AlreadyExists, DBException
    {
        Record project = getProjectForName(domainID, name);
d483 1
a483 2
           throw new AlreadyExists("Project in domain + " domainID 
                                   + " with name " + name);
d485 1
d496 1
d509 3
a511 1
     * @@exception AlreadyExists if a project in this domain with this name exists.
d513 2
a514 1
    public Record addProject (ProjectProfile profile,
d525 18
a542 20
        throws AlreadyExists, DBException
    {        
        Record p = null;
        assertProjectNonexistance(domainID, name);
        try {
            p = updateProject(null,             //projectID
                              profile,          //profile
                              domainID,         //domainID
                              name,             //name
                              license,          //license
                              shortDescription, //shortDescription
                              longDescription,  //longDescription
                              useIndex,         //useIndex
                              status,           //status
                              aliasURL,         //aliasURL
                              proposedBy,       //proposedBy
                              approvedBy        //approvedBy
                              );
        } catch (DoesNotExist ignore) {}
        return p;
d553 1
d558 2
a559 2
     * @@exception DBException if a database error occurs.
     * @@exception DoesNotExist if the specified project is invalid.
d561 11
a571 10
    public void approveProject(String projectID, String userID)
        throws DBException, DoesNotExist
    {
        Record project = getProjectForID(projectID);
        try {
            project.setValue(PROJECT_APPROVED_BY, userID);
            project.save();
        } catch (DataSetException e) {
            throw new DBException
        }
d581 1
d583 3
d592 1
d595 3
a597 2
     * @@exception DBException if a database error occurs.
     * @@exception DoesNotExist if the specified project is invalid.
d599 2
a600 1
    public void updateProjectInfo(String projectID,
d608 2
a609 1
        throws DoesNotExist, DBException
d611 2
a612 1
        updateProject(projectID,        //projectID
d634 1
d656 2
a657 1
    private Record updateProject (String projectID, 
d669 2
a670 1
        throws DoesNotExist, DBException
a671 2

        DBConnection dbConn = null;
d674 1
a674 6

        try {
            dbConn = TurbineDB.getConnection();
        } catch (Exception e) {
            throw new DBException(e);
        }
a678 4
            projects = new TableDataSet(dbconn.getConnection(), 
                                        TABLE_NAME, keydef);
            project = downloads.addRecord();

d681 1
a681 2
            profile = null; //Profile is immutable.
            project = getProjectForID(projectID);
d684 20
a703 1
        try {
d707 1
a707 1
            
d709 1
a709 1
            
d715 1
a715 1
            
d718 1
a718 1
            
d721 1
a721 1
            
d724 1
a724 1
            
d727 1
a727 1
            
a737 1

d750 15
a764 5
        } catch (DataSetException e) {
            throw new DBException(e);
        } catch (SQLException e) {
            throw new DBException(e);
        } finally {
a765 5
            try {
                TurbineDB.releaseConnection(dbConn);
            } catch (Exception e) {
                throw new DBException(e);
            }
d771 4
a774 2
    public Record setLicense (String projectID, String license)
        throws DoesNotExist, DBException
d777 1
a777 1
        Record project = getProjectForID(projectID);
d780 1
a780 6
        String oldLicense = null;
        try {
            oldLicense = project.getValue(PROJECT_LICENSE).asString();
        } catch (DataSetException e) {
            throw new DBException(e);
        }
a784 1

d787 1
a787 1
            
d790 1
a790 1
        /**
d799 2
a800 8
        try {
            project.setValue(PROJECT_LICENSE, license);
            project.save();
        } catch (DataSetException e) {
            throw new DBException(e);
        } catch (SQLException e) {
            throw new DBException(e);
        }
d809 1
a809 6
            String domainID = null;
            try {
                domainID = project.getValue(PROJECT_DOMAIN_ID).asString();
            } catch (DataSetException e) {
                throw new DBException(e);
            }
d811 1
a811 1
            Project p = new Project(dMgr, projectID);
d818 1
a818 1
                ProjectGroup.removeFromPublicGroup(dMgr, p, domainID);
d826 1
a826 1
                ProjectGroup.addToPublicGroup(dMgr, p, domainID);
d840 1
d842 1
a842 1
     * @@exception DBException if a database error occurs.
d844 2
a845 2
    public void  deleteProject (String projectID)
        throws DBException
d847 3
a849 1
        Record project = getProjectForID(projectID);
d864 2
a865 1
     * @@param    projectID       The projectID to obtain the name for
d867 2
a868 2
     * @@exception    DBException if a database error occurs.
     * @@exception    DoesNotExist if the projectID is invalid.
d870 2
a871 2
    public String getProjectName (String projectID)
        throws DBException, DoesNotExist
d873 8
a880 6
        Record project = getProjectForID(projectID);
        String name = null;
        try {
            name = project.getValue(PROJECT_NAME).asString();
        } catch (DataSetException e) {
            throw new DBException(e);
a881 1
        return name;
d891 2
a892 3
     *
     * @@exception    DBException if a database error occurs.
     * @@exception    DoesNotExist if the projectID is invalid.
d894 3
a896 2
    public String getProjectID (String domainID, String name)
        throws DBException, DoesNotExist
d898 9
a906 6
        Record project = getProjectForName(domainID, name);
        String name = null;
        try {
            name = project.getValue(PROJECT_NAME).asString();
        } catch (DataSetException e) {
            throw new DBException(e);
a907 1
        return name;
d913 1
d916 1
a916 3
     *
     * @@exception    DBException if a database error occurs.
     * @@exception    DoesNotExist if the projectID is invalid.
d918 6
a923 8
        public String getProjectDomain (String projectID)
        throws DBException, DoesNotExist
        {
            String domainName = null;
        String domainID = null;
        Record project = getProjectForID(projectID);

        try {            
d925 3
a927 3
        } catch (DataSetException e) {
            throw new DBException(e);
        }
d931 7
a937 2
        domainName = domMgr.getDomainName(domainID);
        return domainName;
d941 1
a941 1
     * Retrieves a DataSet containing the project specified by ID
d944 9
a952 8
     * @@param  domainID      ID of the project to be retrieved
     * @@return The requested project's record.
     *
     * @@exception    DBException if a database error occurs.
     * @@exception    DoesNotExist if there is no such proejct.
     */
    public Record getProjectForID(Connection connection, String projectID)
            throws DBException, DoesNotExist
d954 16
a969 4
        Criterion c = new Criterion (PROJECT_ID, domainID);
        c.and(new Criterion(PROJECT_NAME, name);
        Record project = getFirstMatchingRecord(c);
        if (project == null)
d971 1
a971 1
            throw new DoesNotExist("Project with id " + projectID));
d975 1
a975 1
    
d977 1
a977 1
     * Retrieves a Record containing the project specified by domain and name.
d979 2
a980 2
     * @@param  domainID      Domain of the project to be retrieved
     * @@param  name          Name of the project to be retrieved
d982 2
a983 2
     * @@exception    DBException if a database error occurs.
     * @@exception    DoesNotExist if there is no such proejct.
d985 2
a986 2
    public Record getProjectForName(String domainID, String name)
        throws DBException, DoesNotExist
d988 16
a1003 4
        Criterion c = new Criterion (PROJECT_DOMAIN_ID, domainID);
        c.and(new Criterion(PROJECT_NAME, name));
        Record project = getFirstMatchingRecord(c);
        if (project == null)
d1005 1
a1005 2
            throw new DoesNotExist("Project with name " + name 
                                   + " in domain " + domainID);
d1009 1
a1009 1
    
d1011 1
a1011 1
     * Retrieves a project from alias URL.
d1013 1
d1018 3
a1020 2
     * @@exception    DBException if a database error occurs.
     * @@exception    DoesNotExist if there is no such proejct.
d1022 4
a1025 2
    public Record getProjectForAliasURL (String aliasURL)
            throws DBException, DoesNotExist
d1030 14
a1043 2
            DataSet projects = getRecords(c);
            if (projects.size() > 1)
d1045 7
a1051 6
                throw new DBException("Duplicate alias URL: " + aliasURL);
            } else {
                try {
                    project = projects.getRecord(0);
                } catch (DataSetException e) {
                    throw new DBException(e);
d1053 5
d1066 1
d1069 2
a1070 2
     *
     * @@exception    DBException if a database error occurs.
d1072 9
a1080 2
    public DataSet getProjectsForDomain (String domainID)
        throws DBException
d1082 29
a1110 1
        return getProjectsForDomainType(domainID, ProjectType.REGULAR);
d1116 1
d1119 2
a1120 1
     * @@exception    DBException if a database error occurs.
d1122 3
a1124 2
    public DataSet getCategoriesForDomain (String domainID)
        throws DBException
d1126 2
a1127 1
        return getProjectsForDomainType(domainID, ProjectType.CATEGORY);
d1134 1
d1138 2
a1139 1
     * @@exception    DBException if a database error occurs.
d1141 19
a1159 6
    public DataSet getProjectsForDomainType (String domainID, String type)
        throws DBException
    {
        Criterion c = new Criterion(PROJECT_DOMAIN_ID, domainID);
        c.and(new Criterion(PROJECT_TYPE, type));
        return getRecords(c);
d1165 1
d1167 2
a1168 79
     * @@exception    DBException if a database error occurs.
     */
    public DataSet getAllProjects ()
        throws DBException
    {
        return getRecords(null);
    }


    /**
     * Retrieves a DataSet containing unapproved projects for a domain.
     *
     * @@param  domainID      The domain for which to get projects.
     * @@return a DataSet
     * @@exception    DBException if a database error occurs.
     */
    public DataSet getUnapprovedProjectsForDomain (String domainID)
        throws DBException
    {
	// Get the userID for user "**Nobody"
	UserManager uMgr =(UserManager) getDataManager().getManager
            ("org.tigris.helm.database.UserManager");
	String nobodyUserID  = uMgr.getNobodyUserID();
        
	// Now look up the unapproved projects (i.e., APPROVED_BY "**Nobody")
        return getProjectsInDomainApprovedByUser (domainID, nobodyUserID);
    }        

    /**
     * Retrieves a DataSet containing projects approved by a particular
     * user.
     *
     * @@param  domainID      The domain for which to get projects.
     * @@return a DataSet
     * @@exception    DBException if a database error occurs.
     */
    public DataSet getProjectsInDomainApprovedByUser 
        (String domainID, String userID)
        throws DBException
    {        
        Criterion c = new Criterion(PROJECT_DOMAIN_ID, domainID);
        c.add(new Criterion(PROJECT_APPROVED_BY, userID));
        return getRecords(c);
    }

    
    /**
     * Returns the first record matching a given Criterion. 
     *
     * @@param criterion Criterion to use in select.
     *
     * @@exception DBException if a database error occurs.
     *
     * @@return Null if no matching record, first record in recordset
     * otherwise.  
     */
    private Record getFirstMatchingRecord(Criterion criterion)
        throws DBException
    {
        Record r = null;
        try {
            DataSet s = getRecords(criterion);
            if (s != null && s.containsRecord(0))
            {
                r = s.getRecord(0);
            }
        } catch (DataSetException e) {
            throw new DBException(e);
        }

        return r;
    }

    /**
     * Returns records matching a given Criterion.
     *
     * @@param criterion Criterion to use in select.
     *
     * @@exception DBException if a database error occurs.
d1170 2
a1171 2
    public DataSet getRecords(Criterion criterion)
    throws DBException
d1173 14
a1186 7
        DataSet s = null;
        try {
            s = runSelect(tableName, criterion, PROJECT_NAME);
        } catch (Exception e) {
            throw new DBException(e);
        }
        return s;
d1193 1
d1196 2
a1197 1
     * @@exception    DBException if a database error occurs.
d1199 3
a1201 2
    public DataSet getProjectsForCategory (String categoryID)
        throws DBException
d1228 15
a1242 5
        } catch (DataSetException e) {
            throw new DBException(e);
        } catch (SQLException e) {
            throw new DBException(e);
        } finally {
d1249 2
a1250 2
     * Retrieves a DataSet containing all categories in which a
     * given project resides.
d1252 1
a1254 1
     * @@exception    DBException if a database error occurs.
d1256 2
d1259 3
a1261 2
    public DataSet getCategoriesForProject (String projectID)
        throws DBException
d1296 15
a1310 5
        } catch (DataSetException e) {
            throw new DBException(e);
        } catch (SQLException e) {
            throw new DBException(e);
        } finally {
d1314 292
a1605 1
    }               
@


1.55
log
@More converted TableManagers.
@
text
@@


1.54
log
@Added basic record obtaining methods.
@
text
@d776 1
a781 1
            registerToClose(projects);
d1024 1
a1024 1
            DataSet projects = getMatchingRecords(c);
d1080 1
a1080 1
        return getMatchingRecords(c);
d1092 1
a1092 1
        return getMatchingRecords(null);
d1129 1
a1129 1
        return getMatchingRecords(c);
@


1.53
log
@More TableManagers de-connectionified.
@
text
@d1132 47
@


1.52
log
@Moved TableManagers to new keydef constructor and keydef-less runSelect.
@
text
@d420 33
a487 1
     * @@param connection A database connection.
d492 1
a492 1
    public boolean isApproved(Connection connection, String projectID)
d495 20
a514 6
        Record r = getProjectForID(connection, projectID);
        String approvedBy = r.getValue(PROJECT_APPROVED_BY).asString();
        log.info("Approved by " + approvedBy);
        UserUserGroupManager usrGrpMgr = (UserUserGroupManager)
            dMgr.getManager("org.tigris.helm.database.UserUserGroupManager");
        return (!approvedBy.equals(usrGrpMgr.getNobodyUserID(connection)));
d520 1
a520 2
    public boolean assertProjectNonexistance(Connection connection, 
                                             String domainID, String name)
d523 1
a523 3
        boolean alreadyExists = false;
	
        Record project = getProjectForName(connection, domainID, name);
d526 2
a527 1
	   alreadyExists = true;
a528 1
	 return alreadyExists;
a538 1
     * @@param connection        The JDBC database connection to use.
d551 1
a551 3
     * @@exception SQLException
     * @@exception DataSetException 
     * @@exception UpdateException
d553 1
a553 2
    public Record addProject (Connection connection,
                              ProjectProfile profile,
d564 20
a583 17
        throws DoesNotExist, AlreadyExists, DBException
    {
        
        return updateProject(connection, 
                             null,             //projectID
                             profile,          //profile
                             domainID,         //domainID
                             name,             //name
                             license,          //license
                             shortDescription, //shortDescription
                             longDescription,  //longDescription
                             useIndex,         //useIndex
                             status,           //status
                             aliasURL,         //aliasURL
                             proposedBy,       //proposedBy
                             approvedBy        //approvedBy
                             );
a593 1
     * @@param connection  The JDBC database connection to use.
d598 2
a599 2
     * @@exception SQLException
     * @@exception DataSetException 
d601 2
a602 4
    public void approveProject(Connection connection,
                               String projectID,
                               String userID)
        throws DBException
d604 7
a610 6
        Record project = getProjectForID(connection, projectID);
        project.setValue(PROJECT_APPROVED_BY, userID);
        String status = project.getValue(PROJECT_STATUS).asString();
        String license = project.getValue(PROJECT_LICENSE).asString();
        String domainID = project.getValue(PROJECT_DOMAIN_ID).asString();
        project.save();
a619 1
     * @@param connection        The JDBC database connection to use.
a620 3
     * @@param profile           Profile of the project to be created.
     * @@param domainID          ID of domain in which the project resides.
     * @@param name              Name of the project.
a626 1
     * @@param categoryID        Category ID of this project
d629 2
a630 3
     * @@exception SQLException
     * @@exception DataSetException 
     * @@exception JoistDatabaseException
d632 1
a632 2
    public void updateProjectInfo(Connection connection,
                                  String projectID,
d642 1
a642 2
        updateProject(connection,
                      projectID,        //projectID
a663 1
     * @@param connection        The JDBC database connection to use.
d685 1
a685 2
    private Record updateProject (Connection connection,
                                  String projectID, 
d699 2
d703 6
a708 1
        String action = null;
d713 4
d719 2
a720 1
            profile = null; //Immutable.
d723 1
a723 19
        try
        {
            projects = new TableDataSet(connection, TABLE_NAME, keydef);

            if (projectID != null)
            {
                // Updating an existing project; get it.
                projects.where(PROJECT_ID + '=' + projectID);                
                projects.fetchRecords(1);
                if (debug) log.debug("Getting Record for existing project");
                project = projects.getRecord(0);
            }
            else
            {
                // Adding a new project.
                if (debug) log.debug("Adding Record for new project");
                project = projects.addRecord();
            }

d727 1
a727 1

d729 1
a729 1

d735 1
a735 1

d738 1
a738 1

d741 1
a741 1

d744 1
a744 1

d747 1
a747 1

d758 1
d771 1
a771 3
        }
        catch (DataSetException e)
        {
d773 1
a773 3
        }
        catch (SQLException e)
        {
d775 6
a780 3
        }
        finally
        {
d787 1
a787 2
    public Record setLicense (Connection connection, String projectID, 
                              String license)
d791 1
a791 1
        Record project = getProjectForID(connection, projectID);
d794 6
a799 1
        String oldLicense = project.getValue(PROJECT_LICENSE).asString();
d804 1
d807 1
a807 1

d810 1
a810 1
        /*
d819 8
a826 2
        project.setValue(PROJECT_LICENSE, license);
        project.save();
d835 6
a840 1
            String domainID = project.getValue(PROJECT_DOMAIN_ID).asString();
d842 1
a842 1
            Project p = new Project(connection, dMgr, projectID);
d849 1
a849 1
                ProjectGroup.removeFromPublicGroup(connection, dMgr, p, domainID);
d857 1
a857 1
                ProjectGroup.addToPublicGroup(connection, dMgr, p, domainID);
a870 1
     * @@param      connection    the JDBC database connection
d872 1
a872 1
     * @@exception SQLException
d874 1
a874 1
    public void  deleteProject (Connection connection, String projectID)
d877 1
a877 3
        String action = "Deleting Project";

        Record project = getProjectForID(connection, projectID);
d892 1
a892 2
     * @@param    connection    A JDBC database connection
     * @@param    projectID       The projectID to obtain 
d894 2
a895 2
     * @@exception    SQLException
     * @@exception    DataSetException
d897 2
a898 2
    public String getProjectName (Connection connection, String projectID)
        throws DBException
d900 6
a905 8
        Record project = getProjectForID(connection, projectID);
        if (project != null)
        {
            return project.getValue(PROJECT_NAME).asString();
        }
        else
        {
            throw new DBException("No such project: " + projectID);
d907 1
d918 2
a919 1
     * @@exception DBException
d921 2
a922 3
    public String getProjectID (Connection connection, String domainID, 
                                String name)
        throws DBException
d924 6
a929 9
        Record project = getProjectForName(connection, domainID, name);
        if (project != null)
        {
            return project.getValue(PROJECT_ID).asString();
        }
        else
        {
            throw new DBException("Invalid domain/project: " + 
                                  domainID + '/' + name);
d931 1
a936 1
     * @@param connection   A JDBC database connection
d940 2
a941 1
     * @@exception DBException
d943 8
a950 6
    public String getProjectDomain (Connection connection, String projectID)
        throws DBException
    {
        Record project = getProjectForID(connection, projectID);
        String domainID;
        if (project != null)
d952 3
a954 2
        else
            throw new DBException("bad projectID (no record): " + projectID);
d958 2
a959 5
        try {
            return domMgr.getDomainName(domainID);
        } catch (JoistDatabaseException e) {
            throw new DBException(e);
        }
d963 1
a963 1
     * Retrieves a Record containing the project specified by domain and name.
d966 5
a970 5
     * @@param  domainID      Domain of the project to be retrieved
     * @@param  name          Name of the project to be retrieved
     * @@return The request project's data.
     * @@exception    SQLException
     * @@exception    DataSetException
d972 2
a973 3
    public Record getProjectForName(Connection connection, String domainID, 
                                    String name)
        throws DBException
d975 4
a978 16
        Record project = null;
        DataSet projects = getProjects(null,           //order
                                       connection,     //connection
                                       null,           //projectID
                                       null,           //profile
                                       null,           //type
                                       domainID,       //domainID
                                       name,           //name
                                       null,           //aliasURL
                                       null,           //license
                                       null,           //shortDescription
                                       null,           //longDescription
                                       null,           //status
                                       null            //approvedBy
                                       );
        if (projects != null && projects.containsRecord(0))
d980 1
a980 1
            project = projects.getRecord(0);
d984 1
a984 1

d986 1
a986 1
     * Retrieves a DataSet containing the project specified by ID
d988 2
a989 2
     * @@param  connection    A JDBC database connection
     * @@param  domainID      ID of the project to be retrieved
d991 2
a992 2
     *
     * @@exception DBException
d994 2
a995 2
    public Record getProjectForID(Connection connection, String projectID)
        throws DBException
d997 4
a1000 16
        Record project = null;
        DataSet projects = getProjects(null,           //order
                                       connection,     //connection
                                       projectID,      //projectID
                                       null,           //profile
                                       null,           //type
                                       null,           //domainID
                                       null,           //name
                                       null,           //aliasURL
                                       null,           //license
                                       null,           //shortDescription
                                       null,           //longDescription
                                       null,           //status
                                       null            //approvedBy
                                       );
        if (projects != null && projects.containsRecord(0))
d1002 2
a1003 1
            project = projects.getRecord(0);
d1007 1
a1007 1
        
d1009 1
a1009 1
     * Retrieves a project from domain and alias URL.
a1010 1
     * @@param    conn     The JDBC database connection use to.
d1015 2
a1016 3
     * @@exception SQLException
     * @@exception DataSetException
     * @@exception JoistDatabaseException
d1018 2
a1019 4
    // TODO: is domainID needed here? JER
    public Record getProjectForAliasURL (Connection conn, String domainID, 
                                         String aliasURL)
        throws DBException
d1024 2
a1025 14
            TableDataSet projects = null;
            projects.where(buildWhereClause(null,      //projectID
                                            null,      //profile
                                            null,      //type
                                            domainID,  //domainID
                                            null,      //name
                                            aliasURL,  //aliasURL
                                            null,      //license
                                            null,      //shortDescription
                                            null,      //longDescription
                                            null,      //status
                                            null       //approvedBy
                                            ));
            try
d1027 6
a1032 8
                projects = new TableDataSet(conn, TABLE_NAME);
                projects.fetchRecords();
                if (projects.size() > 1)
                {
                    // NOTE: Used to throw JoistDatabaseException.
                    throw new DBException("Duplicate alias URL for "
                                          + "domain: " + aliasURL + 
                                          " for " +domainID);
a1033 5
                project = projects.getRecord(0);
            }
            finally
            {
                registerToClose(projects);
a1041 1
     * @@param  connection    A JDBC database connection.
d1045 1
a1045 1
     * @@exception DBException 
d1047 1
a1047 2
    public DataSet getProjectsForDomain (Connection connection, 
                                         String domainID)
d1050 1
a1050 35
        return getProjectsForDomainType(connection, domainID, 
                                        ProjectType.REGULAR);
    }

    public String getProjectsQuery()
    {
        return "SELECT * FROM " + TABLE_NAME;
    }

    public String getProjectsForDomainQuery(String domainID)
    {
        Criterion c = new Criterion(PROJECT_TYPE, ProjectType.REGULAR);
        c.and(new Criterion(PROJECT_DOMAIN_ID, domainID));
        String query = getProjectsQuery() + " WHERE " + c.toString();
        return query;
    }

    public String getProjectsNotInGroupQuery(String domainID, String groupID)
    {
        Criterion c = new Criterion(PROJECT_TYPE, ProjectType.REGULAR);
        c.and(new Criterion(PROJECT_DOMAIN_ID, domainID));
        c.and(new Criterion(ProjectProjectGroupManager.PROJECT_GROUP_ID,
                            Criterion.DOES_NOT_MATCH, groupID));
        
        String otherTable = ProjectProjectGroupManager.TABLE_NAME;
        StringBuffer q = new StringBuffer();
        q.append("SELECT ").append(TABLE_NAME).append(".* FROM ")
            .append(TABLE_NAME).append(", ").append(otherTable)
            .append(" WHERE ").append(TABLE_NAME).append('.').append(PROJECT_ID)
            .append('=').append(otherTable).append('.')
            .append(ProjectProjectGroupManager.PROJECT_ID).append(" AND ");
        q.append(c.toString());
                
        log.info("Project query: " + q.toString());
        return q.toString();
a1055 1
     * @@param  connection    A JDBC database connection.
d1058 1
a1058 2
     * @@exception    SQLException
     * @@exception DataSetException 
d1060 1
a1060 2
    public DataSet getCategoriesForDomain (Connection connection, 
                                         String domainID)
d1063 1
a1063 2
        return getProjectsForDomainType(connection, domainID, 
                                        ProjectType.CATEGORY);
a1069 1
     * @@param  connection    A JDBC database connection.
d1073 1
a1073 2
     * @@exception    SQLException
     * @@exception DataSetException 
d1075 1
a1075 3
    public DataSet getProjectsForDomainType (Connection connection, 
                                             String domainID,
                                             String type)
d1078 3
a1080 14
        return getProjects(PROJECT_NAME,           //order
                           connection,     //connection
                           null,           //projectID
                           null,           //profile
                           type,           //type
                           domainID,       //domainID
                           null,           //name
                           null,           //aliasURL
                           null,           //license
                           null,           //shortDescription
                           null,           //longDescription
                           null,           //status
                           null            //approvedBy
                           );
a1085 1
     * @@param  connection    A JDBC database connection.
d1087 15
a1101 2
     * @@exception    SQLException
     * @@exception DataSetException 
d1103 1
a1103 1
    public DataSet getAllProjects (Connection connection)
d1106 24
a1129 14
        return getProjects(PROJECT_NAME,           //order
                           connection,     //connection
                           null,           //projectID
                           null,           //profile
                           null,           //type
                           null,           //domainID
                           null,           //name
                           null,           //aliasURL
                           null,           //license
                           null,           //shortDescription
                           null,           //longDescription
                           null,           //status
                           null            //approvedBy
                           );
a1135 1
     * @@param  connection    A JDBC database connection.
d1138 1
a1138 2
     * @@exception    SQLException
     * @@exception DataSetException 
d1140 1
a1140 2
    public DataSet getProjectsForCategory (Connection connection, 
                                           String categoryID)
d1168 5
a1172 15
        }
        catch (DataSetException e)
        {
            log.exception(e);
            if (debug) log.debug(action + e.getMessage());
            throw e;
        }
        catch (SQLException e)
        {
            log.exception(e);
            if (debug) log.debug(action + e.getMessage());
            throw e;
        }
        finally
        {
d1179 2
a1180 2
     * Retrieves a DataSet containing all categories belonging to a
     * given project.
a1181 1
     * @@param  connection   A JDBC database connection.
d1184 1
a1185 2
     * @@exception SQLException
     * @@exception DataSetException 
d1187 1
a1187 2
    public DataSet getCategoriesForProject (Connection connection, 
                                           String projectID)
d1223 5
a1227 15
        }
        catch (DataSetException e)
        {
            log.exception(e);
            if (debug) log.debug(action + e.getMessage());
            throw e;
        }
        catch (SQLException e)
        {
            log.exception(e);
            if (debug) log.debug(action + e.getMessage());
            throw e;
        }
        finally
        {
d1231 1
a1231 275
    }        

    /**
     * Retrieves a DataSet containing unapproved projects for a domain.
     *
     * @@param  connection    A JDBC database connection.
     * @@param  domainID      The domain for which to get projects.
     * @@return a DataSet
     * @@exception    SQLException
     * @@exception DataSetException 
     */
    public DataSet getUnapprovedProjectsForDomain (Connection connection, 
                                                   String domainID)
        throws DBException
    {
	// Get the userID for user "**Nobody"
	DataManager dMgr = getDataManager();
	UserManager uMgr =
	    (UserManager) dMgr.getManager("org.tigris.helm.database.UserManager");
	String nobodyUserID = null;
        Record userRcd = uMgr.getUserForLoginID("**Nobody");
        nobodyUserID = userRcd.getValue("userID").asString();
        
	// Now look up the unapproved projects (i.e., APPROVED_BY "**Nobody")
        return getProjectsInDomainApprovedByUser (connection, domainID, 
                                                  nobodyUserID);
    }        

    /**
     * Retrieves a DataSet containing projects approved by a particular
     * user.
     *
     * @@param  connection    A JDBC database connection.
     * @@param  domainID      The domain for which to get projects.
     * @@return a DataSet
     * @@exception    SQLException
     * @@exception DataSetException 
     */
    public DataSet getProjectsInDomainApprovedByUser (Connection connection, 
                                                      String domainID,
                                                      String userID)
        throws DBException
    {
        
        return getProjects(PROJECT_NAME,           //order
                           connection,     //connection
                           null,           //projectID
                           null,           //profile
                           null,           //type
                           domainID,       //domainID
                           null,           //name
                           null,           //aliasURL
                           null,           //license
                           null,           //shortDescription
                           null,           //longDescription
                           null,           //status
                           userID          //approvedBy
                           );
    }
       
    /**
     *  Retrieves projects by any of their fields
     *
     * @@param   connection        A JDBC database connection
     * @@param   projectID         A project ID
     * @@param   profile           A project profile
     * @@param   type              A project type
     * @@param   domainID          A project ID 
     * @@param   name              A project name
     * @@param   aliasURL          An alias URL
     * @@param   license           A license
     * @@param   shortDescription  A short description
     * @@param   longDescription   A long description
     * @@param   approvedBy        A user ID
     * @@return     a DataSet
     * @@exception    SQLException
     * @@exception    DataSetException
     */
    private TableDataSet getProjects(String order,
                                     Connection connection,
                                     String projectID,
                                     ProjectProfile profile,
                                     String type,
                                     String domainID,
                                     String name,
                                     String aliasURL,
                                     String license,
                                     String shortDescription,
                                     String longDescription,
                                     String status,
                                     String approvedBy)
        throws DBException
    {
        String action = "Getting Projects: ";
        TableDataSet projects = null;

        try
        {
            projects = new TableDataSet(connection, TABLE_NAME, keydef);
            projects.where(buildWhereClause(projectID,        //projectID
                                            profile,          //profile
                                            type,             //type
                                            domainID,         //domainID
                                            name,             //name
                                            aliasURL,         //aliasURL
                                            license,          //license
                                            shortDescription, //shortDescription
                                            longDescription,  //longDescription
                                            status,           //status
                                            approvedBy        //approvedBy
                                            ));
            if (order != null)
            {
                projects.order(order);
            }
            projects.fetchRecords();
        }
        catch (DataSetException e)
        {
            log.exception(e);
            if (debug) log.debug(action + e.getMessage());
            throw e;
        }
        catch (SQLException e)
        {
            log.exception(e);
            if (debug) log.debug(action + e.getMessage());
            throw e;
        }
        finally
        {
            registerToClose(projects);
        }
        return projects;
    }
    
    /**
     * Creates a SQL <code>where</code> clause.
     */
    protected static String buildWhereClause (String projectID, 
                                              ProjectProfile profile,
                                              String type,
                                              String domainID,
                                              String name,
                                              String aliasURL,
                                              String license,
                                              String shortDescription,
                                              String longDescription,
                                              String status,
                                              String approvedBy
                                              )
    {
        StringBuffer whereClause = new StringBuffer();
        
        boolean firstclause = true;

        if (projectID != null)
        {
            whereClause.append(PROJECT_ID).append('=').append(projectID);
            firstclause = false;
        }

        if (profile != null)
        {
            if (!firstclause)
            {
                whereClause.append(" AND ");
            }
            whereClause.append(PROJECT_PROFILE).append('=');
            whereClause.append(escapeAndQuoteSQL(profile.getKey()));
            firstclause = false;
        }

        if (type != null)
        {
            if (!firstclause)
            {
                whereClause.append(" AND ");
            }
            whereClause.append(PROJECT_TYPE).append('=');
            whereClause.append(escapeAndQuoteSQL(type));
            firstclause = false;
        }

        if (domainID != null)
        {
            if (!firstclause)
            {
                whereClause.append(" AND ");
            }
            firstclause = false;
            whereClause.append(PROJECT_DOMAIN_ID).append('=').append(domainID);
        }

        if (name != null)
        {
            if (!firstclause)
            {
                whereClause.append(" AND ");
            }
            firstclause = false;
            whereClause.append("LOWER(").append(PROJECT_NAME)
                .append(")=LOWER(").append(escapeAndQuoteSQL(name))
                .append(')');
        }

        if (aliasURL != null)
        {
            if (!firstclause)
            {
                whereClause.append(" AND ");
            }
            firstclause = false;
            whereClause.append(PROJECT_ALIAS_URL).append('=')
                .append(escapeAndQuoteSQL(aliasURL));
        }

        if (license != null)
        {
            if (!firstclause)
            {
                whereClause.append(" AND ");
            }
            firstclause = false;
            whereClause.append(PROJECT_LICENSE).append('=')
                .append(escapeAndQuoteSQL(license));
        }

        if (shortDescription != null)
        {
            if (!firstclause)
            {
                whereClause.append(" AND ");
            }
            firstclause = false;
            whereClause.append(PROJECT_SHORT_DESCRIPTION).append(" LIKE ")
                .append(escapeAndQuoteSQL("*" + shortDescription + "*"));
        }
        
        if (longDescription != null)
        {
            if (!firstclause)
            {
                whereClause.append(" AND ");
            }
            firstclause = false;
            whereClause.append(PROJECT_LONG_DESCRIPTION).append(" LIKE ")
                .append(escapeAndQuoteSQL("*" + longDescription + "*"));
        }

        if (status != null)
        {
            if (!firstclause)
            {
                whereClause.append(" AND ");
            }
            firstclause = false;
            status = escapeAndQuoteSQL(status);
            whereClause.append(PROJECT_STATUS).append('=');
            whereClause.append(status);
        }

        if (approvedBy != null)
        {
            if (!firstclause)
            {
                whereClause.append(" AND ");
            }
            firstclause = false;
            whereClause.append(PROJECT_APPROVED_BY).append('=')
		.append(approvedBy);
        }

        return whereClause.toString();
    }
@


1.51
log
@Ported UserManager and RoleManager to Helm. Started moving other TableManagers toward a grab-connection-on-demand model. Massive breakage ensues. dlr and I are working on it.
@
text
@d416 1
a416 1
        super(dataMgr);
d683 1
a683 2
            projects = new TableDataSet(connection, TABLE_NAME, 
                                        new KeyDef().addAttrib(PROJECT_ID));
d1402 1
a1402 2
            projects = new TableDataSet(connection, TABLE_NAME, 
                                        new KeyDef().addAttrib(PROJECT_ID));
@


1.50
log
@Making use of DBException.
@
text
@d1323 1
a1323 1
	    (UserManager) dMgr.getManager("org.joist.database.UserManager");
d1325 2
a1326 18
	try {
	    Record userRcd = uMgr.getUserForLoginID(connection, "**Nobody");
	    nobodyUserID = userRcd.getValue("userID").asString();
	}
	catch (JoistDatabaseException e) {
	    String message =
		"JoistDatabase problem in getUnapprovedProjectsForDomain: " +
		e.getMessage();
            if (debug) log.debug(message);
            throw new DataSetException(message);
	}
	catch (SQLException e) {
            if (debug) log.debug(
		"SQL problem in getUnapprovedProjectsForDomain: "
		+ e.getMessage());
            log.exception(e);
            throw e;
	}
@


1.49
log
@Protect against NullPointerExceptions.
@
text
@d310 1
a310 1
                    throw new Exception ("Could not obtain hostProjectID");
d408 1
a408 1
    
d461 1
a461 1
        throws SQLException, DataSetException, JoistDatabaseException
d468 1
a468 1
        return(!approvedBy.equals(usrGrpMgr.getNobodyUserID(connection)));
d476 1
a476 1
        throws AlreadyExists, SQLException, DataSetException
d525 1
a525 2
        throws SQLException, DataSetException, JoistDatabaseException, 
               DoesNotExist, AlreadyExists
d563 1
a563 1
        throws SQLException, DataSetException, JoistDatabaseException
d607 1
a607 2
        throws SQLException, DataSetException, JoistDatabaseException,
               DoesNotExist
d667 1
a667 2
        throws SQLException, DataSetException, JoistDatabaseException,
               DoesNotExist
d750 1
a750 3
            log.exception(e);
            if (debug) log.debug(action + ": " + e.getMessage());
            throw e;
d754 1
a754 3
            log.exception(e);
            if (debug) log.debug(action + ": " + e.getMessage());
            throw e;
d766 1
a766 2
        throws SQLException, DataSetException, JoistDatabaseException,
               DoesNotExist
d837 1
a837 1
        throws SQLException, DataSetException, JoistDatabaseException
d863 1
a863 1
        throws SQLException, DataSetException, JoistDatabaseException
d872 1
a872 1
            throw new JoistDatabaseException("No such project: " + projectID);
d883 2
a884 2
     * @@exception    SQLException
     * @@exception    DataSetException
d888 1
a888 1
        throws SQLException, DataSetException, JoistDatabaseException
d897 2
a898 2
            throw new JoistDatabaseException("Invalid domain/project: " + 
                                             domainID + '/' + name);
d908 2
a909 1
     * @@exception DataSetException
d912 1
a912 1
        throws DataSetException, SQLException
d919 1
a919 2
            throw new DataSetException("bad projectID (no record): " + 
                    projectID);
d926 1
a926 3
            log.exception(e);
            if (debug) log.debug("JoistDatabaseException in getProjectDomain");
            throw new DataSetException(e.getMessage());
d942 1
a942 1
        throws SQLException, DataSetException
d972 2
a973 2
     * @@exception    SQLException
     * @@exception    DataSetException
d976 1
a976 1
        throws SQLException, DataSetException
d1015 1
a1015 1
        throws SQLException, DataSetException, JoistDatabaseException
d1039 4
a1042 3
                    throw new JoistDatabaseException("Duplicate alias URL for "
                                                     + "domain: " + aliasURL + 
                                                     " for " +domainID);
d1060 2
a1061 2
     * @@exception    SQLException
     * @@exception DataSetException 
d1065 1
a1065 1
        throws SQLException, DataSetException
d1115 1
a1115 1
        throws SQLException, DataSetException
d1135 1
a1135 1
        throws SQLException, DataSetException
d1162 1
a1162 1
        throws SQLException, DataSetException
d1192 1
a1192 1
        throws SQLException, DataSetException
d1252 1
a1252 1
        throws SQLException, DataSetException
d1318 1
a1318 1
        throws SQLException, DataSetException
d1362 1
a1362 1
        throws SQLException, DataSetException
d1412 1
a1412 1
        throws SQLException, DataSetException
@


1.48
log
@How about making sure a new business object initializes properly before committing code that puts it into HelmServlet.
@
text
@d396 2
a397 2
                projects.close();
                domains.close();
@


1.47
log
@The check for null happens internally.
@
text
@d170 5
@


1.46
log
@Migrated to latest Turbine CVS to avoid connection release bug (fixed long ago in Turbine CVS--we just had a bunk version).
@
text
@d393 1
a393 4
                if (dbConn != null)
                {
                    TurbineDB.releaseConnection(dbConn);
                }
@


1.45
log
@minor cleanup
@
text
@d272 1
a272 1
            dbConn = PoolBrokerService.getInstance().getConnection();
d395 1
a395 1
                    PoolBrokerService.getInstance().releaseConnection(dbConn);
@


1.44
log
@Assure case-insensitive project name comparisons.  This may be
MySQL-specific.
@
text
@d1095 2
a1096 1
        c.and(new Criterion(ProjectProjectGroupManager.PROJECT_GROUP_ID, Criterion.DOES_NOT_MATCH, groupID));
d1099 7
a1105 7
       StringBuffer q = new StringBuffer();
       q.append("SELECT ").append(TABLE_NAME).append(".* FROM ")
           .append(TABLE_NAME).append(", ").append(otherTable)
           .append(" WHERE ").append(TABLE_NAME).append(".").append(PROJECT_ID)
           .append("=").append(otherTable).append(".")
           .append(ProjectProjectGroupManager.PROJECT_ID).append(" AND ");
       q.append(c.toString());
d1107 2
a1108 2
       log.info("Project query: " + q.toString());
       return q.toString();
@


1.43
log
@Handling word mark via business logic instead.
@
text
@d1529 3
a1531 2
            whereClause.append(PROJECT_NAME).append('=')
                .append(escapeAndQuoteSQL(name));
@


1.42
log
@Added WORD_MARK constant.
@
text
@a104 5
     * The word mark field (merely a stylized version of the name field).
     */
    public static final String WORD_MARK = "WORD_MARK";

    /**
@


1.41
log
@Many, many pagination changes.
@
text
@d105 5
@


1.40
log
@Updated to support new HELM_PROJECT.USE_INDEX field (may make use of
new DBFlag class to do so).
@
text
@a1087 1
        log.info("Project query: " + query);
d1089 19
@


1.39
log
@Support for users in the host domain.
@
text
@d292 1
a292 1
            // domainManager.
d494 12
a505 10
     * @@param   connection        The JDBC database connection to use.
     * @@param   domainID          ID of Domain in which the project resides.
     * @@param   name              Name of the project.
     * @@param   license           License of the project.
     * @@param   shortDescription  A short description of the project.
     * @@param   longDescription   A long description of the project.
     * @@param   aliasURL          URL to use as alias, if any.
     * @@param   proposedBy        User who proposed the project.
     * @@param   approvedBy        User who approved the project, if any.
     * @@return  The database record for the project.
d518 1
d535 1
d587 2
d602 1
d617 1
d642 2
d662 1
d718 4
a721 1
                project.setValue(PROJECT_LONG_DESCRIPTION,longDescription);
d724 1
a724 1
                project.setValue(PROJECT_STATUS,status);
a747 1

@


1.38
log
@Initial work for USE_INDEX field.
@
text
@d1074 3
a1076 1
        return getProjectsQuery() + " WHERE " + c.toString();
@


1.37
log
@First tenative steps towards the new pagination/filtering regime.
@
text
@d120 5
d1429 1
a1429 1
    }    
@


1.36
log
@Removed init of TurbineResourceService--now in UnsecureServlet.
@
text
@d1060 12
@


1.35
log
@It would be nice to actually be able to see the error message.  ;P
@
text
@a56 1
import org.apache.turbine.services.resources.TurbineResourceService;
a266 3
            TurbineResourceService.setPropertiesFileName
                ((String)JoistProperties.getInstance()
                 .getProperty("turbineResourcesFileName"));
@


1.34
log
@little cleanup
@
text
@d399 1
a400 1
                if (debug) log.debug(action + e.getMessage());
@


1.33
log
@ProjectGroupDelete should work now (as should project deletion in general)
@
text
@d265 1
a265 1
        //Get a connection from the TurbineConnectionPool.
a402 1

@


1.32
log
@better logging for an error case
@
text
@d835 1
a835 4
        String projectName = project.getValue(PROJECT_NAME).asString();

        TableDataSet projects = null;
        try
d837 2
a838 41
            //Delete the project.
            projects = new TableDataSet(connection, TABLE_NAME, 
                                        new KeyDef().addAttrib(PROJECT_ID));

            projects.where(buildWhereClause(projectID, //projectID
                                            null,      //profile
                                            ProjectType.REGULAR, //type
                                            null,      //domainID
                                            null,      //name
                                            null,      //aliasURL
                                            null,      //license
                                            null,      //shortDescription
                                            null,      //longDescription
                                            null,      //status
                                            null      //approvedBy
                                            ));
            projects.fetchRecords();
            if (projects.containsRecord(0)) 
            {
                Record r = projects.getRecord(0);
                r.markToBeDeleted();
                r.save();
            }
        }
        catch (DataSetException e)
        {
            log.exception(e);
            if (debug) log.debug(action + ": " + projectID + ": " + 
                                 e.getMessage());
            throw e;
        }
        catch (SQLException e)
        {
            log.exception(e);
            if (debug) log.debug(action + ": " + projectID + ": " + 
                                 e.getMessage());
            throw e;
        }
        finally
        {
            registerToClose(projects);
@


1.32.2.1
log
@merged in changes from HEAD
@
text
@d835 4
a838 1
        if (project != null)
d840 41
a880 2
            project.markToBeDeleted();
            project.save();
@


1.31
log
@Added project group edit and delete.
@
text
@d953 2
a954 1
            throw new DataSetException("bad projectID (no record found)");
@


1.30
log
@All project group activity now goes through the ProjectGroup object.
@
text
@d17 1
a17 1
 * software developed by CollabNet (http://www.Collab.Net/)."
@


1.29
log
@Moved the rest of the isValidProjectName() implementation over.
@
text
@d70 1
d756 2
a757 2
    public Record setLicense (Connection connection, String projectID,
                            String license)
d796 4
a799 2
            //If we used not to be proprietary and now we are, remove this project
            //from the public projects list.
d803 1
a803 2
                prjGrpMgr.removeProjectFromGroup
                    (connection, projectID, getPublicDomainProjectID(domainID));
d811 1
a811 2
                prjGrpMgr.addProjectToGroup
                    (connection, projectID, getPublicDomainProjectID(domainID));
@


1.28
log
@Moved functionality used by servlets into Project business object.
@
text
@a54 2
import gnu.regexp.*;

a162 5

    /**
     * The regular expression used to check project names for validity.
     */
    private static final String PROJECT_NAME_RE = "^[-a-z0-9]{1,64}$";
@


1.27
log
@Sort projects by name whenever possible.
@
text
@a475 29
     * Checks whether a project name is valid.
     *
     * @@param name The project name to check.
     * @@return     Whether the name is valid.
     *
     * @@exception REException Malformed regular expression.
     */
    public boolean isValidProjectName(String name)
    {
        boolean isValid = false;

        if (name != null && name.length() > 0)
        {
            RE projectRE = null;
            try
            {
                projectRE= new RE(PROJECT_NAME_RE);
                isValid = projectRE.isMatch(name);
            }
            catch (REException e)
            {
                log.exception(e);
            }
        }

        return isValid;
    }

    /**
@


1.26
log
@Initial run at ProjectGroup business object.
@
text
@d1174 1
a1174 1
        return getProjects(null,           //order
d1201 1
a1201 1
        return getProjects(null,           //order
d1402 1
a1402 1
        return getProjects(null,           //order
@


1.25
log
@Implemented requestable roles and requesting roles in proprietary projects.
@
text
@d529 1
a529 1
     * @@param connection  The JDBC database connection to use.
d538 1
a538 1
     * @@return  The system-assigned project ID for the project.
@


1.24
log
@Removed assertProjectNonexistance()--moved this functionality into the
business object (where it now belongs).
@
text
@d504 17
d767 1
a767 1
                setLicense(connection, projectID,  license);
d791 1
a791 1
    public void setLicense (Connection connection, String projectID,
d803 1
a803 1
            return;
d815 1
a815 1
            return;
d822 2
a823 2
        //If we are not approved, quit now.
        if (!approved)
d825 23
a847 25
            return;
        }

        ProjectProjectGroupManager prjGrpMgr = (ProjectProjectGroupManager)
            dMgr.getManager
            ("org.tigris.helm.database.ProjectProjectGroupManager");
        
        String domainID = project.getValue(PROJECT_DOMAIN_ID).asString();

        //If we used not to be proprietary and now we are, remove this project
        //from the public projects list.
        if ((!wasProprietary || oldLicense == null) && isProprietary)
        {
            log.info("Removing project from public group.");
            prjGrpMgr.removeProjectFromGroup
                (connection, projectID, getPublicDomainProjectID(domainID));
        }
        
        //If we used to be proprietary and now we're not, add this project
        //to the public projects list.
        if ((wasProprietary || oldLicense == null) && !isProprietary)
        {
            log.info("Adding project to public group.");
            prjGrpMgr.addProjectToGroup
                (connection, projectID, getPublicDomainProjectID(domainID));
d850 1
@


1.23
log
@Can't proprietarize approved open source projects.
@
text
@a503 17
    /**
     * Checks whether a project name already exists in the given domain.
     */
    public boolean assertProjectNonexistance(Connection connection, 
                                             String domainID, String name)
        throws AlreadyExists, SQLException, DataSetException
    {
        boolean alreadyExists = false;
	
        Record project = getProjectForName(connection, domainID, name);
        if (project != null)
        {
	   alreadyExists = true;
        }
	 return alreadyExists;
    }

@


1.22
log
@Don't run MemberAdd on non-base projects.
@
text
@d808 10
d823 1
a823 1
        if (!isApproved(connection, projectID))
@


1.21
log
@Made the TigrisUpdate stuff saner with the use of business objects.
@
text
@d210 10
@


1.20
log
@getting users for a project sorted alphabetically by name
@
text
@d66 1
d546 1
a546 1
               UpdateException, AlreadyExists
d583 1
a583 2
        throws SQLException, DataSetException, JoistDatabaseException,
               UpdateException              
d625 1
a625 1
               UpdateException
d682 1
a682 1
               UpdateException
d784 1
a784 1
               UpdateException
d846 1
a846 2
        throws SQLException, DataSetException, JoistDatabaseException, 
               UpdateException
@


1.19
log
@Got rid of message munging on project approval.
@
text
@d168 1
a168 1
    private static final String PROJECT_NAME_RE = "^[-a-zA-Z0-9]{1,64}$";
@


1.18
log
@moved check to see if projectname already exists to happen in ProjectAdd.java instead of in the add method of ProjectManager, since now the project does not get added until ProjectAddStep2
@
text
@a589 4
        if (status.equals("Unapproved") || status.equals("") || status == null)
        {
            project.setValue(PROJECT_STATUS, "Approved");
        }
@


1.17
log
@Modernized ProjectEdit; began to get rid of superfluous UpdateException handling.
@
text
@d494 1
a494 2
     * Throws an exception if a project in the given domain with the
     * given name already exists.
d496 2
a497 2
    void assertProjectNonexistance(Connection connection, String domainID,
                                   String name)
d500 2
d505 1
a505 2
            throw new AlreadyExists("Project " + 
                                    project.getValue(PROJECT_NAME).asString());
d507 1
a546 1
        assertProjectNonexistance(connection, domainID, name);
@


1.16
log
@Fixed security bug. Also display buttons for role manipulation in UserEdit only if you can use those roles.
@
text
@a472 1
        throws REException
@


1.15
log
@minor javadoc cleanup
@
text
@d185 5
d195 5
@


1.14
log
@removed Member Policy field
@
text
@d406 1
a406 1
     * @@return         The ID of the special host project.
d416 1
d427 1
@


1.13
log
@removed more unneeded imports
@
text
@a512 1
     * @@param   memberPolicy      Member policy of the project.
a529 1
                              String memberPolicy,
a546 1
                             memberPolicy,     //memberPolicy
a603 1
     * @@param memberPolicy      Member policy of the project. Looks like 
d615 1
a615 2
                                  String aliasURL,
                                  String memberPolicy
a629 1
                      memberPolicy,     //memberPolicy
a653 1
     * @@param memberPolicy      Member policy of the project.
a671 1
                                  String memberPolicy,
a732 3
            if (memberPolicy != null)
                project.setValue(PROJECT_MEMBER_POLICY, memberPolicy);

a863 1
                                            null,      //memberPolicy
a1002 1
                                       null,           //memberPolicy
a1036 1
                                       null,           //memberPolicy
a1076 1
                                            null,      //memberPolicy
a1160 1
                           null,           //memberPolicy
a1187 1
                           null,           //memberPolicy
a1388 1
                           null,           //memberPolicy
a1405 1
     * @@param   memberPolicy      A member policy
a1422 1
                                     String memberPolicy,
a1442 1
                                            memberPolicy,     //memberPolicy
a1482 1
                                              String memberPolicy,
a1592 11
        }

        if (memberPolicy != null)
        {
            if (!firstclause)
            {
                whereClause.append(" AND ");
            }
            firstclause = false;
            whereClause.append(PROJECT_MEMBER_POLICY).append('=');
            whereClause.append(memberPolicy);
@


1.12
log
@Removed some unnecessary imports.
@
text
@d53 1
a53 2
import org.webmacro.util.*;
import org.webmacro.servlet.*;
d80 1
d274 3
a276 2
            //This is generally useful--it should be static member of domainManager.
            //Get the project ID for the special hostwide project.
@


1.11
log
@Permission checking bugfixes; one more big one on the way.
@
text
@a50 1

a51 3

import javax.servlet.*;
import javax.servlet.http.*;
@


1.10
log
@Cleaned up.
@
text
@d449 1
d452 1
a452 1
        return(approvedBy.equals(usrGrpMgr.getNobodyUserID(connection)));
d809 6
d825 1
d832 1
a832 2
        if ((wasProprietary || oldLicense == null) && !isProprietary 
            && isApproved(connection, projectID))
d834 1
@


1.9
log
@Resolved merge conflicts.
@
text
@a499 27
  public ProjectManager(DataManager dataMgr) {
      super(dataMgr);
  }
  
  /**
   * Add a new project to the database. This should set up all the
   * tables and such that any other database accessor will expect to
   * find.
   *
   * @@param tigris the Tigris context to add the project to
   * @@param project the name to give to the project in the domain
   * @@param longName a longer, descriptive, name
   *
   * @@exception SQLException if there was a database error
   * @@exception UpdateException if the update program could not be run
   * @@exception AlreadyExists if a project by this name already exists
   */
  public static String addProject(Connection connection, String domain, 
				String project, String longName) 
      throws SQLException, UpdateException, AlreadyExists {
    Statement s = connection.createStatement();
    
    // Check to see if the project does not already exist
    ResultSet r = s.executeQuery("SELECT project FROM "
                                 + "domain_projects WHERE project "
                                 + "= '" + project + "'");
					    
@


1.8
log
@Got rid of privateModule altogether.
@
text
@d17 1
a17 1
 * software developed by Collab.Net (http://www.Collab.Net/)."
d27 1
a27 1
 * permission of Collab.Net.
d32 1
a32 1
 * IN NO EVENT SHALL COLLAB.NET OR ITS CONTRIBUTORS BE LIABLE FOR ANY
d44 1
a44 1
 * individuals on behalf of Collab.Net.
d50 3
a52 3
import org.webmacro.util.*;
import org.webmacro.servlet.*;
import org.webmacro.engine.*;
d57 4
a60 3
import com.sun.java.util.collections.ArrayList;
import com.sun.java.util.collections.List;
import java.sql.*;
d64 4
d69 1
a69 7
import org.joist.database.TableManager;
import org.joist.database.DataManager;
import org.joist.util.PasswordGenerator;
import org.tigris.helm.database.ModuleManager;
import org.tigris.helm.tool.TigrisUpdate;
import org.tigris.helm.tool.UpdateException;
import org.tigris.helm.tool.MailingList;
d71 5
a75 1
// TODO: this has not be rewritten to look like Joist TableManagers
d80 1
a80 3
 * database integrity.  It does not deal with minor edits, or other
 * project-related activities such as modules. The database may be
 * directly consulted for this purpose.
d82 3
a84 2
 * <p>All the methods of this class are static; there should be no need
 * to instantiate an object of this class.
d86 137
a222 1
public class ProjectManager extends TableManager {
d225 1
a225 1
     * This exception indicates that the given project already exists.
d227 167
a393 2
  public static class AlreadyExists extends Exception {
    private String project;
d396 1
a396 1
     * Create a new "project already exists" exception
d398 1
a398 1
     * @@param project the project that already exists
d400 4
a403 3
    public AlreadyExists(String project) {
	    super("Project " + project + " already exists");
	    this.project = project;
d407 3
a409 1
     * Return the project name that already exists
d411 3
a413 2
    public String getProject() {
	    return project;
a414 1
  } /* end class AlreadyExists */
d416 8
a423 7
  /**
   * This exception is thrown when an attempt is made to delete
   * a project with modules outstanding
   */
  public static class HasModules extends Exception {
    public HasModules(String project) {
	super("Project " + project + " has modules and cannot be deleted");
d425 1
a425 8
  } /* end class HasModules */
  
  /**
   * A project entry from the Tigris database
   */
  public static class Entry {
    private String project, longname;
    
d427 7
a433 8
     * Create a new user entry with the given project and long name
     * 
     * @@param project the (short) name of the project
     * @@param longname a longer name for the project, or null if none
     */
    public Entry(String project, String longname) {
	this.project = project;
	this.longname = (longname != null) ? longname : project;
d435 17
a451 3
    
    public String getProject() {
	return project;
d453 29
a481 3
    
    public String getLongName() {
	return longname;
a482 1
  } /* end class Entry */
d484 15
d528 452
a979 1
    String password = PasswordGenerator.password();
d981 64
a1044 20
    // If any rows are found, the project name is already taken
    if (r.next()) throw new AlreadyExists(project);
    
    // N.B. Because MySQL does not support transactions or
    // prepared statements, we add the actual domain_projects entry
    // last. This ensures that, although support tables may exist,
    // the user entry itself is only set up once the project
    // completely exists.
    
    // Add standard mailing lists
    
    String[] lists = { "dev", "announce", "users", "cvs", "bugs" };
    for (int i = 0; i < lists.length; i++) {
	// Note that we ask not to run the update program
	try {
	    MailingList.addMailingList(connection, project, lists[i], false);
	} catch (MailingList.AlreadyExists e) {
	    // Can't happen, since we just added the project. Ignore
	    // it.
	}
d1046 34
a1079 10
    
    // Now add standard modules
    String moduleName = "www";
    String moduleDescription = "Project Web site";
    try {	
	ModuleManager.addModuleNoUpdate(connection, domain, project, moduleName,
					moduleDescription, true);
    } catch (ModuleManager.AlreadyExists e) {
	// This exception can't actually be raised, since we've just
	// inserted the project. So don't bother with it.
d1081 53
a1133 29
    s.executeUpdate("INSERT INTO module_website (project,module,vhost,"
                    + "root) VALUES ('" + project + "','www','Y','/')");
    
    // Finally, add to the projects table
    s.executeUpdate("INSERT INTO domain_projects (project,long_name) "
                    + "VALUES ('" + project + "','" + longName + "')");

    TigrisUpdate.addProject(connection, domain, project, longName, password);
    TigrisUpdate.addModule(connection, domain, project, "www", "Project Web site", true);    
    return password;
  }
  
  /**
   * Remove a project from the database. If the project has any modules,
   * an exception will be thrown
   *
   * @@param connection The JDBC database connection
   * @@param project The name of the project to delete
   * @@exception SQLException if there was a database error
   * @@exception UpdateException if the update program could not be run
   * @@exception HasModules if the project has any modules
   */
  public static void deleteProject(Connection connection, String project)
    throws SQLException, UpdateException, HasModules {
    Statement s = connection.createStatement();
    
    // Verify there are no modules
    if (!ModuleManager.getModules(connection, project).isEmpty()) {
	    throw new HasModules(project);
d1135 16
a1150 26
    
    // Delete project from all rows
    String whereQuery = " WHERE project = '" + project + '\'';
    s.executeUpdate("DELETE FROM domain_projects" + whereQuery);
    s.executeUpdate("DELETE FROM project_mlists" + whereQuery);
    s.executeUpdate("DELETE FROM project_privs" + whereQuery);
    
    // Update the database
    TigrisUpdate.delProject(connection, project);
  }
  
  /**
   * Retrive a list of projects from the database.
   *
   * @@param connection the JDBC database connection
   * @@return a List of Project.Entry objects representing all the projects
   *         in this domain, ordered alphabetically by project name
   */
  public static List listProjects(Connection connection) throws SQLException {
    ArrayList projects = new ArrayList();
    
    Statement s = connection.createStatement();
    ResultSet r = s.executeQuery("SELECT project,long_name FROM "
                                 + "domain_projects ORDER BY project");
    while (r.next()) {
	    projects.add(new Entry(r.getString(1), r.getString(2)));
a1151 3
    
    return projects;
  }
d1153 15
a1167 13
  public static List getProjectsForUser(Connection connection, String userID)
    throws SQLException {
    ArrayList projects = new ArrayList();
    
    Statement s = connection.createStatement();
    // TODO--2.0: project homepage column
    ResultSet r = s.executeQuery("SELECT domain_projects.project,domain_projects.long_name " +
                                 "FROM project_privs, domain_projects " +
                                 "WHERE username='" + userID + "' " +
                                 "AND project_privs.project=domain_projects.project "+
                                 "ORDER BY project");
    while (r.next()) {
	    projects.add(new Entry(r.getString(1), r.getString(2)));
a1168 3
    
    return projects;
  }
d1170 59
a1228 13
  public static List getUsersForProject(Connection connection, String projectName)
    throws SQLException {
    ArrayList users = new ArrayList();
    
    Statement s = connection.createStatement();
    // TODO--2.0: project homepage column
    ResultSet r = 
	s.executeQuery("SELECT project_privs.username " +
		       "FROM project_privs " +
		       "WHERE project='" + projectName + "' " +
		       "ORDER BY project_privs.username");
    while (r.next()) {
	    users.add(r.getString(1));
a1229 3
    
    return users;
  }
d1231 168
a1398 8
  public static void setDescription(Connection connection, String project,
                                    String longName)
  throws SQLException {
    Statement s = connection.createStatement();
    s.executeUpdate("UPDATE domain_projects SET long_name = '"
                    + longName
                    + "' WHERE project = '" + project + "'");
  }
d1400 260
a1659 11
  public static String getDescription(Connection connection, String project)
    throws SQLException {
    Statement s = connection.createStatement();
    ResultSet projset = s.executeQuery("SELECT long_name "
                                       + "FROM domain_projects WHERE "
                                       + "project = '" + project + "'");
    if (projset.next())
      return projset.getString(1);
    else
      return null;
  }
d1661 3
a1663 1
} /* end class ProjectManager */
@


1.7
log
@Collab.Net --> CollabNet in copyright.
@
text
@d204 1
a204 1
					moduleDescription, true, false);
d217 1
a217 1
    TigrisUpdate.addModule(connection, domain, project, "www", "Project Web site", true, false);    
@


1.6
log
@Added SelfServeProjectAdd servlet, factoring out project creation
logic into ProjectCreator tool class. Big update to TigrisUpdate to
make it run kmaples' Perl scripts directly. Also updates to
{Project,Module}{Add,Manager}.
@
text
@d2 1
a2 1
 * Copyright (c) 2000 Collab.Net.  All rights reserved.
@


1.5
log
@
Obtained from:
Submitted by:
Reviewed by:

Moved from org.helm to org.tigris.helm
Moved from org/helm to org/tigris/helm

perl -pi.bak -e, how I love thee

note: this update was done POST-CVS-REPOSITORY surgury.  In order to
get this right, you may need to remove the directories

$CVSROOT/helm/java/org/helm
$CVSROOT/helm/data/htdoc/look/www/org/helm
$CVSROOT/helm/templates/org/helm

before doing the "CVS update" call, since those directories don't
exist anymore and CVS will try to create lockfiles for you in them,
giving you an error.
@
text
@d66 2
a71 2


d85 1
d164 3
a166 3
  public static void addProject(Connection connection, String project,
                                String longName) throws SQLException,
                                UpdateException, AlreadyExists {
d174 2
d200 5
a204 3
    try {
	ModuleManager.addModuleNoUpdate(connection, project, "www",
					"Project Web site", false);
d216 3
a218 4
    
    TigrisUpdate.addProject(connection, project);

    
@


1.4
log
@switched from collections2.jar to collections.jar
@
text
@d48 1
a48 1
package org.helm.database;
d66 3
a68 3
import org.helm.tool.TigrisUpdate;
import org.helm.tool.UpdateException;
import org.helm.tool.MailingList;
@


1.3
log
@Added tigris.org license
PR:
Obtained from:
Submitted by:
Reviewed by:
@
text
@d57 2
a58 2
import java.util.ArrayList;
import java.util.List;
@


1.2
log
@updated TView since some of it was moved into joist; made copyrights consistent
@
text
@d1 46
a46 1
// Copyright (c) 2000 Collab.Net, Inc. All Rights Reserved.
@


1.1
log
@initial checking
@
text
@a167 1
// Copyright (c) 2000 Collab.Net, Inc.
@


1.1.1.1
log
@Merging newhelm tree into helm, as per IZ issue #557.  Previous major version of helm is tagged TIGRIS_NOV_11_2000.
@
text
@d1 1
a1 45
/* ================================================================
 * Copyright (c) 2000 CollabNet.  All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 * 
 * 1. Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 * 
 * 2. Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * 
 * 3. The end-user documentation included with the redistribution, if
 * any, must include the following acknowlegement: "This product includes
 * software developed by CollabNet (http://www.Collab.Net/)."
 * Alternately, this acknowlegement may appear in the software itself, if
 * and wherever such third-party acknowlegements normally appear.
 * 
 * 4. The hosted project names must not be used to endorse or promote
 * products derived from this software without prior written
 * permission. For written permission, please contact info@@collab.net.
 * 
 * 5. Products derived from this software may not use the "Tigris" name
 * nor may "Tigris" appear in their names without prior written
 * permission of CollabNet.
 * 
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL COLLABNET OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * ====================================================================
 * 
 * This software consists of voluntary contributions made by many
 * individuals on behalf of CollabNet.
 */
d3 1
d5 3
a7 5
package org.tigris.helm.database;

import java.sql.*;

import java.util.*;
d12 3
a14 2
import org.webmacro.util.*;
import org.webmacro.servlet.*;
d16 1
a16 1
import gnu.regexp.*;
d18 6
a23 1
import com.workingdogs.village.*;
a24 3
import org.apache.turbine.services.resources.TurbineResourceService;
import org.apache.turbine.services.db.*;
import org.apache.turbine.util.db.pool.*;
a25 2
import org.joist.util.*;
import org.joist.database.*;
d27 1
a27 5
import org.tigris.helm.AlreadyExists;
import org.tigris.helm.database.*;
import org.tigris.helm.security.*;
import org.tigris.helm.tool.*;
import org.tigris.helm.project.*;
d32 3
a34 1
 * database integrity.
d36 2
a37 3
 * @@author <a href="mailto:akosut@@leland.stanford.edu">Alexi Kosut</a>
 * @@author <a href="mailto:jrobbins@@collab.net">Jason Robbins</a>
 * @@author <a href="mailto:leonardr@@collab.net">Leonard Richardson</a>
d39 1
a39 143
public class ProjectManager extends TableManager
{
    /**
     * The name of the database table that this <code>TableManager</code> 
     * manages.
     */
    public static final String TABLE_NAME = "HELM_PROJECT";

    /**
     * The primary database key field.
     */
    public static final String PROJECT_ID = "PROJECT_ID";

    /**
     * The domain field.
     */
    public static final String PROJECT_DOMAIN_ID = "DOMAIN_ID";

    /**
     * The name field.
     */
    public static final String PROJECT_NAME = "NAME";

    /**
     * The license field.
     */
    public static final String PROJECT_LICENSE = "LICENSE";

    /**
     * The short description field.
     */
    public static final String PROJECT_SHORT_DESCRIPTION = "SHORT_DESCRIPTION";

    /**
     * The long description field.
     */
    public static final String PROJECT_LONG_DESCRIPTION = "LONG_DESCRIPTION";

    /**
     * The project profile
     */
    public static final String PROJECT_PROFILE = "PROFILE";

    /**
     * The project type.
     */
    public static final String PROJECT_TYPE = "TYPE";

    /**
     * The project status field.
     */
    public static final String PROJECT_STATUS = "STATUS";

    /**
     * The category ID field.
     */
    public static final String PROJECT_CATEGORY_ID = "CATEGORY_ID";

    /**
     * The alias URL field.
     */
    public static final String PROJECT_ALIAS_URL = "ALIAS_URL";

    /**
     * The member policy field.
     */
    public static final String PROJECT_MEMBER_POLICY = "MEMBER_POLICY";

    /**
     * The user ID of the user who proposed this project.
     */
    public static final String PROJECT_PROPOSED_BY = "PROPOSED_BY";

    /**
     * The user ID of the user who approved this project.
     */
    public static final String PROJECT_APPROVED_BY = "APPROVED_BY";

    /**
     * The proprietariness field.
     */
    public static final String PROJECT_IS_PROPRIETARY = "IS_PROPRIETARY";

    /**
     * The regular expression used to check project names for validity.
     */
    private static final String PROJECT_NAME_RE = "^[-a-zA-Z0-9]{1,64}$";

    /**
     * The special name of projects which represent all public
     * projects in a domain.  
     */
    public static final String DOMAIN_PUBLIC_PROJECT_NAME = 
        "*All public projects in domain";

    /**
     * The special name of projects which represent all projects in a
     * domain.
     */
    public static final String DOMAIN_PROJECT_NAME =
        "*All projects in domain";

    /**
     * The special name of the project representing all projects on
     * the host.  
     */
    public static final String HOST_PROJECT_NAME = 
        "**All projects on host";

    /**
     * SQL statement used to lock the tables used in the initializer.
     */
    private static final String LOCK_TABLES = "lock tables " + 
        "HELM_DOMAIN read, " +
        "HELM_PROJECT read";

    /**
     * SQL statement used to unlock the tables used in the initializer.
     */
    private static final String UNLOCK_TABLES = "unlock tables";

    /**
     * Project ID for the special host project, set at class loading time.
     */
    private static String hostProjectID;

    /**
     * A mapping of domain names to special project IDs, populated
     * at class loading time.
     */
    private static Hashtable projectIDForDomain;

    /**
     * A mapping of domain names to project IDs representing the
     * public projects in the domain, populated at class loading time.  
     */
    private static Hashtable publicProjectIDForDomain;

    /**
     * A general-purpose DataManager
     */
    private DataManager dMgr;

d41 1
a41 1
     * Open the log file.
d43 2
a44 162
    private static Log log = new Log("projMgr", "ProjectManager");

    /**
     * Whether to log debugging information.
     */
    private static boolean debug = true;
    
    static
    {
        String action = "Static initialization of ProjectManager: ";
        
        projectIDForDomain = new Hashtable();
        publicProjectIDForDomain = new Hashtable();

        DBConnection dbConn = null;
        Connection connection = null;
        DataManager dMgr = new DataManager();
        DomainManager domMgr = (DomainManager)dMgr
            .getManager("org.tigris.helm.database.DomainManager");

        TableDataSet projects = null;
        DataSet domains = null;
        //Get a connection from the TurbineConnectionPool.
        try 
        {
            TurbineResourceService.setPropertiesFileName
                ((String)JoistProperties.getInstance()
                 .getProperty("turbineResourcesFileName"));
            dbConn = PoolBrokerService.getInstance().getConnection();
            connection = dbConn.getConnection();

            Statement stmt = null;        
            try
            {
                // Grab a light weight database lock.
                stmt = connection.createStatement();
                stmt.executeUpdate(LOCK_TABLES);
            }
            catch (Exception e)
            {
                log.info("Table locking/unlocking error in static " +
                          "initializer: " + e.getMessage());
                throw new RuntimeException(e.getMessage());
            }

            Hashtable domainNameForID = new Hashtable();
            //This is generally useful--it should be static member of domainManager.
            //Get the project ID for the special hostwide project.
            try
            {
                projects = new TableDataSet(connection, TABLE_NAME);
                projects.where("name=" + escapeAndQuoteSQL(HOST_PROJECT_NAME));
                projects.fetchRecords();
                if (projects.size() > 0)
                {
                    hostProjectID = projects.getRecord(0)
                        .getValue(PROJECT_ID).asString();
                }
                else
                {
                    throw new Exception ("Could not obtain hostProjectID");
                }
            }
            finally
            {
                if (projects != null) projects.close();
            }

            //Get a list of domains. Map the domain name to its ID
            //for later.
            domains = domMgr.listDomains(connection);
            int domainNum = domains.size();
            for (int i = 0; i < domainNum; i++)
            {
                Record domain = domains.getRecord(i);
                String domainID = domain.getValue(DomainManager.DOMAIN_ID)
                    .asString();
                String domainName = domain.getValue(DomainManager.DOMAIN_NAME)
                    .asString();
                domainNameForID.put(domainID, domainName);
            }

            String query = null;
            //Get the project IDs of all the special domain-wide projects.
            try
            {
                projects = new TableDataSet(connection, TABLE_NAME);
                query = PROJECT_NAME + "=" + 
                    escapeAndQuoteSQL(DOMAIN_PROJECT_NAME);
                projects.where(query);
                projects.fetchRecords();
                for (int i = 0; i < projects.size(); i++)
                {
                    Record project = projects.getRecord(i);
                    String projectID = project.getValue(PROJECT_ID).asString();
                    String domainID = 
                        project.getValue(PROJECT_DOMAIN_ID).asString();
                    projectIDForDomain.put(domainID, projectID);
                }
            }
            finally
            {
                if (projects != null) projects.close();
            }

            //Get the project IDs of all the special public project groups.
            //This stuff should go into a method since it's almost the same
            //as the stuff above.
            query = PROJECT_NAME + "=" +
                escapeAndQuoteSQL(DOMAIN_PUBLIC_PROJECT_NAME);
            try
            {
                projects = new TableDataSet(connection, TABLE_NAME);
                projects.where(query);
                projects.fetchRecords();
                for (int i = 0; i < projects.size(); i++)
                {
                    Record project = projects.getRecord(i);
                    String projectID = project.getValue(PROJECT_ID).asString();
                    String domainID = 
                        project.getValue(PROJECT_DOMAIN_ID).asString();
                    publicProjectIDForDomain.put(domainID, projectID);
                }
            }
            finally
            {
                if (projects != null) projects.close();
            }

            if (stmt != null)
            {
                // Unlock the database tables.
                stmt.executeUpdate(UNLOCK_TABLES);
                stmt.close();
            }
        }
        catch (Exception e)
        {
            log.exception(e);
            if (debug) log.debug(action + e.getMessage());
            throw new RuntimeException(e.getMessage());
        }
        finally
        {
            try 
            {
                projects.close();
                domains.close();
                if (dbConn != null)
                {
                    PoolBrokerService.getInstance().releaseConnection(dbConn);
                }
            }
            catch (Exception e)
            {
                log.exception(e);
                if (debug) log.debug(action + e.getMessage());
                throw new RuntimeException(e.getMessage());
            }

        }
    }
d47 1
a47 1
     * Creates a new instance.
d49 1
a49 1
     * @@param dataMgr The associated <code>DataManager</code>.
d51 3
a53 4
    public ProjectManager(DataManager dataMgr)
    {
        super(dataMgr);
        dMgr = dataMgr;
d57 1
a57 3
     * Returns the host project ID
     *
     * @@return         The ID of the special host project.
d59 2
a60 3
    public String getHostProjectID()
    {
        return hostProjectID;
d62 1
d64 7
a70 8
    /**
     * Returns the domain project ID for the specified domain.
     *
     * @@return         The ID of the special domain project.
     */
    public String getDomainProjectID(String domainID)
    {
        return (String)projectIDForDomain.get(domainID);
d72 8
a79 1

d81 8
a88 7
     * Returns the "public projects" project ID for the specified domain.
     *
     * @@return         The ID of the special domain project.
     */
    public String getPublicDomainProjectID(String domainID)
    {
        return (String)publicProjectIDForDomain.get(domainID);
d90 3
a92 17

    /**
     * Checks whether a project has been approved.
     *
     * @@param connection A database connection.
     * @@param projectID The project ID to check.
     * @@return     Whether the project has been approved.
     *
     */
    public boolean isApproved(Connection connection, String projectID)
        throws SQLException, DataSetException, JoistDatabaseException
    {
        Record r = getProjectForID(connection, projectID);
        String approvedBy = r.getValue(PROJECT_APPROVED_BY).asString();
        UserUserGroupManager usrGrpMgr = (UserUserGroupManager)
            dMgr.getManager("org.tigris.helm.database.UserUserGroupManager");
        return(approvedBy.equals(usrGrpMgr.getNobodyUserID(connection)));
d94 3
a96 45

    /**
     * Checks whether a project name is valid.
     *
     * @@param name The project name to check.
     * @@return     Whether the name is valid.
     *
     * @@exception REException Malformed regular expression.
     */
    public boolean isValidProjectName(String name)
        throws REException
    {
        boolean isValid = false;

        if (name != null && name.length() > 0)
        {
            RE projectRE = null;
            try
            {
                projectRE= new RE(PROJECT_NAME_RE);
                isValid = projectRE.isMatch(name);
            }
            catch (REException e)
            {
                log.exception(e);
            }
        }

        return isValid;
    }

    /**
     * Throws an exception if a project in the given domain with the
     * given name already exists.
     */
    void assertProjectNonexistance(Connection connection, String domainID,
                                   String name)
        throws AlreadyExists, SQLException, DataSetException
    {
        Record project = getProjectForName(connection, domainID, name);
        if (project != null)
        {
            throw new AlreadyExists("Project " + 
                                    project.getValue(PROJECT_NAME).asString());
        }
d98 1
d101 48
a148 54
    ////////////////////////////////////////////////////////////////
    // Project addition
    ////////////////////////////////////////////////////////////////

    /**
     * Adds a project.
     *
     * @@param connection  The JDBC database connection to use.
     * @@param   domainID          ID of Domain in which the project resides.
     * @@param   name              Name of the project.
     * @@param   license           License of the project.
     * @@param   shortDescription  A short description of the project.
     * @@param   longDescription   A long description of the project.
     * @@param   aliasURL          URL to use as alias, if any.
     * @@param   memberPolicy      Member policy of the project.
     * @@param   proposedBy        User who proposed the project.
     * @@param   approvedBy        User who approved the project, if any.
     * @@return  The system-assigned project ID for the project.
     *
     * @@exception SQLException
     * @@exception DataSetException 
     * @@exception UpdateException
     */
    public Record addProject (Connection connection,
                              ProjectProfile profile,
                              String domainID,
                              String name, 
                              String license,
                              String shortDescription,
                              String longDescription,
                              String status,
                              String aliasURL,
                              String memberPolicy,
                              String proposedBy,
                              String approvedBy)
        throws SQLException, DataSetException, JoistDatabaseException, 
               UpdateException, AlreadyExists
    {
        assertProjectNonexistance(connection, domainID, name);
        
        return updateProject(connection, 
                             null,             //projectID
                             profile,          //profile
                             domainID,         //domainID
                             name,             //name
                             license,          //license
                             shortDescription, //shortDescription
                             longDescription,  //longDescription
                             status,           //status
                             aliasURL,         //aliasURL
                             memberPolicy,     //memberPolicy
                             proposedBy,       //proposedBy
                             approvedBy        //approvedBy
                             );
d150 8
a157 33


    ////////////////////////////////////////////////////////////////
    // Project manipulation
    ////////////////////////////////////////////////////////////////

    /**
     * Approves the project in the name of the given userID.
     *
     * @@param connection  The JDBC database connection to use.
     * @@param projectID   The project to approve.
     * @@param userID      The user approving the project.
     * @@return  The system-assigned project ID for the project.
     *
     * @@exception SQLException
     * @@exception DataSetException 
     */
    public void approveProject(Connection connection,
                               String projectID,
                               String userID)
        throws SQLException, DataSetException, JoistDatabaseException,
               UpdateException              
    {
        Record project = getProjectForID(connection, projectID);
        project.setValue(PROJECT_APPROVED_BY, userID);
        String status = project.getValue(PROJECT_STATUS).asString();
        String license = project.getValue(PROJECT_LICENSE).asString();
        String domainID = project.getValue(PROJECT_DOMAIN_ID).asString();
        if (status.equals("Unapproved") || status.equals("") || status == null)
        {
            project.setValue(PROJECT_STATUS, "Approved");
        }
        project.save();
d159 6
d166 3
a168 239
    /**
     * Updates a project's info.
     * This is public version of the private updateProject.  Used
     * by, eg., ProjectEdit  to update project info.
     * <p>
     * Pass nulls for all args you do not want to change.
     *
     * @@param connection        The JDBC database connection to use.
     * @@param projectID         The database key of the project to update.
     * @@param profile           Profile of the project to be created.
     * @@param domainID          ID of domain in which the project resides.
     * @@param name              Name of the project.
     * @@param license           License of the project.
     * @@param shortDescription  A short description of the project.
     * @@param longDescription   A long description of the project.
     * @@param status            Status of the project.
     * @@param categoryID        Category ID of this project
     * @@param aliasURL          Project URL
     * @@param memberPolicy      Member policy of the project. Looks like 
     *
     * @@exception SQLException
     * @@exception DataSetException 
     * @@exception JoistDatabaseException
     */
    public void updateProjectInfo(Connection connection,
                                  String projectID,
                                  String license,
                                  String shortDescription,
                                  String longDescription,
                                  String status, 
                                  String aliasURL,
                                  String memberPolicy
                                  )
        throws SQLException, DataSetException, JoistDatabaseException,
               UpdateException
    {
        updateProject(connection,
                      projectID,        //projectID
                      null,             //profile
                      null,             //domainID
                      null,             //name
                      license,          //license
                      shortDescription, //shortDescription
                      longDescription,  //longDescription
                      status,           //status
                      aliasURL,         //aliasURL
                      memberPolicy,     //memberPolicy
                      null,             //proposedBy
                      null              //approvedBy
                      );
    }
   
    /**
     * Updates an existing project or adds a new project to the database 
     * (depending on whether given a <code>projectID</code> or not).
     *
     * Note: This method only changes the database. It does not
     * run scripts.
     *
     * @@param connection        The JDBC database connection to use.
     * @@param projectID         The database key of the project to update 
     *                            (or null, in which case a new project is 
     *                            created).
     * @@param profile           Profile of a new project (immutable).
     * @@param domainID          ID of domain in which the project resides.
     * @@param name              Name of the project.
     * @@param license           License of the project.
     * @@param shortDescription  A short description of the project.
     * @@param longDescription   A longer description of the project.
     * @@param status            Status of the project.
     * @@param aliasURL          Project URL
     * @@param memberPolicy      Member policy of the project.
     * @@param proposedBy        ID of user who proposed project.
     * @@param approvedBy        ID of user who approved project.
     *
     * @@return  The system-assigned project ID for the project.
     *
     * @@exception SQLException
     * @@exception DataSetException 
     */
    private Record updateProject (Connection connection,
                                  String projectID, 
                                  ProjectProfile profile,
                                  String domainID,
                                  String name, 
                                  String license,
                                  String shortDescription,
                                  String longDescription,
                                  String status,
                                  String aliasURL,
                                  String memberPolicy,
                                  String proposedBy,
                                  String approvedBy)
        throws SQLException, DataSetException, JoistDatabaseException,
               UpdateException
    {
        Record project = null;
        TableDataSet projects = null;
        String action = null;
        
        if (projectID == null)
        {
            action = "Adding Project";
        } else {
            action = "Updating Project";
            profile = null; //Immutable.
        }

        try
        {
            projects = new TableDataSet(connection, TABLE_NAME, 
                                        new KeyDef().addAttrib(PROJECT_ID));

            if (projectID != null)
            {
                // Updating an existing project; get it.
                projects.where(PROJECT_ID + '=' + projectID);                
                projects.fetchRecords(1);
                if (debug) log.debug("Getting Record for existing project");
                project = projects.getRecord(0);
            }
            else
            {
                // Adding a new project.
                if (debug) log.debug("Adding Record for new project");
                project = projects.addRecord();
            }

            // Do update.
            if (domainID != null) project.setValue(PROJECT_DOMAIN_ID, 
                                                   domainID);

            if (name != null) project.setValue(PROJECT_NAME, name);

            if (profile != null) 
            {
                project.setValue(PROJECT_PROFILE, profile.getKey());
                project.setValue(PROJECT_TYPE, profile.getType());
            }

            if (shortDescription != null) 
                project.setValue(PROJECT_SHORT_DESCRIPTION, shortDescription);

            if (longDescription != null) 
                project.setValue(PROJECT_LONG_DESCRIPTION,longDescription);

            if (status != null) 
                project.setValue(PROJECT_STATUS,status);

            if (aliasURL != null)
                project.setValue(PROJECT_ALIAS_URL, aliasURL);

            if (memberPolicy != null)
                project.setValue(PROJECT_MEMBER_POLICY, memberPolicy);

            if (proposedBy != null)
                project.setValue(PROJECT_PROPOSED_BY, proposedBy);

            if (approvedBy != null)
                project.setValue(PROJECT_APPROVED_BY, approvedBy);

            project.save();
            if (projectID == null)
            {
                // NOTE: There is no way to refresh a Village Record which has
                // been created using TableDataSet.addRecord().
                projectID = getLastInsertedID(connection).toString();
                project.setValue(PROJECT_ID, projectID);
            }

            if (license != null) 
            { 
                setLicense(connection, projectID,  license);
            }

        }
        catch (DataSetException e)
        {
            log.exception(e);
            if (debug) log.debug(action + ": " + e.getMessage());
            throw e;
        }
        catch (SQLException e)
        {
            log.exception(e);
            if (debug) log.debug(action + ": " + e.getMessage());
            throw e;
        }
        finally
        {
            registerToClose(projects);
        }
        
        return project;
    }

    public void setLicense (Connection connection, String projectID,
                            String license)
        throws SQLException, DataSetException, JoistDatabaseException,
               UpdateException
    {
        //Get the project.
        Record project = getProjectForID(connection, projectID);

        //Get the old license--see if it's proprietary.
        String oldLicense = project.getValue(PROJECT_LICENSE).asString();
        if (oldLicense != null && oldLicense.equals(license))
        {
            return;
        }
        boolean wasProprietary = Licenses.isProprietary(oldLicense);
        boolean isProprietary = Licenses.isProprietary(license);

        //Set the new license.
        project.setValue(PROJECT_LICENSE, license);
        project.save();

        ProjectProjectGroupManager prjGrpMgr = (ProjectProjectGroupManager)
            dMgr.getManager
            ("org.tigris.helm.database.ProjectProjectGroupManager");
        
        String domainID = project.getValue(PROJECT_DOMAIN_ID).asString();

        //If we used not to be proprietary and now we are, remove this project
        //from the public projects list.
        if ((!wasProprietary || oldLicense == null) && isProprietary)
        {
            prjGrpMgr.removeProjectFromGroup
                (connection, projectID, getPublicDomainProjectID(domainID));
        }
        
        //If we used to be proprietary and now we're not, add this project
        //to the public projects list.
        if ((wasProprietary || oldLicense == null) && !isProprietary 
            && isApproved(connection, projectID))
        {
            prjGrpMgr.addProjectToGroup
                (connection, projectID, getPublicDomainProjectID(domainID));
        }
d170 20
d191 26
a216 67

    ////////////////////////////////////////////////////////////////
    // Project deletion
    ////////////////////////////////////////////////////////////////

    /**
     * Deletes an existing project from the database
     *
     * @@param      connection    the JDBC database connection
     * @@param      projectID       the ID of the project to delete
     * @@exception SQLException
     */
    public void  deleteProject (Connection connection, String projectID)
        throws SQLException, DataSetException, JoistDatabaseException, 
               UpdateException
    {
        String action = "Deleting Project";

        Record project = getProjectForID(connection, projectID);
        String projectName = project.getValue(PROJECT_NAME).asString();

        TableDataSet projects = null;
        try
        {
            //Delete the project.
            projects = new TableDataSet(connection, TABLE_NAME, 
                                        new KeyDef().addAttrib(PROJECT_ID));

            projects.where(buildWhereClause(projectID, //projectID
                                            null,      //profile
                                            ProjectType.REGULAR, //type
                                            null,      //domainID
                                            null,      //name
                                            null,      //aliasURL
                                            null,      //license
                                            null,      //shortDescription
                                            null,      //longDescription
                                            null,      //status
                                            null,      //memberPolicy
                                            null      //approvedBy
                                            ));
            projects.fetchRecords();
            if (projects.containsRecord(0)) 
            {
                Record r = projects.getRecord(0);
                r.markToBeDeleted();
                r.save();
            }
        }
        catch (DataSetException e)
        {
            log.exception(e);
            if (debug) log.debug(action + ": " + projectID + ": " + 
                                 e.getMessage());
            throw e;
        }
        catch (SQLException e)
        {
            log.exception(e);
            if (debug) log.debug(action + ": " + projectID + ": " + 
                                 e.getMessage());
            throw e;
        }
        finally
        {
            registerToClose(projects);
        }
d218 3
d222 13
a234 25
    ////////////////////////////////////////////////////////////////
    // Project retrieval
    ////////////////////////////////////////////////////////////////

    /**
     * Gets a project name for a project ID.
     *
     * @@param    connection    A JDBC database connection
     * @@param    projectID       The projectID to obtain 
     * @@return     a String
     * @@exception    SQLException
     * @@exception    DataSetException
     */
    public String getProjectName (Connection connection, String projectID)
        throws SQLException, DataSetException, JoistDatabaseException
    {
        Record project = getProjectForID(connection, projectID);
        if (project != null)
        {
            return project.getValue(PROJECT_NAME).asString();
        }
        else
        {
            throw new JoistDatabaseException("No such project: " + projectID);
        }
d236 3
d240 13
a252 24
    /**
     * Retrieves the ID for a project with known name and domain
     *
     * @@param    connection    A JDBC database connection
     * @@param    domainId      Domain in which the project resides
     * @@param    projectName   The project name to identify
     * @@return     a String
     * @@exception    SQLException
     * @@exception    DataSetException
     */
    public String getProjectID (Connection connection, String domainID, 
                                String name)
        throws SQLException, DataSetException, JoistDatabaseException
    {
        Record project = getProjectForName(connection, domainID, name);
        if (project != null)
        {
            return project.getValue(PROJECT_ID).asString();
        }
        else
        {
            throw new JoistDatabaseException("Invalid domain/project: " + 
                                             domainID + '/' + name);
        }
d255 2
a256 28
    /**
     * Given a projectID, find the associated domain name.
     *
     * @@param connection   A JDBC database connection
     * @@param projectID    The projectID whose domain will be found
     * @@return a String
     * @@exception DataSetException
     */
    public String getProjectDomain (Connection connection, String projectID)
        throws DataSetException, SQLException
    {
        Record project = getProjectForID(connection, projectID);
        String domainID;
        if (project != null)
            domainID = project.getValue(PROJECT_DOMAIN_ID).asString();
        else
            throw new DataSetException("bad projectID (no record found)");

        DomainManager domMgr = (DomainManager)dMgr
            .getManager("org.tigris.helm.database.DomainManager");
        try {
            return domMgr.getDomainName(domainID);
        } catch (JoistDatabaseException e) {
            log.exception(e);
            if (debug) log.debug("JoistDatabaseException in getProjectDomain");
            throw new DataSetException(e.getMessage());
        }
    }
d258 20
a277 125
    /**
     * Retrieves a Record containing the project specified by domain and name.
     *
     * @@param  connection    A JDBC database connection
     * @@param  domainID      Domain of the project to be retrieved
     * @@param  name          Name of the project to be retrieved
     * @@return The request project's data.
     * @@exception    SQLException
     * @@exception    DataSetException
     */
    public Record getProjectForName(Connection connection, String domainID, 
                                    String name)
        throws SQLException, DataSetException
    {
        Record project = null;
        DataSet projects = getProjects(null,           //order
                                       connection,     //connection
                                       null,           //projectID
                                       null,           //profile
                                       null,           //type
                                       domainID,       //domainID
                                       name,           //name
                                       null,           //aliasURL
                                       null,           //license
                                       null,           //shortDescription
                                       null,           //longDescription
                                       null,           //status
                                       null,           //memberPolicy
                                       null            //approvedBy
                                       );
        if (projects != null && projects.containsRecord(0))
        {
            project = projects.getRecord(0);
        }
        return project;
    }

    /**
     * Retrieves a DataSet containing the project specified by ID
     *
     * @@param  connection    A JDBC database connection
     * @@param  domainID      ID of the project to be retrieved
     * @@return The requested project's record.
     * @@exception    SQLException
     * @@exception    DataSetException
     */
    public Record getProjectForID(Connection connection, String projectID)
        throws SQLException, DataSetException
    {
        Record project = null;
        DataSet projects = getProjects(null,           //order
                                       connection,     //connection
                                       projectID,      //projectID
                                       null,           //profile
                                       null,           //type
                                       null,           //domainID
                                       null,           //name
                                       null,           //aliasURL
                                       null,           //license
                                       null,           //shortDescription
                                       null,           //longDescription
                                       null,           //status
                                       null,           //memberPolicy
                                       null            //approvedBy
                                       );
        if (projects != null && projects.containsRecord(0))
        {
            project = projects.getRecord(0);
        }
        return project;
    }
        
    /**
     * Retrieves a project from domain and alias URL.
     *
     * @@param    conn     The JDBC database connection use to.
     * @@param    domainID The ID of the domain (or <code>null</code>).
     * @@param    aliasURL The project alias URL.
     * @@return            The project for an alias URL.
     *
     * @@exception SQLException
     * @@exception DataSetException
     * @@exception JoistDatabaseException
     */
    // TODO: is domainID needed here? JER
    public Record getProjectForAliasURL (Connection conn, String domainID, 
                                         String aliasURL)
        throws SQLException, DataSetException, JoistDatabaseException
    {
        Record project = null;
        if (aliasURL != null && aliasURL.length() > 0)
        {
            TableDataSet projects = null;
            projects.where(buildWhereClause(null,      //projectID
                                            null,      //profile
                                            null,      //type
                                            domainID,  //domainID
                                            null,      //name
                                            aliasURL,  //aliasURL
                                            null,      //license
                                            null,      //shortDescription
                                            null,      //longDescription
                                            null,      //status
                                            null,      //memberPolicy
                                            null       //approvedBy
                                            ));
            try
            {
                projects = new TableDataSet(conn, TABLE_NAME);
                projects.fetchRecords();
                if (projects.size() > 1)
                {
                    throw new JoistDatabaseException("Duplicate alias URL for "
                                                     + "domain: " + aliasURL + 
                                                     " for " +domainID);
                }
                project = projects.getRecord(0);
            }
            finally
            {
                registerToClose(projects);
            }
        }
        return project;
    }
d279 1
a279 528
    /**
     * Retrieves a DataSet containing all regular projects for a domain.
     *
     * @@param  connection    A JDBC database connection.
     * @@param  domainID      The domain for which to get projects.
     * @@return a DataSet
     * @@exception    SQLException
     * @@exception DataSetException 
     */
    public DataSet getProjectsForDomain (Connection connection, 
                                         String domainID)
        throws SQLException, DataSetException
    {
        return getProjectsForDomainType(connection, domainID, 
                                        ProjectType.REGULAR);
    }

    /**
     * Retrieves a DataSet containing all category projects for a domain.
     *
     * @@param  connection    A JDBC database connection.
     * @@param  domainID      The domain for which to get categories.
     * @@return a DataSet
     * @@exception    SQLException
     * @@exception DataSetException 
     */
    public DataSet getCategoriesForDomain (Connection connection, 
                                         String domainID)
        throws SQLException, DataSetException
    {
        return getProjectsForDomainType(connection, domainID, 
                                        ProjectType.CATEGORY);
    }

    /**
     * Retrieves a DataSet containing all projects for a domain and
     * a given type.
     *
     * @@param  connection    A JDBC database connection.
     * @@param  domainID      The domain for which to get projects.
     * @@param  type          The type of project to get.
     * @@return a DataSet
     * @@exception    SQLException
     * @@exception DataSetException 
     */
    public DataSet getProjectsForDomainType (Connection connection, 
                                             String domainID,
                                             String type)
        throws SQLException, DataSetException
    {
        return getProjects(null,           //order
                           connection,     //connection
                           null,           //projectID
                           null,           //profile
                           type,           //type
                           domainID,       //domainID
                           null,           //name
                           null,           //aliasURL
                           null,           //license
                           null,           //shortDescription
                           null,           //longDescription
                           null,           //status
                           null,           //memberPolicy
                           null            //approvedBy
                           );
    }        

    /**
     * Retrieves a DataSet containing all projects on the site.
     *
     * @@param  connection    A JDBC database connection.
     * @@return a DataSet
     * @@exception    SQLException
     * @@exception DataSetException 
     */
    public DataSet getAllProjects (Connection connection)
        throws SQLException, DataSetException
    {
        return getProjects(null,           //order
                           connection,     //connection
                           null,           //projectID
                           null,           //profile
                           null,           //type
                           null,           //domainID
                           null,           //name
                           null,           //aliasURL
                           null,           //license
                           null,           //shortDescription
                           null,           //longDescription
                           null,           //status
                           null,           //memberPolicy
                           null            //approvedBy
                           );
    }

    /**
     * Retrieves a DataSet containing all projects belonging to a
     * given category.
     *
     * @@param  connection    A JDBC database connection.
     * @@param  categoryID    The ID of the category to filter.
     * @@return a DataSet
     * @@exception    SQLException
     * @@exception DataSetException 
     */
    public DataSet getProjectsForCategory (Connection connection, 
                                           String categoryID)
        throws SQLException, DataSetException
    {
        String action = "Getting Projects for Domain Category: ";
        QueryDataSet projects = null;

        ProjectProjectGroupManager prjGrpMgr = (ProjectProjectGroupManager)
            dMgr.getManager("org.tigris.helm.database.ProjectProjectGroupManager");

        try
        {
            String otherTable = prjGrpMgr.TABLE_NAME;
            String otherProjectID = otherTable + "." + prjGrpMgr.joinBaseField;
            String otherCategoryID = otherTable + "." + prjGrpMgr.joinCompositeField;
            String projectID = TABLE_NAME + "." + PROJECT_ID;

            StringBuffer q = new StringBuffer();
            q.append("select ").append(TABLE_NAME).append(".* from ")
                .append(TABLE_NAME).append(", ").append(otherTable);
            q.append(" where ").append(projectID)
                .append("=").append(otherProjectID);
            q.append(" and ").append(otherCategoryID)
                .append("=").append(categoryID);

            projects = new QueryDataSet(connection, q.toString());

            projects.fetchRecords();
            
        }
        catch (DataSetException e)
        {
            log.exception(e);
            if (debug) log.debug(action + e.getMessage());
            throw e;
        }
        catch (SQLException e)
        {
            log.exception(e);
            if (debug) log.debug(action + e.getMessage());
            throw e;
        }
        finally
        {
            registerToClose(projects);
        }
        return projects;        
    }        

    /**
     * Retrieves a DataSet containing all categories belonging to a
     * given project.
     *
     * @@param  connection   A JDBC database connection.
     * @@param  projectID    The ID of the project for which to 
     *                       obtain categories.
     * @@return a DataSet
     * @@exception SQLException
     * @@exception DataSetException 
     */
    public DataSet getCategoriesForProject (Connection connection, 
                                           String projectID)
        throws SQLException, DataSetException
    {
        String action = "Getting Categories for Project: ";
        QueryDataSet categories = null;
        
        ProjectProjectGroupManager prjGrpMgr = (ProjectProjectGroupManager)
            dMgr.getManager("org.tigris.helm.database.ProjectProjectGroupManager");

	PreparedStatement stmt = null;        
        try
        {
            String groupTable = prjGrpMgr.TABLE_NAME;
            String groupProjectIDField = groupTable + "." + 
                prjGrpMgr.joinBaseField;
            String groupCategoryIDField = groupTable + "." + 
                prjGrpMgr.joinCompositeField;
            String projectIDField = TABLE_NAME + "." + 
                PROJECT_ID;
            String projectTypeField = TABLE_NAME + "." + 
                PROJECT_TYPE;

            StringBuffer q = new StringBuffer();
            q.append("select ").append(TABLE_NAME).append(".* from ")
                .append(TABLE_NAME).append(", ").append(groupTable);
            q.append(" where ").append(projectTypeField).append("='")
                .append(ProjectType.CATEGORY).append("'");
            q.append(" and ").append(groupProjectIDField).append("=")
                .append(projectID);
            q.append(" and ").append(projectIDField).append("=")
                .append(groupCategoryIDField);

            categories = new QueryDataSet(connection, q.toString());

            categories.fetchRecords();
            
        }
        catch (DataSetException e)
        {
            log.exception(e);
            if (debug) log.debug(action + e.getMessage());
            throw e;
        }
        catch (SQLException e)
        {
            log.exception(e);
            if (debug) log.debug(action + e.getMessage());
            throw e;
        }
        finally
        {
            registerToClose(categories);
        }
        return categories;        
    }        

    /**
     * Retrieves a DataSet containing unapproved projects for a domain.
     *
     * @@param  connection    A JDBC database connection.
     * @@param  domainID      The domain for which to get projects.
     * @@return a DataSet
     * @@exception    SQLException
     * @@exception DataSetException 
     */
    public DataSet getUnapprovedProjectsForDomain (Connection connection, 
                                                   String domainID)
        throws SQLException, DataSetException
    {
	// Get the userID for user "**Nobody"
	DataManager dMgr = getDataManager();
	UserManager uMgr =
	    (UserManager) dMgr.getManager("org.joist.database.UserManager");
	String nobodyUserID = null;
	try {
	    Record userRcd = uMgr.getUserForLoginID(connection, "**Nobody");
	    nobodyUserID = userRcd.getValue("userID").asString();
	}
	catch (JoistDatabaseException e) {
	    String message =
		"JoistDatabase problem in getUnapprovedProjectsForDomain: " +
		e.getMessage();
            if (debug) log.debug(message);
            throw new DataSetException(message);
	}
	catch (SQLException e) {
            if (debug) log.debug(
		"SQL problem in getUnapprovedProjectsForDomain: "
		+ e.getMessage());
            log.exception(e);
            throw e;
	}
        
	// Now look up the unapproved projects (i.e., APPROVED_BY "**Nobody")
        return getProjectsInDomainApprovedByUser (connection, domainID, 
                                                  nobodyUserID);
    }        

    /**
     * Retrieves a DataSet containing projects approved by a particular
     * user.
     *
     * @@param  connection    A JDBC database connection.
     * @@param  domainID      The domain for which to get projects.
     * @@return a DataSet
     * @@exception    SQLException
     * @@exception DataSetException 
     */
    public DataSet getProjectsInDomainApprovedByUser (Connection connection, 
                                                      String domainID,
                                                      String userID)
        throws SQLException, DataSetException
    {
        
        return getProjects(null,           //order
                           connection,     //connection
                           null,           //projectID
                           null,           //profile
                           null,           //type
                           domainID,       //domainID
                           null,           //name
                           null,           //aliasURL
                           null,           //license
                           null,           //shortDescription
                           null,           //longDescription
                           null,           //status
                           null,           //memberPolicy
                           userID          //approvedBy
                           );
    }
       
    /**
     *  Retrieves projects by any of their fields
     *
     * @@param   connection        A JDBC database connection
     * @@param   projectID         A project ID
     * @@param   profile           A project profile
     * @@param   type              A project type
     * @@param   domainID          A project ID 
     * @@param   name              A project name
     * @@param   aliasURL          An alias URL
     * @@param   license           A license
     * @@param   shortDescription  A short description
     * @@param   longDescription   A long description
     * @@param   memberPolicy      A member policy
     * @@param   approvedBy        A user ID
     * @@return     a DataSet
     * @@exception    SQLException
     * @@exception    DataSetException
     */
    private TableDataSet getProjects(String order,
                                     Connection connection,
                                     String projectID,
                                     ProjectProfile profile,
                                     String type,
                                     String domainID,
                                     String name,
                                     String aliasURL,
                                     String license,
                                     String shortDescription,
                                     String longDescription,
                                     String status,
                                     String memberPolicy,
                                     String approvedBy)
        throws SQLException, DataSetException
    {
        String action = "Getting Projects: ";
        TableDataSet projects = null;

        try
        {
            projects = new TableDataSet(connection, TABLE_NAME, 
                                        new KeyDef().addAttrib(PROJECT_ID));
            projects.where(buildWhereClause(projectID,        //projectID
                                            profile,          //profile
                                            type,             //type
                                            domainID,         //domainID
                                            name,             //name
                                            aliasURL,         //aliasURL
                                            license,          //license
                                            shortDescription, //shortDescription
                                            longDescription,  //longDescription
                                            status,           //status
                                            memberPolicy,     //memberPolicy
                                            approvedBy        //approvedBy
                                            ));
            if (order != null)
            {
                projects.order(order);
            }
            projects.fetchRecords();
        }
        catch (DataSetException e)
        {
            log.exception(e);
            if (debug) log.debug(action + e.getMessage());
            throw e;
        }
        catch (SQLException e)
        {
            log.exception(e);
            if (debug) log.debug(action + e.getMessage());
            throw e;
        }
        finally
        {
            registerToClose(projects);
        }
        return projects;
    }    
    
    /**
     * Creates a SQL <code>where</code> clause.
     */
    protected static String buildWhereClause (String projectID, 
                                              ProjectProfile profile,
                                              String type,
                                              String domainID,
                                              String name,
                                              String aliasURL,
                                              String license,
                                              String shortDescription,
                                              String longDescription,
                                              String status,
                                              String memberPolicy,
                                              String approvedBy
                                              )
    {
        StringBuffer whereClause = new StringBuffer();
        
        boolean firstclause = true;

        if (projectID != null)
        {
            whereClause.append(PROJECT_ID).append('=').append(projectID);
            firstclause = false;
        }

        if (profile != null)
        {
            if (!firstclause)
            {
                whereClause.append(" AND ");
            }
            whereClause.append(PROJECT_PROFILE).append('=');
            whereClause.append(escapeAndQuoteSQL(profile.getKey()));
            firstclause = false;
        }

        if (type != null)
        {
            if (!firstclause)
            {
                whereClause.append(" AND ");
            }
            whereClause.append(PROJECT_TYPE).append('=');
            whereClause.append(escapeAndQuoteSQL(type));
            firstclause = false;
        }

        if (domainID != null)
        {
            if (!firstclause)
            {
                whereClause.append(" AND ");
            }
            firstclause = false;
            whereClause.append(PROJECT_DOMAIN_ID).append('=').append(domainID);
        }

        if (name != null)
        {
            if (!firstclause)
            {
                whereClause.append(" AND ");
            }
            firstclause = false;
            whereClause.append(PROJECT_NAME).append('=')
                .append(escapeAndQuoteSQL(name));
        }

        if (aliasURL != null)
        {
            if (!firstclause)
            {
                whereClause.append(" AND ");
            }
            firstclause = false;
            whereClause.append(PROJECT_ALIAS_URL).append('=')
                .append(escapeAndQuoteSQL(aliasURL));
        }

        if (license != null)
        {
            if (!firstclause)
            {
                whereClause.append(" AND ");
            }
            firstclause = false;
            whereClause.append(PROJECT_LICENSE).append('=')
                .append(escapeAndQuoteSQL(license));
        }

        if (shortDescription != null)
        {
            if (!firstclause)
            {
                whereClause.append(" AND ");
            }
            firstclause = false;
            whereClause.append(PROJECT_SHORT_DESCRIPTION).append(" LIKE ")
                .append(escapeAndQuoteSQL("*" + shortDescription + "*"));
        }
        
        if (longDescription != null)
        {
            if (!firstclause)
            {
                whereClause.append(" AND ");
            }
            firstclause = false;
            whereClause.append(PROJECT_LONG_DESCRIPTION).append(" LIKE ")
                .append(escapeAndQuoteSQL("*" + longDescription + "*"));
        }

        if (status != null)
        {
            if (!firstclause)
            {
                whereClause.append(" AND ");
            }
            firstclause = false;
            status = escapeAndQuoteSQL(status);
            whereClause.append(PROJECT_STATUS).append('=');
            whereClause.append(status);
        }

        if (memberPolicy != null)
        {
            if (!firstclause)
            {
                whereClause.append(" AND ");
            }
            firstclause = false;
            whereClause.append(PROJECT_MEMBER_POLICY).append('=');
            whereClause.append(memberPolicy);
        }

        if (approvedBy != null)
        {
            if (!firstclause)
            {
                whereClause.append(" AND ");
            }
            firstclause = false;
            whereClause.append(PROJECT_APPROVED_BY).append('=')
		.append(approvedBy);
        }

        return whereClause.toString();
    }
}
@


