1/* 2 * Copyright (c) 2002, 2013, 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