head	1.7;
access;
symbols
	TIGRIS_1_1_0RC2:1.1.2.2.2.1
	TIGRIS_1_1_0RC1:1.1.2.2
	TIGRIS_1_1:1.1.2.2.0.2
	TIGRIS_1_0_8:1.1.2.2
	TIGRIS_1_0_8RC3:1.1.2.2
	TIGRIS_1_0_8RC2:1.1.2.2
	TIGRIS_1_0_8RC1:1.1.2.2
	TIGRIS_1_0_7:1.1.2.2
	TIGRIS_1_0_7RC3:1.1.2.2
	TIGRIS_1_0_7RC2:1.1.2.2
	TIGRIS_1_0_7RC1:1.1.2.2
	TIGRIS_1_0_6:1.1.2.2
	TIGRIS_1_0_6RC5:1.1.2.2
	TIGRIS_1_0_6RC4:1.1.2.2
	TIGRIS_1_0_6RC3:1.1.2.2
	TIGRIS_1_0_6RC2:1.1.2.1
	TIGRIS_1_0_6RC1:1.1.2.1
	TIGRIS_1_0:1.1.0.2;
locks; strict;
comment	@# @;


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

1.6
date	2001.08.22.18.35.04;	author leonardr;	state Exp;
branches;
next	1.5;

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

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

1.3
date	2001.07.19.18.42.23;	author dlr;	state Exp;
branches;
next	1.2;

1.2
date	2001.06.08.19.19.41;	author leonardr;	state Exp;
branches;
next	1.1;

1.1
date	2001.05.31.02.41.37;	author leonardr;	state Exp;
branches
	1.1.2.1;
next	;

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

1.1.2.2
date	2001.06.07.23.21.16;	author leonardr;	state Exp;
branches
	1.1.2.2.2.1;
next	1.1.2.3;

1.1.2.3
date	2001.08.06.22.59.55;	author jrobbins;	state Exp;
branches;
next	;

1.1.2.2.2.1
date	2001.08.06.23.39.16;	author jrobbins;	state Exp;
branches;
next	;


desc
@@


1.7
log
@Corrected compile-time error.
@
text
@/* ================================================================
 * Copyright (c) 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.tool.task;

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

import org.apache.turbine.util.Log;

import org.tigris.helm.tool.HelmProperties;

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

/**
 * A utility class which builds arguments for and runs scripts.
 *
 * @@author <a href="mailto:leonardr@@collab.net">Leonard Richardson</a>
 * @@version $Id: ScriptTool.java,v 1.6 2001/08/22 18:35:04 leonardr Exp $
 */
public class ScriptTool
{
    /**
     * Whether or not to print debugging information.
     */
    private static final boolean DEBUG = false;

    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 HELM_SCRIPT_DIR = "/helm/perl/scripts/";

    //
    // 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.
     */
    public static Map makeProjectArgs(Project project)
        throws TaskException 
    {
        Map args = new HashMap();
        if (project != null)
        {
            try
            {
                makeArgMapping(args, "domain_name",
                               project.getDomain().getName());
            }
            catch (Exception e)
            {
                throw new TaskException(e);
            }
            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.
     */
    public 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;
    }

    /**
     * Transforms a map of arguments into a list.
     */
    public 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;
    }

    ///////////////////////////////////////////////////////////////////
    // Script runner.
    ///////////////////////////////////////////////////////////////////

    /**
     * Run a script with the argument mappings for the given project.
     */
    public static synchronized void runProjectScript(String command, Project p)
        throws TaskException 
    {
        runScript(command, makeProjectArgs(p));
    }

    /**
     * Run a script with the given argument mappings.
     */
    public 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.
     */
    public static synchronized void runScript(String command, List argList)
        throws TaskException 
    {
        runScript(HELM_SCRIPT_DIR, command, argList, null);
    }

    /**
     * Run a command with a populated environment.
     * @@param scriptDir Directory in which the script to be run is found.
     * @@param command Command to run.
     * @@param argList List of arguments-value pairs to pass.
     * @@param stdin String to feed to script's standard input.
     */
    public static synchronized void runScript(String scriptDir, String command,
                                              List argList, String stdin)
        throws TaskException 
    {
        //Get the variables to be put in the script's environment.
        String htdoc_root =
            (String) HelmProperties.getProperty("documentRoot");
        String sandbox = (String) HelmProperties.getProperty("SANDBOX");
        String dbName = (String) HelmProperties.getProperty("databaseName");
        String dbUser = (String) HelmProperties.getProperty("databaseUser");
        String dbPassword =
            (String) HelmProperties.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 + scriptDir + 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);                        

            OutputStream in = pr.getOutputStream();
            if (stdin != null)
            {
                in.write(stdin.getBytes());
            }
            in.close();
        } 
        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.6
log
@Added convenience method for running a script using a given project's arguments.
@
text
@d64 1
a64 1
 * @@version $Id: ScriptTool.java,v 1.5 2001/08/02 17:03:11 leonardr Exp $
d99 1
a99 1
        throws Exception 
d104 9
a112 1
            makeArgMapping(args, "domain_name", project.getDomain().getName());
@


1.5
log
@ScriptTool can now take a string to be passed as standard input to the script.
@
text
@d64 1
a64 1
 * @@version $Id: ScriptTool.java,v 1.4 2001/07/30 19:29:58 leonardr Exp $
d155 9
@


1.4
log
@Stop coddling IZ in terms of user accounts; assume that IZ can get its permissions from Helm through the XML-RPC interface.
@
text
@d64 1
a64 1
 * @@version $Id: ScriptTool.java,v 1.3 2001/07/19 18:42:23 dlr Exp $
d78 1
a78 1
    protected static final String SCRIPT_DIR = "/helm/perl/scripts/";
d173 14
d206 1
a206 1
        args[0] = sandbox + SCRIPT_DIR + command;
d224 1
a224 1
            }            
d230 8
a237 1
            pr = rt.exec(args, env);            
@


1.3
log
@Updated in light of the port of Joist JoistProperties class to Helm (as class HelmProperties).
@
text
@d64 1
a64 1
 * @@version $Id: ScriptTool.java,v 1.2 2001/06/08 19:19:41 leonardr Exp $
d118 1
a118 1
                                      String moduleDescription, String isWeb)
a131 33
        }
        return args;
    }

    /**
     * Takes a list of users and an optional role, and returns a map
     * of arguments.
     */
    public 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);
@


1.2
log
@Turned off debugging.
@
text
@d55 1
a55 1
import org.joist.util.JoistProperties;
d64 1
a64 1
 * @@version $Id: ScriptTool.java,v 1.1 2001/05/31 02:41:37 leonardr Exp $
d208 4
a211 4
            (String) JoistProperties.getProperty("documentRoot");
        String sandbox = (String) JoistProperties.getProperty("SANDBOX");
        String dbName = (String) JoistProperties.getProperty("databaseName");
        String dbUser = (String) JoistProperties.getProperty("databaseUser");
d213 1
a213 1
            (String) JoistProperties.getProperty("databasePassword");
@


1.1
log
@Factored out script running code to support new IssueTrackingRebuildService.
@
text
@d64 1
a64 1
 * @@version $Id: TaskRunnerService.java,v 1.26 2001/05/22 20:34:56 leonardr Exp $
d71 1
a71 1
    private static final boolean DEBUG = true;
@


1.1.2.1
log
@Ported minimal cluster functionality so that I could also port IssueTrackingRebuildService, which builds on it.
@
text
@d64 1
a64 1
 * @@version $Id: ScriptTool.java,v 1.1 2001/05/31 02:41:37 leonardr Exp $
d109 1
a109 1
                           DBFlag.flagValueOf(project.isProprietary())); 
@


1.1.2.2
log
@Turned off debug.
@
text
@d64 1
a64 1
 * @@version $Id: ScriptTool.java,v 1.1.2.1 2001/06/01 19:18:08 leonardr Exp $
d71 1
a71 1
    private static final boolean DEBUG = false;
d243 1
a243 1
            }                        
@


1.1.2.2.2.1
log
@adding files and code from head needed for new runScripts() done by leonardr
@
text
@d55 1
a55 1
import org.tigris.helm.tool.HelmProperties;
d64 1
a64 1
 * @@version $Id: ScriptTool.java,v 1.1.2.3 2001/08/06 22:59:55 jrobbins Exp $
d78 1
a78 1
    protected static final String HELM_SCRIPT_DIR = "/helm/perl/scripts/";
a191 1

a205 14
        runScript(HELM_SCRIPT_DIR, command, argList, null);
    }

    /**
     * Run a command with a populated environment.
     * @@param scriptDir Directory in which the script to be run is found.
     * @@param command Command to run.
     * @@param argList List of arguments-value pairs to pass.
     * @@param stdin String to feed to script's standard input.
     */
    public static synchronized void runScript(String scriptDir, String command,
                                              List argList, String stdin)
        throws TaskException 
    {
d208 4
a211 4
            (String) HelmProperties.getProperty("documentRoot");
        String sandbox = (String) HelmProperties.getProperty("SANDBOX");
        String dbName = (String) HelmProperties.getProperty("databaseName");
        String dbUser = (String) HelmProperties.getProperty("databaseUser");
d213 1
a213 1
            (String) HelmProperties.getProperty("databasePassword");
d225 1
a225 1
        args[0] = sandbox + scriptDir + command;
d249 1
a249 8
            pr = rt.exec(args, env);                        

            OutputStream in = pr.getOutputStream();
            if (stdin != null)
            {
                in.write(stdin.getBytes());
            }
            in.close();
@


1.1.2.3
log
@adding files and code from head needed for new runScripts() done by leonardr
@
text
@d55 1
a55 1
import org.tigris.helm.tool.HelmProperties;
d64 1
a64 1
 * @@version $Id: ScriptTool.java,v 1.1.2.2 2001/06/07 23:21:16 leonardr Exp $
d78 1
a78 1
    protected static final String HELM_SCRIPT_DIR = "/helm/perl/scripts/";
a191 1

a205 14
        runScript(HELM_SCRIPT_DIR, command, argList, null);
    }

    /**
     * Run a command with a populated environment.
     * @@param scriptDir Directory in which the script to be run is found.
     * @@param command Command to run.
     * @@param argList List of arguments-value pairs to pass.
     * @@param stdin String to feed to script's standard input.
     */
    public static synchronized void runScript(String scriptDir, String command,
                                              List argList, String stdin)
        throws TaskException 
    {
d208 4
a211 4
            (String) HelmProperties.getProperty("documentRoot");
        String sandbox = (String) HelmProperties.getProperty("SANDBOX");
        String dbName = (String) HelmProperties.getProperty("databaseName");
        String dbUser = (String) HelmProperties.getProperty("databaseUser");
d213 1
a213 1
            (String) HelmProperties.getProperty("databasePassword");
d225 1
a225 1
        args[0] = sandbox + scriptDir + command;
d249 1
a249 8
            pr = rt.exec(args, env);                        

            OutputStream in = pr.getOutputStream();
            if (stdin != null)
            {
                in.write(stdin.getBytes());
            }
            in.close();
@


