/*
*
* Perforce/Java Integration Layer
* Copyright (C) 2001-2002 David Freels
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.dafreels.vcs.command;
//Java
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
//Perforce VCS
import com.dafreels.vcs.command.PropertyInterface;
import com.dafreels.vcs.command.MessageFormatter;
import com.dafreels.opentools.Main;
import com.borland.primetime.ide.*;
/**
* Title:
* Description:
* Copyright: Copyright (c) 2001
* Company: DF Systems
* @author David Freels
* @version 1.0
*/
public final class CommandTool
{
private static Process proc;
private static boolean _ready = false;
private static StringBuffer _output = new StringBuffer("");
private static boolean _writeOut = true;
private static boolean _showTimings = false;
static
{
_showTimings = Boolean.getBoolean("Perforce.CommandTool.showTimings");
}
private static String setCommandLine(String command, boolean debug, PropertyInterface props)
{
//Get the Path to the P4 executable
if ( props.getExecutable() == null || props.getExecutable().length() == 0 )
{
System.out.println("[CommandTool](setCommandLine) no P4 executable set");
MessageFormatter.addErrorMessage("No P4 executable set. Please configure Perforce first" );
return null;
}
StringBuffer commandLine = new StringBuffer(props.getExecutable());
if(debug && (props.getDebugLevel() > 0 && debug))
{
commandLine.append(" -v"+props.getDebugLevel());
}
//Add the client spec
if ( props.getClientSpec() == null || props.getClientSpec().length() == 0 )
{
MessageFormatter.addErrorMessage("No P4 ClientSpec set. Please configure Perforce first" );
return null;
}
commandLine.append(" -c "+props.getClientSpec());
//Add the host information
if ( props.getPort() == null || props.getPort().length() == 0 )
{
MessageFormatter.addErrorMessage("No P4 Port set. Please configure Perforce first" );
return null;
}
commandLine.append(" -p "+props.getPort());
//Add the command
commandLine.append(" "+command);
//Display the command
//writeMessage(commandLine.toString());
return commandLine.toString();
}
private static String[] setCommandLineArray(String command, boolean debug, PropertyInterface props)
{
//Get the Path to the P4 executable
if ( props.getExecutable() == null || props.getExecutable().length() == 0 )
{
System.out.println("[CommandTool](setCommandLine) no P4 executable set");
MessageFormatter.addErrorMessage("No P4 executable set. Please configure Perforce first" );
return null;
}
java.util.ArrayList list = new java.util.ArrayList(20);
String exe = props.getExecutable();
if ( exe.indexOf(" ") > -1 )
{
exe = "\"".concat(exe).concat("\"");
}
list.add(exe);
if(debug && (props.getDebugLevel() > 0 && debug))
{
list.add("-v"+props.getDebugLevel());
}
//Add the client spec
if ( props.getClientSpec() == null || props.getClientSpec().length() == 0 )
{
MessageFormatter.addErrorMessage("No P4 ClientSpec set. Please configure Perforce first" );
return null;
}
list.add("-c"+props.getClientSpec());
//Add the host information
if ( props.getPort() == null || props.getPort().length() == 0 )
{
MessageFormatter.addErrorMessage("No P4 Port set. Please configure Perforce first" );
return null;
}
list.add("-p"+ props.getPort());
//Add the command
java.util.StringTokenizer tokenizer = new java.util.StringTokenizer(command, " ");
while (tokenizer.hasMoreTokens())
{
list.add(tokenizer.nextToken());
}
//Display the command
//writeMessage(commandLine.toString());
String[] cmds = new String[list.size()];
list.toArray(cmds);
return cmds;
}
public synchronized static boolean runCommand(Command command, PropertyInterface props)
{
if ( command == null )
{
return false;
}
return runCommand(command.toString(), props);
}
public synchronized static boolean runCommand(String command, PropertyInterface props)
{
return runCommand(command, false, props);
}
public synchronized static boolean runCommand(String command, boolean useStdIn, PropertyInterface props)
{
return runCommand(command, useStdIn, true, false, props);
}
public synchronized static boolean runCommand(String command, boolean useStdIn,
boolean output, boolean debug, PropertyInterface props)
{
long t1 = System.currentTimeMillis();
//Set the Perforce variables using the props object
//This allows each IDE integration layer to pass the
//properties in an independent manner.
_ready = false;
_writeOut = output;
/*
String commandLine = setCommandLine(command, debug, props);
if ( commandLine == null )
{
return false;
}
*/
String[] commandArray = setCommandLineArray(command, debug, props);
if ( commandArray == null )
{
return false;
}
for (int i = 0; i < commandArray.length; i++ )
{
System.out.println("commandArray["+i+"]="+commandArray[i]);
}
long t3 = 0, t4 = 0;
//Execute the command and trap the messages to be sent to the Message View
try
{
t3 = System.currentTimeMillis();
System.out.println("launching p4 command");
//proc = Runtime.getRuntime().exec(commandLine);
proc = Runtime.getRuntime().exec(commandArray);
System.out.println("back from p4 command");
t4 = System.currentTimeMillis();
_ready = true;
if(!useStdIn)
{
return finishCommand();
} else
{
return true;
}
} catch(java.io.IOException ioe)
{
System.out.println("[CommandTool] (runCommand)\n"+ioe.toString());
return false;
}
finally
{
long t2 = System.currentTimeMillis();
if ( _showTimings )
{
System.out.println("[CommandTool] (runCommand) Runtime.exec() took:"
+ (t4-t3)+" ms");
System.out.println("[CommandTool] (runCommand) Command:"+command+" took:"
+ (t2-t1)+" ms");
}
}
}
public static void writeToOut(String message)
{
//writeMessage("ChangeList: ");
//writeMessage(message);
try
{
java.io.BufferedWriter sw = new java.io.BufferedWriter(new java.io.OutputStreamWriter(proc.getOutputStream()));
sw.write(message);
sw.flush();
sw.close();
finishCommand();
} catch(java.io.IOException ioe)
{
System.out.println("[CommandTool] (writeToOut)\n"+ioe.toString());
}
}
public static boolean isStreamReady()
{
return _ready;
}
public static boolean finishCommand()
{
//Hold the errors produced by the command
String errors = "";
//Hold messages produced by the command
String message = "";
long t1 = System.currentTimeMillis();
try
{
//Create a thread to read the output stream and store the output
ProcessReader pr = ProcessReader.getInstance(proc);
//ProcessReader pr = new ProcessReader(proc.getInputStream());
//new Thread(pr).start();
//Wait for the process to complete
System.out.println("calling waitFor");
int code = proc.waitFor();
//Wait for the ProcessReaders to finish
System.out.println("waiting for process to finish");
while(!pr.isFinished())
{ // let some other threads run if they want
Thread.yield();
}
System.out.println("process is finished");
pr = null;
proc.destroy();
//System.gc();
return true;
} catch(InterruptedException ie)
{
System.out.println("[CommandTool] (finishCommand)"+System.getProperty("line.separator")+ie.toString());
return false;
}
finally
{
long t2 = System.currentTimeMillis();
if ( _showTimings )
{
System.out.println("[CommandTool] (finishCommand) took:"
+(t2-t1)+" ms");
}
}
}
public static String getOutput()
{
return _output.toString();
}
}