View Javadoc

1   /*
2   	StatCvs - CVS statistics generation 
3   	Copyright (C) 2002  Lukasz Pekacki <lukasz@pekacki.de>
4   	http://statcvs.sf.net/
5       
6   	This library is free software; you can redistribute it and/or
7   	modify it under the terms of the GNU Lesser General Public
8   	License as published by the Free Software Foundation; either
9   	version 2.1 of the License, or (at your option) any later version.
10  
11  	This library is distributed in the hope that it will be useful,
12  	but WITHOUT ANY WARRANTY; without even the implied warranty of
13  	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  	Lesser General Public License for more details.
15  
16  	You should have received a copy of the GNU Lesser General Public
17  	License along with this library; if not, write to the Free Software
18  	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19      
20  	$RCSfile: CvsLogUtils.java,v $
21  	$Date: 2008/04/02 11:22:15 $
22  */
23  package net.sf.statcvs.util;
24  
25  /**
26   * Utility class containing various methods related to CVS logfile parsing
27   * 
28   * @author Richard Cyganiak <rcyg@gmx.de>
29   * @version $Id: CvsLogUtils.java,v 1.5 2008/04/02 11:22:15 benoitx Exp $
30   */
31  public class CvsLogUtils {
32  
33      /**
34       * <p>Determines if a file is in the attic by comparing the location of
35       * the RCS file and the working file.</p>
36       * 
37       * <p>The RCS file is the file containing the version history.
38       * It is located in the CVSROOT directory of the repository.
39       * It's name ends in ",v". The filename is absoulte.</p>
40       * 
41       * <p>The working filename is the actual filename relative to the
42       * root of the checked-out module.</p>
43       * 
44       * <p>A file is said to be in the attic if and only if it is dead
45       * on the main branch. If a file is in the attic, it's RCS file is
46       * moved to a subdirectory called "Attic". This method checks if
47       * the RCS file is in the "Attic" subdirectory.
48       *  
49       * @param rcsFilename a version-controlled file's RCS filename
50       * @param workingFilename a version-controlled file's working filename
51       * @return <tt>true</tt> if the file is in the attic
52       */
53      public static boolean isInAttic(final String rcsFilename, final String workingFilename) {
54          final int lastDelim = workingFilename.lastIndexOf("/");
55          final String filename = workingFilename.substring(lastDelim + 1, workingFilename.length());
56  
57          final int rcsPathLength = rcsFilename.length() - filename.length() - 2;
58          final String rcsPath = rcsFilename.substring(0, rcsPathLength);
59          return rcsPath.endsWith("/Attic/");
60      }
61  
62      /**
63       * Returns <code>true</code> if this revision is part of the main branch,
64       * and <code>false</code> if it is part of a side branch. Revisions
65       * like 1.1 and 5.212 are on the main branch, 1.1.1.1 and 1.4.2.13 and
66       * 1.4.2.13.4.1 are on side branches.
67       * @param revisionNumber the revision's number, for example "1.1"
68       * @return <code>true</code> if this revision is part of the main branch.
69       */
70      public static boolean isOnMainBranch(final String revisionNumber) {
71          int index = 0;
72          int dotCount = 0;
73          while (revisionNumber.indexOf('.', index) != -1) {
74              index = revisionNumber.indexOf('.', index) + 1;
75              dotCount++;
76          }
77          return (dotCount == 1);
78      }
79  
80      /**
81       * Determines the module name by comparing the RCS filename and
82       * the working filename.  
83       * @param rcsFilename a version-controlled file's RCS filename
84       * @param workingFilename a version-controlled file's working filename
85       * @return the module name
86       */
87      public static String getModuleName(final String rcsFilename, final String workingFilename) {
88          int localLenght = workingFilename.length() + ",v".length();
89          if (CvsLogUtils.isInAttic(rcsFilename, workingFilename)) {
90              localLenght += "/Attic".length();
91          }
92          final String cvsroot = rcsFilename.substring(0, rcsFilename.length() - localLenght - 1);
93          final int lastSlash = cvsroot.lastIndexOf("/");
94          if (lastSlash == -1) {
95              return "";
96          }
97          return cvsroot.substring(lastSlash + 1);
98      }
99  
100     /**
101      * Returns <tt>true</tt> if files with a given keyword substitution
102      * should be treated as binary files. That is, they should be assumed
103      * to be 0 lines of code. Possible values are the same as for the -kXXX
104      * option of CVS (for example, kv, kvl, b).
105      * @param kws the keyword substitution, as of CVS option -kXXX
106      * @return <tt>true</tt> if this is a binary keyword substitution
107      * @throws IllegalArgumentException if <tt>kws</tt> is not a known keyword substitution
108      */
109     public static boolean isBinaryKeywordSubst(final String kws) {
110         if ("kv".equals(kws)) {
111             return false;
112         }
113         if ("kvl".equals(kws)) {
114             return false;
115         }
116         if ("k".equals(kws)) {
117             return false;
118         }
119         if ("o".equals(kws)) {
120             return false;
121         }
122         if ("b".equals(kws)) {
123             return true;
124         }
125         if ("v".equals(kws)) {
126             return false;
127         }
128         if ("u".equals(kws)) {
129             return false;
130         }
131         throw new IllegalArgumentException("unknown keyword substitution: " + kws);
132     }
133 }