    001package org.vishia.guiBzr;
    002
    003import java.io.BufferedReader;
    004import java.io.File;
    005import java.io.FileNotFoundException;
    006import java.io.FileReader;
    007import java.io.IOException;
    008import java.text.DateFormat;
    009import java.text.SimpleDateFormat;
    010import java.util.LinkedList;
    011import java.util.List;
    012
    013import org.vishia.mainCmd.MainCmd_ifc;
    014import org.vishia.mainCmd.Report;
    015import org.vishia.util.FileSystem;
    016
    017public class BzrGetStatus
    018{
    019
    020  /**TODO only private local using here, it should be a part of DataProject.
    021   *
    022   */
    023  List<File> listBzrDirs = new LinkedList<File>();
    024
    025  final MainData mainData;
    026
    027  final MainCmd_ifc mainCmdifc;
    028
    029  /**The format of a timestamp in the log output. */
    030  private final DateFormat logDateFormat= new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
    031
    032
    033  private final List<DataFile> listUnknownFiles = new LinkedList<DataFile>();
    034
    035  public BzrGetStatus(MainCmd_ifc mainCmdifc, MainData mainData)
    036  { this.mainCmdifc = mainCmdifc;
    037    this.mainData = mainData;
    038  }
    039
    040
    041
    042  /**Searches all locations of source-archives in the current project folder and all sub folders.
    043   * A project means a software project with some sources consisting of some Components with its own archives.
    044   * @calls {@link #captureStatus(DataCmpn)} for all found software-archives.
    045   * @param sProjectPath Path to the project folder.
    046   *
    047   */
    048  void getBzrLocations(String sProjectPath)
    049  {
    050    listBzrDirs.clear();
    051    try{ FileSystem.addFileToList(sProjectPath + "/**/.bzr", listBzrDirs);
    052    } catch(Exception exc){ }
    053    int zCmpn = listBzrDirs.size();
    054    mainData.currPrj.init(zCmpn);
    055    //int ixCmpn = 0;
    056    for(File fileBzr: listBzrDirs){
    057      File bzrLocation = fileBzr.getParentFile();
    058      int ixCmpn = mainData.currPrj.createComponentsData(bzrLocation);
    059      ixCmpn +=1;
    060    }
    061  }
    062
    063
    064
    065  /**Captures the status of a software archive of one component in comparison of its real source files.
    066   * <ul>
    067   * <li>last revision of files, last revision in archive, number and timestamp
    068   * <li>get status
    069   * </ul>
    070   * It fills the indexed instance of {@link DataCmpn}
    071   * @param ixData The index of the component, index in data
    072   */
    073  void captureStatus(DataCmpn data)
    074  {
    075    //DataCmpn data = mainData.currPrj.data[ixData];
    076    data.uBzrError.setLength(0);
    077    data.uBzrLastVersion.setLength(0);
    078    data.uBzrStatusOutput.setLength(0);
    079    mainData.cmdExec.setCurrentDir(data.dirWorkingtree);
    080    String sCmdStatus = mainData.cfg.indexCmds.get("status");
    081    String sCmdheadRevision = mainData.cfg.indexCmds.get("headRevision");
    082    mainCmdifc.writeInfo(sCmdStatus);
    083    mainData.cmdExec.execute(sCmdStatus, null, data.uBzrStatusOutput, data.uBzrError);
    084    mainCmdifc.writeInfo(sCmdheadRevision);
    085    mainData.cmdExec.execute(sCmdheadRevision, null, data.uBzrLastVersion, data.uBzrError);
    086    mainCmdifc.writeInfo(" done.\n");
    087    getVersionFromLogOutput(data.uBzrLastVersion, data, data.revisionWorkingTreeTop);
    088    File fileBzrVersion = new File(data.dirWorkingtree, "_bzrVersion.txt");
    089    if(fileBzrVersion.exists()){
    090      String lastLogfile = FileSystem.readFile(fileBzrVersion);
    091      StringBuilder uLog = new StringBuilder(lastLogfile);
    092      getVersionFromLogOutput(uLog, data, data.revisionSbox);
    093    }
    094  }
    095
    096
    097
    098  void captureStatusAllArchives(DataCmpn data){
    099    captureStatus(data);
    100    //
    101    data.uBzrLastVersion.setLength(0);
    102    String sCmdheadRevision = mainData.cfg.indexCmds.get("headRevision");
    103
    104    mainCmdifc.writeInfoln(sCmdheadRevision + " archive");
    105    mainData.cmdExec.setCurrentDir(data.dirArchive);
    106    mainData.cmdExec.execute(sCmdheadRevision, null, data.uBzrLastVersion, data.uBzrError);
    107    getVersionFromLogOutput(data.uBzrLastVersion, data, data.revisionArchive);
    108    if(data.dirRemoteArchive !=null){
    109      mainCmdifc.writeInfoln(sCmdheadRevision + " remote archive");
    110      mainData.cmdExec.setCurrentDir(data.dirRemoteArchive);
    111      mainData.cmdExec.execute(sCmdheadRevision, null, data.uBzrLastVersion, data.uBzrError);
    112      getVersionFromLogOutput(data.uBzrLastVersion, data, data.revisionRemoteArchive);
    113    }
    114
    115  }
    116
    117
    118
    119
    120  /**Reads the status output and fills the {@link #listUnknownFiles},
    121   * {@link DataCmpn#listModifiedFiles}, {@link DataCmpn#listNewFiles},
    122   * {@link DataCmpn#listAddFiles}, {@link DataCmpn#listRemovedFiles},
    123   *
    124   */
    125  void initListFiles()
    126  {
    127    DataCmpn data = mainData.currCmpn;
    128    StringBuilder uStatus = data.uBzrStatusOutput;
    129    String sLine;
    130    listUnknownFiles.clear();
    131    List<DataFile> listFiles = listUnknownFiles;
    132    String sType = "?";
    133    int posLine = 0, posLineEnd;
    134    int pos;
    135    data.listAddFiles = null;
    136    data.listModifiedFiles = null;
    137    data.listNewFiles = null;
    138    data.listRemovedFiles = null;
    139    data.listRenamedFiles = null;
    140    data.indexFiles.clear();
    141
    142    while( (posLineEnd = uStatus.indexOf("\n", posLine))>=0){
    143      sLine = uStatus.substring(posLine, posLineEnd);
    144      if( (pos = sLine.indexOf("modified:"))>=0){
    145        listFiles = data.listModifiedFiles = new LinkedList<DataFile>();
    146        sType = "chg";
    147      } else if( (pos = sLine.indexOf("unknown:"))>=0){
    148        listFiles = data.listNewFiles = new LinkedList<DataFile>();
    149        sType = "new";
    150      } else if( (pos = sLine.indexOf("removed:"))>=0){
    151        listFiles = data.listRemovedFiles = new LinkedList<DataFile>();
    152        sType = "del";
    153      } else if( (pos = sLine.indexOf("added:"))>=0){
    154        listFiles = data.listAddFiles = new LinkedList<DataFile>();
    155        sType = "add";
    156      } else if( (pos = sLine.indexOf("renamed:"))>=0){
    157        listFiles = data.listRenamedFiles = new LinkedList<DataFile>();
    158        sType = "mov";
    159      } else {
    160        //line with a file path
    161        String sFilePath = sLine.trim();
    162        if(sFilePath.endsWith("*")){
    163          sFilePath = sFilePath.substring(0, sFilePath.length()-1).trim();
    164        }
    165        int posSep = sFilePath.indexOf("=>");
    166        if( posSep >=0){
    167          sFilePath = sFilePath.substring(posSep+2).trim();
    168        }
    169        sFilePath = sFilePath.replace('\\', '/');
    170        File file = new File(mainData.currCmpn.dirWorkingtree, sFilePath);
    171        DataFile fileData = new DataFile(file, sFilePath, sType);
    172        listFiles.add(fileData);
    173        data.indexFiles.put(sFilePath, fileData);
    174      }
    175      posLine = posLineEnd +1;
    176    }
    177
    178  }
    179
    180
    181
    182  void getVersionFromLogOutput(StringBuilder uLog, DataCmpn data, DataCmpn.Revision revision)
    183  {
    184
    185    try{
    186      String sLine;
    187      int posLine = 0, posLineEnd;
    188      int pos;
    189      boolean bRevnrOk = false, bRevDateOk = false;
    190      while( (!bRevnrOk || !bRevDateOk) && (posLineEnd = uLog.indexOf("\n", posLine))>=0){
    191        sLine = uLog.substring(posLine, posLineEnd);
    192        if( (pos = sLine.indexOf("revno:"))>=0){
    193          //line: revno: <#?revision>
    194          String sRevision = sLine.substring(pos + 6).trim();
    195          //int nrRev = Integer.parseInt(sRevision);
    196          revision.nr = sRevision;
    197          bRevnrOk = true;
    198        } else if( (pos = sLine.indexOf("timestamp:"))>=0){
    199          //line: timestamp: <timestamp>
    200          String sDate = sLine.substring(pos + 15, pos+34).trim();
    201          long dateVersion = logDateFormat.parse(sDate).getTime();
    202          revision.date = dateVersion;
    203          bRevDateOk = true;
    204        }
    205        posLine = posLineEnd +1;
    206      }
    207    } catch(Exception exc){ throw new RuntimeException(exc); }
    208  }
    209}