package com.jbase.jbuilder5vcs; // jBuilder import import com.borland.jbuilder.node.JBProject; import com.borland.primetime.node.Project; import com.borland.primetime.vfs.Url; import com.borland.primetime.teamdev.vcs.VCSFileInfo; import com.borland.primetime.ide.Browser; // java import import java.util.Set; import java.util.List; import java.util.Map; import java.util.HashSet; import java.util.ArrayList; import java.util.HashMap; import java.io.File; import java.util.StringTokenizer; /** * Title: JBuilder/Perforce<br> * Description: Integration of Perforce on jBuilder<br> * This class is a mirror of the P4 client, it maintain the list of<br> * file on the pending list and on the depot list. * Copyright: Copyright (c) 2001<br> * <DL><DT><b>Company:</b></DT><DD>jBase.</DD></DL> * @author <a href="mailto:hervea@jbase.com">Herv Aubert</a> * @author <a href="mailto:nicolasj@jbase.com">Nicolas Jorand</a> * @version 1.0 * @since JDK 1.3 */ public class P4ClientSpec { public static final String KEY_CLIENT = "Client"; public static final String KEY_UPDATE = "Update"; public static final String KEY_ACCESS = "Access"; public static final String KEY_OWNER = "Owner"; public static final String KEY_HOST = "Host"; public static final String KEY_DESCRIPTION = "Description"; public static final String KEY_ROOT = "Root"; public static final String KEY_OPTIONS = "Options"; public static final String KEY_VIEW = "View"; public static final String KEY_FILES = "Files"; private String depot; //Name of the Depot private String client; //Name of the Client private String update; //Date of the last update private String access; //Date of the last access private String owner; //Name of the Owner private String host; //Name of the Host private String description; //Name of the Description private String root; //The root directory on the host client private String [] options; //The table of the different option for the sync private String [] view; //The table of the different directory to sync private Set _FileOnP4 = new HashSet(); // Collection with file on P4 private Set _FileOnPending = new HashSet(); // Collection with file on P4 private Map _FileStatus = (Map)new HashMap(); // File status on the project public Url _url = null; public P4ClientSpec() { } /********************************************** * Creates new P4ClientSpec */ public P4ClientSpec(String ClientSpec, String sListOfFile, String sListPending) { initClass(ClientSpec, sListOfFile, sListPending); } /********************************************** * Properties Get and Set */ public void setDepot(String depot){ this.depot=depot; } public String getDepot(){ String sDepot = this.depot; // A view content the depot try{ // The depot name are between a "//" and the next "/" int nPosStart = sDepot.indexOf("//"); int nPosEnd = sDepot.indexOf("/",nPosStart+2); // +2 -> forget the "//" found ! if (nPosStart != -1){ sDepot = sDepot.substring(nPosStart,nPosEnd+1); // +1 -> to get the file separator }else{ sDepot = null; } }catch(Exception e){ sDepot = null; }finally{ return sDepot; } } public void setClient(String client){ this.client=client; } public String getClient (){ return this.client; } public void setUpdate(String update){ this.client=client; } public String getUpdate (){ return this.update; } public void setAccess(String access){ this.access=access; } public String getAccess (){ return this.access; } public void setOwner(String owner){ this.owner=owner; } public String getOwner (){ return this.owner; } public void setHost(String host){ this.host=host; } public String getHost (){ return this.host; } public void setDescriptiont(String description){ this.description=description; } public String getDescription (){ return this.description; } public void setRoot(String root){ this.root=root; } public String getRoot (){ String sRoot = this.root.replace('\\','/');// P4 not support the backslash!! return sRoot; } public String getOptions (int id){ return this.options[id]; } public void setOptions(String options,int id){ this.options[id]=options; } /** * Check on the collection respective (depot or pending) if <p> * the file past on parameter exist. */ public boolean isUnderVCS(String sFile, int nDepotPending){ boolean bRet = false; String sRoot = this.getRoot(); String sDepot = this.getDepot(); String sFileOnPending = ""; if (nDepotPending == Actions.ON_PENDING_LIST){ // Replace the root by the depot name sFileOnPending = sDepot + sFile.substring(sRoot.length()+1).replace('\\','/'); } if (nDepotPending == Actions.ON_PENDING_LIST){ if (_FileOnPending != null){ bRet = _FileOnPending.contains(sFileOnPending); } }else if(nDepotPending == Actions.ON_DEPOT_LIST){ if (_FileOnP4 != null){ bRet = _FileOnP4.contains(sFile.toLowerCase().replace('\\','/')); } }else if(nDepotPending == Actions.ON_DEP_OR_PEN_LIST){ if (_FileOnP4 != null){ bRet = _FileOnP4.contains(sFile.toLowerCase().replace('\\','/')); } if (!bRet & _FileOnPending != null){ bRet = _FileOnPending.contains(sFileOnPending); } } return bRet; } /** * Get the status list of the specified project, */ public Map getStatus(Project project){ _FileStatus = (Map)new HashMap(); try{ JBProject jproject = (JBProject)project; Url[] sourcePath = jproject.getPaths().getSourcePath(); Url projectPath = jproject.getProjectPath(); Url[] totalPath = new Url[sourcePath.length+1]; System.arraycopy(sourcePath,0,totalPath,0,sourcePath.length); // add the project path totalPath[totalPath.length-1] = projectPath; for (int i=0;i<totalPath.length;i++){ // For debug if jBuilder is launch on verbose mode System.out.println("*********** P4ClientSpec:getStatus:PathOnProject["+i+"] = "+totalPath[i].getFile()+" ***********"); this.setFileStatus(totalPath[i].getFileObject()); } System.out.println("**********************"); }catch(Exception e){ e.printStackTrace(); }finally{ System.out.println("****** RESUME ********"); System.out.println("size of FileStatus = "+_FileStatus.size()); java.util.Iterator it1 = _FileStatus.keySet().iterator(); java.util.Collection col = _FileStatus.values(); java.util.Iterator it = col.iterator(); for (int i=0;it.hasNext();i++ ) { System.out.println("elements["+it1.next().toString()+" = "); List l =(List)it.next(); java.util.Iterator itl = l.iterator() ; for (;itl.hasNext(); ) { System.out.println("\t"+itl.next().toString()); } System.out.println("\n"); } System.out.println("****** RESUME ********"); return (Map)_FileStatus; } } /** * Scan the first dir and all children to determine if each file is on P4 or not.<p> * And add the file on the HashMap _FileStatus. the convention is :<p> * (Key,Object) where:<p> * Key = instance of FileInfo, identifies a directory.<p> * Object = List -> ArrayList, each elements are instance of FileInfo and identifies a file.<p> * I tried to create a tree with multiple level, but it doesn't work !!!!<p> * I tried this:<p> * (Key,Object) where:<p> * Key = instance of FileInfo, identifies a directory(usually 'com').<p> * Object = A HashMap with the subdirectory and this HashMap had a List ...... * */ private void setFileStatus( File startDir ) { VCSFileInfo currentDir = null; List currentList = null; try { JBProject prj = (JBProject)Browser.getActiveBrowser().getActiveProject(); Url bakPath = prj.getPaths().getBakPath(); Url outPath = prj.getPaths().getOutPath(); File[] list = startDir.listFiles(); Url url = null; // Url used to the map object int len = list.length; for ( int i=0; i<len; i++ ) { // For each file or directory ... // For debug if jBuilder is launch on verbose mode System.out.print("P4ClientSpec:setFileStatus:File["+i+"] = "+list[i]); if (list[i].isDirectory()) { // Is a directory, recursive call // For debug if jBuilder is launch on verbose mode System.out.print(" Is a directory\n"); setFileStatus(list[i]); url = new Url(list[i]); }else{ String fname = list[i].getCanonicalPath(); url = new Url(list[i]).getParent(); // For debug if jBuilder is launch on verbose mode System.out.print(" Is a file and parent = "+url.getFile()+"\n"); Url urltmp = new Url(list[i]); currentDir = new VCSFileInfo(url,new RevisionStatus(RevisionStatus.STATUS_ON_DEPOT)); currentList = (List)_FileStatus.get(currentDir); if ( currentList == null){ currentList =(List)new ArrayList(); _FileStatus.put(currentDir, currentList); } // Test if is it on the project view boolean bOnProject = true;// this doesn't work :Browser.getActiveBrowser().getActiveProject().isProjectUrl(url); // Skip files that are backups or compiled classes if ( bakPath.isChild(url) || outPath.isChild(url) || list[i].getName().endsWith("~") || list[i].getName().endsWith("jpx.local") ) { continue; } if (bOnProject && ! this.isUnderVCS(fname,Actions.ON_DEP_OR_PEN_LIST)) { // Not in P4 currentList.add(new VCSFileInfo(urltmp,new RevisionStatus(RevisionStatus.STATUS_NEW) )); }else if (bOnProject && !this.isUnderVCS(fname,Actions.ON_PENDING_LIST) ) { // Only on the depot list currentList.add(new VCSFileInfo(urltmp,new RevisionStatus(RevisionStatus.STATUS_ON_DEPOT) )); }else if(bOnProject){ // On the pending list currentList.add(new VCSFileInfo(urltmp,new RevisionStatus(RevisionStatus.STATUS_ON_WORKSPACE) )); }// endif on p4(yes, no, may be..) }// endif is directory }// end For currentDir = new VCSFileInfo(url,new RevisionStatus(RevisionStatus.STATUS_ON_DEPOT)); List tmpList = (List)_FileStatus.get(currentDir); if (currentList != null) { _FileStatus.put(currentDir,currentList); } } catch (Exception ex) { ex.printStackTrace(); } } /********************************************** * Name: searchKeyStr * * This methode seach in a text a key and when is done, * the answer start in the next char TAB to the ENDLN * * Input: String the text * String the key * * Output: String the answer from the key */ private String searchKeyStr(String text,String strKey){ try{ int posX1=0; int posX2=0; int posX3=0; posX1=text.indexOf(strKey+":"); posX2=text.indexOf("\t",posX1); posX3=text.indexOf("\n",posX2); return text.substring(posX2+1,posX3); }catch(Exception e){ return null; } } /********************************************** * This methode create a "SET" with all the <p> * file(s) on P4 * * Input: String the list of file on p4 format (depot-file#revision-number - local-path) * * Output: Set collection with all file on P4 (c:\toto\titi...) */ private Set setFiles(String sListOfFile){ try{ int posX1=0; int posX2=0; Set col = (Set)new HashSet(); do{ posX1=sListOfFile.indexOf("-",posX1); posX2=sListOfFile.indexOf("\n",posX1); posX1 += 2; col.add(sListOfFile.substring(posX1,posX2).toLowerCase().replace('\\','/')); }while((posX1=sListOfFile.indexOf("-",posX2)) != -1); return col; }catch(Exception e){ return null; } } /*********************************************** * Add filse on the depot colection * * @param sFileToAdd List of files to add * */ public void addFileOnDepot(StringBuffer sFileToAdd){ String sInput = sFileToAdd.toString(); StringTokenizer st = new StringTokenizer(sInput); if (_FileOnP4 == null) _FileOnP4 = new HashSet(); while(st.hasMoreTokens()){ String sFile = st.nextToken().trim().toLowerCase(); // Change the depot to the root String sFiletmp = sFile.substring(getDepot().length()); sFile = getRoot()+ "/" + sFiletmp; _FileOnP4.add(sFile); } } /********************************************** * This methode create a "SET" with all the <p> * file(s) on P4 in the pending list * * Input: String the list of file on p4 format * String the key * * Output: Set collection with all file on pending (//depot/...) */ private Set setFilesPending(String sListOfFile){ try{ int posX1=0; int posX2=0; int posX3=0; Set col = (Set)new HashSet(); // First use of posX1 are index of key posX1=sListOfFile.indexOf(this.KEY_FILES + ":"); posX2=sListOfFile.indexOf("//",posX1); do{ posX3=sListOfFile.indexOf("\t",posX2); col.add(sListOfFile.substring(posX2,posX3)); }while((posX2=sListOfFile.indexOf("//",posX3)) != -1); return col; }catch(Exception e){ return null; } } /*********************************************** * Add filse on the pending colection * * @param sFileToAdd List of files to add * */ public void addFileOnPending(StringBuffer sFileToAdd){ String sInput = sFileToAdd.toString(); StringTokenizer stTemp = new StringTokenizer(sInput); if (_FileOnPending == null) _FileOnPending = new HashSet(); while(stTemp!= null && stTemp.hasMoreTokens()){ _FileOnPending.add(stTemp.nextToken()); } } /*********************************************** * Remove file from the pending colection * * @param sFileToRemove List of files to add * */ public void removeFileFromPending(StringBuffer sFileToRemove){ String sInput = sFileToRemove.toString(); StringTokenizer stTemp = new StringTokenizer(sInput); if (_FileOnPending == null) _FileOnPending = new HashSet(); while(stTemp.hasMoreTokens()){ _FileOnPending.remove(stTemp.nextToken()); } } /** * For refresh the list of avaible file on P4 and reconfigure */ public void refresh(String ClientSpec,String sListOfFile, String sListPending){ initClass(ClientSpec, sListOfFile, sListPending); } /** * Init the class, this methode should make a refresh */ private void initClass(String ClientSpec, String sListOfFile, String sListPending){ this.depot=searchKeyStr(ClientSpec,KEY_VIEW); this.client=searchKeyStr(ClientSpec,KEY_CLIENT); this.update=searchKeyStr(ClientSpec,KEY_UPDATE); this.access=searchKeyStr(ClientSpec,KEY_ACCESS); this.owner=searchKeyStr(ClientSpec,KEY_OWNER); this.host=searchKeyStr(ClientSpec,KEY_HOST); this.description=searchKeyStr(ClientSpec,KEY_DESCRIPTION); this.root=searchKeyStr(ClientSpec,KEY_ROOT); // Set the collection of file _FileOnP4 = this.setFiles(sListOfFile); // Set the collection of file pending _FileOnPending = this.setFilesPending(sListPending); } /** * For test only */ public static void main(String argv[]){ // For test only /* P4ClientSpec my = new P4ClientSpec(); String s = "Change: new\r\n"; s = s+ "Client: nicolasj-njorand2\r\n"; s = s+ "User: nicolasj\r\n"; s = s+ "Status: new\r\n"; s = s+ "Description:\r\n"; s = s+ " <enter description here>\r\n"; s = s+ "Files:\r\n"; s = s+ " //depot/Tools/jBuilderOT/jBuilderVCS/projects/jBuilderVCS.html # add\r\n"; s = s+ " //depot/Tools/jBuilderOT/jBuilderVCS/src/com/jbase/jbuildervcs/Actions.java # edit\r\n"; s = s+ " //depot/Tools/jBuilderOT/jBuilderVCS/src/com/jbase/jbuildervcs/P4ClientSpec.java # edit\r\n"; s = s+ " //depot/Tools/jBuilderOT/jBuilderVCS/src/com/jbase/jbuildervcs/P4Cmd.java # edit\r\n"; s = s+ " //depot/Tools/jBuilderOT/jBuilderVCS/src/com/jbase/jbuildervcs/PerforceVCS.java # edit\r\n"; Set col = my.setFilesPending(s); java.util.Iterator it = col.iterator(); for (;it.hasNext();){ String scol = (String)it.next(); System.out.println(scol); System.out.println(col.contains((Object)new String("//depot/Tools/jBuilderOT/jBuilderVCS/src/com/jbase/jbuildervcs/PerforceVCS.java"))); } */ } }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#1 | 2918 | Jeff Hanna | Branching the integration tree | ||
//guest/perforce_software/integrations/jbuilder/jBuilder5VCS/src/com/jbase/jbuilder5vcs/P4ClientSpec.java | |||||
#1 | 1072 | rmg |
Integrate the "jBuilder5VCS" frmo Nicolas Jorand into //public; Plan is to add some top-level documentation before linking it into the "roadmap", or making any sort of general public announcement. |
||
//guest/nicolas_jorand/jBuilder5VCS/src/com/jbase/jbuilder5vcs/P4ClientSpec.java | |||||
#1 | 939 | nicolas_jorand | First input of perforce integration for jBuilder5 |