DirDiff.java revision 8845:4be14673b9bf
1/*
2 * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package build.tools.dirdiff;
27
28import java.io.File;
29import java.util.TreeSet;
30
31public class DirDiff implements Runnable {
32    private final static String FILE_SEPARATOR = System.getProperty("file.separator");
33    private static final boolean traversSccsDirs;
34    private static final boolean recurseExtraDirs;
35    private static final boolean verboseMode;
36    private static final boolean checkSizes;
37    private static long SizeTolerance = 0;
38    private File goldenDir = null;
39    private File testDir = null;
40
41    // static initializer:
42      static {
43          String traversePropertyValue = System.getProperty("sccs");
44          traversSccsDirs = (traversePropertyValue != null &&
45                              traversePropertyValue.toLowerCase().equals("true"))? true : false;
46          if (traversSccsDirs) {
47              System.err.println("traversing SCCS directories...");
48          }
49
50          String verbosePropertyValue = System.getProperty("verbose");
51          verboseMode = (verbosePropertyValue != null &&
52                              verbosePropertyValue.toLowerCase().equals("true"))? true : false;
53          if (verboseMode) {
54              System.err.println("verbose mode truned on...");
55          }
56
57          String noRecurseExtraDirsPropertyValue = System.getProperty("recurse");
58          recurseExtraDirs = (noRecurseExtraDirsPropertyValue != null &&
59                              noRecurseExtraDirsPropertyValue.toLowerCase().equals("true"))? true : false;
60          if (recurseExtraDirs) {
61              System.err.println("recursing extra directories...");
62          }
63
64          String sizeToleranceValue = System.getProperty("sizeTolerance");
65          checkSizes = (sizeToleranceValue != null);
66          if (checkSizes) {
67              try {
68                  SizeTolerance = Long.parseLong(sizeToleranceValue);
69              }
70              catch (NumberFormatException e) {
71                  System.err.println("Invlalid sizeTolerance value: " + sizeToleranceValue);
72                  System.err.println("Expecting a long value.  Exiting.");
73                  System.exit(1);
74              }
75              System.err.println("checking matching files for size differences of at least " + SizeTolerance);
76          }
77      }
78
79  public DirDiff(File inGoldenDir, File inTestDir) {
80      goldenDir = inGoldenDir;
81      testDir = inTestDir;
82  }
83
84  private void whatToDoWithMatchingFiles(File goldenChild, File testChild) {
85      if (verboseMode) {
86          System.out.println("Files Match:\t" + goldenChild.getAbsolutePath() +
87                             " and " + testChild.getAbsolutePath());
88      }
89      if (checkSizes) {
90          // compare file sizes...
91          long goldenLength = 0;
92          long testLength = 0;
93          try {
94              goldenLength = goldenChild.length();
95              testLength = testChild.length();
96          }
97          catch (Exception e) {
98              System.err.println("Error: exception thrown and caught:");
99              e.printStackTrace();
100          }
101          if (java.lang.Math.abs(goldenLength - testLength) > SizeTolerance) {
102              if (goldenLength > testLength) {
103                  System.out.println("File short [" + (testLength - goldenLength) + "]:\t" + testChild.getAbsolutePath());
104              } else {
105                  System.out.println("File long [" + (testLength - goldenLength) + "]:\t" + testChild.getAbsolutePath());
106              }
107          }
108      }
109  }
110
111
112  private void whatToDoWithMatchingDirs(File goldenChild, File testChild) {
113      if (verboseMode) {
114          System.out.println("Dirs Match:\t" + goldenChild.getAbsolutePath() +
115                             " and " + testChild.getAbsolutePath());
116      }
117  }
118
119  private void whatToDoWithMissingFiles(File missingFile) {
120      long length = 0;
121      try {
122          length = missingFile.length();
123      }
124      catch (Exception e) {
125          System.err.println("Error: exception thrown and caught:");
126          e.printStackTrace();
127      }
128
129      System.out.println("Missing File [" + length + "]:\t" + missingFile.getAbsolutePath());
130  }
131
132  private void whatToDoWithExtraFiles(File extraFile) {
133      long length = 0;
134      try {
135          length = extraFile.length();
136      }
137      catch (Exception e) {
138          System.err.println("Error: exception thrown and caught:");
139          e.printStackTrace();
140      }
141
142      System.out.println("Extra File [" + length + "]:\t" + extraFile.getAbsolutePath());
143  }
144
145  private void whatToDoWithMissingDirs(File missingDir) {
146      System.out.println("Missing Dir:\t" + missingDir.getAbsolutePath());
147  }
148
149  private void whatToDoWithExtraDirs(File extraDir) {
150      System.out.println("Extra Dir:\t" + extraDir.getAbsolutePath());
151  }
152
153  private void whatToDoWithNonMatchingChildren(File goldenChild, File testChild) {
154      System.out.println("Type Mismatch:\t" + goldenChild.getAbsolutePath() + " is a " +
155                         (goldenChild.isDirectory()? "directory" : "file") +
156                         " and " + testChild.getAbsolutePath() + " is a " +
157                         (testChild.isDirectory()? "directory" : "file"));
158  }
159
160  public void run() {
161      File[] currentTestDirs = null;
162      if (testDir != null) {
163          currentTestDirs = testDir.listFiles();
164      }
165
166      File[] currentGoldenDirs = null;
167      TreeSet<String> goldDirSet = new TreeSet<>();
168      if (goldenDir != null) {
169          currentGoldenDirs = goldenDir.listFiles();
170          for (int i=0; i<currentGoldenDirs.length; i++) {
171              goldDirSet.add(currentGoldenDirs[i].getName());
172          }
173      }
174
175      // now go through the list of members
176      if (currentGoldenDirs != null) {
177          for (int i=0; i<currentGoldenDirs.length; i++) {
178              File newGoldenDir = currentGoldenDirs[i];
179
180              // do not traverse SCCS directories...
181              if (!(newGoldenDir.getAbsolutePath().endsWith("SCCS")) || traversSccsDirs ) {
182                  // start a compare of this child and the like-named test child...
183                  File newTestDir = new File(testDir.getAbsolutePath() + FILE_SEPARATOR +
184                                             newGoldenDir.getName());
185
186                  if (newTestDir.exists()) {
187                      if (newGoldenDir.isDirectory()) {
188                          if (newTestDir.isDirectory()) {
189                              whatToDoWithMatchingDirs(newGoldenDir, newTestDir);
190                              Thread t = new Thread( new DirDiff(newGoldenDir, newTestDir));
191                              t.start();
192                          } else {
193                              whatToDoWithNonMatchingChildren(newGoldenDir, newTestDir);
194                          }
195                      } else { // of... newGoldenDir.isDirectory()...
196                          if (newTestDir.isDirectory()) {
197                              whatToDoWithNonMatchingChildren(newGoldenDir, newTestDir);
198                          }
199                           whatToDoWithMatchingFiles(newGoldenDir, newTestDir);
200                      }
201                  } else { // of... newTestDir.exists()...
202                      if (newGoldenDir.isDirectory()) {
203                          whatToDoWithMissingDirs(newTestDir);
204                          Thread t = new Thread( new DirDiff(newGoldenDir, newTestDir));
205                          t.start();
206                      } else {
207                          whatToDoWithMissingFiles(newTestDir);
208                      }
209                  }
210              }
211          }
212      }
213
214      // look for extra test objs...
215      if (currentTestDirs != null) {
216          for (int i=0; i<currentTestDirs.length; i++) {
217              // do not traverse SCCS directories...
218              if (!(currentTestDirs[i].getAbsolutePath().endsWith("SCCS")) || traversSccsDirs ) {
219                  if (!goldDirSet.contains(currentTestDirs[i].getName())) {
220                      if (currentTestDirs[i].isDirectory()) {
221                          whatToDoWithExtraDirs(currentTestDirs[i]);
222                          if (recurseExtraDirs) {
223                              Thread t = new Thread( new DirDiff( null, currentTestDirs[i]));
224                              t.start();
225                          }
226                      } else {
227                          whatToDoWithExtraFiles(currentTestDirs[i]);
228                      }
229                  }
230              }
231          }
232      }
233  }
234
235  public static void main(String[] args) {
236      if (args.length != 2) {
237          System.err.println("You must provide two directory names on the command line.");
238          System.err.println("Usage:\tDirDiff dir1 dir2");
239          System.err.println("\tJava Runtime Properties (set to \"true\"):");
240          System.err.println("\t\tsccs\trecurse SCCS directories");
241          System.err.println("\t\tverbose\tprint verbose diagnostics");
242          System.err.println("\t\trecurse\trecursing extra directories showing extra files");
243          System.err.println("\t\tsizeTolerance\tset tolerance for size differences - default is infinite");
244
245          System.exit(0);
246      } else {
247          File golden = new File(args[0]);
248          File test = new File(args[1]);
249
250          if (!golden.exists()) {
251              System.err.println("Error: path " + golden.getAbsolutePath() +
252                                 " does not exist. Skipping.");
253              System.exit(0);
254          }
255          if (!golden.isDirectory()) {
256              System.err.println("Error: path " + golden.getAbsolutePath() +
257                                 " must be a directory. Skipping.");
258              System.exit(0);
259          }
260          if (!test.exists()) {
261              System.err.println("Error: path " + test.getAbsolutePath() +
262                                 " does not exist. Skipping.");
263              System.exit(0);
264          }
265          if (!test.isDirectory()) {
266              System.err.println("Error: path " + test.getAbsolutePath() +
267                                 " must be a directory. Skipping.");
268              System.exit(0);
269          }
270
271          Thread t = new Thread( new DirDiff(golden, test));
272          t.start();
273      }
274  }
275}
276