/******************************* Copyright notice ******************************* Copyright (C)2002 by Andrei Loskutov <loskutov@gmx.de>. 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. THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS 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 THE AUTHOR OR 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. ********************************************************************************/ package adiag.connection; import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.util.ArrayList; import java.util.Hashtable; import javax.swing.JOptionPane; import adiag.Const; import adiag.gui.App; import adiag.model.Version; import adiag.util.Toolz; /** * The connection to Perforce-prozess as encapsulated objekt. * @author Andrei Loskutov */ public abstract class Connector { /** which branches we know? * key is path as String, value is ArrayList with versions */ protected Hashtable br_table; /** the Debug-Messages-output-list */ protected StringWriter sout; /** the Debug-Messages-output-list */ protected PrintWriter out; /** current app instance */ protected App app; /** Instance of Runtime */ protected Runtime rt; /** file Instance for the 1:1 file output of input */ protected File filelog; /** file name for the 1:1 file output of input */ protected static String file_out_name = "tp4branchview.log"; /** directory, for the 1:1 file output of input, default is "user.home" from JDK - Properties */ protected static String file_out_dir = System.getProperty("user.home"); /** * Default Constructor, call init() */ protected Connector() { super(); init(); } /** * will be called from constructor */ protected void init() { br_table = new Hashtable(13); sout = new StringWriter(1000); out = new PrintWriter( sout ); } /** * Constructor * @param app current GUI, for error feedback etc */ public Connector(App app) { this(); this.app = app; } /** * close connector and all probably opened streams * @throws IOException if something goes wrong */ public abstract void close() throws IOException ; /** * convert all data / error messages from currrent data stream to String * @return convert all data / error messages from currrent data stream to String */ public String dataToString() { out.flush(); return sout.toString(); } /** * See return description * @return Array with all "root"- revisions from all branches, or empty aray * @throws Exception if something goes wrong */ public Version[] getData() throws Exception{ String path = app.getPath(); if(path != null){ String [] paths = null; if(app.isDiscoverAllBranches()){ paths = getUnknownBranches(false); } if( paths == null || paths.length == 0){ paths = new String []{path}; } System.out.println("try to receive data: "+Toolz.makeLine(paths, " ")); return getP4Data(paths); } else { return new Version[0]; } } /** * See return description * @return File the instance of current Log-file */ public final File getLogFile(){ if(filelog == null){ return new File(file_out_dir, file_out_name); } else { return filelog; } } /** * See return description * @return String the path to Diff - tool */ protected final String getDiffPath(){ return app.getDiffPath(); } /** * Method setLogFile set the instance of Log-file * @param f the instance of Log-file */ public final void setLogFile(File f){ filelog = f; } /** * Return array with "root"-Versions (each one for different branch) * <pre> * //give not all needed information * FileEntry fe = new FileEntry(env, "//apis/entw/src/batch/batch_i/bat_glob.h"); * // ist nicht fertig implementirt: * Vector v = FileEntry.getFileLog(env, "//apis/entw/src/batch/batch_i/bat_glob.h"); * System.out.println("filelog hat " +v.size() +" Eintrge"); * for (int i = 0; i < v.size(); i++){ * FileEntry f = (FileEntry)v.get(i); * System.out.println(f.toXML()); * } * </pre> * @param apath array with paths of files to request it from perforce * @return Array with "root"-Versions (each one for different branch), or an empty array * @throws Exception if something goes wrong */ protected Version[] getP4Data(String [] apath) throws Exception { //System.out.println("received paths: " + Toolz.makeLine(apath, " : ")); /*if(apath.length > 10){ if(!app.yesno( "You are about to send request over " + apath.length + " files at one time."+ " This may cause some troubles. Are you sure ???")){ //\nAre you sure ??? return getVersions(); } } */ // create or update branch data readP4Out(apath); ArrayList p = null; Version [] ver = null; ArrayList pend = new ArrayList(br_table.keySet()); Version tmp; ArrayList need_to_discover = new ArrayList(); for (int i = 0; i < pend.size(); i++){ p = (ArrayList)br_table.get(pend.get(i)); // check for new data, set some flags and update todo list for (int j = 0; j < p.size(); j++){ tmp = (Version)p.get(j); // set flag if we receive data directly from perforce tmp.setReceived(tmp.isReceived() || Toolz.count(apath, tmp.getPath())>0 ); // update todo list if needed if(!tmp.isReceived() && app.isDiscoverAllBranches() && !tmp.isChangeNumOk()){ if(!need_to_discover.contains(tmp.getPath())){ need_to_discover.add(tmp.getPath()); } } } ver = Toolz.sort(p); p.clear(); // update parent connections for (int j = 1; j < ver.length; j++){ ver[j-1].setNext(ver[j]); ver[j].setPrev(ver[j-1]); p.add(ver[j-1]); } p.add(ver[ver.length-1]); br_table.put(pend.get(i), p); } // recursive call if todo isn't empty if( !need_to_discover.isEmpty() && !app.isOffline() ){ return getP4Data((String[])need_to_discover.toArray(new String[need_to_discover.size()])); } return getRootVersions(); } /** * @return Version[] array with root versions or empty array * @throws IOException if something goes wrong */ protected Version[] getRootVersions() throws IOException { ArrayList c = new ArrayList(br_table.values()); ArrayList al = new ArrayList(); for (int i = 0; i < c.size(); i++){ // search and return really(!!!) first element ArrayList t = (ArrayList)c.get(i); if(t.size()>0){ al.add( Toolz.getFirst( (Version)t.get(0) )); } } return (Version[])al.toArray(new Version[al.size()]); } /** * read native P4 Log * @param apath initial paths for requested files/directories * @throws Exception if something goes wrong */ protected abstract void readP4Out(String [] apath) throws Exception; /* * log example for file //depot/perforce/testroot/itest/test.txt: * info: //depot/perforce/testroot/itest/test.txt info1: #4 change 107 integrate on 2002/05/27 by Andy_the_Great@andy (text) info1: info1: merge test info2: merge from //depot/perforce/testroot/prod/test.txt#1,#3 info1: #3 change 93 edit on 2002/05/25 by Andy_the_Great@andy (text) info1: info1: noch ein edit... info2: copy into //depot/perforce/testroot/entw/test.txt#6 info2: ignored by //depot/perforce/testroot/kdtest/test.txt#4 info1: #2 change 67 edit on 2002/05/14 by Andy_the_Great@andy (text) info1: info1: bearbeitet info2: branch into //depot/perforce/testroot/entw/test.txt#1 info1: #1 change 66 branch on 2002/05/14 by Andy_the_Great@andy (text) info1: info1: kdtest zum itest info2: branch from //depot/perforce/testroot/kdtest/test.txt#1,#2 info: //depot/perforce/testroot/kdtest/test.txt info1: #2 change 65 edit on 2002/05/14 by Andy_the_Great@andy (text) info1: info1: bearbeitet info2: branch into //depot/perforce/testroot/itest/test.txt#1 info1: #1 change 64 branch on 2002/05/14 by Andy_the_Great@andy (text) info1: info1: branch zum kdtest vom prod info2: branch from //depot/perforce/testroot/prod/test.txt#1,#2 info: //depot/perforce/testroot/prod/test.txt info1: #2 change 63 edit on 2002/05/14 by Andy_the_Great@andy (text) info1: info1: bearbeitet info2: branch into //depot/perforce/testroot/entw/test.txt#4 info2: branch into //depot/perforce/testroot/kdtest/test.txt#1 info1: #1 change 62 add on 2002/05/14 by Andy_the_Great@andy (text) info1: info1: Test erstellt im prod exit: 0 */ /** * parse data from LineReader to the model - Objekts and call close() after work * @param apath first path in log file * @param in LineReader with raw data * @throws Exception if something goes wrong */ protected void parseP4FileLog(String apath, LineReader in) throws Exception { String l = null, vnum, temp; int changenum = 0; Version v = null; String[] words = null; boolean from_to = false; /* We assume that the p4 command was called with -s which sends all * messages to standard out pre-pended with a string that indicates * what kind of messsage it is: error,warning,text,info,exit */ while (null != (l = in.readLine())) { out.println(l); if(l.indexOf(":")>=0){ if(!l.startsWith("info")){ continue; } else { // is it path line? temp = l.substring(l.indexOf(":") + 1); if(l.startsWith("info:")){ apath = temp.trim(); continue; } else { from_to = l.startsWith("info2:"); l = temp; } } } else { continue; } // parse version nummer, create version, we have the change - Line // we test for " #", because p4 make *one* space character before '#' // only on changes, // and it may be simple comment line with '#' at start; // P4 make then one space character *and* one tab stop before. if (l.startsWith(" #") && l.indexOf("change") > 1) { // we don't need trim because getWords do it for us // read number from: // #3 change 903 edit on 2001/11/09 by loskut@loskut-wa114387 (ktext) // #6 change 1667 integrate on 2002/05/27 by schroed@schroed-whaj3103 (ktext) words = Toolz.split(l); // words contain now all information vnum = words[0].substring(1, words[0].length()); int vnumi = Toolz.intValue(vnum); changenum = Toolz.intValue(words[2]); v = getVersion(apath, vnumi, true); // only if change unknown!!! if(!v.isChangeNumOk()){ v.setChange(changenum); } v.setChangeType(words[3]); v.setDate(words[5]); v.setUser(words[7]); } else {// Branch/Edit/etc informations or comment l = l.trim(); int startIdx = -1; // comment! if(!from_to || (startIdx = Const.getStartLineCode(l)) < 0 ){ if (l.length() > 0) { if(v!=null) { v.addDescriptionLine(l); } } continue; } int command_length = Const.getStartLineCodeLength(startIdx); int start_change = l.indexOf("#"); // branch from //depot/perforce/testroot/kdtest/test.txt#1,#2 String b_path = l.substring(command_length, start_change); int v_idx = l.lastIndexOf("#"); int end_idx = l.length(); String b_vnum = l.substring(v_idx + 1, end_idx); Version b_v = getVersion(b_path, Toolz.intValue(b_vnum), true); // set branch to/from connections if (startIdx < Const.FROM_NUMBER) { b_v.addNextBranch(v); v.addPrevBranch(b_v, Const.LINES[startIdx]); } else { b_v.addPrevBranch(v, Const.LINES[startIdx - Const.FROM_NUMBER]); v.addNextBranch(b_v); } } // end else } // end while close(); System.runFinalization(); System.gc(); } /** * Compare two versions, but as default does nothing and must be overriden! * @param a first Version * @param b second Version * @throws Exception if something goes wrong */ public void diff(Version a, Version b) throws Exception { JOptionPane.showMessageDialog( app, "This feature is not available now.", "Information", JOptionPane.INFORMATION_MESSAGE); } /** * See return description * @param report_even_if_not_dicover_all if true, return all branches even * if only one at time is allowed to be discover (by settings) * @return String[] all paths of branches, if thay haven't full information about * change numbers or if they been never directly examined */ public String[] getUnknownBranches(boolean report_even_if_not_dicover_all){ ArrayList p = null; ArrayList pend = new ArrayList(br_table.keySet()); Version tmp = null; ArrayList need_to_discover = new ArrayList(); boolean discover_all = app.isDiscoverAllBranches() || report_even_if_not_dicover_all; for (int i = 0; i < pend.size(); i++){ p = (ArrayList)br_table.get(pend.get(i)); for (int j = 0; j < p.size(); j++){ tmp = (Version)p.get(j); if(!tmp.isChangeNumOk() || (!tmp.isReceived() && discover_all)){ if(!need_to_discover.contains(tmp.getPath())){ need_to_discover.add(tmp.getPath()); } } } } return (String[])need_to_discover.toArray(new String[need_to_discover.size()]); } /** * Search version from branch table and if not found, create one (depend on parameter) * @return founded / created version or null, of nothing found and 'create' flag is false * @param path version path * @param num version number * @param create true, to create new version, if nothing found */ protected Version getVersion(String path, int num, boolean create) { ArrayList ht = (ArrayList)br_table.get(path); if(ht == null){ // branch don't exist yet ht = new ArrayList(); br_table.put(path, ht); } Version v = Toolz.getForNummer(ht, num); if(v == null && create){ // version don't exist yet! v = new Version(); v.setVersNumber(num); v.setPath(path); ht.add(v); } return v; } }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#5 | 2735 | andrei_loskutov | sources are now included to binary distribution at http://andrei.gmxhome.de/perforce/index.html | ||
#4 | 2554 | andrei_loskutov |
#25.12.2002 23:29 Revision 1.3.0.4 beta 1) Some small refactoring 2) First integration with P4eclipse: properties etc, thanks Boris Pr�ssmann 5) Better integration to Eclipse: use Eclipse internal compare tool for diff. 6) Fix some minor bugs. #14.12.2002 23:15 Revision 1.3.0.3 beta 1) Fix endless loop bug if p4 path was not set. 2) Fix never getting focus bug after error message shown 3) Fix painting bug on JDK 1.4.1 (must be verified!!!) 4) Some small refactoring 5) Fix error handling. 6) Fix some minor bugs. |
||
#3 | 2552 | andrei_loskutov | 1.3.0.4 changes | ||
#2 | 2460 | andrei_loskutov |
1) Change configuration: always reed properties 2) Change password store to hex format/password field 3) Create standalone/not standalone state for new branchview eclipse wrapper 4) Refactor all main classes to remove cyclic package dependency 5) Add workaround to fix new JDK 1.4.1 Swing bugs on JScrollPane/JViewPort 6) Add dispose methods to panel/connector 7) Minor internal GUI fixes/refactorings |
||
#1 | 2222 | andrei_loskutov |
#13.10.2002 22:16 Revision 1.2.1 1) Documentation task is finished... Yes!!! 2) New feature: copy P4 depot path 3) Some small fixes to menu shortkeys belongs ctrl + c and ctrl + d 4) Clipboard fix because of JDK 1.2 - 1.3 bug 5) Smallest refactoring on some methods. 6) Html help updated |