package com.jbase.jbuilder5vcs;
// jBuilder import
import com.borland.primetime.node.Node;
import com.borland.primetime.vfs.Url;
import com.borland.primetime.node.Project;
import com.borland.primetime.teamdev.vcs.VCSFileInfo;
import com.borland.primetime.teamdev.vcs.VCS;
import com.borland.primetime.ide.Browser;
import com.borland.primetime.util.runner.OutputRunnerListener;
import com.borland.primetime.teamdev.frontend.VCSCommitBrowser;
// java import
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.JLabel;
import javax.swing.JPanel;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Iterator;
/**
* Title: JBuilder/Perforce
* Description: call command of P4.<br>
* <dl><dt>command supported:</dt>
* <dd>- sync</dd>
* <dd>- edit</dd>
* <dd>- submit</dd>
* <dd>- revert</dd>
* <dd>- client</dd>
* <dd>- add</dd>
* <dd>- have</dd>
* <dd>- change</dd></dl>
* This class has a field variable with a p4ClientSpec. It's for<br>
* save on cash the definition of the P4 Client.<br>
* <DL><DT><b>Company:</b></DT><DD>jBase.</DD></DL>
* @author <a href="mailto:nicolasj@jbase.com">Nicolas Jorand</a>
* @version 1.0
* @since JDK 1.3
*/
public class P4Cmd {
// Constants Used by the P4 console
public static final String CMD_P4 = "p4 ";
public static final String CMD_SYNC = "sync ";
public static final String CMD_EDIT = "edit ";
public static final String CMD_SUBMIT = "submit ";
public static final String CMD_REVERT = "revert ";
public static final String CMD_CLIENT = "client ";
public static final String CMD_ADD = "add ";
public static final String CMD_HAVE = "have ";
public static final String CMD_CHANGE = "change ";
public static final String CMD_PASSWORD = "-P ";
public static final String CMD_USER = "-u ";
public static final String CMD_CLIENT_OPTION = "-c ";
public static final String CMD_CONSOLE_MODE = "-o ";
public static final String CMD_CONSOLE_INPUT = "-i ";
public static final String CMD_FILE_TYPE = "-t ";
public static final String CMD_HOST_OPTION = "-H ";
public static final String CMD_PORT_OPTION = "-p ";
public static final String CMD_FILE_TYPE_TEXT = "text ";
// Constantes for the messages
public static final String MSG_CONNECT_IMPOSSIBLE ="Impossible to connect with P4 ! Check settings.";
public static final String MSG_CONNECT_TITLE = "P4 connection";
public static final String MSG_NO_ITEMS = "Please select item(s) to synchronize";
public static final String MSG_P4_SYNCHRO_TITLE = "P4 synchronize";
public static final String MSG_P4_ADD_TITLE = "P4 Add";
public static final String MSG_P4_REVERT_TITLE = "P4 Revert";
public static final String MSG_P4_SUBMIT_TITLE = "P4 Submit";
public static final String MSG_P4_EDIT_TITLE = "P4 Edit";
public static final String MSG_P4_COMMIT_TITLE = "P4 Commit";
public static final String MSG_IS_UPTODATE = "File(s) are up to date";
public static final String MSG_SUCCESSFULL = "Operation Successfull !";
public static final String MSG_UNSUCCESSFULL = "Operation not complete Successfull !";
public static final String MSG_ENTER_COMMENT = " Please enter a comment";
public static final String MSG_NO_SUBMITTED = "No Submitted ";
public static final String MSG_COMMIT = "Commit ";
public static final String MSG_COMMITTED = "OK :-)";
// Message from P4
public static final String MSG_P4_UPTODATE = "file(s) up-to-date";
public static final String MSG_P4_UPDATING = "updating";
public static final String MSG_P4_FILE_NOT_ON_CLIENT = "file(s) not on client";
public static final String MSG_P4_OPEN_FOR_ADD = "opened for add";
public static final String MSG_P4_WAS_ADD = "was add";
public static final String MSG_P4_OPEN_FOR_EDIT = "opened for edit";
public static final String MSG_P4_SUBMITTED = "submitted";
public static final String MSG_P4_NO_CONNECTION = "client error";
public static final String MSG_P4_FILE_REVERTED = "reverted";
public static final String MSG_P4_FILE_REVERTED_AFTER_ADD = "abandoned";
public static P4ClientSpec _mySpec; // Cash specification of P4 client
public P4Cmd() {
try{
initClass();
}catch(Exception e){
e.printStackTrace();
}
}
/**
* For synchronize file(s) with P4,<p>
* First, get description of the P4 client for get the root path and the name of the depot<p>
* Second, Check the connection with p4 by read the description value.<p>
* Third, create the list of file to synchronize.<p>
* Fourth, create the command line for P4 by adding user, password, List of file and send to p4
* Last, update the lists file on the P4ClientSpec
* @param nodeList List of file must be synchronize
* @return String The successfull response from P4
* @exception P4ErrorApplication
* Applicative error from P4
* @exception P4ErrorConnection
* Connection to P4 defect
*/
public String sync(Node[] nodeList) throws P4ErrorApplication, P4ErrorConnection{
return sync(nodeList,null,null);
}
/**
* For synchronize file(s) with P4,<p>
* First, get description of the P4 client for get the root path and the name of the depot<p>
* Second, Check the connection with p4 by read the description value.<p>
* Third, create the list of file to synchronize.<p>
* Fourth, create the command line for P4 by adding user, password, List of file and send to p4
* Last, update the lists file on the P4ClientSpec
* @param fileList List of file must be synchronize
* @param prj The active project for get P4 information (eg: User,...)
* @return String The successfull response from P4
* @exception P4ErrorApplication
* Applicative error from P4
* @exception P4ErrorConnection
* Connection to P4 defect
*/
public String sync(Set fileList, Project prj) throws P4ErrorApplication, P4ErrorConnection{
return sync(null,fileList,prj);
}
/**
* For synchronize file(s) with P4,<p>
* First, get description of the P4 client for get the root path and the name of the depot<p>
* Second, Check the connection with p4 by read the description value.<p>
* Third, create the list of file to synchronize.<p>
* Fourth, create the command line for P4 by adding user, password, List of file and send to p4
* Last, update the lists file on the P4ClientSpec
* @param nodeList List of file must be synchronize
* @param fileList List of file must be synchronize(if come form the commit browser)
* @param prj The active project for get P4 information (eg: User,...)
* @return String The successfull response from P4
* @exception P4ErrorApplication
* Applicative error from P4
* @exception P4ErrorConnection
* Connection to P4 defect
*/
public String sync(Node[] nodeList,Set fileList, Project prj) throws P4ErrorApplication, P4ErrorConnection{
String sPathFile = null;
String sRoot = null;
String sDepot = null;
String sUserPass = null;
String sRet = null;
StringBuffer sFileToSyn = new StringBuffer(); // File(s) will be synchronize
// Get information of P4
sRoot = _mySpec.getRoot();
sDepot = _mySpec.getDepot();
// Test the connection, if connection is down, throws a P4ErrorConnection
connectionAlert();
if(nodeList != null && nodeList.length == 0) { // Connection to P4 OK, Have a item in selection in jBuilder ?
// No item selected in jBuilder
throw new P4ErrorApplication(MSG_NO_ITEMS, MSG_P4_SYNCHRO_TITLE);
}
sUserPass = "";
if (nodeList != null){
sUserPass = getOptions(nodeList[0].getProject());
}else{
sUserPass = getOptions(prj);
}
// Create the commande for synchro. for the file selectioned
if (nodeList != null){
sFileToSyn = setFileToSend(nodeList, sRoot, sDepot);
}else{
sFileToSyn = setFileToSend(fileList, sRoot, sDepot);
}
String[] sCmdf = {this.CMD_P4 + sUserPass + this.CMD_SYNC + sFileToSyn.toString()};
sRet = this.sendCmd(sCmdf);
if (sRet == null){ // The connection is down ...
throw new P4ErrorConnection(MSG_CONNECT_IMPOSSIBLE);
}
// Make a refresh of the description object
this.refresh();
// Check the console return and popup a message according to the return.
if (!(sRet.indexOf(MSG_P4_UPTODATE)!=-1 || sRet.indexOf(MSG_P4_UPDATING)!=-1)){
throw new P4ErrorApplication(sRet,MSG_P4_SYNCHRO_TITLE);
}
return sRet;
}
/**
* For "check-out" file(s) from P4 and update the lists file on the P4ClientSpec
* @param nodeList List of file must be edited
* @return String The successfull response from P4
* @exception P4ErrorApplication
* Applicative error from P4
* @exception P4ErrorConnection
* Connection to P4 defect
*/
public String edit(Node[] nodeList) throws P4ErrorApplication, P4ErrorConnection{
return edit(nodeList,null,null);
}
/**
* For "check-out" file(s) from P4 and update the lists file on the P4ClientSpec
* @param fileList List of file must be edited
* @param prj The active project for get P4 information (eg: User,...)
* @return String The successfull response from P4
* @exception P4ErrorApplication
* Applicative error from P4
* @exception P4ErrorConnection
* Connection to P4 defect
*/
public String edit(Set fileList, Project prj) throws P4ErrorApplication, P4ErrorConnection{
return edit(null,fileList,prj);
}
/**
* For "check-out" file(s) from P4 and update the lists file on the P4ClientSpec
* @param nodeList List of file must be edited
* @param fileList List of file must be edited(if come form the commit browser)
* @param prj The active project for get P4 information (eg: User,...)
* @return String The successfull response from P4
* @exception P4ErrorApplication
* Applicative error from P4
* @exception P4ErrorConnection
* Connection to P4 defect
*/
public String edit(Node[] nodeList,Set fileList, Project prj) throws P4ErrorApplication, P4ErrorConnection{
String sRet = null;
String sPathFile = null;
String sRoot = null;
String sDepot = null;
String sUserPass = null;
StringBuffer sFileToSyn = new StringBuffer(); // File(s) will be edit
// Get information of P4
sRoot = _mySpec.getRoot();
sDepot = _mySpec.getDepot();
// Test the connection, if connection is down, throws a P4ErrorConnection
connectionAlert();
if(nodeList != null && nodeList.length == 0) { // Connection to P4 OK, Have a item in selection in jBuilder ?
// No item selected in jBuilder
throw new P4ErrorApplication(MSG_NO_ITEMS, MSG_P4_SYNCHRO_TITLE);
}
if (nodeList != null){
sUserPass = getOptions(nodeList[0].getProject());
}else{
sUserPass = getOptions(prj);
}
// Create the commande for edit. for the file selectioned
if (nodeList != null){
sFileToSyn = setFileToSend(nodeList, sRoot, sDepot);
}else{
sFileToSyn = setFileToSend(fileList, sRoot, sDepot);
}
String[] sCmdf = {this.CMD_P4 + sUserPass + this.CMD_EDIT + this.CMD_FILE_TYPE + this.CMD_FILE_TYPE_TEXT + sFileToSyn.toString()};
sRet = this.sendCmd(sCmdf);
if (sRet == null){ // The connection is down ...
throw new P4ErrorConnection(MSG_CONNECT_IMPOSSIBLE);
}
// Check the console return and popup a message according to the return.
if (!(sRet.indexOf(MSG_P4_OPEN_FOR_EDIT)!=-1)){
throw new P4ErrorApplication(sRet,MSG_P4_EDIT_TITLE);
}
// set the local depot/pending list
_mySpec.addFileOnPending(sFileToSyn);
return sRet;
}
/**
* For submit all modifications to P4 and update the lists file on the P4ClientSpec
* Warning: If another user had modified and submit the files, you must launch P4
* for merge the files. A Information box will throw to the user!!!
* @param nodeList List of file must be submit
* @return String The successfull response from P4
* @exception P4ErrorApplication
* Applicative error from P4
* @exception P4ErrorConnection
* Connection to P4 defect
*/
public String submit(Node[] nodeList, String sDescription) throws P4ErrorApplication, P4ErrorConnection{
String sRet = null;
String sPathFile = null;
String sRoot = null;
String sDepot = null;
String sUserPass = null;
StringBuffer sFileToSyn = new StringBuffer(); // File(s) will be edit
// Get information of P4
sRoot = _mySpec.getRoot();
sDepot = _mySpec.getDepot();
// Test the connection, if connection is down, throws a P4ErrorConnection
connectionAlert();
if(nodeList.length == 0) { // Connection to P4 OK, Have a item in selection in jBuilder ?
// No item selected in jBuilder
throw new P4ErrorApplication(MSG_NO_ITEMS, MSG_P4_SYNCHRO_TITLE);
}
sUserPass = getOptions(nodeList[0].getProject());
// Create the commande for submit. for the file selectioned
sFileToSyn = setFileToSend(nodeList, sRoot, sDepot, true);
String sCommande = createSubmitCmd(sDescription, sFileToSyn);
String[] sCmdf = {this.CMD_P4 + sUserPass + this.CMD_SUBMIT + this.CMD_CONSOLE_INPUT , sCommande};
sRet = this.sendCmd(sCmdf);
if (sRet == null){ // The connection is down ...
throw new P4ErrorConnection(MSG_CONNECT_IMPOSSIBLE);
}
// Check the console return and popup a message according to the return.
if (!(sRet.indexOf(MSG_P4_SUBMITTED)!=-1)){
throw new P4ErrorApplication(sRet,MSG_P4_EDIT_TITLE);
}
// set the local depot/pending list
StringBuffer sFileForRefresh = setFileToSend(nodeList, sRoot, sDepot);
_mySpec.removeFileFromPending(sFileForRefresh);
_mySpec.addFileOnDepot(sFileForRefresh);
return sRet;
}
/**
* For submit all modifications selected on the status window to P4. I separate the submit <br>
* and the commit methode, because, the first think was to change the icon directly on the jBuilder<br>
* project tree, but I don't found how change dynamically. At the moment I use the VCSCommitBrowser
* Warning: If another user had modified and submit the files, you must launch P4
* for merge the files. A Information box will throw to the user!!!
* @param nodeList List of file must be submit
* @return String The successfull response from P4
* @exception P4ErrorApplication
* Applicative error from P4
* @exception P4ErrorConnection
* Connection to P4 defect
*/
public String commit(Set fileList, OutputRunnerListener oOutrunner, Project prj) throws P4ErrorApplication, P4ErrorConnection{
String sRet = null;
String sPathFile = null;
String sRoot = null;
String sDepot = null;
String sUserPass = null;
StringBuffer sFileToSyn = new StringBuffer(); // File(s) will be edit
boolean bAllTransmit = true;
// Get information of P4
sRoot = _mySpec.getRoot();
sDepot = _mySpec.getDepot();
// Test the connection, if connection is down, throws a P4ErrorConnection
connectionAlert();
if(fileList.size() == 0) { // Connection to P4 OK, Have a item in selection in jBuilder ?
// No item selected in jBuilder
throw new P4ErrorApplication(MSG_NO_ITEMS, MSG_P4_SYNCHRO_TITLE);
}
sUserPass = getOptions(prj);
Iterator it = fileList.iterator();
while (it.hasNext()) {
VCSFileInfo iFile = (VCSFileInfo)it.next();
sFileToSyn = setFileToSend(iFile.getFile().toString(), sRoot, sDepot, false);
// Remove all CR+LF, P4 do not support multi line
String sDescription = iFile.getComment().replace('\n',' ').replace('\r',' ');
if (sDescription.equalsIgnoreCase(VCSCommitBrowser.NO_SUMMARY_COMMENT)) {
oOutrunner.stderrText(MSG_NO_SUBMITTED + sFileToSyn);
oOutrunner.stderrText(MSG_ENTER_COMMENT);
bAllTransmit = false;
continue;
}
String sCommande = createSubmitCmd(sDescription, sFileToSyn);
oOutrunner.stdoutText(MSG_COMMIT + sFileToSyn + " ...");
String[] sCmdf = {this.CMD_P4 + sUserPass + this.CMD_SUBMIT + this.CMD_CONSOLE_INPUT , sCommande};
sRet = this.sendCmd(sCmdf);
// Check the result
if (sRet == null){ // The connection is down ...
oOutrunner.stderrText(MSG_CONNECT_IMPOSSIBLE);
bAllTransmit = false;
break; // Not necessary to insist
}else if (!(sRet.indexOf(MSG_P4_SUBMITTED)!=-1)){
// Put in the console the error
oOutrunner.stderrText(sRet);
bAllTransmit = false;
}else{
// All right ! set the local depot/pending list
oOutrunner.stdoutText(MSG_COMMITTED);
_mySpec.removeFileFromPending(sFileToSyn);
}
}// end While
if (bAllTransmit){
oOutrunner.processFinished(bAllTransmit,MSG_SUCCESSFULL);
}else{
oOutrunner.processFinished(bAllTransmit,MSG_UNSUCCESSFULL);
}
return sRet;
}
/**
* Undo the modifications and update the lists file on the P4ClientSpec
* @param nodeList List of file must be reverted
* @return String The successfull response from P4
* @exception P4ErrorApplication
* Applicative error from P4
* @exception P4ErrorConnection
* Connection to P4 defect
*/
public String revert(Node[] nodeList) throws P4ErrorApplication, P4ErrorConnection{
return revert(nodeList,null,null);
}
/**
* Undo the modifications and update the lists file on the P4ClientSpec
* @param fileList List of file must be reverted(if come form the commit browser)
* @param prj The active project for get P4 information (eg: User,...)
* @return String The successfull response from P4
* @exception P4ErrorApplication
* Applicative error from P4
* @exception P4ErrorConnection
* Connection to P4 defect
*/
public String revert(Set fileList, Project prj) throws P4ErrorApplication, P4ErrorConnection{
return revert(null,fileList,prj);
}
/**
* Undo the modifications and update the lists file on the P4ClientSpec
* @param nodeList List of file must be reverted
* @param fileList List of file must be reverted(if come form the commit browser)
* @param prj The active project for get P4 information (eg: User,...)
* @return String The successfull response from P4
* @exception P4ErrorApplication
* Applicative error from P4
* @exception P4ErrorConnection
* Connection to P4 defect
*/
public String revert(Node[] nodeList,Set fileList, Project prj) throws P4ErrorApplication, P4ErrorConnection{
String sRet = null;
String sPathFile = null;
String sRoot = null;
String sDepot = null;
String sUserPass = null;
StringBuffer sFileToAdd = new StringBuffer(); // File(s) will be revert
// Get information of P4
sRoot = _mySpec.getRoot();
sDepot = _mySpec.getDepot();
// Test the connection, if connection is down, throws a P4ErrorConnection
connectionAlert();
if(nodeList!=null && nodeList.length == 0) { // Connection to P4 OK, Have a item in selection in jBuilder ?
// No item selected in jBuilder
throw new P4ErrorApplication(MSG_NO_ITEMS, MSG_P4_SYNCHRO_TITLE);
}
if(nodeList != null){
sUserPass = getOptions(nodeList[0].getProject());
}else{
sUserPass = getOptions(prj);
}
// Create the commande for revert for the file selectioned
if(nodeList != null){
sFileToAdd = setFileToSend(nodeList, sRoot, sDepot);
}else{
sFileToAdd = setFileToSend(fileList, sRoot, sDepot);
}
String[] sCmdf = {this.CMD_P4 + sUserPass + this.CMD_REVERT + sFileToAdd.toString()};
sRet = this.sendCmd(sCmdf);
if (sRet == null){ // The connection is down ...
throw new P4ErrorConnection(MSG_CONNECT_IMPOSSIBLE);
}
// Check the console return and popup a message according to the return.
if (!( (sRet.indexOf(this.MSG_P4_FILE_REVERTED) != -1) || (sRet.indexOf(this.MSG_P4_FILE_REVERTED_AFTER_ADD) != -1) )){
throw new P4ErrorApplication(sRet,MSG_P4_REVERT_TITLE);
}
// set the local depot/pending list
_mySpec.removeFileFromPending(sFileToAdd);
return sRet;
}
/**
* Add file(s) to P4 and update the lists file on the P4ClientSpec
* @param nodeList List of file must be added
* @return String The successfull response from P4
* @exception P4ErrorApplication
* Applicative error from P4
* @exception P4ErrorConnection
* Connection to P4 defect
*/
public String add(Node[] nodeList) throws P4ErrorApplication, P4ErrorConnection{
return add(nodeList,null,null);
}
/**
* Add file(s) to P4 and update the lists file on the P4ClientSpec
* @param fileList List of file must be added(if come form the commit browser)
* @param prj The active project for get P4 information (eg: User,...)
* @return String The successfull response from P4
* @exception P4ErrorApplication
* Applicative error from P4
* @exception P4ErrorConnection
* Connection to P4 defect
*/
public String add(Set fileList, Project prj) throws P4ErrorApplication, P4ErrorConnection{
return add(null,fileList,prj);
}
/**
* Add file(s) to P4 and update the lists file on the P4ClientSpec
* @param nodeList List of file must be added(if come form the commit browser)
* @param fileList List of file must be added(if come form the commit browser)
* @param prj The active project for get P4 information (eg: User,...)
* @return String The successfull response from P4
* @exception P4ErrorApplication
* Applicative error from P4
* @exception P4ErrorConnection
* Connection to P4 defect
*/
public String add(Node[] nodeList,Set fileList, Project prj) throws P4ErrorApplication, P4ErrorConnection{
String sRet = null;
String sPathFile = null;
String sRoot = null;
String sDepot = null;
String sUserPass = null;
StringBuffer sFileToAdd = new StringBuffer(); // File(s) will be add
// Get information of P4
sRoot = _mySpec.getRoot();
sDepot = _mySpec.getDepot();
// Test the connection, if connection is down, throws a P4ErrorConnection
connectionAlert();
if(nodeList != null && nodeList.length == 0) { // Connection to P4 OK, Have a item in selection in jBuilder ?
// No item selected in jBuilder
throw new P4ErrorApplication(MSG_NO_ITEMS, MSG_P4_SYNCHRO_TITLE);
}
if (nodeList != null){
sUserPass = getOptions(nodeList[0].getProject());
}else{
sUserPass = getOptions(prj);
}
// Create the commande for add. for the file selectioned
if (nodeList != null){
sFileToAdd = setFileToSend(nodeList, sRoot, sDepot);
}else{
sFileToAdd = setFileToSend(fileList, sRoot, sDepot);
}
String[] sCmdf = {this.CMD_P4 + sUserPass + this.CMD_ADD + this.CMD_FILE_TYPE + this.CMD_FILE_TYPE_TEXT + sFileToAdd.toString()};
sRet = this.sendCmd(sCmdf);
if (sRet == null){ // The connection is down ...
throw new P4ErrorConnection(MSG_CONNECT_IMPOSSIBLE);
}
// Check the console return and popup a message according to the return.
if (!(sRet.indexOf(this.MSG_P4_OPEN_FOR_ADD) != -1)){
throw new P4ErrorApplication(sRet,MSG_P4_ADD_TITLE);
}
// set the local depot/pending list
_mySpec.addFileOnPending(sFileToAdd);
return sRet;
}
/**
* Test if the file pass on parameter is under P4.<p>
* Return true if it's
*/
public boolean isOnVCS(Url url,Project project, int nDepotPending){
String sUserPass = getOptions(project);
String sDepotFileName = null;
String sFileToSyn = null;
String sPathFile = null;
sPathFile = url.getFileObject().getAbsolutePath();
return _mySpec.isUnderVCS(sPathFile, nDepotPending);
}
/**
* Try to connect with P4, for this make a refresh
* @return boolean, true if connect sucessfull.
*/
public boolean connect() throws P4ErrorConnection {
boolean bRet = false;
this.refresh();
if (this.isConnected()){
bRet = true;
}else{
throw new P4ErrorConnection(MSG_CONNECT_IMPOSSIBLE);
}
return bRet;
}
/**
* Send a command to p4 and return the response of the console <b>WITHOUT</b> the comment lines
*/
private String sendCmd(String[] cmd){
String sReturn = null;
String sTemp = null;
BufferedReader out = null;
// For debug if jBuilder is lauch in verbose mode.
System.out.println("P4Cmd:sendCmd:sCommande= ->");
for (int i = 0; i < cmd.length; i++) {
System.out.println(cmd[i].toString());
}
try
{
// Get the runtime and exec the first command
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec(cmd[0]);
// Get the outputstream of the proccess for send all another command
OutputStream in = proc.getOutputStream();
for (int ni= 1 ; ni<cmd.length ; ni++) in.write(cmd[ni].getBytes());
in.flush();
in.close();
// Get the error stream, if the process write on the error stream
InputStream stderr = proc.getErrorStream();
InputStreamReader isr = new InputStreamReader(stderr);
BufferedReader br = new BufferedReader(isr);
// Get the standard stream
InputStream std = proc.getInputStream();
InputStreamReader isrstd = new InputStreamReader(std);
BufferedReader brstd = new BufferedReader(isrstd);
// Get all information from the standard stream of the process.<p>
// without the line start with '#', it's a comment line
String line = null;
StringBuffer sbResp = new StringBuffer("");
while ( (line = brstd.readLine()) != null){
if (!line.startsWith("#")){ // Do not add comment line !
sbResp.append(line+"\n");
}
}
// Get all information from the error stream of the process.<p>
// without the line start with '#', it's a comment line
line = null;
StringBuffer sbError = new StringBuffer("");
while ( (line = br.readLine()) != null){
if (!line.startsWith("#")){ // Do not add comment line !
sbError.append(line+"\n");
}
}
// Wait for the end of process
int exitVal = proc.waitFor();
// Return the full buffer
if(sbResp.toString().equalsIgnoreCase("")){
// Check if connection isn't availlable
if (sbError.toString().indexOf(MSG_P4_NO_CONNECTION) == -1){
sReturn = sbError.toString();
}
}else{
// Check if connection isn't availlable
if (sbResp.toString().indexOf(MSG_P4_NO_CONNECTION) == -1){
sReturn = sbResp.toString();
}
}
}catch (Throwable t){
t.printStackTrace();
}finally{
System.out.println("<- End of sendCmd");
return sReturn;
}
}
/**
* Refresch the class, get the description from P4
*/
public void refresh(){
// Create a P4 description object and get informations
String sOptions = getOptions(Browser.getActiveBrowser().getActiveProject());
String[] sCmd = {this.CMD_P4 + sOptions + this.CMD_CLIENT + this.CMD_CONSOLE_MODE};
String[] sCmdFile = {this.CMD_P4 + sOptions + this.CMD_HAVE};
String[] sCmdChange = {this.CMD_P4 + sOptions + this.CMD_CHANGE + CMD_CONSOLE_MODE};
_mySpec.refresh(sendCmd(sCmd),sendCmd(sCmdFile),sendCmd(sCmdChange));
}
/**
* Get the status from the current description
*/
public Map getStatus(Project project){
return _mySpec.getStatus(project);
}
/**
* Check on a attribute of the P4ClientSpec, if it's null, the connection<br>
* is down
*/
public boolean isConnected(){
boolean bRet = false;
if (_mySpec != null && _mySpec.getClient() != null)
bRet = true;
return bRet;
}
/**
* Create the command for add user and password on P4 command.
*/
private String getOptions(Project project){
String sUser = project.getAutoProperty(VCS.CATEGORY,PerforceVCS.PROP_USER);
String sPass = project.getAutoProperty(VCS.CATEGORY,PerforceVCS.PROP_PASSWORD);
String sClient = project.getAutoProperty(VCS.CATEGORY,PerforceVCS.PROP_CLIENT);
String sHost = project.getAutoProperty(VCS.CATEGORY,PerforceVCS.PROP_HOST);
String sPort = project.getAutoProperty(VCS.CATEGORY,PerforceVCS.PROP_PORT);
String sDefaultPort = project.getAutoProperty(VCS.CATEGORY,PerforceVCS.PROP_PORT_DEFAULT);
// Create commande for userid and password, perhaps the user can has not password
String sRet = "";
if (sPass!=null && sPass.equalsIgnoreCase("")){
sRet = CMD_USER + sUser + " ";
}else{
sRet = CMD_USER + sUser + " " + CMD_PASSWORD + sPass + " ";
}
// Add the information of Host, Port, Client
if (sDefaultPort != null && !sDefaultPort.equalsIgnoreCase("")){
if (!sDefaultPort.equalsIgnoreCase("true")){
if (sHost != null && !sHost.equalsIgnoreCase("")){
String sAddPort = "";
if (sPort != null && !sPort.equalsIgnoreCase("")){
sAddPort = ":" + sPort;
}
sRet += CMD_PORT_OPTION + sHost + sAddPort + " ";
}
}
}
if (sClient != null && !sClient.equalsIgnoreCase("")){
sRet += CMD_CLIENT_OPTION + sClient + " ";
}
return sRet;
}
/**
* Return a string buffer with all the file on nodelist, the root will be replace by the depot,<p>
* All file will be separate by space. <p>
*/
private StringBuffer setFileToSend(Node[] nodeList, String sRoot, String sDepot){
return setFileToSend(nodeList, sRoot, sDepot, false);
}
/**
* Return a string buffer with all the file on nodelist, the root will be replace by the depot,<p>
* All file will be separate by space. <p>
*/
private StringBuffer setFileToSend(Set fileList, String sRoot, String sDepot){
return setFileToSend(fileList, sRoot, sDepot, false);
}
/**
* Return a string buffer with the file passed, the root will be replace by the depot,<p>
* if bMultiline is set to true, all file will be separate by a cr + lf. (usefull for the submit command) <p>
* if bMultiline is set to false, all file will be separate by space. <p>
*/
private StringBuffer setFileToSend(String sPathFile, String sRoot, String sDepot,boolean bMultiline){
StringBuffer sbFile = new StringBuffer();
String sEnd = " ";
String sStart = "";
if (bMultiline){
sStart = "\t";
sEnd = "\n";
}
sPathFile = sPathFile.replace('\\','/');
if (sPathFile.toLowerCase().startsWith(sRoot.toLowerCase())){
int nPosEnd = sRoot.length();
sbFile.append(sStart + sDepot + sPathFile.substring(nPosEnd+1) + sEnd);
}
return sbFile;
}
/**
* Return a string buffer with all the file on nodelist, the root will be replace by the depot,<p>
* if bMultiline is set to true, all file will be separate by a cr + lf. (usefull for the submit command) <p>
* if bMultiline is set to false, all file will be separate by space. <p>
*/
private StringBuffer setFileToSend(Node[] nodeList, String sRoot, String sDepot,boolean bMultiline){
String sPathFile = "";
StringBuffer sbFile = new StringBuffer();
String sEnd = " ";
String sStart = "";
if (bMultiline){
sStart = "\t";
sEnd = "\n";
}
for (int i=0;i<nodeList.length;i++){
sPathFile = nodeList[i].getLongDisplayName();
if (sPathFile.toLowerCase().startsWith(sRoot.toLowerCase())){
int nPosEnd = sRoot.length();
sbFile.append(sStart + sDepot + sPathFile.substring(nPosEnd+1) + sEnd);
}
}
return sbFile;
}
/**
* Return a string buffer with all the file on nodelist, the root will be replace by the depot,<p>
* if bMultiline is set to true, all file will be separate by a cr + lf. (usefull for the submit command) <p>
* if bMultiline is set to false, all file will be separate by space. <p>
*/
private StringBuffer setFileToSend(Set nodeList, String sRoot, String sDepot,boolean bMultiline){
String sPathFile = "";
StringBuffer sbFile = new StringBuffer();
String sEnd = " ";
String sStart = "";
if (bMultiline){
sStart = "\t";
sEnd = "\n";
}
Iterator it = nodeList.iterator();
while(it.hasNext()){
VCSFileInfo oFile = (VCSFileInfo)it.next();
sPathFile = oFile.getFile().toString().replace('\\','/');
if (sPathFile.toLowerCase().startsWith(sRoot.toLowerCase())){
int nPosEnd = sRoot.length();
sbFile.append(sStart + sDepot + sPathFile.substring(nPosEnd+1) + sEnd);
}
}
return sbFile;
}
private void initClass(){
// Create a P4 description object and get informations
String[] sCmd = {this.CMD_P4 + this.CMD_CLIENT + this.CMD_CONSOLE_MODE};
String[] sCmdFile = {this.CMD_P4 + this.CMD_HAVE};
String[] sCmdChange = {this.CMD_P4 + this.CMD_CHANGE + CMD_CONSOLE_MODE};
_mySpec = new P4ClientSpec(sendCmd(sCmd),sendCmd(sCmdFile),sendCmd(sCmdChange));
}
/**
* Create the commande for the submit action
*/
private String createSubmitCmd(String sDescription, StringBuffer sFileToSyn){
StringBuffer sCommande = new StringBuffer("Change: new\r\n");
sCommande.append("Client: ").append(_mySpec.getClient()).append("\n");
sCommande.append("User: ").append(_mySpec.getOwner()).append("\n");
sCommande.append("Status: new\r\n");
sCommande.append("Description:\r\n");
sCommande.append("\t").append(sDescription).append("\n");
sCommande.append("Files:\r\n");
sCommande.append("\t").append(sFileToSyn.toString()).append("\n");
return sCommande.toString();
}
/**
* Test the connection, if isn't OK, throw a exception
*/
private void connectionAlert() throws P4ErrorConnection {
if (!this.isConnected()){
throw new P4ErrorConnection(MSG_CONNECT_IMPOSSIBLE);
}
}
}