head	1.23;
access;
symbols
	TIGRIS_1_1_0RC2:1.6.6.8
	TIGRIS_1_1_0RC1:1.6.6.8
	TIGRIS_1_1:1.6.6.8.0.2
	TIGRIS_1_0_8:1.6.6.8
	TIGRIS_1_0_8RC3:1.6.6.8
	TIGRIS_1_0_8RC2:1.6.6.8
	TIGRIS_1_0_8RC1:1.6.6.8
	TIGRIS_1_0_7:1.6.6.8
	TIGRIS_1_0_7RC3:1.6.6.8
	TIGRIS_1_0_7RC2:1.6.6.8
	TIGRIS_1_0_7RC1:1.6.6.8
	TIGRIS_1_0_6:1.6.6.8
	TIGRIS_1_0_6RC5:1.6.6.8
	TIGRIS_1_0_6RC4:1.6.6.7
	TIGRIS_1_0_6RC3:1.6.6.7
	TIGRIS_1_0_6RC2:1.6.6.7
	TIGRIS_1_0_6RC1:1.6.6.7
	TIGRIS_1_0_5:1.6.6.4
	TIGRIS_1_0_5RC6:1.6.6.4
	TIGRIS_1_0_5RC5:1.6.6.4
	TIGRIS_1_0_5RC4:1.6.6.2
	TIGRIS_1_0_5RC3:1.6.6.1
	TIGRIS_1_0_5RC2:1.6
	TIGRIS_1_0_5RC1:1.6
	TIGRIS_1_0_4:1.6
	TIGRIS_1_0_3:1.6
	TIGRIS_1_0_2:1.6
	TIGRIS_1_0_1:1.6
	TIGRIS_1_0:1.6.0.6
	TIGRIS_1_0_0:1.6
	TIGRIS_1_0_0_RC1:1.6.0.2
	dlr:1.1.1
	HELM_PEER_PORT_BRANCH:1.1.1.1;
locks; strict;
comment	@# @;


1.23
date	2001.08.11.09.08.02;	author dlr;	state Exp;
branches;
next	1.22;

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

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

1.20
date	2001.06.13.23.07.35;	author leonardr;	state Exp;
branches;
next	1.19;

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

1.18
date	2001.05.31.02.41.37;	author leonardr;	state Exp;
branches;
next	1.17;

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

1.16
date	2001.05.23.01.50.13;	author dlr;	state Exp;
branches;
next	1.15;

1.15
date	2001.05.18.21.56.26;	author leonardr;	state Exp;
branches;
next	1.14;

1.14
date	2001.05.18.19.38.04;	author leonardr;	state Exp;
branches;
next	1.13;

1.13
date	2001.05.17.14.51.16;	author leonardr;	state Exp;
branches;
next	1.12;

1.12
date	2001.05.16.00.08.24;	author leonardr;	state Exp;
branches;
next	1.11;

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

1.10
date	2001.05.09.01.59.49;	author leonardr;	state Exp;
branches;
next	1.9;

1.9
date	2001.04.18.00.05.40;	author leonardr;	state Exp;
branches;
next	1.8;

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

1.7
date	2001.04.07.00.04.37;	author leonardr;	state Exp;
branches;
next	1.6;

1.6
date	2001.03.14.00.04.13;	author leonardr;	state Exp;
branches
	1.6.6.1;
next	1.5;

1.5
date	2001.03.13.19.08.00;	author leonardr;	state Exp;
branches;
next	1.4;

1.4
date	2001.03.12.21.16.34;	author leonardr;	state Exp;
branches;
next	1.3;

1.3
date	2001.03.07.01.53.22;	author lucas;	state Exp;
branches;
next	1.2;

1.2
date	2001.02.21.03.02.22;	author edk;	state Exp;
branches;
next	1.1;

1.1
date	2001.02.05.16.36.54;	author leonardr;	state dead;
branches
	1.1.1.1
	1.1.2.1;
next	;

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

1.1.2.1
date	2001.02.05.16.36.54;	author leonardr;	state Exp;
branches;
next	1.1.2.2;

1.1.2.2
date	2001.02.05.17.43.01;	author leonardr;	state Exp;
branches;
next	1.1.2.3;

1.1.2.3
date	2001.02.15.19.22.24;	author leonardr;	state Exp;
branches;
next	1.1.2.4;

1.1.2.4
date	2001.02.15.20.50.37;	author leonardr;	state Exp;
branches;
next	1.1.2.5;

1.1.2.5
date	2001.02.16.00.53.03;	author leonardr;	state Exp;
branches;
next	1.1.2.6;

1.1.2.6
date	2001.02.16.03.01.27;	author dlr;	state Exp;
branches;
next	1.1.2.7;

1.1.2.7
date	2001.02.18.02.54.29;	author leonardr;	state Exp;
branches;
next	1.1.2.8;

1.1.2.8
date	2001.02.18.08.26.37;	author dlr;	state Exp;
branches;
next	;

1.6.6.1
date	2001.05.18.17.02.18;	author leonardr;	state Exp;
branches;
next	1.6.6.2;

1.6.6.2
date	2001.05.18.19.13.56;	author leonardr;	state Exp;
branches;
next	1.6.6.3;

1.6.6.3
date	2001.05.19.01.16.52;	author leonardr;	state Exp;
branches;
next	1.6.6.4;

1.6.6.4
date	2001.05.19.01.20.03;	author leonardr;	state Exp;
branches;
next	1.6.6.5;

1.6.6.5
date	2001.05.24.23.31.09;	author leonardr;	state Exp;
branches;
next	1.6.6.6;

1.6.6.6
date	2001.06.01.19.18.07;	author leonardr;	state Exp;
branches;
next	1.6.6.7;

1.6.6.7
date	2001.06.01.19.26.36;	author leonardr;	state Exp;
branches;
next	1.6.6.8;

1.6.6.8
date	2001.06.13.23.14.19;	author leonardr;	state Exp;
branches;
next	;


desc
@@


1.23
log
@Upgrading to Turbine 3.0-dev, Fulcrum 1.0, and Torque 1.0.
@
text
@/* ================================================================
 * Copyright (c) 2000-2001 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.om;

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

import org.apache.turbine.util.Log;
import org.apache.commons.util.exception.NestableException;

import org.tigris.helm.om.*;
import org.tigris.helm.security.*;
import org.tigris.helm.tool.task.*;
import org.tigris.helm.tool.DBFlag;

/**
 * Helm task.
 *
 * @@author <a href="mailto:leonardr@@collab.net">Leonard Richardson</a>
 */
public class HelmTask extends Task
{
    /**
     * Whether or not to print debugging information.
     */
    private static final boolean DEBUG = true;

    /**
     * The name of the component which runs our tasks.
     */
    public static final String COMPONENT_NAME = "Helm";

    /**
     * The name of the component which runs our tasks.
     */
    public static final String PROJECT_ADD_COMMAND = "ProjectAdd";

    ////////////////////////////////////////////////////////////////
    // Project scripts.
    ////////////////////////////////////////////////////////////////

    /**
     * Add a new project to CVS, Issuezilla, etc.
     */
    public static void addProject(User onBehalfOf, Project project)
        throws Exception
    {
	String cmd = PROJECT_ADD_COMMAND;
        add(onBehalfOf, project.getID(), cmd, 
            ScriptTool.makeProjectArgs(project));
    }

    /**
     * Remove a project from CVS, Issuezilla, etc.
     */
    public static void deleteProject(User onBehalfOf, Project project)
        throws Exception
    {
     
        String cmd = "ProjectDelete";
        add(onBehalfOf, project.getID(), cmd, 
            ScriptTool.makeProjectArgs(project));
    }

    //
    // Generation of module tasks.
    //

    /**
     * Add a new module to Issuezilla.
     */
    public static void addModule(User onBehalfOf,
                                 Project project,
                                 String moduleName,
                                 String moduleDescription,
                                 String isWeb)
        throws Exception
    {
	String cmd = "ModuleAdd";
        Map args = ScriptTool.makeProjectArgs(project);
        args.putAll(ScriptTool.makeModuleArgs(moduleName, moduleDescription, isWeb));
        add(onBehalfOf, project.getID(), cmd, args);
    }

    /**
     * Remove a module from Issuezilla.
     */
    public static void deleteModule(User onBehalfOf,
                                    Project project,
                                    String moduleName)
        throws Exception
    {
	String cmd = "ModuleDelete";

	Map args = ScriptTool.makeProjectArgs(project);
        args.putAll(ScriptTool.makeModuleArgs(moduleName, null, null));
        add(onBehalfOf, project.getID(), cmd, args);
    }
    
    // Overridden methods.

    /**
     * Add a task to be performed. Takes a List of arguments--use
     * one of the wrapper methods (eg. MemberAdd) to make a list.
     */
    public static Task add (User onBehalfOf, String affectedObjectID, 
                            String command, Map arguments)
        throws Exception
    {
        return Task.add(onBehalfOf, COMPONENT_NAME, affectedObjectID,
                        command, ScriptTool.listifyArguments(arguments));
    }

    // running of tasks

    /**
     * Runs the given task.
     */
    public static void runTask(Task t)
        throws TaskException
    {
        if (!t.getComponent().equals(COMPONENT_NAME))
        {
            throw new TaskException
                ("HelmTask cannot run a task for component " 
                 + t.getComponent());
        }

        TaskException ue = null;
        String command = t.getCommand();
        ArrayList args = null;        
        
        try 
        {
            args = t.readArgsArray();
        }
        catch (Exception e) {
            throw new TaskException(e);
        }

        if (command != null)
        {
            try                 
            {
                if (command.equals("Initialize Project Resources"))
                {
                    //For every child of this project, this task will
                    //generate an AddProject and a number of
                    //ModuleAdds.  
                    Project project = ProjectPeer.getInstance
                        (String.valueOf(t.getAffectedObjectId()));
                    User user = UserPeer.getInstance
                        (String.valueOf(t.getOnBehalfOf()));
                    project.runCreationScripts(user);
                }
                else
                {
                    ScriptTool.runScript(command, args);
                }
            } 
            catch (Exception e) 
            {                
                //TODO: If this happens, reset the timestamp of the script
                //rather than deleting it.
                ue = new TaskException(e);
            }

            t.setAsDone(); 

            if (ue != null) 
            { 
                throw ue;                
            }
        }
    }   

}


@


1.22
log
@Stop coddling IZ in terms of user accounts; assume that IZ can get its permissions from Helm through the XML-RPC interface.
@
text
@d53 1
a53 1
import org.apache.turbine.util.TurbineException;
@


1.21
log
@Huge patch of the day: Got rid of redundant HELM_DOMAIN table. The project representation of the domain and the host is now the canonical one. Host and Domain now subclass ProjectGroup. The canonical representation of a project's membership in a domain group is now the corresponding mapping in HELM_PROJECT_PROJECTGROUP. Schema changes: No more HELM_DOMAIN table (obviously); no more DOMAIN_ID in HELM_PROJECT; HELM_USER and HELM_VC_VIEW now have foreign keys in HELM_PROJECT instead of HELM_DOMAIN.
@
text
@a143 32
   /**
    * Remove user from all projects in domain.
    */
    public static void deleteUser(User onBehalfOf, Domain domain, User user)
        throws Exception
    {
        // Get a special project from the domain representing 
        // 'all projects in domain', and run MemberDelete script
        // against that project a final time when deleting the 
        // user alltogether:

        List userList = new ArrayList();
        userList.add(user);

        String cmd = "MemberDelete";
	Map args = ScriptTool.makeProjectArgs(domain);
        args.putAll(ScriptTool.makeUserArgs(userList, null));

        add(onBehalfOf, domain.getID(), cmd, args);
    }

    /**
     * Disable all Issuezilla accounts for the given project.
     */
    public static void disableAllAccounts(User onBehalfOf, Project project)
        throws Exception
    {	
	String cmd = "MemberDisableAll";
        add(onBehalfOf, project.getID(), cmd, 
            ScriptTool.makeProjectArgs(project));
    }

d193 1
a193 2
                    //ModuleAdds.  The project's issue tracking
                    //accounts will also be built.
a198 1
                    project.rebuildIssueTracking();
@


1.20
log
@Don't send warning email if there's a ProjectAdd task in the task list which might resolve the problem.
@
text
@a157 1
        Project domainProject = domain.getSpecialProject();
d159 1
a159 1
	Map args = ScriptTool.makeProjectArgs(domainProject);
d162 1
a162 1
        add(onBehalfOf, domainProject.getID(), cmd, args);
@


1.19
log
@Got rid of IssueTrackingRebuild task for good.
@
text
@d77 5
d92 1
a92 1
	String cmd = "ProjectAdd";
d255 1
@


1.18
log
@Factored out script running code to support new IssueTrackingRebuildService.
@
text
@a103 12
    /**
     * Rebuild a project's issue tracking. This is something of a
     * special case, as it triggers many scripts being run instead of
     * just one. 
     */
    public static void rebuildIssueTracking(Project project)
        throws Exception
    {     
        String cmd = "Rebuild Issue Tracking";
        add(UserPeer.getSuperUser(), project.getID(), cmd, new HashMap());
    }

@


1.17
log
@Got rid of denormalized project-project group mapping table in favor of per-JVM caching solution.
@
text
@a50 1
import java.io.*;
a53 3
import org.apache.turbine.util.TurbineException;

import org.joist.util.JoistProperties;
a76 7
    public static final long MILLIS_TO_WAIT_FOR_SCRIPT = 1000 * 60 * 2;

    public static final long INCREMENTAL_WAIT_MILLIS = 1000;

    //FIXME: Please! This should be in a conf file somewhere.
    protected static final String SCRIPT_DIR = "/helm/perl/scripts/";

d88 2
a89 1
        add(onBehalfOf, project.getID(), cmd, makeProjectArgs(project));
d100 2
a101 1
        add(onBehalfOf, project.getID(), cmd, makeProjectArgs(project));
d131 2
a132 2
        Map args = makeProjectArgs(project);
        args.putAll(makeModuleArgs(moduleName, moduleDescription, isWeb));
d146 2
a147 2
	Map args = makeProjectArgs(project);
        args.putAll(makeModuleArgs(moduleName, null, null));
d167 2
a168 2
	Map args = makeProjectArgs(domainProject);
        args.putAll(makeUserArgs(userList, null));
d180 2
a181 105
        add(onBehalfOf, project.getID(), cmd, makeProjectArgs(project));
    }

    //
    // Argument builders--these all return a Map suitable for passing
    // to <code>add</code> or <code>runScript</code>. Every script right
    // now calls makeProjectArgs; some will call one of the other
    // argument builders as well.
    //

    private static void makeArgMapping(Map map, String key, String value)
    {
        if (value != null && !("".equals(value)))
        {
            map.put(key,value);
        }
    }

    /**
     * Returns a map populated with all relevant fields from a project.
     */
    private static Map makeProjectArgs(Project project)
        throws Exception 
    {
        Map args = new HashMap();
        if (project != null)
        {
            makeArgMapping(args, "domain_name", project.getDomain().getName());
            makeArgMapping(args, "project_name", project.getName());
            makeArgMapping(args, "project_id", project.getID());
            makeArgMapping(args, "description", project.getShortDescription());
            makeArgMapping(args, "is_private", DBFlag.flagValueOf(project.isPrivate())); 
        }
        return args;
    }

    /**
     * Returns a map populated with module information.
     */
    private static Map makeModuleArgs(String moduleName, 
                                      String moduleDescription, String isWeb)
    {
        Map args = new HashMap();
        if (moduleName != null)
        {
            makeArgMapping(args, "module_name", moduleName);
        }
        if (moduleDescription != null)
        {
            makeArgMapping(args, "module_description", moduleDescription);
        }
        if (isWeb != null)
        {
            makeArgMapping(args, "is_web", isWeb);
        }
        return args;
    }

    /**
     * Takes a list of users and an optional role, and returns a map
     * of arguments.
     */
    private static Map makeUserArgs(List users, String role)
    {
        Map args = new HashMap();
        if (users != null)
        {
            StringBuffer userRealNames = new StringBuffer();
            StringBuffer userLoginNames = new StringBuffer();
            for (Iterator i = users.iterator(); i.hasNext();)
            {
                User user = (User)i.next();
                userRealNames.append(user.getRealName());
                userLoginNames.append(user.getLoginName());
                if (i.hasNext())
                {
                    userRealNames.append(":");
                    userLoginNames.append(":");
                }
            }
            makeArgMapping(args, "issues_realname", userRealNames.toString());
            makeArgMapping(args, "issues_username", userLoginNames.toString());
        }

        if (role != null)
        {
            makeArgMapping(args, "issues_role", role);
        }
        return args;
    }

    /**
     * Transforms a map of arguments into a list.
     */
    private static List listifyArguments(Map argMap)
    {
        List argList = new ArrayList();
        for (Iterator i = argMap.keySet().iterator(); i.hasNext();)
        {
            String name = (String)i.next();
            String value = (String)argMap.get(name);
            String argument = "--" + name + "=" + value;
            argList.add(argument);
        }
        return argList;
d195 1
a195 1
                        command, listifyArguments(arguments));
d198 1
a198 1
    // Things which run scripts: runTask and doIssueTrackingRebuild.
a241 8
                else if (command.equals("Rebuild Issue Tracking"))
                {   
                    Project project = ProjectPeer.getInstance
                        (String.valueOf(t.getAffectedObjectId()));
                    User user = UserPeer.getInstance
                        (String.valueOf(t.getOnBehalfOf()));
                    doIssueTrackingRebuild(project);
                }
d244 1
a244 1
                    runScript(command, args);
d261 1
a261 218
    }

    /**
     * Resyncs a project's issue tracking accounts with the Helm roles
     * for that project. 
     */
    private static void doIssueTrackingRebuild(Project toRebuild)
        throws Exception, ACLException
    {
       
        String[] accountTypes = {"observer", "developer", "admin"};
        String[] actions = 
        {
            "Project Issue Tracking - Submit",
            "Project Issue Tracking - Change",
            "Project Issue Tracking - Configure"
        };

        int types = accountTypes.length;
        List[] userLists = new List[types];
        Vector[][] roleIDs = new Vector[types][2];

        //See which roles and which private-recursive roles have the
        //given permission.
        for (int i = 0; i < types; i++)
        {
            List roles = RolePeer.getRolesWithAction(actions[i]);
            for (int j = 0; j <= 1; j++)
            {
                roleIDs[i][j] = new Vector(roles.size());
            }

            for (Iterator j = roles.iterator(); j.hasNext();)
            {
                Role r = (Role)j.next();
                roleIDs[i][0].add(r.getID());
                if (r.canRecurseIntoPrivateProjects())
                {
                    roleIDs[i][1].add(r.getID());
                }
            }
        }

        //Process all of the denormalized children of the project to
        //be rebuilt (the project to be rebuilt is a denormalized
        //child of itself).
        for (Iterator i = toRebuild.getPermissionedChildren().iterator(); 
             i.hasNext();)
        {
            Project project = (Project)i.next();
            if (DEBUG)
            {
                Log.debug("ITR processing project " + project.getName());
            }
            if (!(project.isHost() || project.isDomain()))
            {
                //For each relevant action, find the users who have that
                //action in this project.
                for (int j = 0; j < types; j++)
                {
                    userLists[j] = project.getUsersWithRoles(roleIDs[j]);
                }
                
                //The account types are arranged in increasing order of
                //power. Thus, a user with account type i should not be in
                //the list of users with account type j < i.
                for (int j = 0; j < types; j++)
                {
                    for (int k = types-1; k > j; k--)
                    {
                        userLists[j].removeAll(userLists[k]);
                    }
                }
                
                //Disable all accounts for the project, and then add the
                //appropriate accounts back.
                Map args = makeProjectArgs(project);
                runScript("MemberDisableAll", args);
                for (int j = 0; j < types; j++)
                {
                    if (DEBUG)
                    {
                        Log.debug(userLists[j].size() + " accounts of type " 
                                  + accountTypes[j]);
                    }
                    if (userLists[j].size() > 0)
                    {
                        Map memberArgs = makeProjectArgs(project);
                        memberArgs.putAll(makeUserArgs(userLists[j], 
                                                       accountTypes[j]));
                        runScript("MemberAdd", memberArgs);
                    }
                }
            }
        }
    }
    
    ///////////////////////////////////////////////////////////////////
    // Script runner.
    ///////////////////////////////////////////////////////////////////

    private static synchronized void runScript(String command, Map argList)
        throws TaskException 
    {
        runScript(command, listifyArguments(argList));
    }

    /**
     * Run a command with a populated environment.
     * @@param command Command to run.
     * @@param argList Map of arguments and values to pass.
     */
    private static synchronized void runScript(String command, List argList)
        throws TaskException 
    {
        //Get the variables to be put in the script's environment.
        String htdoc_root =
            (String) JoistProperties.getProperty("documentRoot");
        String sandbox = (String) JoistProperties.getProperty("SANDBOX");
        String dbName = (String) JoistProperties.getProperty("databaseName");
        String dbUser = (String) JoistProperties.getProperty("databaseUser");
        String dbPassword =
            (String) JoistProperties.getProperty("databasePassword");

        String[] env = 
        {
            "HTDOC_ROOT=" + htdoc_root, 
            "SANDBOX="+sandbox, 
            "DATABASE_NAME=" + dbName,
            "DATABASE_USER=" + dbUser,
            "DATABASE_PASSWORD=" + dbPassword
        };

        String args[] = new String[argList.size()+1];
        args[0] = sandbox + SCRIPT_DIR + command;
        for (int i = 0; i < argList.size(); i++)
        {
            args[i+1] = (String)argList.get(i);
        }

        Runtime rt = Runtime.getRuntime();
        Process pr;
        int exitCode = 0;
        boolean finishedRunning = false;
        String errorMessage = "";

        StringBuffer scriptName = new StringBuffer();
        if (DEBUG) 
        {
            for (int i = 0; i < args.length; i++)
            {
                scriptName.append(args[i]).append(" ");
            }            
            Log.debug("Running " + scriptName.toString());
        }

        try 
        {
            pr = rt.exec(args, env);            
        } 
        catch (IOException e) 
        {
            throw new TaskException("IO error while running script.");
        }

        long elapsedSeconds = 0;
        try 
        {
            while (!finishedRunning && elapsedSeconds < 
                   MILLIS_TO_WAIT_FOR_SCRIPT)
            {                
                Thread.sleep(INCREMENTAL_WAIT_MILLIS);
                elapsedSeconds += INCREMENTAL_WAIT_MILLIS;
                try
                {
                    exitCode = pr.exitValue();
                    finishedRunning = true;
                }
                catch (IllegalThreadStateException ignore)
                {
                    //The script has not yet finished running. Wait a
                    //while and try again.
                }
            }
            if (elapsedSeconds >= MILLIS_TO_WAIT_FOR_SCRIPT)
            {
                exitCode = -1;
                errorMessage = "Script did not finish running within " 
                    + MILLIS_TO_WAIT_FOR_SCRIPT + " milliseconds.";
            }
            else
            {
                errorMessage = "Exit code: " 
                    + new Integer(exitCode).toString();
            }
        } 
        catch (InterruptedException e) 
        {
            throw new TaskException("Script was interrupted.");
        }

        if (exitCode != 0) 
        {
            /*
              //Get the standard error.
            InputStream err = pr.getErrorStream();
            try 
            {
                byte[] errMsg = new byte[err.available()];
                err.read(errMsg);
                errorMessage = new String(errMsg);
            }
            catch (IOException ignore) {}
            */
            throw new TaskException(scriptName.toString() + "\n\n" +
                                    errorMessage);
        }
    }
@


1.16
log
@Ported Helm from WebMacro to Velocity.
@
text
@d427 1
a427 1
        for (Iterator i = toRebuild.getRecursiveChildren().iterator(); 
@


1.15
log
@Fixed up cluster singleton interface and made the task runner into a cluster singleton.
@
text
@d54 2
@


1.14
log
@Don't run scripts unless there are members to add.
@
text
@d60 1
d197 8
d214 5
a218 6
            args.put("domain_name", project.getDomain().getName());
            args.put("project_name", project.getName());
            args.put("project_id", project.getID());
            args.put("brand_name", project.getBrand());
            args.put("description", project.getShortDescription());
            args.put("is_private", new Boolean(project.isPrivate())); 
d232 1
a232 1
            args.put("module_name", moduleName);
d236 1
a236 1
            args.put("module_description", moduleDescription);
d240 1
a240 1
            args.put("is_web", isWeb);
d267 2
a268 2
            args.put("issues_realname", userRealNames.toString());
            args.put("issues_username", userLoginNames.toString());
d273 1
a273 1
            args.put("issues_role", role);
d388 1
a388 1

@


1.13
log
@Refactored a lot of code to get rid of the good-looking but very slow IssueTrackingAccount{Descriptor,Map} classes. Also cleaned up the script-running interface quite a bit.
@
text
@d456 7
a462 4
                    Map memberArgs = makeProjectArgs(project);
                    memberArgs.putAll(makeUserArgs(userLists[j], 
                                                   accountTypes[j]));
                    runScript("MemberAdd", memberArgs);
@


1.12
log
@Reverted bad commit *again*.
@
text
@d58 1
a58 1
import org.tigris.helm.om.*;
d69 5
a84 2
    private static final boolean DEBUG = false;

d96 1
a96 7
	List args = makeProjectArgs(project.getDomainName(),
                                    project.getName(),
                                    project.getID(),
                                    project.getBrand(),
                                    project.getShortDescription(),
                                    new Boolean(project.isPrivate()));
        add(onBehalfOf, project.getID(), cmd, args);
d107 1
a107 8
        List args = makeProjectArgs(project.getDomainName(),
                                    project.getName(),
                                    project.getID(),
                                    project.getBrand(),
                                    null,
                                    null
                                    );
        add(onBehalfOf, project.getID(), cmd, args);
d111 3
a113 1
     * Rebuild a project's issue tracking.
d119 1
a119 1
        add(UserPeer.getSuperUser(), project.getID(), cmd, new ArrayList());
d137 2
a138 8
	List args = makeModuleArgs(project.getDomainName(),
                                   project.getName(),
                                   project.getID(), 
                                   project.getBrand(),
                                   moduleName,
                                   moduleDescription,
                                   isWeb
                                   );
d152 2
a153 99
	List args = makeModuleArgs(project.getDomainName(),
                                   project.getName(),
                                   project.getID(), 
                                   project.getBrand(),
                                   moduleName,
                                   null,
                                   null
                                   );
        add(onBehalfOf, project.getID(), cmd, args);
    }
    
    //
    // Generation of user tasks
    //

    /**
     * Add a new user to Issuezilla.
     */
    public static void addMember(User onBehalfOf, Project project, User user, 
                                 String trackingRole)
        throws Exception
    {        
        List users = new ArrayList();
        users.add(user);
        addMembers(onBehalfOf, project, users, trackingRole);
    }

    /**
     * Add a number of new users to Issuezilla.
     */
    public static void addMembers(User onBehalfOf, Project project, 
                                  List users, String userRole)
        throws Exception
    {	
        StringBuffer userRealNames = new StringBuffer();
        StringBuffer userLoginNames = new StringBuffer();
        for (Iterator i = users.iterator(); i.hasNext();)
        {
            User user = (User)i.next();
            userRealNames.append(user.getRealName());
            userLoginNames.append(user.getLoginName());
            if (i.hasNext())
            {
                userRealNames.append(":");
                userLoginNames.append(":");
            }
        }

	String cmd = "MemberAdd";
	List args = makeUserArgs(project.getDomainName(),
                                 project.getName(),
                                 project.getID(),
                                 project.getBrand(),
                                 userRealNames.toString(),
                                 userLoginNames.toString(),
                                 userRole
                                 );
        add(onBehalfOf, project.getID(), cmd, args);
    }

    /**
     * Remove a user from Issuezilla.
     */
    public static void deleteMember(User onBehalfOf, Project project, 
                                    User user)
        throws Exception
    {
        List users = new ArrayList();
        users.add(user);
        deleteMembers(onBehalfOf, project, users);
    }

    /**
     * Remove a user from Issuezilla.
     */
    public static void deleteMembers(User onBehalfOf, Project project, 
                                     List users)
        throws Exception
    {	
        StringBuffer userLoginNames = new StringBuffer();
        for (Iterator i = users.iterator(); i.hasNext();)
        {
            User user = (User)i.next();
            userLoginNames.append(user.getLoginName());
            if (i.hasNext())
            {
                userLoginNames.append(":");
            }
        }

	String cmd = "MemberDelete";
	List args = makeUserArgs(project.getDomainName(),  //domainName
                                 project.getName(),        //projectName
                                 project.getID(),          //projectID
                                 project.getBrand(),       //brandName
                                 null,                     //userRealName
                                 userLoginNames.toString(),//userLoginname
                                 null                      //userRole
                                 );
d168 3
d172 5
a176 1
        deleteMember(onBehalfOf, domainProject, user);
d180 1
a180 1
     * Disable all Issuezilla accoutns for the given project.
d186 1
a186 9

	List args = makeProjectArgs(project.getDomainName(),
                                    project.getName(),
                                    project.getID(),
                                    project.getBrand(),
                                    project.getShortDescription(),
                                    new Boolean(project.isPrivate())
                                    );
        add(onBehalfOf, project.getID(), cmd, args);
d190 4
a193 2
    // Argument builders--these all call makeArgs and return a List
    // suitable for passing to <code>add</code>.
d197 20
a216 2
     * Convenience function to take only the arguments neccessary
     * for scripts that deal with projects.
d218 49
a266 118
    public static List makeProjectArgs(String domainName, 
                                       String projectName, 
                                       String projectID, 
                                       String brandName,
                                       String projectDescription,
                                       Boolean isPrivate) 
    {
        return makeArgs(domainName,
                        projectName,
                        projectID,
                        brandName,
                        projectDescription,
                        isPrivate,
                        null,        //moduleName
                        null,        //moduleDescription
                        null,        //isWeb
                        null,        //userRealName
                        null,        //userUsername
                        null         //userRole
                        );
    }

    /**
     * Convenience function to take only the arguments neccessary
     * for scripts that deal with modules.
     */
    public static List makeModuleArgs(String domainName, 
                                      String projectName, 
                                      String projectID, 
                                      String brandName,
                                      String moduleName,
                                      String moduleDescription,
                                      String moduleIsWeb)
    {
        return makeArgs(domainName,        //domainName
                        projectName,       //projectName
                        projectID,         //projectID
                        brandName,         //brandName
                        null,              //projectDescription
                        null,              //isPrivate
                        moduleName,        //moduleName
                        moduleDescription, //moduleDescription
                        moduleIsWeb,       //isWeb
                        null,              //userRealName
                        null,              //userUsername
                        null               //userRole
                        );
    }

    /**
     * Convenience function to take only the arguments neccessary
     * for scripts that deal with users.
     */
    public static List makeUserArgs(String domainName, 
                                    String projectName, 
                                    String projectID, 
                                    String brandName,
                                    String userRealName,
                                    String userUsername,
                                    String userRole)
    {
        return makeArgs(domainName,   //domainName
                        projectName,  //projectName
                        projectID,    //projectID
                        brandName,    //brandName
                        null,         //projectDescription
                        null,         //isPrivate
                        null,         //moduleName
                        null,         //moduleDescription
                        null,         //isWeb
                        userRealName, //userRealName
                        userUsername, //userUsername
                        userRole      //userRole
                        );
    }

    /**
     * Takes a script name and a bunch of arguments and makes a List
     * suitable for passing to <code>add</code>.
     */
    private static List makeArgs(String domainName, 
                                 String projectName, 
                                 String projectID, 
                                 String brandName,
                                 String projectDescription, 
                                 Boolean isPrivate,
                                 String moduleName, 
                                 String moduleDescription,
                                 String isWeb, 
                                 String userRealName,
                                 String userName,
                                 String userRole)
    {
        List args = new ArrayList();
        if (domainName != null || "".equals(domainName)) 
            args.add("--domain_name="+domainName);
        if  (projectName != null && !"".equals(projectName)) 
            args.add("--project_name="+projectName); 
        if  (projectID != null && !"".equals(projectID)) 
            args.add("--project_id="+projectID);
        if  (brandName != null && !"".equals(brandName)) 
            args.add("--brand_name="+brandName);
        if  (projectDescription!=null && !"".equals(projectDescription)) 
            args.add("--description="+projectDescription); 
        if  (isPrivate != null && !"".equals(isPrivate)) 
            args.add("--is_private="+isPrivate.booleanValue()); 
        if  (moduleName !=null && !"".equals(moduleName)) 
            args.add("--module_name="+moduleName);  
        if  (moduleDescription != null && !"".equals(moduleDescription)) 
            args.add("--module_description="+moduleDescription); 
        if  (isWeb != null && !"".equals(isWeb)) 
            args.add("--is_web="+isWeb);
        if  (userRealName != null && !"".equals(userRealName)) 
            args.add("--issues_realname="+userRealName);
        if  (userName != null && !"".equals(userName)) 
            args.add("--issues_username="+userName);
        if  (userRole != null && !"".equals(userRole))
            args.add("--issues_role="+userRole);
d270 15
a284 3
    //
    // Overridden methods
    //
d286 1
d293 1
a293 1
                            String command, List arguments)
d297 1
a297 1
                        command, arguments);
d299 6
a304 1
    
d311 2
a312 1
                ("HelmTask cannot run a task for component " + t.getComponent());
d319 2
a320 1
        try {
d333 4
a336 2
                    //This will just turn this task into a large number
                    //of script-running tasks.
d342 1
a342 1
                    project.rebuildIssueTracking(user.getACL());
d350 1
a350 1
                    rebuildIssueTracking(project);
d372 92
d468 7
d478 1
a478 1
     * @@param argList ArrayList of arguments to pass.
d480 1
a480 1
    private static synchronized void runScript (String command, List argList)
d483 1
a483 10
        String args[] = new String[argList.size()+1];
        args[0] = command;
        for (int i = 0; i < argList.size(); i++)
        {
            String arg = (String)argList.get(i);
            args[i+1] = arg;
        }

        //Get the sandbox directory and htdoc_root to put in the
        //script's environment.
d492 7
a498 5
        String[] env = {"HTDOC_ROOT=" + htdoc_root, 
                        "SANDBOX="+sandbox, 
                        "DATABASE_NAME=" + dbName,
                        "DATABASE_USER=" + dbUser,
                        "DATABASE_PASSWORD=" + dbPassword
d501 7
d515 1
a515 1
        for (int i = 0; i < args.length; i++)
d517 1
a517 1
            if (args[i] == null)
d519 2
a520 6
                args[i] = "NULL";
            }
            scriptName.append(args[i]).append(" ");
        }            
        if (DEBUG) 
        {
a525 1
            args[0] = sandbox + SCRIPT_DIR + args[0];
a586 1

@


1.11
log
@Reverting bad commit.
@
text
@d200 3
a202 1
        if (!users.isEmpty())
d204 4
a207 3
            StringBuffer userRealNames = new StringBuffer();
            StringBuffer userLoginNames = new StringBuffer();
            for (Iterator i = users.iterator(); i.hasNext();)
d209 2
a210 8
                User user = (User)i.next();
                userRealNames.append(user.getRealName());
                userLoginNames.append(user.getLoginName());
                if (i.hasNext())
                {
                    userRealNames.append(":");
                    userLoginNames.append(":");
                }
a211 11
            
            String cmd = "MemberAdd";
            List args = makeUserArgs(project.getDomainName(),
                                     project.getName(),
                                     project.getID(),
                                     project.getBrand(),
                                     userRealNames.toString(),
                                     userLoginNames.toString(),
                                     userRole
                                     );
            add(onBehalfOf, project.getID(), cmd, args);
d213 11
a266 89

    /**
     * Runs 
     */
    private static void doIssueTrackingRebuild(Project toRebuild, 
                                               AccessControlList acl)
    {
        acl.assertPermission("Project Role - Grant", toRebuild);
        User onBehalfOf = acl.getUser();

        String[] accountTypes = {"observer", "developer", "admin"};
        String[] actions = 
        {
            "Project Issue Tracking - Submit",
            "Project Issue Tracking - Change",
            "Project Issue Tracking - Configure"
        };

        int types = accountTypes.length;
        List[] userLists = new List[types];
        Vector[][] roleIDs = new Vector[types][2];

        //See which roles and which private-recursive roles have the
        //given permission.
        for (int i = 0; i < types; i++)
        {
            List roles = RolePeer.getRolesWithAction(actions[i]);
            for (int j = 0; j <= 1; j++)
            {
                roleIDs[i][j] = new Vector(roles.size());
            }

            for (Iterator j = roles.iterator(); j.hasNext();)
            {
                Role r = (Role)j.next();
                roleIDs[i][0].add(r.getID());
                if (r.canRecurseIntoPrivateProjects())
                {
                    roleIDs[i][1].add(r.getID());
                }
            }
        }

        //Process all of the denormalized children of the project to
        //be rebuilt (the project to be rebuilt is a denormalized
        //child of itself).
        for (Iterator i = getRecursiveChildren().iterator(); i.hasNext();)
        {
            Project project = (Project)i.next();
            if (DEBUG)
            {
                Log.debug("Processing project " + project.getName());
            }
            if (!(project.isHost() || project.isDomain()))
            {
                //For each relevant action, find the users who have that
                //action in this project.
                for (int j = 0; j < types; j++)
                {
                    userLists[j] = project.getUsersWithRoles(roleIDs[j]);
                }
                
                //The account types are arranged in increasing order of
                //power. Thus, a user with account type i should not be in
                //the list of users with account type j < i.
                for (int j = 0; j < types; j++)
                {
                    for (int k = types-1; k > j; k--)
                    {
                        userLists[j].removeAll(userLists[k]);
                    }
                }
                
                //Disable all accounts for the project, and then add the
                //appropriate accounts back.
                HelmTask.disableAllAccounts(onBehalfOf, project);
                for (int j = 0; j < types; j++)
                {
                    if (DEBUG)
                    {
                        Log.debug(userLists[j].size() + " accounts of type " 
                                  + accountTypes[j]);
                    }
                    HelmTask.addMembers(onBehalfOf, project, userLists[j], 
                                        accountTypes[j]);
                }
            }
        }
    }
d489 1
a489 1
                    rebuildIssueTracking(user.getACL());
@


1.10
log
@Made IssueTrackingRebuild about a million times faster.
@
text
@d270 89
d581 1
a581 1
                    project.rebuildIssueTracking(user.getACL());
d655 4
a658 1
        if (DEBUG) Log.debug("Running " + scriptName.toString());
@


1.9
log
@Instead of waiting forever for a script to finish, fail with an error if it doesn't complete within two minutes.
@
text
@d200 1
a200 3
        StringBuffer userRealNames = new StringBuffer();
        StringBuffer userLoginNames = new StringBuffer();
        for (Iterator i = users.iterator(); i.hasNext();)
d202 3
a204 4
            User user = (User)i.next();
            userRealNames.append(user.getRealName());
            userLoginNames.append(user.getLoginName());
            if (i.hasNext())
d206 8
a213 2
                userRealNames.append(":");
                userLoginNames.append(":");
d215 11
a226 11

	String cmd = "MemberAdd";
	List args = makeUserArgs(project.getDomainName(),
                                 project.getName(),
                                 project.getID(),
                                 project.getBrand(),
                                 userRealNames.toString(),
                                 userLoginNames.toString(),
                                 userRole
                                 );
        add(onBehalfOf, project.getID(), cmd, args);
d490 3
a492 6

                    IssueTrackingAccountDescriptor before = 
                        new IssueTrackingAccountDescriptor();
                    IssueTrackingAccountDescriptor after = 
                        new IssueTrackingAccountDescriptor(project);
                    before.syncTo(after, UserPeer.getSuperUser());
@


1.8
log
@Don't store arguments which consist of the empty string.
@
text
@d73 4
d553 2
a554 1
        int exitCode;
d577 2
a578 1
       
d581 27
a607 2
            exitCode = pr.waitFor();
            errorMessage = "Exit code: " + new Integer(exitCode).toString();
d614 1
a614 1
        if (pr.exitValue() != 0) 
@


1.7
log
@Added is_private flag to scripts.
@
text
@d400 9
a408 5
        if (domainName != null) args.add("--domain_name="+domainName);
        if (projectName!=null) args.add("--project_name="+projectName); 
        if (projectID!=null) args.add("--project_id="+projectID);
        if (brandName!=null) args.add("--brand_name="+brandName);
        if (projectDescription!=null) 
d410 1
a410 1
        if (isPrivate!=null) 
d412 3
a414 2
        if (moduleName!=null) args.add("--module_name="+moduleName);  
        if (moduleDescription!=null) 
d416 8
a423 4
        if (isWeb!=null) args.add("--is_web="+isWeb);
        if (userRealName!=null) args.add("--issues_realname="+userRealName);
        if (userName!=null) args.add("--issues_username="+userName);
        if (userRole!=null) args.add("--issues_role="+userRole);
@


1.6
log
@Gated a lot of task debug information which was annoying dlr.
@
text
@d93 2
a94 1
                                    project.getShortDescription());
d110 1
d291 2
a292 1
                                    project.getShortDescription()
d310 2
a311 1
                                       String projectDescription) 
d318 1
d345 1
d372 1
d391 1
d406 2
@


1.6.6.1
log
@Filter out empty string arguments as well as null arguments.
@
text
@d392 5
a396 5
        if (isArg(domainName)) args.add("--domain_name="+domainName);
        if (isArg(projectName)) args.add("--project_name="+projectName); 
        if (isArg(projectID)) args.add("--project_id="+projectID);
        if (isArg(brandName)) args.add("--brand_name="+brandName);
        if (isArg(projectDescription)) 
d398 2
a399 2
        if (isArg(moduleName)) args.add("--module_name="+moduleName);  
        if (isArg(moduleDescription)) 
d401 4
a404 4
        if (isArg(isWeb)) args.add("--is_web="+isWeb);
        if (isArg(userRealName)) args.add("--issues_realname="+userRealName);
        if (isArg(userName)) args.add("--issues_username="+userName);
        if (isArg(userRole)) args.add("--issues_role="+userRole);
a405 5
    }

    private static boolean isArg(String arg)
    {
        return (arg != null && !("".equals(arg)));
@


1.6.6.2
log
@Don't run member scripts unless there are members affected.
@
text
@d194 3
a196 1
        if (users.size() > 0)
d198 4
a201 3
            StringBuffer userRealNames = new StringBuffer();
            StringBuffer userLoginNames = new StringBuffer();
            for (Iterator i = users.iterator(); i.hasNext();)
d203 2
a204 8
                User user = (User)i.next();
                userRealNames.append(user.getRealName());
                userLoginNames.append(user.getLoginName());
                if (i.hasNext())
                {
                    userRealNames.append(":");
                    userLoginNames.append(":");
                }
a205 11
            
            String cmd = "MemberAdd";
            List args = makeUserArgs(project.getDomainName(),
                                     project.getName(),
                                     project.getID(),
                                     project.getBrand(),
                                     userRealNames.toString(),
                                     userLoginNames.toString(),
                                     userRole
                                     );
            add(onBehalfOf, project.getID(), cmd, args);
d207 11
d239 2
a240 1
        if (users.size() > 0)
d242 3
a244 2
            StringBuffer userLoginNames = new StringBuffer();
            for (Iterator i = users.iterator(); i.hasNext();)
d246 1
a246 6
                User user = (User)i.next();
                userLoginNames.append(user.getLoginName());
                if (i.hasNext())
                {
                    userLoginNames.append(":");
                }
a247 11
            
            String cmd = "MemberDelete";
            List args = makeUserArgs(project.getDomainName(),  //domainName
                                     project.getName(),        //projectName
                                     project.getID(),          //projectID
                                     project.getBrand(),       //brandName
                                     null,                     //userRealName
                                     userLoginNames.toString(),//userLoginname
                                     null                      //userRole
                                     );
            add(onBehalfOf, project.getID(), cmd, args);
d249 11
@


1.6.6.3
log
@Use rebuildIssueTracking instead of IssueTrackingAccountDescriptor.
@
text
@d476 5
a480 1
                    project.rebuildIssueTracking(UserPeer.getSuperUser().acl());
@


1.6.6.4
log
@Use rebuildIssueTracking instead of IssueTrackingAccountDescriptor.
@
text
@d476 1
a476 1
                    project.rebuildIssueTracking(UserPeer.getSuperUser().getACL());
@


1.6.6.5
log
@Ported task running system in from HEAD.
@
text
@a53 2
import org.apache.turbine.util.TurbineException;
import org.apache.turbine.util.TurbineException;
d58 1
a58 1
import org.tigris.helm.security.*;
a59 1
import org.tigris.helm.tool.DBFlag;
a68 5
     * Whether or not to print debugging information.
     */
    private static final boolean DEBUG = true;

    /**
a72 4
    public static final long MILLIS_TO_WAIT_FOR_SCRIPT = 1000 * 60 * 2;

    public static final long INCREMENTAL_WAIT_MILLIS = 1000;

d76 2
d89 6
a94 1
        add(onBehalfOf, project.getID(), cmd, makeProjectArgs(project));
d105 7
a111 1
        add(onBehalfOf, project.getID(), cmd, makeProjectArgs(project));
d115 1
a115 3
     * Rebuild a project's issue tracking. This is something of a
     * special case, as it triggers many scripts being run instead of
     * just one. 
d121 1
a121 1
        add(UserPeer.getSuperUser(), project.getID(), cmd, new HashMap());
d139 8
a146 2
        Map args = makeProjectArgs(project);
        args.putAll(makeModuleArgs(moduleName, moduleDescription, isWeb));
d160 8
a167 2
	Map args = makeProjectArgs(project);
        args.putAll(makeModuleArgs(moduleName, null, null));
d171 3
a173 21
   /**
    * Remove user from all projects in domain.
    */
    public static void deleteUser(User onBehalfOf, Domain domain, User user)
        throws Exception
    {
        // Get a special project from the domain representing 
        // 'all projects in domain', and run MemberDelete script
        // against that project a final time when deleting the 
        // user alltogether:

        List userList = new ArrayList();
        userList.add(user);

        Project domainProject = domain.getSpecialProject();
        String cmd = "MemberDelete";
	Map args = makeProjectArgs(domainProject);
        args.putAll(makeUserArgs(userList, null));

        add(onBehalfOf, domainProject.getID(), cmd, args);
    }
d176 1
a176 1
     * Disable all Issuezilla accounts for the given project.
d178 2
a179 1
    public static void disableAllAccounts(User onBehalfOf, Project project)
d181 4
a184 18
    {	
	String cmd = "MemberDisableAll";
        add(onBehalfOf, project.getID(), cmd, makeProjectArgs(project));
    }

    //
    // Argument builders--these all return a Map suitable for passing
    // to <code>add</code> or <code>runScript</code>. Every script right
    // now calls makeProjectArgs; some will call one of the other
    // argument builders as well.
    //

    private static void makeArgMapping(Map map, String key, String value)
    {
        if (value != null && !("".equals(value)))
        {
            map.put(key,value);
        }
d188 1
a188 1
     * Returns a map populated with all relevant fields from a project.
d190 5
a194 5
    private static Map makeProjectArgs(Project project)
        throws Exception 
    {
        Map args = new HashMap();
        if (project != null)
d196 24
a219 5
            makeArgMapping(args, "domain_name", project.getDomain().getName());
            makeArgMapping(args, "project_name", project.getName());
            makeArgMapping(args, "project_id", project.getID());
            makeArgMapping(args, "description", project.getShortDescription());
            makeArgMapping(args, "is_private", DBFlag.flagValueOf(project.isProprietary())); 
a220 1
        return args;
d224 1
a224 1
     * Returns a map populated with module information.
d226 3
a228 2
    private static Map makeModuleArgs(String moduleName, 
                                      String moduleDescription, String isWeb)
d230 3
a232 14
        Map args = new HashMap();
        if (moduleName != null)
        {
            makeArgMapping(args, "module_name", moduleName);
        }
        if (moduleDescription != null)
        {
            makeArgMapping(args, "module_description", moduleDescription);
        }
        if (isWeb != null)
        {
            makeArgMapping(args, "is_web", isWeb);
        }
        return args;
d236 1
a236 2
     * Takes a list of users and an optional role, and returns a map
     * of arguments.
d238 5
a242 4
    private static Map makeUserArgs(List users, String role)
    {
        Map args = new HashMap();
        if (users != null)
a243 1
            StringBuffer userRealNames = new StringBuffer();
a247 1
                userRealNames.append(user.getRealName());
a250 1
                    userRealNames.append(":");
d254 11
a264 2
            makeArgMapping(args, "issues_realname", userRealNames.toString());
            makeArgMapping(args, "issues_username", userLoginNames.toString());
d266 16
d283 15
a297 5
        if (role != null)
        {
            makeArgMapping(args, "issues_role", role);
        }
        return args;
d300 5
d306 2
a307 1
     * Transforms a map of arguments into a list.
d309 106
a414 1
    private static List listifyArguments(Map argMap)
d416 1
a416 9
        List argList = new ArrayList();
        for (Iterator i = argMap.keySet().iterator(); i.hasNext();)
        {
            String name = (String)i.next();
            String value = (String)argMap.get(name);
            String argument = "--" + name + "=" + value;
            argList.add(argument);
        }
        return argList;
d419 4
a422 1
    // Overridden methods.
d429 1
a429 1
                            String command, Map arguments)
d433 1
a433 1
                        command, listifyArguments(arguments));
d435 1
a435 6

    // Things which run scripts: runTask and doIssueTrackingRebuild.

    /**
     * Runs the given task.
     */
d442 1
a442 2
                ("HelmTask cannot run a task for component " 
                 + t.getComponent());
d449 1
a449 2
        try 
        {
d462 2
a463 4
                    //For every child of this project, this task will
                    //generate an AddProject and a number of
                    //ModuleAdds.  The project's issue tracking
                    //accounts will also be built.
d469 1
a469 1
                    project.rebuildIssueTracking();
d475 2
a476 3
                    User user = UserPeer.getInstance
                        (String.valueOf(t.getOnBehalfOf()));
                    doIssueTrackingRebuild(project);
a497 81



    /**
     * Clear the Issuezilla accounts and rebuild them according to
     * what's in the database.
     */
    public static void doIssueTrackingRebuild(Project p)
        throws ACLException, Exception
    {
        Log.debug("Rebuilding issue tracking for " + p.getName());

        Vector observerRoleIDs = RolePeer.getRoleIDsWithAction
            ("Project Issue Tracking - Submit");
        Vector developerRoleIDs = RolePeer.getRoleIDsWithAction
            ("Project Issue Tracking - Change");
        Vector adminRoleIDs = RolePeer.getRoleIDsWithAction
            ("Project Issue Tracking - Configure");
        Log.debug(adminRoleIDs.size() + " admin roles, "
                  + developerRoleIDs.size() + " developer roles, "
                  + observerRoleIDs.size() + " observer roles.");

        for (Iterator i = p.selfAndChildren().iterator(); i.hasNext();)
        {
            Project project = (Project)i.next();
            if (!(project.isHost() || project.isDomain()))
            {
                Map args = makeProjectArgs(project);
                if (project.isLocked())
                {
                    runScript("MemberDisableAll", args);
                }
                else
                {
                    String projectID = project.getID();
                    
                    List observers = project.
                        getUsersWithRoles(observerRoleIDs);
                    List developers = project.
                        getUsersWithRoles(developerRoleIDs);
                    List admins = project.
                        getUsersWithRoles(adminRoleIDs);
                    
                    observers.removeAll(developers);
                    observers.removeAll(admins);
                    developers.removeAll(admins);
                    
                    Log.debug(admins.size() + " admins, "
                              + developers.size() + " developers, "
                              + observers.size() + " observers.");

                    //NOTE: If one of these scripts fails, the rest
                    //will not be run.
                    runScript("MemberDisableAll", args);

                    if (observers.size() > 0)
                    {
                        Map observerArgs = makeProjectArgs(project);
                        observerArgs.putAll
                            (makeUserArgs(observers, "observer"));
                        runScript("MemberAdd", observerArgs);
                    }

                    if (developers.size() > 0)
                    {                    
                        Map developerArgs = makeProjectArgs(project);
                        developerArgs.putAll(makeUserArgs(developers, 
                                                          "developer"));
                        runScript("MemberAdd", developerArgs);
                    }
                    
                    if (admins.size() > 0)
                    {
                        Map adminArgs = makeProjectArgs(project);
                        adminArgs.putAll(makeUserArgs(admins, "admin"));
                        runScript("MemberAdd", adminArgs);
                    }
                }
            }
        }
    }
a501 7

    private static synchronized void runScript(String command, Map argList)
        throws TaskException 
    {
        runScript(command, listifyArguments(argList));
    }

d505 1
a505 1
     * @@param argList Map of arguments and values to pass.
d507 1
a507 1
    private static synchronized void runScript(String command, List argList)
d510 10
a519 1
        //Get the variables to be put in the script's environment.
d528 5
a532 7
        String[] env = 
        {
            "HTDOC_ROOT=" + htdoc_root, 
            "SANDBOX="+sandbox, 
            "DATABASE_NAME=" + dbName,
            "DATABASE_USER=" + dbUser,
            "DATABASE_PASSWORD=" + dbPassword
a534 7
        String args[] = new String[argList.size()+1];
        args[0] = sandbox + SCRIPT_DIR + command;
        for (int i = 0; i < argList.size(); i++)
        {
            args[i+1] = (String)argList.get(i);
        }

d537 1
a537 2
        int exitCode = 0;
        boolean finishedRunning = false;
d541 1
a541 1
        if (DEBUG) 
d543 1
a543 1
            for (int i = 0; i < args.length; i++)
d545 5
a549 4
                scriptName.append(args[i]).append(" ");
            }            
            Log.debug("Running " + scriptName.toString());
        }
d553 1
d560 1
a560 2

        long elapsedSeconds = 0;
d563 2
a564 27
            while (!finishedRunning && elapsedSeconds < 
                   MILLIS_TO_WAIT_FOR_SCRIPT)
            {                
                Thread.sleep(INCREMENTAL_WAIT_MILLIS);
                elapsedSeconds += INCREMENTAL_WAIT_MILLIS;
                try
                {
                    exitCode = pr.exitValue();
                    finishedRunning = true;
                }
                catch (IllegalThreadStateException ignore)
                {
                    //The script has not yet finished running. Wait a
                    //while and try again.
                }
            }
            if (elapsedSeconds >= MILLIS_TO_WAIT_FOR_SCRIPT)
            {
                exitCode = -1;
                errorMessage = "Script did not finish running within " 
                    + MILLIS_TO_WAIT_FOR_SCRIPT + " milliseconds.";
            }
            else
            {
                errorMessage = "Exit code: " 
                    + new Integer(exitCode).toString();
            }
d571 1
a571 1
        if (exitCode != 0) 
d589 1
@


1.6.6.6
log
@Ported minimal cluster functionality so that I could also port IssueTrackingRebuildService, which builds on it.
@
text
@d62 1
d99 1
a99 2
        add(onBehalfOf, project.getID(), cmd, 
            ScriptTool.makeProjectArgs(project));
d110 1
a110 2
        add(onBehalfOf, project.getID(), cmd, 
            ScriptTool.makeProjectArgs(project));
d140 2
a141 3
        Map args = ScriptTool.makeProjectArgs(project);
        args.putAll(ScriptTool.makeModuleArgs
                    (moduleName, moduleDescription, isWeb));
d155 2
a156 2
	Map args = ScriptTool.makeProjectArgs(project);
        args.putAll(ScriptTool.makeModuleArgs(moduleName, null, null));
d176 2
a177 2
	Map args = ScriptTool.makeProjectArgs(domainProject);
        args.putAll(ScriptTool.makeUserArgs(userList, null));
d189 105
a293 2
        add(onBehalfOf, project.getID(), cmd, 
            ScriptTool.makeProjectArgs(project));
d307 1
a307 1
                        command, ScriptTool.listifyArguments(arguments));
d354 8
d364 1
a364 1
                    ScriptTool.runScript(command, args);
d381 204
a584 1
    }   
@


1.6.6.7
log
@Got rid of IssueTrackingRebuild task.
@
text
@d114 12
@


1.6.6.8
log
@Ported over ITR failure mail reduction code from HEAD.
@
text
@a79 5
    /**  
     * The name of the command to add a project.
     */
    public static final String PROJECT_ADD_COMMAND = "ProjectAdd";    

@


1.5
log
@Added a new type of task which redoes the issue tracking of a project. This causes some unneccessary scripts to be run (since we lose the context of how the issue tracking was before a change was made), but it lets us offload the time it takes to build an IssueTrackingAccountDescriptor onto the task-runner thread so that the user doesn't see it. The immediate performance effect (in the two places that now use the task instead of making their own ITADs) is to reduce user-visible project creation time from 10 seconds to 3 seconds (YMMV).
@
text
@d76 1
a76 1
    private static final boolean DEBUG = true;
@


1.4
log
@Cleanup and introduction of (future) code to get the script's standard error instead of using the completely unhelpful return code.
@
text
@d59 1
a59 1
import org.tigris.helm.tool.task.TaskException;
d114 10
d460 11
d472 1
a472 1
                {                    
d475 3
a477 1
            } catch (Exception e) {
@


1.3
log
@Corrected regex madness for Torque upgrade.  -dlr
@
text
@d443 4
a446 2
                    Project project = ProjectPeer.getInstance(String.valueOf(t.getAffectedObjectId()));
                    User user = UserPeer.getInstance(String.valueOf(t.getOnBehalfOf()));
d450 2
a451 1
                else {
d508 1
d521 2
a522 1
        try {
d524 4
a527 2
            pr = rt.exec(args, env);
        } catch (IOException e) {
d530 3
a532 2
        
        try {
d534 4
a537 1
        } catch (InterruptedException e) {
d540 16
a555 3
        if (pr.exitValue() != 0) {
            throw new TaskException(scriptName.toString() + "\n\nExit code: "
                                      + new Integer(exitCode).toString());
@


1.2
log
@adding files from the branch to the head
@
text
@d58 1
a58 3
import org.tigris.helm.om.peer.*;
import org.tigris.helm.om.base.*;

@


1.1
log
@file HelmTask.java was initially added on branch HELM_PEER_PORT_BRANCH.
@
text
@d1 539
@


1.1.1.1
log
@Replacing the HEAD with the HELM_PEER_PORT_BRANCH.
@
text
@a0 539
/* ================================================================
 * Copyright (c) 2000-2001 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.om;

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

import org.apache.turbine.util.Log;

import org.joist.util.JoistProperties;

import org.tigris.helm.om.*;
import org.tigris.helm.om.peer.*;
import org.tigris.helm.om.base.*;

import org.tigris.helm.tool.task.TaskException;

/**
 * Helm task.
 *
 * @@author <a href="mailto:leonardr@@collab.net">Leonard Richardson</a>
 */
public class HelmTask extends Task
{
    /**
     * The name of the component which runs our tasks.
     */
    public static final String COMPONENT_NAME = "Helm";

    //FIXME: Please! This should be in a conf file somewhere.
    protected static final String SCRIPT_DIR = "/helm/perl/scripts/";

    private static final boolean DEBUG = true;

    ////////////////////////////////////////////////////////////////
    // Project scripts.
    ////////////////////////////////////////////////////////////////

    /**
     * Add a new project to CVS, Issuezilla, etc.
     */
    public static void addProject(User onBehalfOf, Project project)
        throws Exception
    {
	String cmd = "ProjectAdd";
	List args = makeProjectArgs(project.getDomainName(),
                                    project.getName(),
                                    project.getID(),
                                    project.getBrand(),
                                    project.getShortDescription());
        add(onBehalfOf, project.getID(), cmd, args);
    }

    /**
     * Remove a project from CVS, Issuezilla, etc.
     */
    public static void deleteProject(User onBehalfOf, Project project)
        throws Exception
    {
     
        String cmd = "ProjectDelete";
        List args = makeProjectArgs(project.getDomainName(),
                                    project.getName(),
                                    project.getID(),
                                    project.getBrand(),
                                    null
                                    );
        add(onBehalfOf, project.getID(), cmd, args);
    }

    //
    // Generation of module tasks.
    //

    /**
     * Add a new module to Issuezilla.
     */
    public static void addModule(User onBehalfOf,
                                 Project project,
                                 String moduleName,
                                 String moduleDescription,
                                 String isWeb)
        throws Exception
    {
	String cmd = "ModuleAdd";
	List args = makeModuleArgs(project.getDomainName(),
                                   project.getName(),
                                   project.getID(), 
                                   project.getBrand(),
                                   moduleName,
                                   moduleDescription,
                                   isWeb
                                   );
        add(onBehalfOf, project.getID(), cmd, args);
    }

    /**
     * Remove a module from Issuezilla.
     */
    public static void deleteModule(User onBehalfOf,
                                    Project project,
                                    String moduleName)
        throws Exception
    {
	String cmd = "ModuleDelete";

	List args = makeModuleArgs(project.getDomainName(),
                                   project.getName(),
                                   project.getID(), 
                                   project.getBrand(),
                                   moduleName,
                                   null,
                                   null
                                   );
        add(onBehalfOf, project.getID(), cmd, args);
    }
    
    //
    // Generation of user tasks
    //

    /**
     * Add a new user to Issuezilla.
     */
    public static void addMember(User onBehalfOf, Project project, User user, 
                                 String trackingRole)
        throws Exception
    {        
        List users = new ArrayList();
        users.add(user);
        addMembers(onBehalfOf, project, users, trackingRole);
    }

    /**
     * Add a number of new users to Issuezilla.
     */
    public static void addMembers(User onBehalfOf, Project project, 
                                  List users, String userRole)
        throws Exception
    {	
        StringBuffer userRealNames = new StringBuffer();
        StringBuffer userLoginNames = new StringBuffer();
        for (Iterator i = users.iterator(); i.hasNext();)
        {
            User user = (User)i.next();
            userRealNames.append(user.getRealName());
            userLoginNames.append(user.getLoginName());
            if (i.hasNext())
            {
                userRealNames.append(":");
                userLoginNames.append(":");
            }
        }

	String cmd = "MemberAdd";
	List args = makeUserArgs(project.getDomainName(),
                                 project.getName(),
                                 project.getID(),
                                 project.getBrand(),
                                 userRealNames.toString(),
                                 userLoginNames.toString(),
                                 userRole
                                 );
        add(onBehalfOf, project.getID(), cmd, args);
    }

    /**
     * Remove a user from Issuezilla.
     */
    public static void deleteMember(User onBehalfOf, Project project, 
                                    User user)
        throws Exception
    {
        List users = new ArrayList();
        users.add(user);
        deleteMembers(onBehalfOf, project, users);
    }

    /**
     * Remove a user from Issuezilla.
     */
    public static void deleteMembers(User onBehalfOf, Project project, 
                                     List users)
        throws Exception
    {	
        StringBuffer userLoginNames = new StringBuffer();
        for (Iterator i = users.iterator(); i.hasNext();)
        {
            User user = (User)i.next();
            userLoginNames.append(user.getLoginName());
            if (i.hasNext())
            {
                userLoginNames.append(":");
            }
        }

	String cmd = "MemberDelete";
	List args = makeUserArgs(project.getDomainName(),  //domainName
                                 project.getName(),        //projectName
                                 project.getID(),          //projectID
                                 project.getBrand(),       //brandName
                                 null,                     //userRealName
                                 userLoginNames.toString(),//userLoginname
                                 null                      //userRole
                                 );
        add(onBehalfOf, project.getID(), cmd, args);
    }
    
   /**
    * Remove user from all projects in domain.
    */
    public static void deleteUser(User onBehalfOf, Domain domain, User user)
        throws Exception
    {
        // Get a special project from the domain representing 
        // 'all projects in domain', and run MemberDelete script
        // against that project a final time when deleting the 
        // user alltogether:

        Project domainProject = domain.getSpecialProject();
        deleteMember(onBehalfOf, domainProject, user);
    }

    /**
     * Disable all Issuezilla accoutns for the given project.
     */
    public static void disableAllAccounts(User onBehalfOf, Project project)
        throws Exception
    {	
	String cmd = "MemberDisableAll";

	List args = makeProjectArgs(project.getDomainName(),
                                    project.getName(),
                                    project.getID(),
                                    project.getBrand(),
                                    project.getShortDescription()
                                    );
        add(onBehalfOf, project.getID(), cmd, args);
    }

    //
    // Argument builders--these all call makeArgs and return a List
    // suitable for passing to <code>add</code>.
    //

    /**
     * Convenience function to take only the arguments neccessary
     * for scripts that deal with projects.
     */
    public static List makeProjectArgs(String domainName, 
                                       String projectName, 
                                       String projectID, 
                                       String brandName,
                                       String projectDescription) 
    {
        return makeArgs(domainName,
                        projectName,
                        projectID,
                        brandName,
                        projectDescription,
                        null,        //moduleName
                        null,        //moduleDescription
                        null,        //isWeb
                        null,        //userRealName
                        null,        //userUsername
                        null         //userRole
                        );
    }

    /**
     * Convenience function to take only the arguments neccessary
     * for scripts that deal with modules.
     */
    public static List makeModuleArgs(String domainName, 
                                      String projectName, 
                                      String projectID, 
                                      String brandName,
                                      String moduleName,
                                      String moduleDescription,
                                      String moduleIsWeb)
    {
        return makeArgs(domainName,        //domainName
                        projectName,       //projectName
                        projectID,         //projectID
                        brandName,         //brandName
                        null,              //projectDescription
                        moduleName,        //moduleName
                        moduleDescription, //moduleDescription
                        moduleIsWeb,       //isWeb
                        null,              //userRealName
                        null,              //userUsername
                        null               //userRole
                        );
    }

    /**
     * Convenience function to take only the arguments neccessary
     * for scripts that deal with users.
     */
    public static List makeUserArgs(String domainName, 
                                    String projectName, 
                                    String projectID, 
                                    String brandName,
                                    String userRealName,
                                    String userUsername,
                                    String userRole)
    {
        return makeArgs(domainName,   //domainName
                        projectName,  //projectName
                        projectID,    //projectID
                        brandName,    //brandName
                        null,         //projectDescription
                        null,         //moduleName
                        null,         //moduleDescription
                        null,         //isWeb
                        userRealName, //userRealName
                        userUsername, //userUsername
                        userRole      //userRole
                        );
    }

    /**
     * Takes a script name and a bunch of arguments and makes a List
     * suitable for passing to <code>add</code>.
     */
    private static List makeArgs(String domainName, 
                                 String projectName, 
                                 String projectID, 
                                 String brandName,
                                 String projectDescription, 
                                 String moduleName, 
                                 String moduleDescription,
                                 String isWeb, 
                                 String userRealName,
                                 String userName,
                                 String userRole)
    {
        List args = new ArrayList();
        if (domainName != null) args.add("--domain_name="+domainName);
        if (projectName!=null) args.add("--project_name="+projectName); 
        if (projectID!=null) args.add("--project_id="+projectID);
        if (brandName!=null) args.add("--brand_name="+brandName);
        if (projectDescription!=null) 
            args.add("--description="+projectDescription); 
        if (moduleName!=null) args.add("--module_name="+moduleName);  
        if (moduleDescription!=null) 
            args.add("--module_description="+moduleDescription); 
        if (isWeb!=null) args.add("--is_web="+isWeb);
        if (userRealName!=null) args.add("--issues_realname="+userRealName);
        if (userName!=null) args.add("--issues_username="+userName);
        if (userRole!=null) args.add("--issues_role="+userRole);
        return args;
    }

    //
    // Overridden methods
    //


    /**
     * Add a task to be performed. Takes a List of arguments--use
     * one of the wrapper methods (eg. MemberAdd) to make a list.
     */
    public static Task add (User onBehalfOf, String affectedObjectID, 
                            String command, List arguments)
        throws Exception
    {
        return Task.add(onBehalfOf, COMPONENT_NAME, affectedObjectID,
                        command, arguments);
    }
    
    public static void runTask(Task t)
        throws TaskException
    {
        if (!t.getComponent().equals(COMPONENT_NAME))
        {
            throw new TaskException
                ("HelmTask cannot run a task for component " + t.getComponent());
        }

        TaskException ue = null;
        String command = t.getCommand();
        ArrayList args = null;        
        
        try {
            args = t.readArgsArray();
        }
        catch (Exception e) {
            throw new TaskException(e);
        }

        if (command != null)
        {
            try                 
            {
                if (command.equals("Initialize Project Resources"))
                {
                    //This will just turn this task into a large number
                    //of script-running tasks.
                    Project project = ProjectPeer.getInstance(String.valueOf(t.getAffectedObjectId()));
                    User user = UserPeer.getInstance(String.valueOf(t.getOnBehalfOf()));
                    project.runCreationScripts(user);
                    project.rebuildIssueTracking(user.getACL());
                }
                else {
                    runScript(command, args);
                }
            } catch (Exception e) {
                //TODO: If this happens, reset the timestamp of the script
                //rather than deleting it.
                ue = new TaskException(e);
            }

            t.setAsDone(); 

            if (ue != null) 
            { 
                throw ue;                
            }
        }
    }
    
    ///////////////////////////////////////////////////////////////////
    // Script runner.
    ///////////////////////////////////////////////////////////////////
    /**
     * Run a command with a populated environment.
     * @@param command Command to run.
     * @@param argList ArrayList of arguments to pass.
     */
    private static synchronized void runScript (String command, List argList)
        throws TaskException 
    {
        String args[] = new String[argList.size()+1];
        args[0] = command;
        for (int i = 0; i < argList.size(); i++)
        {
            String arg = (String)argList.get(i);
            args[i+1] = arg;
        }

        //Get the sandbox directory and htdoc_root to put in the
        //script's environment.
        String htdoc_root =
            (String) JoistProperties.getProperty("documentRoot");
        String sandbox = (String) JoistProperties.getProperty("SANDBOX");
        String dbName = (String) JoistProperties.getProperty("databaseName");
        String dbUser = (String) JoistProperties.getProperty("databaseUser");
        String dbPassword =
            (String) JoistProperties.getProperty("databasePassword");

        String[] env = {"HTDOC_ROOT=" + htdoc_root, 
                        "SANDBOX="+sandbox, 
                        "DATABASE_NAME=" + dbName,
                        "DATABASE_USER=" + dbUser,
                        "DATABASE_PASSWORD=" + dbPassword
        };

        Runtime rt = Runtime.getRuntime();
        Process pr;
        int exitCode;

        StringBuffer scriptName = new StringBuffer();
        for (int i = 0; i < args.length; i++)
        {
            if (args[i] == null)
            {
                args[i] = "NULL";
            }
            scriptName.append(args[i]).append(" ");
        }            
        if (DEBUG) Log.debug("Running " + scriptName.toString());

        try {
            args[0] = sandbox + SCRIPT_DIR + args[0];
            pr = rt.exec(args, env);
        } catch (IOException e) {
            throw new TaskException("IO error while running script.");
        }
        
        try {
            exitCode = pr.waitFor();
        } catch (InterruptedException e) {
            throw new TaskException("Script was interrupted.");
        }
        if (pr.exitValue() != 0) {
            throw new TaskException(scriptName.toString() + "\n\nExit code: "
                                      + new Integer(exitCode).toString());
        }
    }
}



@


1.1.2.1
log
@Added HelmTask subclass of Task, which contains the functionality that used to be in TigrisUpdate.
@
text
@a0 439
/* ================================================================
 * 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.om;

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

import org.apache.turbine.util.Log;

import org.joist.util.JoistProperties;

import org.tigris.helm.om.*;
import org.tigris.helm.om.peer.*;

import org.tigris.helm.tool.task.TaskException;

public class HelmTask extends Task
{
    public static final String COMPONENT_NAME="Helm";

    //FIXME: Please! This should be in a conf file somewhere.
    static final String script_dir = "/helm/perl/scripts/";

    public static final boolean debug = true;

    //
    // Generation of user tasks
    //

    /**
     * Add a new user to Issuezilla.
     */
    public static void addMember(User onBehalfOf, Project project, User user, 
                                 String trackingRole)
        throws Exception
    {        
        List users = new ArrayList();
        users.add(user);
        addMembers(onBehalfOf, project, users, trackingRole);
    }

    /**
     * Add a number of new users to Issuezilla.
     */
    public static void addMembers(User onBehalfOf, Project project, 
                                  List users, String userRole)
        throws Exception
    {	
        StringBuffer userRealNames = new StringBuffer();
        StringBuffer userLoginNames = new StringBuffer();
        for (Iterator i = users.iterator(); i.hasNext();)
        {
            User user = (User)i.next();
            userRealNames.append(user.getRealName());
            userLoginNames.append(user.getLoginName());
            if (i.hasNext())
            {
                userRealNames.append(":");
                userLoginNames.append(":");
            }
        }

        String oboID=null;
        if (onBehalfOf != null)
        {
            oboID = onBehalfOf.getID();
        }

	String cmd = "MemberAdd";
	List args = makeUserArgs(project.getDomainName(),
                                 project.getName(),
                                 project.getID(),
                                 project.getBrand(),
                                 userRealNames.toString(),
                                 userLoginNames.toString(),
                                 userRole
                                 );
        add(oboID, project.getID(), cmd, args);
    }

    /**
     * Remove a user from Issuezilla.
     */
    public static void deleteMember(User onBehalfOf, Project project, 
                                    User user)
        throws Exception
    {
        List users = new ArrayList();
        users.add(user);
        deleteMembers(onBehalfOf, project, users);
    }

    /**
     * Remove a user from Issuezilla.
     */
    public static void deleteMembers(User onBehalfOf, Project project, 
                                     List users)
        throws Exception
    {	
        StringBuffer userLoginNames = new StringBuffer();
        for (Iterator i = users.iterator(); i.hasNext();)
        {
            User user = (User)i.next();
            userLoginNames.append(user.getLoginName());
            if (i.hasNext())
            {
                userLoginNames.append(":");
            }
        }

        String oboID=null;
        if (onBehalfOf != null)
        {
            oboID = onBehalfOf.getID();
        }

	String cmd = "MemberDelete";
	List args = makeUserArgs(project.getDomainName(),  //domainName
                                 project.getName(),        //projectName
                                 project.getID(),          //projectID
                                 project.getBrand(),       //brandName
                                 null,                     //userRealName
                                 userLoginNames.toString(),//userLoginname
                                 null                      //userRole
                                 );
        add(oboID, project.getID(), cmd, args);
    }
    
   /**
    * Remove user from all projects in domain.
    */
    public static void deleteUser(User onBehalfOf, Domain domain, User user)
        throws Exception
    {
        // Get a special project from the domain representing 
        // 'all projects in domain', and run MemberDelete script
        // against that project a final time when deleting the 
        // user alltogether:

        Project domainProject = domain.getSpecialProject();
        deleteMember(onBehalfOf, domainProject, user);
    }

    //
    // Argument builders--these all call makeArgs and return a List
    // suitable for passing to <code>add</code>.
    //

    /**
     * Convenience function to take only the arguments neccessary
     * for scripts that deal with projects.
     */
    public static List makeProjectArgs(String domainName, 
                                       String projectName, 
                                       String projectID, 
                                       String brandName,
                                       String projectDescription) 
    {
        return makeArgs(domainName,
                        projectName,
                        projectID,
                        brandName,
                        projectDescription,
                        null,        //moduleName
                        null,        //moduleDescription
                        null,        //isWeb
                        null,        //userRealName
                        null,        //userUsername
                        null         //userRole
                        );
    }

    /**
     * Convenience function to take only the arguments neccessary
     * for scripts that deal with modules.
     */
    public static List makeModuleArgs(String domainName, 
                                      String projectName, 
                                      String projectID, 
                                      String brandName,
                                      String moduleName,
                                      String moduleDescription,
                                      String moduleIsWeb)
    {
        return makeArgs(domainName,        //domainName
                        projectName,       //projectName
                        projectID,         //projectID
                        brandName,         //brandName
                        null,              //projectDescription
                        moduleName,        //moduleName
                        moduleDescription, //moduleDescription
                        moduleIsWeb,       //isWeb
                        null,              //userRealName
                        null,              //userUsername
                        null               //userRole
                        );
    }

    /**
     * Convenience function to take only the arguments neccessary
     * for scripts that deal with users.
     */
    public static List makeUserArgs(String domainName, 
                                    String projectName, 
                                    String projectID, 
                                    String brandName,
                                    String userRealName,
                                    String userUsername,
                                    String userRole)
    {
        return makeArgs(domainName,   //domainName
                        projectName,  //projectName
                        projectID,    //projectID
                        brandName,    //brandName
                        null,         //projectDescription
                        null,         //moduleName
                        null,         //moduleDescription
                        null,         //isWeb
                        userRealName, //userRealName
                        userUsername, //userUsername
                        userRole      //userRole
                        );
    }

    /**
     * Takes a script name and a bunch of arguments and makes a List
     * suitable for passing to <code>add</code>.
     */
    private static List makeArgs(String domainName, 
                                 String projectName, 
                                 String projectID, 
                                 String brandName,
                                 String projectDescription, 
                                 String moduleName, 
                                 String moduleDescription,
                                 String isWeb, 
                                 String userRealName,
                                 String userName,
                                 String userRole)
    {
        List args = new ArrayList();
        if (domainName != null) args.add("--domain_name="+domainName);
        if (projectName==null) args.add("--project_name="+projectName); 
        if (projectID==null) args.add("--project_id="+projectID);
        if (brandName==null) args.add("--brand_name="+brandName);
        if (projectDescription==null) 
            args.add("--description="+projectDescription); 
        if (moduleName==null) args.add("--module_name="+moduleName);  
        if (moduleDescription==null) 
            args.add("--module_description="+moduleDescription); 
        if (isWeb==null) args.add("--is_web="+isWeb);
        if (userRealName==null) args.add("--issues_realname="+userRealName);
        if (userName==null) args.add("--issues_username="+userName);
        if (userRole==null) args.add("--issues_role="+userRole);
        return args;
    }

    //
    // Overridden methods
    //

    /**
     * Add a task to be performed. Takes a List of arguments--use
     * one of the wrapper methods (eg. MemberAdd) to make a list.
     */
    public static Task add (String onBehalfOf, String affectedObjectID, 
                            String command, List arguments)
        throws Exception
    {
        return Task.add(onBehalfOf, COMPONENT_NAME, affectedObjectID,
                        command, arguments);
    }
    
    public static void runTask(Task t) throws TaskException
    {
        if (!t.getComponent().equals(COMPONENT_NAME))
        {
            throw new TaskException
                ("HelmTask cannot run a task for component " + t.getComponent());
        }

        TaskException ue = null;
        String command = null;
        ArrayList args = null;        
        command = t.getCommand();
        
        try {
            args = t.readArgsArray();
        } catch (Exception e) {
            throw new TaskException(e.getMessage());
        }

        if (command != null)
        {
            try 
            {
                if (command.equals("Initialize Project Resources"))
                {
                    //This will just turn this task into a large number
                    //of script-running tasks.
                    Project project = ProjectPeer.getInstance(String.valueOf(t.getAffectedObjectId()));
                    User user = UserPeer.getInstance(String.valueOf(t.getOnBehalfOf()));
                    //project.runCreationScripts(user);
                    //project.rebuildIssueTracking(user);
                } else {
                    runScript(command, args);
                }
            } catch (Exception e) {
                //TODO: If this happens, reset the timestamp of the script
                //rather than deleting it.
                ue = new TaskException(e.getMessage());
            }

            t.setAsDone(); 

            if (ue != null) 
            { 
                throw ue;                
            }
        }
    }
    
    ///////////////////////////////////////////////////////////////////
    // Script runner.
    ///////////////////////////////////////////////////////////////////
    /**
     * Run a command with a populated environment.
     * @@param command Command to run.
     * @@param argList ArrayList of arguments to pass.
     */
    private static synchronized void runScript (String command, List argList)
        throws TaskException 
    {
        String args[] = new String[argList.size()+1];
        args[0] = command;
        for (int i = 0; i < argList.size(); i++)
        {
            String arg = (String)argList.get(i);
            args[i+1] = arg;
        }

        //Get the sandbox directory and htdoc_root to put in the
        //script's environment.
        String htdoc_root =
            (String) JoistProperties.getProperty("documentRoot");
        String sandbox = (String) JoistProperties.getProperty("SANDBOX");
        String dbName = (String) JoistProperties.getProperty("databaseName");
        String dbUser = (String) JoistProperties.getProperty("databaseUser");
        String dbPassword =
            (String) JoistProperties.getProperty("databasePassword");

        String[] env = {"HTDOC_ROOT=" + htdoc_root, 
                        "SANDBOX="+sandbox, 
                        "DATABASE_NAME=" + dbName,
                        "DATABASE_USER=" + dbUser,
                        "DATABASE_PASSWORD=" + dbPassword
        };

        Runtime rt = Runtime.getRuntime();
        Process pr;
        int exitCode;

        StringBuffer scriptName = new StringBuffer();
        for (int i = 0; i < args.length; i++)
        {
            if (args[i] == null)
            {
                args[i] = "NULL";
            }
            scriptName.append(args[i]).append(" ");
        }            
        if (debug) Log.debug("Running " + scriptName.toString());

        try {
            args[0] = sandbox + script_dir + args[0];
            pr = rt.exec(args, env);
        } catch (IOException e) {
            throw new TaskException("IO error while running script.");
        }
        
        try {
            exitCode = pr.waitFor();
        } catch (InterruptedException e) {
            throw new TaskException("Script was interrupted.");
        }
        if (pr.exitValue() != 0) {
            throw new TaskException(scriptName.toString() + "\n\nExit code: "
                                      + new Integer(exitCode).toString());
        }
    }
}



@


1.1.2.2
log
@Ported more TigrisUpdate methods to HelmTask
@
text
@a70 83
    ////////////////////////////////////////////////////////////////
    // Project scripts.
    ////////////////////////////////////////////////////////////////

    /**
     * Add a new project to CVS, Issuezilla, etc.
     */
    public static void addProject(User onBehalfOf, Project project)
        throws Exception
    {
	String cmd = "ProjectAdd";
	List args = makeProjectArgs(project.getDomainName(),
                                    project.getName(),
                                    project.getID(),
                                    project.getBrand(),
                                    project.getShortDescription());
        add(onBehalfOf, project.getID(), cmd, args);
    }

    /**
     * Remove a project from CVS, Issuezilla, etc.
     */
    public static void deleteProject(User onBehalfOf, Project project)
        throws Exception
    {
     
        String cmd = "ProjectDelete";
        List args = makeProjectArgs(project.getDomainName(),
                                    project.getName(),
                                    project.getID(),
                                    project.getBrand(),
                                    null
                                    );
        add(onBehalfOf, project.getID(), cmd, args);
    }

    //
    // Generation of module tasks.
    //

    /**
     * Add a new module to Issuezilla.
     */
    public static void addModule(User onBehalfOf,
                                 Project project,
                                 String moduleName,
                                 String moduleDescription,
                                 String isWeb)
        throws Exception
    {
	String cmd = "ModuleAdd";
	List args = makeModuleArgs(project.getDomainName(),
                                   project.getName(),
                                   project.getID(), 
                                   project.getBrand(),
                                   moduleName,
                                   moduleDescription,
                                   isWeb
                                   );
        add(onBehalfOf, project.getID(), cmd, args);
    }

    /**
     * Remove a module from Issuezilla.
     */
    public static void deleteModule(User onBehalfOf,
                                    Project project,
                                    String moduleName)
        throws Exception
    {
	String cmd = "ModuleDelete";

	List args = makeModuleArgs(project.getDomainName(),
                                   project.getName(),
                                   project.getID(), 
                                   project.getBrand(),
                                   moduleName,
                                   null,
                                   null
                                   );
        add(onBehalfOf, project.getID(), cmd, args);
    }
    
d108 6
d123 1
a123 1
        add(onBehalfOf, project.getID(), cmd, args);
d156 6
d171 1
a171 1
        add(onBehalfOf, project.getID(), cmd, args);
a306 1

d311 1
a311 1
    public static Task add (User onBehalfOf, String affectedObjectID, 
@


1.1.2.3
log
@Ported IssueTrackingRebuild servlet.
@
text
@a259 17
    /**
     * Disable all Issuezilla accoutns for the given project.
     */
    public static void disableAllAccounts(User onBehalfOf, Project project)
        throws Exception
    {	
	String cmd = "MemberDisableAll";

	List args = makeProjectArgs(project.getDomainName(),
                                    project.getName(),
                                    project.getID(),
                                    project.getBrand(),
                                    project.getShortDescription()
                                    );
        add(onBehalfOf, project.getID(), cmd, args);
    }

@


1.1.2.4
log
@Normalized copyright dates.
@
text
@d2 1
a2 1
 * Copyright (c) 2000-2001 CollabNet.  All rights reserved.
@


1.1.2.5
log
@Fixed what has got to be one of the stupidest logic inversions I've ever made.
@
text
@d376 4
a379 4
        if (projectName!=null) args.add("--project_name="+projectName); 
        if (projectID!=null) args.add("--project_id="+projectID);
        if (brandName!=null) args.add("--brand_name="+brandName);
        if (projectDescription!=null) 
d381 2
a382 2
        if (moduleName!=null) args.add("--module_name="+moduleName);  
        if (moduleDescription!=null) 
d384 4
a387 4
        if (isWeb!=null) args.add("--is_web="+isWeb);
        if (userRealName!=null) args.add("--issues_realname="+userRealName);
        if (userName!=null) args.add("--issues_username="+userName);
        if (userRole!=null) args.add("--issues_role="+userRole);
@


1.1.2.6
log
@Added new imports necessitated by Torque.
@
text
@a58 1
import org.tigris.helm.om.base.*;
@


1.1.2.7
log
@Fixes for taskrunner.
@
text
@d418 1
a418 1
        String command = t.getCommand();
d420 1
d430 1
a430 1
            try                 
d438 2
a439 2
                    project.runCreationScripts(user);
                    project.rebuildIssueTracking(user.getACL());
@


1.1.2.8
log
@Cleanup and documentation.
@
text
@a62 5
/**
 * Helm task.
 *
 * @@author <a href="mailto:leonardr@@collab.net">Leonard Richardson</a>
 */
d65 1
a65 4
    /**
     * The name of the component which runs our tasks.
     */
    public static final String COMPONENT_NAME = "Helm";
d68 1
a68 1
    protected static final String SCRIPT_DIR = "/helm/perl/scripts/";
d70 1
a70 1
    private static final boolean DEBUG = true;
d409 1
a409 2
    public static void runTask(Task t)
        throws TaskException
d423 2
a424 3
        }
        catch (Exception e) {
            throw new TaskException(e);
d439 1
a439 2
                }
                else {
d445 1
a445 1
                ue = new TaskException(e);
d506 1
a506 1
        if (DEBUG) Log.debug("Running " + scriptName.toString());
d509 1
a509 1
            args[0] = sandbox + SCRIPT_DIR + args[0];
@


