View Javadoc

1   /**
2    * Copyright 2005, ObjectLab Financial Ltd
3    * All rights protected.
4    */
5   
6   package net.sf.statsvn;
7   
8   import java.text.SimpleDateFormat;
9   import java.util.HashSet;
10  import java.util.Iterator;
11  import java.util.Set;
12  import java.util.SortedSet;
13  
14  import net.sf.statcvs.model.Repository;
15  import net.sf.statcvs.model.Revision;
16  import net.sf.statcvs.model.SymbolicName;
17  import net.sf.statcvs.model.VersionedFile;
18  import net.sf.statsvn.output.SvnConfigurationOptions;
19  
20  /**
21   * Execute a Repository Dump on the TaskLogger.
22   * 
23   * @author Benoit Xhenseval
24   */
25  public class RepoDump {
26  	private static final int WIDTH_FOR_NUMBER = 5;
27  
28  	private static final SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
29  
30  	private final Repository repository;
31  
32  	private int totalDelta;
33  
34  	private int totalLastRev;
35  
36  	private int totalNumRevision;
37  
38  	private int totalMisMatch;
39  
40  	private int numberMisMatch;
41  
42  	private int totalCurrentLOCPerFile;
43  
44  	public RepoDump(final Repository repo) {
45  		repository = repo;
46  	}
47  
48  	public void dump() {
49  		final SortedSet revisions = repository.getRevisions();
50  		final Set filesViaRevisions = dumpPerRevision(revisions);
51  
52  		SvnConfigurationOptions.getTaskLogger().info("\n\n#### DUMP PER FILE ####");
53  
54  		final SortedSet files = repository.getFiles();
55  		dumpPerFile(files);
56  		dumpPerTags();
57  
58  		SvnConfigurationOptions.getTaskLogger().info("----------------------------------");
59  		SvnConfigurationOptions.getTaskLogger().info("Current Repo Line Code :" + repository.getCurrentLOC());
60  		SvnConfigurationOptions.getTaskLogger().info("-----Via Files--------------------");
61  		SvnConfigurationOptions.getTaskLogger().info("Number of Files via Files  :" + files.size());
62  		SvnConfigurationOptions.getTaskLogger().info(
63  		        "Sum Current LOC via File   :" + totalCurrentLOCPerFile + "\tDiff with Repo LOC " + (repository.getCurrentLOC() - totalCurrentLOCPerFile) + " "
64  		                + (repository.getCurrentLOC() - totalCurrentLOCPerFile == 0 ? "OK" : "NOT Ok"));
65  		SvnConfigurationOptions.getTaskLogger().info("# of File Revision via File:" + totalNumRevision);
66  		SvnConfigurationOptions.getTaskLogger().info("-----Via Revisions----------------");
67  		SvnConfigurationOptions.getTaskLogger().info(
68  		        "# of Files via Revisions   :" + padIntRight(filesViaRevisions.size(), WIDTH_FOR_NUMBER) + "\tDiff with via Files:"
69  		                + (files.size() - filesViaRevisions.size()) + (files.size() - filesViaRevisions.size() == 0 ? " OK" : "NOT Ok"));
70  		SvnConfigurationOptions.getTaskLogger().info(
71  		        "# of File Revision via Revi:" + padIntRight(revisions.size(), WIDTH_FOR_NUMBER) + "\tDiff with via Files:"
72  		                + (totalNumRevision - revisions.size()) + (totalNumRevision - revisions.size() == 0 ? " OK" : "NOT Ok"));
73  		SvnConfigurationOptions.getTaskLogger().info(
74  		        "Sum Delta via Revisions    :" + padIntRight(totalDelta, WIDTH_FOR_NUMBER) + "\tDiff with Repo LOC "
75  		                + (repository.getCurrentLOC() - totalDelta) + " " + (repository.getCurrentLOC() - totalDelta == 0 ? "OK" : "NOT Ok"));
76  		if (numberMisMatch > 0) {
77  			SvnConfigurationOptions.getTaskLogger().info("**** PROBLEM ******");
78  			SvnConfigurationOptions.getTaskLogger().info(
79  			        "Number of Mismatches       :" + padIntRight(numberMisMatch, WIDTH_FOR_NUMBER) + "\tLOC Mismatch:" + totalMisMatch);
80  		}
81  		SvnConfigurationOptions.getTaskLogger().info(
82  		        "Tot LOC via Last Rev file  :" + padIntRight(totalLastRev, WIDTH_FOR_NUMBER) + "\tDiff with Repo LOC "
83  		                + (repository.getCurrentLOC() - totalLastRev) + (repository.getCurrentLOC() - totalDelta == 0 ? " OK" : " NOT Ok"));
84  		SvnConfigurationOptions.getTaskLogger().info("----------------------------------");
85  	}
86  
87  	private void dumpPerTags() {
88  		if (repository.getSymbolicNames() != null) {
89  			SvnConfigurationOptions.getTaskLogger().info("\n\n#### DUMP PER TAG ####");
90  			for (final Iterator it = repository.getSymbolicNames().iterator(); it.hasNext();) {
91  				final SymbolicName symbol = (SymbolicName) it.next();
92  				SvnConfigurationOptions.getTaskLogger().info("\nTAG: " + symbol.getName() + " / " + symbol.getDate());
93  				int loc = 0;
94  				for (final Iterator rev = symbol.getRevisions().iterator(); rev.hasNext();) {
95  					final Revision revision = (Revision) rev.next();
96  					SvnConfigurationOptions.getTaskLogger().info(
97  					        "  LOC:" + padIntRight(revision.getLines(), WIDTH_FOR_NUMBER) + " Rev:" + padRight(revision.getRevisionNumber(), WIDTH_FOR_NUMBER)
98  					                + " File: " + revision.getFile().getFilenameWithPath() + " dead:" + revision.isDead());
99  					loc += revision.getLines();
100 				}
101 				SvnConfigurationOptions.getTaskLogger().info("Total LOC: " + loc);
102 			}
103 		}
104 	}
105 
106 	private void dumpPerFile(final SortedSet files) {
107 		totalCurrentLOCPerFile = 0;
108 		totalNumRevision = 0;
109 		int fileNumber = 0;
110 		totalMisMatch = 0;
111 		numberMisMatch = 0;
112 		for (final Iterator it = files.iterator(); it.hasNext();) {
113 			final VersionedFile rev = (VersionedFile) it.next();
114 			totalCurrentLOCPerFile += rev.getCurrentLinesOfCode();
115 			totalNumRevision += rev.getRevisions().size();
116 			SvnConfigurationOptions.getTaskLogger().info("File " + ++fileNumber + "/ " + rev.getFilenameWithPath() + " \tLOC:" + rev.getCurrentLinesOfCode());
117 			int sumDelta = 0;
118 			// go through all revisions for this file.
119 			for (final Iterator it2 = rev.getRevisions().iterator(); it2.hasNext();) {
120 				final Revision revi = (Revision) it2.next();
121 
122 				sumDelta += revi.getLinesDelta();
123 				if (revi.isBeginOfLog()) {
124 					sumDelta += revi.getLines();
125 				}
126 				SvnConfigurationOptions.getTaskLogger()
127 				        .info(
128 				                "\tRevision:" + padRight(revi.getRevisionNumber(), WIDTH_FOR_NUMBER) + " \tDelta:"
129 				                        + padIntRight(revi.getLinesDelta(), WIDTH_FOR_NUMBER) + "\tLines:" + padIntRight(revi.getLines(), WIDTH_FOR_NUMBER)
130 				                        + "\t" + printBoolean("Ini:", revi.isInitialRevision()) + "\t" + printBoolean("BegLog", revi.isBeginOfLog()) + "\t"
131 				                        + printBoolean("Dead", revi.isDead()) + "\tSumDelta:" + padIntRight(sumDelta, WIDTH_FOR_NUMBER) + " "
132 				                        + revi.getSymbolicNames());
133 			}
134 			if (sumDelta != rev.getCurrentLinesOfCode()) {
135 				SvnConfigurationOptions.getTaskLogger().info(
136 				        "\t~~~~~SUM DELTA DOES NOT MATCH LOC " + rev.getCurrentLinesOfCode() + " vs " + sumDelta + " Diff:"
137 				                + (rev.getCurrentLinesOfCode() - sumDelta) + " ~~~~~~");
138 				totalMisMatch += (rev.getCurrentLinesOfCode() - sumDelta);
139 				numberMisMatch++;
140 			}
141 		}
142 	}
143 
144 	private Set dumpPerRevision(final SortedSet revisions) {
145 		totalDelta = 0;
146 		final Set filesViaRevisions = new HashSet();
147 		totalLastRev = 0;
148 		SvnConfigurationOptions.getTaskLogger().info("\n\n#### DUMP PER REVISION ####");
149 		String previousRevision = "";
150 		int revTotal = -1;
151 		for (final Iterator it = revisions.iterator(); it.hasNext();) {
152 			final Revision rev = (Revision) it.next();
153 			if (!rev.getRevisionNumber().equals(previousRevision)) {
154 				previousRevision = rev.getRevisionNumber();
155 				if (revTotal != -1) {
156 					SvnConfigurationOptions.getTaskLogger().info("Total for this rev: " + totalDelta);
157 				}
158 				SvnConfigurationOptions.getTaskLogger().info(
159 				        "Revision " + padRight(rev.getRevisionNumber(), WIDTH_FOR_NUMBER) + " " + SDF.format(rev.getDate()));
160 			}
161 			SvnConfigurationOptions.getTaskLogger().info(
162 			        "\tlines:" + padIntRight(rev.getLines(), WIDTH_FOR_NUMBER) + " D:" + padIntRight(rev.getLinesDelta(), WIDTH_FOR_NUMBER) + " Rep:"
163 			                + padIntRight(rev.getReplacedLines(), WIDTH_FOR_NUMBER) + " New:" + padIntRight(rev.getNewLines(), WIDTH_FOR_NUMBER)
164 			                + printBoolean(" Initial", rev.isInitialRevision()) + printBoolean(" BegLog", rev.isBeginOfLog())
165 			                + printBoolean(" Dead", rev.isDead()) + " " + rev.getFile().getFilenameWithPath() + " tags:" + rev.getSymbolicNames());
166 
167 			totalDelta += rev.getLinesDelta();
168 			if (rev.isBeginOfLog()) {
169 				totalDelta += rev.getLines();
170 			}
171 			revTotal = totalDelta;
172 			final VersionedFile file = rev.getFile();
173 			final Revision fileRev = file.getLatestRevision();
174 			if (!fileRev.isDead() /*
175 											 * &&
176 											 * fileRev.getRevisionNumber().equals(rev.getRevisionNumber())
177 											 */&& !filesViaRevisions.contains(file.getFilenameWithPath())) {
178 				totalLastRev += file.getCurrentLinesOfCode();
179 			}
180 			filesViaRevisions.add(file.getFilenameWithPath());
181 		}
182 		SvnConfigurationOptions.getTaskLogger().info("Total for this rev: " + totalDelta);
183 		return filesViaRevisions;
184 	}
185 
186 	private String padIntRight(final int str, final int size) {
187 		return padRight(String.valueOf(str), size);
188 	}
189 
190 	private String printBoolean(final String title, final boolean test) {
191 		return title + ":" + (test ? "Y" : "N");
192 	}
193 
194 	private String padRight(final String str, final int size) {
195 		final StringBuffer buf = new StringBuffer(str);
196 		int requiredPadding = size;
197 		if (str != null) {
198 			requiredPadding = requiredPadding - str.length();
199 		}
200 		if (requiredPadding > 0) {
201 			for (int i = 0; i < requiredPadding; i++) {
202 				buf.append(" ");
203 			}
204 		}
205 		return buf.toString();
206 	}
207 }