package com.jbase.jbuilder5vcs;
// jBuilder import.
import com.borland.primetime.ide.Browser;
import com.borland.primetime.node.Node;
import com.borland.primetime.node.Project;
import com.borland.primetime.node.FileNode;
import com.borland.jbuilder.node.JBProject;
import com.borland.jbuilder.node.PackageNode;
import com.borland.primetime.actions.UpdateAction;
import com.borland.primetime.actions.ActionGroup;
import com.borland.primetime.teamdev.vcs.VCSUtils;
import com.borland.primetime.teamdev.vcs.VCSFactory;
import com.borland.primetime.teamdev.vcs.VCSFileInfo;
import com.borland.primetime.teamdev.frontend.VCSCommitBrowser;
import com.borland.primetime.teamdev.vcs.CommitAction;
import com.borland.primetime.util.runner.OutputRunnerListener;
// java import
import java.awt.event.ActionEvent;
import javax.swing.JOptionPane;
import java.util.HashSet;
import java.util.Set;
import java.util.List;
import java.util.Iterator;
/**
* Title: jBuilder/Perforce<br>
* Description: For integrate perforce on jBuilder5,<br>
* Found all the basic action and group for integrate P4,<br>
* each anonymous class is a menu.<br>
*
* Remark: The truth table for enable menu:<br>
* X -> Does not have <br>
* V -> Must be <br>
* <table border="1">
* <tr align="center"><td>Cmd</td><td> File On Depot</td><td>File on Pending</td><td>New File</td></tr>
* <tr align="center"><td>Sync</td> <td>V</td> <td><BR></td> <td><BR></td></tr>
* <tr align="center"><td>Edit</td> <td>V</td> <td>X</td> <td><BR></td></tr>
* <tr align="center"><td>Revert</td> <td><BR></td> <td>V</td> <td><BR></td></tr>
* <tr align="center"><td>Submit</td> <td><BR></td> <td>V</td> <td><BR></td></tr>
* <tr align="center"><td>Add</td> <td>X</td> <td>X</td> <td>V</td> </tr>
* </table><br>
* If no connection, all menu without "connect" will be disable.
* <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 Actions {
public static final int ON_PENDING_LIST = 0; // Pending list of P4
public static final int ON_DEPOT_LIST = 1; // Depot list of P4
public static final int ON_DEP_OR_PEN_LIST = 2; // On Pending or depot list of P4
// use for get enable
private static final int ALL_FILES_ON_LIST = 0; //all file(s) are on the Pending or Depot list
private static final int NOT_ALL_FILES_ON_LIST = 1; //Not all file(s) are on the Pending or Depot list
private static final int NO_FILES_ON_LIST = 2; //No file(s) are on the Pending or Depot list
private static final int NO_CONNECTION = 3; //No Connection to P4
private static final int IS_PACKAGE = 4; //Ii's a package OR No item selectionned
// Swing message
public static final String MSG_DESCRIPTION = "Description of the changes :";
public Actions() {
}
/**
* Try to connect to P4
*/
public static UpdateAction CONNECT = new UpdateAction("Connect",'C',"try to connect with P4") {
public void update( Object source ) {
PerforceVCS vcs = (PerforceVCS)VCSFactory.getVCS(PerforceVCS.PROP_P4);
setEnabled(!vcs.connected);
}
public void actionPerformed( ActionEvent e ) {
try{
PerforceVCS vcs = (PerforceVCS)VCSFactory.getVCS(PerforceVCS.PROP_P4);
vcs.connect();
JOptionPane.showMessageDialog(Browser.getActiveBrowser(),P4Cmd.MSG_SUCCESSFULL,P4Cmd.MSG_CONNECT_TITLE,JOptionPane.INFORMATION_MESSAGE);
}catch(P4ErrorConnection ec){
JOptionPane.showMessageDialog(Browser.getActiveBrowser(),ec.getMessage(),P4Cmd.MSG_CONNECT_TITLE,JOptionPane.ERROR_MESSAGE);
}catch(Exception ee){
ee.printStackTrace();
}
}
};
/**
* Add file(s) action
*/
public static UpdateAction ADD = new UpdateAction("Add",'A',"Add the selected file(s) to P4") {
public void update( Object source ) {
int nOnDepotList = getEnabledState(Actions.ON_DEPOT_LIST);
int nOnPendingList = getEnabledState(Actions.ON_PENDING_LIST);
// If return equal NO_CONNECTION, it will disable
if (nOnDepotList != IS_PACKAGE && nOnDepotList == NO_FILES_ON_LIST && nOnPendingList == NO_FILES_ON_LIST){
setEnabled(true);
}else{
setEnabled(false);
}
}
public void actionPerformed( ActionEvent e ) {
String sReturn = null; // The return string if action is OK
try{
// Get the node selectionned on the project Tree
Node[] nodeList = Browser.getActiveBrowser().getProjectView().getSelectedNodes();
// Get the Project on the jBuilder Factory
PerforceVCS vcs = (PerforceVCS)VCSFactory.getVCS(PerforceVCS.PROP_P4);
// Try to execute the action, if a connection or application error arrived, inform the user
sReturn = vcs.addFile(nodeList);
JOptionPane.showMessageDialog(Browser.getActiveBrowser(),sReturn,P4Cmd.MSG_P4_ADD_TITLE,JOptionPane.INFORMATION_MESSAGE);
}catch(P4ErrorApplication ee){
JOptionPane.showMessageDialog(Browser.getActiveBrowser(),ee.getMessage(),ee.getTitle(),JOptionPane.ERROR_MESSAGE);
}catch(P4ErrorConnection ec){
JOptionPane.showMessageDialog(Browser.getActiveBrowser(),ec.getMessage(),P4Cmd.MSG_CONNECT_TITLE,JOptionPane.ERROR_MESSAGE);
}
}
};
/**
* Submit modifications to P4
*/
public static UpdateAction SUBMIT = new UpdateAction("Submit",'S',"Commit changes to the repository") {
public void update( Object source ) {
int nOnPendingList = getEnabledState(Actions.ON_PENDING_LIST);
// If return equal NO_CONNECTION, it will disable
if (nOnPendingList != IS_PACKAGE && nOnPendingList == ALL_FILES_ON_LIST){
setEnabled(true);
}else{
setEnabled(false);
}
}
public void actionPerformed( ActionEvent e ) {
String sReturn = null; // The return string if action is OK
try{
// Get the node selectionned on the project Tree
Node[] nodeList = Browser.getActiveBrowser().getProjectView().getSelectedNodes();
// Get the Project on the jBuilder Factory
PerforceVCS vcs = (PerforceVCS)VCSFactory.getVCS(PerforceVCS.PROP_P4);
// Get the description for the submit action
String sDescription = getDescription();
// If the result equal null, the user had click on Cancel
if (sDescription != null){
// Try to execute the action, if a connection or application error arrived, inform the user
sReturn = vcs.submitFile(nodeList, sDescription);
JOptionPane.showMessageDialog(Browser.getActiveBrowser(),sReturn,P4Cmd.MSG_P4_SUBMIT_TITLE,JOptionPane.INFORMATION_MESSAGE);
}
}catch(P4ErrorApplication ee){
JOptionPane.showMessageDialog(Browser.getActiveBrowser(),ee.getMessage(),ee.getTitle(),JOptionPane.ERROR_MESSAGE);
}catch(P4ErrorConnection ec){
JOptionPane.showMessageDialog(Browser.getActiveBrowser(),ec.getMessage(),P4Cmd.MSG_CONNECT_TITLE,JOptionPane.ERROR_MESSAGE);
}finally{
// wc.restore();
}
}
private String getDescription(){
String reply = JOptionPane.showInputDialog( null,
Actions.MSG_DESCRIPTION,
P4Cmd.MSG_P4_SUBMIT_TITLE,
JOptionPane.QUESTION_MESSAGE );
return reply;
}
};
/**
* Synchronise file from P4
*/
public static UpdateAction SYNC = new UpdateAction("Sync",'Y',"Get Lastest version") {
public void update( Object source ) {
int nOnDepotList = getEnabledState(Actions.ON_DEPOT_LIST);
// If return equal NO_CONNECTION, it will disable
if (nOnDepotList != IS_PACKAGE && (nOnDepotList == ALL_FILES_ON_LIST | nOnDepotList == ALL_FILES_ON_LIST)){
setEnabled(true);
}else{
setEnabled(false);
}
}
public void actionPerformed( ActionEvent e ) {
String sReturn = null; // The return string if action is OK
try{
// Get the node selectionned on the project Tree
Node[] nodeList = Browser.getActiveBrowser().getProjectView().getSelectedNodes();
// Get the Project on the jBuilder Factory
PerforceVCS vcs = (PerforceVCS)VCSFactory.getVCS(PerforceVCS.PROP_P4);
// Try to execute the action, if a connection or application error arrived, inform the user
sReturn = vcs.syncFile(nodeList);
JOptionPane.showMessageDialog(Browser.getActiveBrowser(),sReturn,P4Cmd.MSG_P4_SYNCHRO_TITLE,JOptionPane.INFORMATION_MESSAGE);
}catch(P4ErrorApplication ee){
JOptionPane.showMessageDialog(Browser.getActiveBrowser(),ee.getMessage(),ee.getTitle(),JOptionPane.ERROR_MESSAGE);
}catch(P4ErrorConnection ec){
JOptionPane.showMessageDialog(Browser.getActiveBrowser(),ec.getMessage(),P4Cmd.MSG_CONNECT_TITLE,JOptionPane.ERROR_MESSAGE);
}
}
};
/**
* Undo midification from P4
*/
public static UpdateAction REVERT = new UpdateAction("Revert",'R',"Undo modification") {
public void update( Object source ) {
int nOnPendingList = getEnabledState(Actions.ON_PENDING_LIST);
// If return equal NO_CONNECTION, it will disable
if (nOnPendingList != IS_PACKAGE && nOnPendingList == ALL_FILES_ON_LIST ){
setEnabled(true);
}else{
setEnabled(false);
}
}
public void actionPerformed( ActionEvent e ) {
String sReturn = null; // The return string if action is OK
try{
// Get the node selectionned on the project Tree
Node[] nodeList = Browser.getActiveBrowser().getProjectView().getSelectedNodes();
// Get the Project on the jBuilder Factory
PerforceVCS vcs = (PerforceVCS)VCSFactory.getVCS(PerforceVCS.PROP_P4);
// Try to execute the action, if a connection or application error arrived, inform the user
sReturn = vcs.revertFile(nodeList);
JOptionPane.showMessageDialog(Browser.getActiveBrowser(),sReturn,P4Cmd.MSG_P4_REVERT_TITLE,JOptionPane.INFORMATION_MESSAGE);
}catch(P4ErrorApplication ee){
JOptionPane.showMessageDialog(Browser.getActiveBrowser(),ee.getMessage(),ee.getTitle(),JOptionPane.ERROR_MESSAGE);
}catch(P4ErrorConnection ec){
JOptionPane.showMessageDialog(Browser.getActiveBrowser(),ec.getMessage(),P4Cmd.MSG_CONNECT_TITLE,JOptionPane.ERROR_MESSAGE);
}
}
};
/**
* Pass file from depot to default pending list
*/
public static UpdateAction EDIT = new UpdateAction("Edit",'E',"Check out the file") {
public void update( Object source ) {
int nOnDepotList = getEnabledState(Actions.ON_DEPOT_LIST);
int nOnPendingList = getEnabledState(Actions.ON_PENDING_LIST);
// If return equal NO_CONNECTION, it will disable
if (nOnDepotList != IS_PACKAGE && nOnDepotList == ALL_FILES_ON_LIST && nOnPendingList == NO_FILES_ON_LIST){
setEnabled(true);
}else{
setEnabled(false);
}
}
public void actionPerformed( ActionEvent e ) {
String sReturn = null; // The return string if action is OK
try{
// Get the node selectionned on the project Tree
Node[] nodeList = Browser.getActiveBrowser().getProjectView().getSelectedNodes();
// Get the Project on the jBuilder Factory
PerforceVCS vcs = (PerforceVCS)VCSFactory.getVCS(PerforceVCS.PROP_P4);
// Try to execute the action, if a connection or application error arrived, inform the user
sReturn = vcs.editFile(nodeList);
JOptionPane.showMessageDialog(Browser.getActiveBrowser(),sReturn,P4Cmd.MSG_P4_EDIT_TITLE,JOptionPane.INFORMATION_MESSAGE);
}catch(P4ErrorApplication ee){
JOptionPane.showMessageDialog(Browser.getActiveBrowser(),ee.getMessage(),ee.getTitle(),JOptionPane.ERROR_MESSAGE);
}catch(P4ErrorConnection ec){
JOptionPane.showMessageDialog(Browser.getActiveBrowser(),ec.getMessage(),P4Cmd.MSG_CONNECT_TITLE,JOptionPane.ERROR_MESSAGE);
};
}
};
/**
* The project status window for a overview of all file on project
*/
public static UpdateAction PROJECT_STATUS = new UpdateAction("See project status",'t',"See all the changes done to the sources in the project") {
public void update( Object source ) {
int nNoConnection = getEnabledState(Actions.ON_DEPOT_LIST);
setEnabled(!(nNoConnection == Actions.NO_CONNECTION));
}
public void actionPerformed( ActionEvent e ) {
VCSUtils.showProjectStatus(Browser.getActiveBrowser(), COMMIT);
}
};
/**
* Will be call by the VCSCommitBrowser.
* Take all files selected from the VCSFile info and create a list for the PerforcesVCS.commit<br>
* methode with all file selectionned on the CommitBrowser.
*/
public static CommitAction COMMIT = new CommitAction() {
boolean _bCommitOk = true;
// Save the Runner
OutputRunnerListener outRunner = null;
String _sError = "";
public void actionPerformed( ActionEvent e ) {
String sDescription = "";
if (sDescription.equalsIgnoreCase("")){
_bCommitOk = false;
return;
}
}
public boolean wasCommitSuccessfull() {
return _bCommitOk;
}
public String getErrorMessage() {
return _sError;
}
public void setRunnerListener(OutputRunnerListener oOutRunner){
// Add on jBuilder5
outRunner = oOutRunner;
}
/**
* Will be call by the VCSCommitBrowser.
* Take all files selected from the VCSFile info, create a list of file that must be <p>
* added to p4, submit it and create a list for the PerforcesVCS.commit<br>
* methode with all file selectionned on the CommitBrowser.
*/
public void performAction(VCSFileInfo oFile[]){
// Method Add on jBuilder5
Project prj = Browser.getActiveBrowser().getProjectView().getActiveProject();
PerforceVCS vcs = (PerforceVCS)VCSFactory.getVCS(PerforceVCS.PROP_P4);
// init the buffer for action
Set fileNew =(Set) new HashSet();
Set fileOnDepot =(Set) new HashSet();
Set fileOnPending =(Set) new HashSet();
Set fileToDepot =(Set) new HashSet();
// to sort the file receive from the VCSCommitBrowser
for (int i = 0; i < oFile.length; i++) {
VCSFileInfo iFile = oFile[i];
if (iFile.isCommitChanges()){
int nStatus = iFile.getStatus().getStatus();
if (nStatus == RevisionStatus.STATUS_NEW){
fileNew.add(iFile);
fileToDepot.add(iFile);
}else if (nStatus == RevisionStatus.STATUS_ON_DEPOT){
fileOnDepot.add(iFile);
}else if (nStatus == RevisionStatus.STATUS_ON_WORKSPACE){
fileOnPending.add(iFile);
fileToDepot.add(iFile);
}
}
}
try{
// Send the file(s) for add
if (fileNew.size() > 0){
vcs.addFile(fileNew,prj);
}
// commit all file
if (fileToDepot.size() > 0){
vcs.commitFile(fileToDepot,outRunner, prj);
}else{
outRunner.stderrText(P4Cmd.MSG_NO_ITEMS);
outRunner.processFinished(false,P4Cmd.MSG_UNSUCCESSFULL);
}
_bCommitOk = true;
}catch(P4ErrorConnection ec){
_sError = P4Cmd.MSG_CONNECT_IMPOSSIBLE;
}catch(P4ErrorApplication ea){
_sError = ea.getMessage();
}catch (Exception eb){
outRunner.processFinished(false,"Actions:COMMIT:performAction:Exception : "+eb);
}
}
};
/**
* Create a new action group with the action for P4 for the context menu
*/
public static ActionGroup getP4ContextMenu(){
ActionGroup aGroup = new ActionGroup(PerforceVCS.PROP_P4,'S',"Manage file with Perforce",null,true );
aGroup.add(Actions.SYNC);
aGroup.add(Actions.EDIT);
aGroup.add(Actions.REVERT);
aGroup.add(Actions.SUBMIT);
aGroup.add(Actions.ADD);
return aGroup;
}
/**
* Create a new action group with the action for P4 and the connect
*/
public static ActionGroup getP4Menu(){
// First group
ActionGroup connect = new ActionGroup();
connect.add(Actions.CONNECT);
// second GRoup
ActionGroup group = new ActionGroup();
group.add(Actions.PROJECT_STATUS);
group.add(connect);
group.add(Actions.SYNC);
group.add(Actions.EDIT);
group.add(Actions.REVERT);
group.add(Actions.SUBMIT);
group.add(Actions.ADD);
return group;
}
public static UpdateAction ACTION_Refresh = new UpdateAction("Refresh", 'R', "Refresh all files") {
public void update(Object source) {
setEnabled(!(getEnabledState(ON_DEPOT_LIST) == NO_CONNECTION));
}
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(Browser.getActiveBrowser(),"refresh","Refresh",JOptionPane.INFORMATION_MESSAGE);
}
};
/**
* Test the selected nodes and return true if all nodes are managed
* by the VCS.<br>
* <dl>
* <dt>Return:</dt>
* <dd>ALL_FILES_ON_LIST = all file(s) are on the Pending or Depot list</dd>
* <dd>NOT_ALL_FILES_ON_LIST = Not all file(s) are on the Pending or Depot list</dd>
* <dd>NO_FILES_ON_LIST = No file(s) are on the Pending or Depot list</dd>
* <dd>NO_CONNECTION = No Connection to P4</dd>
* <dd>IS_PACKAGE = It's a package OR No item selectionned</dd>
* </dl>
*/
private static int getEnabledState(int nDepotPending) {
PerforceVCS vcs = (PerforceVCS)VCSFactory.getVCS(PerforceVCS.PROP_P4);
Node[] nodes = Browser.getActiveBrowser().getProjectView().getSelectedNodes();
int nNbFileInVCS = 0;
int nRet = NO_FILES_ON_LIST;
// Test the connection first
if (!vcs.connected){
nRet = NO_CONNECTION;
}else{
for( int i=0; i<nodes.length; i++ ) {
if ( nodes[i] instanceof FileNode) {
if (vcs.isUnderVCS(((FileNode)nodes[i]).getUrl(),nDepotPending)) {
nNbFileInVCS ++;
}
}else if(nodes[i] instanceof JBProject){
if (vcs.isUnderVCS(((JBProject)nodes[i]).getUrl(),nDepotPending)) {
nNbFileInVCS ++;
}
}else if(nodes[i] instanceof PackageNode){
nRet = IS_PACKAGE;
break;
}
}
if (nodes.length == 0){
// No file is selectioned return the same as package type
nRet = IS_PACKAGE;
}
if (nRet != IS_PACKAGE && nNbFileInVCS == nodes.length){
nRet = ALL_FILES_ON_LIST ;
}else if (nRet != IS_PACKAGE && nNbFileInVCS != 0 && nNbFileInVCS < nodes.length){
nRet = NOT_ALL_FILES_ON_LIST;
}
}
return(nRet);
}
/**
* Just for tests
*/
public static void main(String[] argv){
String reply = JOptionPane.showInputDialog( null,
"Enter log name:",
"Database Troubles",
JOptionPane.WARNING_MESSAGE );
System.out.println( "User entered: " + reply );
System.exit(0);
}
}