1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/test/com/sun/javadoc/lib/JavadocTester.java Wed Apr 27 01:34:52 2016 +0800 1.3 @@ -0,0 +1,618 @@ 1.4 +/* 1.5 + * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + */ 1.26 + 1.27 +import com.sun.javadoc.*; 1.28 +import java.util.*; 1.29 +import java.io.*; 1.30 + 1.31 + 1.32 +/** 1.33 + * Runs javadoc and then runs regression tests on the resulting output. 1.34 + * This class currently contains three tests: 1.35 + * <ul> 1.36 + * <li> String search: Reads each file, complete with newlines, 1.37 + * into a string. Lets you search for strings that contain 1.38 + * newlines. String matching is case-sensitive. 1.39 + * You can run javadoc multiple times with different arguments, 1.40 + * generating output into different destination directories, and 1.41 + * then perform a different array of tests on each one. 1.42 + * To do this, the run method accepts a test array for testing 1.43 + * that a string is found, and a negated test array for testing 1.44 + * that a string is not found. 1.45 + * <li> Run diffs: Iterate through the list of given file pairs 1.46 + * and diff the pairs. 1.47 + * <li> Check exit code: Check the exit code of Javadoc and 1.48 + * record whether the test passed or failed. 1.49 + * </ul> 1.50 + * 1.51 + * @author Doug Kramer 1.52 + * @author Jamie Ho 1.53 + * @since 1.4.2 1.54 + */ 1.55 +public abstract class JavadocTester { 1.56 + 1.57 + protected static final String FS = System.getProperty("file.separator"); 1.58 + protected static final String PS = System.getProperty("path.separator"); 1.59 + protected static final String NL = System.getProperty("line.separator"); 1.60 + protected static final String SRC_DIR = System.getProperty("test.src", "."); 1.61 + protected static final String JAVA_VERSION = System.getProperty("java.version"); 1.62 + protected static final String[][] NO_TEST = new String[][] {}; 1.63 + protected static final String[] NO_FILE_TEST = new String[] {}; 1.64 + 1.65 + /** 1.66 + * Use this as the file name in the test array when you want to search 1.67 + * for a string in the error output. 1.68 + */ 1.69 + public static final String ERROR_OUTPUT = "ERROR_OUTPUT"; 1.70 + 1.71 + /** 1.72 + * Use this as the file name in the test array when you want to search 1.73 + * for a string in the notice output. 1.74 + */ 1.75 + public static final String NOTICE_OUTPUT = "NOTICE_OUTPUT"; 1.76 + 1.77 + /** 1.78 + * Use this as the file name in the test array when you want to search 1.79 + * for a string in the warning output. 1.80 + */ 1.81 + public static final String WARNING_OUTPUT = "WARNING_OUTPUT"; 1.82 + 1.83 + /** 1.84 + * Use this as the file name in the test array when you want to search 1.85 + * for a string in standard output. 1.86 + */ 1.87 + public static final String STANDARD_OUTPUT = "STANDARD_OUTPUT"; 1.88 + 1.89 + /** 1.90 + * The default doclet. 1.91 + */ 1.92 + public static final String DEFAULT_DOCLET_CLASS = "com.sun.tools.doclets.formats.html.HtmlDoclet"; 1.93 + public static final String DEFAULT_DOCLET_CLASS_OLD = "com.sun.tools.doclets.standard.Standard"; 1.94 + 1.95 + /** 1.96 + * The writer to write error messages. 1.97 + */ 1.98 + public StringWriter errors; 1.99 + 1.100 + /** 1.101 + * The writer to write notices. 1.102 + */ 1.103 + public StringWriter notices; 1.104 + 1.105 + /** 1.106 + * The writer to write warnings. 1.107 + */ 1.108 + public StringWriter warnings; 1.109 + 1.110 + /** 1.111 + * The buffer of warning output.. 1.112 + */ 1.113 + public StringBuffer standardOut; 1.114 + 1.115 + /** 1.116 + * The current subtest number. 1.117 + */ 1.118 + private static int numTestsRun = 0; 1.119 + 1.120 + /** 1.121 + * The number of subtests passed. 1.122 + */ 1.123 + private static int numTestsPassed = 0; 1.124 + 1.125 + /** 1.126 + * The current run of javadoc 1.127 + */ 1.128 + private static int javadocRunNum = 0; 1.129 + 1.130 + /** 1.131 + * Whether or not to match newlines exactly. 1.132 + * Set this value to false if the match strings 1.133 + * contain text from javadoc comments containing 1.134 + * non-platform newlines. 1.135 + */ 1.136 + protected boolean exactNewlineMatch = true; 1.137 + 1.138 + /** 1.139 + * Construct a JavadocTester. 1.140 + */ 1.141 + public JavadocTester() { 1.142 + } 1.143 + 1.144 + /** 1.145 + * Return the bug id. 1.146 + * @return the bug id 1.147 + */ 1.148 + public abstract String getBugId(); 1.149 + 1.150 + /** 1.151 + * Return the name of the bug. 1.152 + * @return the name of the bug 1.153 + */ 1.154 + public abstract String getBugName(); 1.155 + 1.156 + /** 1.157 + * Execute the tests. 1.158 + * 1.159 + * @param tester the tester to execute 1.160 + * @param args the arguments to pass to Javadoc 1.161 + * @param testArray the array of tests 1.162 + * @param negatedTestArray the array of negated tests 1.163 + * @return the return code for the execution of Javadoc 1.164 + */ 1.165 + public static int run(JavadocTester tester, String[] args, 1.166 + String[][] testArray, String[][] negatedTestArray) { 1.167 + int returnCode = tester.runJavadoc(args); 1.168 + tester.runTestsOnHTML(testArray, negatedTestArray); 1.169 + return returnCode; 1.170 + } 1.171 + 1.172 + /** 1.173 + * Execute the tests. 1.174 + * 1.175 + * @param tester the tester to execute 1.176 + * @param args the arguments to pass to Javadoc 1.177 + * @param testArray the array of tests 1.178 + * @param negatedTestArray the array of negated tests 1.179 + * @param fileTestArray the array of file tests 1.180 + * @param negatedFileTestArray the array of negated file tests 1.181 + * @return the return code for the execution of Javadoc 1.182 + */ 1.183 + public static int run(JavadocTester tester, String[] args, 1.184 + String[][] testArray, String[][] negatedTestArray, String[] fileTestArray, 1.185 + String[] negatedFileTestArray) { 1.186 + int returnCode = tester.runJavadoc(args); 1.187 + tester.runTestsOnHTML(testArray, negatedTestArray); 1.188 + tester.runTestsOnFile(fileTestArray, negatedFileTestArray); 1.189 + return returnCode; 1.190 + } 1.191 + 1.192 + /** 1.193 + * Execute Javadoc using the default doclet. 1.194 + * 1.195 + * @param args the arguments to pass to Javadoc 1.196 + * @return the return code from the execution of Javadoc 1.197 + */ 1.198 + public int runJavadoc(String[] args) { 1.199 + float javaVersion = Float.parseFloat(JAVA_VERSION.substring(0,3)); 1.200 + String docletClass = javaVersion < 1.5 ? 1.201 + DEFAULT_DOCLET_CLASS_OLD : DEFAULT_DOCLET_CLASS; 1.202 + return runJavadoc(docletClass, args); 1.203 + } 1.204 + 1.205 + 1.206 + /** 1.207 + * Execute Javadoc. 1.208 + * 1.209 + * @param docletClass the doclet being tested. 1.210 + * @param args the arguments to pass to Javadoc 1.211 + * @return the return code from the execution of Javadoc 1.212 + */ 1.213 + public int runJavadoc(String docletClass, String[] args) { 1.214 + javadocRunNum++; 1.215 + if (javadocRunNum == 1) { 1.216 + System.out.println("\n" + "Running javadoc..."); 1.217 + } else { 1.218 + System.out.println("\n" + "Running javadoc (run " 1.219 + + javadocRunNum + ")..."); 1.220 + } 1.221 + initOutputBuffers(); 1.222 + 1.223 + ByteArrayOutputStream stdout = new ByteArrayOutputStream(); 1.224 + PrintStream prevOut = System.out; 1.225 + System.setOut(new PrintStream(stdout)); 1.226 + 1.227 + ByteArrayOutputStream stderr = new ByteArrayOutputStream(); 1.228 + PrintStream prevErr = System.err; 1.229 + System.setErr(new PrintStream(stderr)); 1.230 + 1.231 + int returnCode = com.sun.tools.javadoc.Main.execute( 1.232 + getBugName(), 1.233 + new PrintWriter(errors, true), 1.234 + new PrintWriter(warnings, true), 1.235 + new PrintWriter(notices, true), 1.236 + docletClass, 1.237 + getClass().getClassLoader(), 1.238 + args); 1.239 + System.setOut(prevOut); 1.240 + standardOut = new StringBuffer(stdout.toString()); 1.241 + System.setErr(prevErr); 1.242 + errors.write(NL + stderr.toString()); 1.243 + 1.244 + printJavadocOutput(); 1.245 + return returnCode; 1.246 + } 1.247 + 1.248 + /** 1.249 + * Create new string writer buffers 1.250 + */ 1.251 + private void initOutputBuffers() { 1.252 + errors = new StringWriter(); 1.253 + notices = new StringWriter(); 1.254 + warnings = new StringWriter(); 1.255 + } 1.256 + 1.257 + /** 1.258 + * Run array of tests on the resulting HTML. 1.259 + * This method accepts a testArray for testing that a string is found 1.260 + * and a negatedTestArray for testing that a string is not found. 1.261 + * 1.262 + * @param testArray the array of tests 1.263 + * @param negatedTestArray the array of negated tests 1.264 + */ 1.265 + public void runTestsOnHTML(String[][] testArray, String[][] negatedTestArray) { 1.266 + runTestsOnHTML(testArray, false); 1.267 + runTestsOnHTML(negatedTestArray, true); 1.268 + } 1.269 + 1.270 + /** 1.271 + * Run array of tests on the generated files. 1.272 + * This method accepts a fileTestArray for testing if a file is generated 1.273 + * and a negatedFileTestArray for testing if a file is not found. 1.274 + * 1.275 + * @param testArray the array of file tests 1.276 + * @param negatedTestArray the array of negated file tests 1.277 + */ 1.278 + public void runTestsOnFile(String[] fileTestArray, String[] negatedFileTestArray) { 1.279 + runTestsOnFile(fileTestArray, false); 1.280 + runTestsOnFile(negatedFileTestArray, true); 1.281 + } 1.282 + 1.283 + /** 1.284 + * Run the array of tests on the resulting HTML. 1.285 + * 1.286 + * @param testArray the array of tests 1.287 + * @param isNegated true if test is negated; false otherwise 1.288 + */ 1.289 + private void runTestsOnHTML(String[][] testArray , boolean isNegated) { 1.290 + for (int i = 0; i < testArray.length; i++) { 1.291 + 1.292 + numTestsRun++; 1.293 + 1.294 + System.out.print("Running subtest #" + numTestsRun + "... "); 1.295 + 1.296 + // Get string to find 1.297 + String stringToFind = testArray[i][1]; 1.298 + 1.299 + // Read contents of file into a string 1.300 + String fileString; 1.301 + try { 1.302 + fileString = readFileToString(testArray[i][0]); 1.303 + } catch (Error e) { 1.304 + if (isNegated) { 1.305 + System.out.println( "FAILED" + "\n" 1.306 + + "for bug " + getBugId() 1.307 + + " (" + getBugName() + ") " 1.308 + + "due to " 1.309 + + e + "\n"); 1.310 + continue; 1.311 + } 1.312 + throw e; 1.313 + } 1.314 + // Find string in file's contents 1.315 + boolean isFound = findString(fileString, stringToFind); 1.316 + if ((isNegated && !isFound) || (!isNegated && isFound) ) { 1.317 + numTestsPassed += 1; 1.318 + System.out.println( "Passed" + "\n" 1.319 + + (isNegated ? "not found:" : "found:") + "\n" 1.320 + + stringToFind + " in " + testArray[i][0] + "\n"); 1.321 + } else { 1.322 + System.out.println( "FAILED" + "\n" 1.323 + + "for bug " + getBugId() 1.324 + + " (" + getBugName() + ")" + "\n" 1.325 + + "when searching for:" + "\n" 1.326 + + stringToFind 1.327 + + " in " + testArray[i][0] + "\n"); 1.328 + } 1.329 + } 1.330 + } 1.331 + 1.332 + /** 1.333 + * Run the array of file tests on the generated files. 1.334 + * 1.335 + * @param testArray the array of file tests 1.336 + * @param isNegated true if test is negated; false otherwise 1.337 + */ 1.338 + private void runTestsOnFile(String[] testArray, boolean isNegated) { 1.339 + String fileName; 1.340 + String failedString; 1.341 + String passedString; 1.342 + for (int i = 0; i < testArray.length; i++) { 1.343 + numTestsRun++; 1.344 + fileName = testArray[i]; 1.345 + failedString = "FAILED" + "\n" 1.346 + + "for bug " + getBugId() + " (" + getBugName() + ") " 1.347 + + "file (" + fileName + ") found" + "\n"; 1.348 + passedString = "Passed" + "\n" + 1.349 + "file (" + fileName + ") not found" + "\n"; 1.350 + System.out.print("Running subtest #" + numTestsRun + "... "); 1.351 + try { 1.352 + File file = new File(fileName); 1.353 + if ((file.exists() && !isNegated) || (!file.exists() && isNegated)) { 1.354 + numTestsPassed += 1; 1.355 + System.out.println(passedString); 1.356 + } else { 1.357 + System.out.println(failedString); 1.358 + } 1.359 + } catch (Error e) { 1.360 + System.err.println(e); 1.361 + } 1.362 + } 1.363 + } 1.364 + 1.365 + /** 1.366 + * Iterate through the list of given file pairs and diff each file. 1.367 + * 1.368 + * @param filePairs the pairs of files to diff. 1.369 + * @throws an Error is thrown if any differences are found between 1.370 + * file pairs. 1.371 + */ 1.372 + public void runDiffs(String[][] filePairs) throws Error { 1.373 + runDiffs(filePairs, true); 1.374 + } 1.375 + 1.376 + /** 1.377 + * Iterate through the list of given file pairs and diff each file. 1.378 + * 1.379 + * @param filePairs the pairs of files to diff. 1.380 + * @param throwErrorIFNoMatch flag to indicate whether or not to throw 1.381 + * an error if the files do not match. 1.382 + * 1.383 + * @throws an Error is thrown if any differences are found between 1.384 + * file pairs and throwErrorIFNoMatch is true. 1.385 + */ 1.386 + public void runDiffs(String[][] filePairs, boolean throwErrorIfNoMatch) throws Error { 1.387 + for (int i = 0; i < filePairs.length; i++) { 1.388 + diff(filePairs[i][0], filePairs[i][1], throwErrorIfNoMatch); 1.389 + } 1.390 + } 1.391 + 1.392 + /** 1.393 + * Check the exit code of Javadoc and record whether the test passed 1.394 + * or failed. 1.395 + * 1.396 + * @param expectedExitCode The exit code that is required for the test 1.397 + * to pass. 1.398 + * @param actualExitCode The actual exit code from the previous run of 1.399 + * Javadoc. 1.400 + */ 1.401 + public void checkExitCode(int expectedExitCode, int actualExitCode) { 1.402 + numTestsRun++; 1.403 + if (expectedExitCode == actualExitCode) { 1.404 + System.out.println( "Passed" + "\n" + " got return code " + 1.405 + actualExitCode); 1.406 + numTestsPassed++; 1.407 + } else { 1.408 + System.out.println( "FAILED" + "\n" + "for bug " + getBugId() 1.409 + + " (" + getBugName() + ")" + "\n" + "Expected return code " + 1.410 + expectedExitCode + " but got " + actualExitCode); 1.411 + } 1.412 + } 1.413 + 1.414 + /** 1.415 + * Print a summary of the test results. 1.416 + */ 1.417 + protected void printSummary() { 1.418 + if ( numTestsRun != 0 && numTestsPassed == numTestsRun ) { 1.419 + // Test passed 1.420 + System.out.println("\n" + "All " + numTestsPassed 1.421 + + " subtests passed"); 1.422 + } else { 1.423 + // Test failed 1.424 + throw new Error("\n" + (numTestsRun - numTestsPassed) 1.425 + + " of " + (numTestsRun) 1.426 + + " subtests failed for bug " + getBugId() 1.427 + + " (" + getBugName() + ")" + "\n"); 1.428 + } 1.429 + } 1.430 + 1.431 + /** 1.432 + * Print the output stored in the buffers. 1.433 + */ 1.434 + protected void printJavadocOutput() { 1.435 + System.out.println(STANDARD_OUTPUT + " : \n" + getStandardOutput()); 1.436 + System.err.println(ERROR_OUTPUT + " : \n" + getErrorOutput()); 1.437 + System.err.println(WARNING_OUTPUT + " : \n" + getWarningOutput()); 1.438 + System.out.println(NOTICE_OUTPUT + " : \n" + getNoticeOutput()); 1.439 + } 1.440 + 1.441 + /** 1.442 + * Read the file and return it as a string. 1.443 + * 1.444 + * @param fileName the name of the file to read 1.445 + * @return the file in string format 1.446 + */ 1.447 + public String readFileToString(String fileName) throws Error { 1.448 + if (fileName.equals(ERROR_OUTPUT)) { 1.449 + return getErrorOutput(); 1.450 + } else if (fileName.equals(NOTICE_OUTPUT)) { 1.451 + return getNoticeOutput(); 1.452 + } else if (fileName.equals(WARNING_OUTPUT)) { 1.453 + return getWarningOutput(); 1.454 + } else if (fileName.equals(STANDARD_OUTPUT)) { 1.455 + return getStandardOutput(); 1.456 + } 1.457 + try { 1.458 + File file = new File(fileName); 1.459 + if ( !file.exists() ) { 1.460 + System.out.println("\n" + "FILE DOES NOT EXIST: " + fileName); 1.461 + } 1.462 + BufferedReader in = new BufferedReader(new FileReader(file)); 1.463 + 1.464 + // Create an array of characters the size of the file 1.465 + char[] allChars = new char[(int)file.length()]; 1.466 + 1.467 + // Read the characters into the allChars array 1.468 + in.read(allChars, 0, (int)file.length()); 1.469 + in.close(); 1.470 + 1.471 + // Convert to a string 1.472 + String allCharsString = new String(allChars); 1.473 + return allCharsString; 1.474 + } catch (FileNotFoundException e) { 1.475 + System.err.println(e); 1.476 + throw new Error("File not found: " + fileName); 1.477 + } catch (IOException e) { 1.478 + System.err.println(e); 1.479 + throw new Error("Error reading file: " + fileName); 1.480 + } 1.481 + } 1.482 + 1.483 + /** 1.484 + * Compare the two given files. 1.485 + * 1.486 + * @param file1 the first file to compare. 1.487 + * @param file2 the second file to compare. 1.488 + * @param throwErrorIFNoMatch flag to indicate whether or not to throw 1.489 + * an error if the files do not match. 1.490 + * @return true if the files are the same and false otherwise. 1.491 + */ 1.492 + public boolean diff(String file1, String file2, boolean throwErrorIFNoMatch) throws Error { 1.493 + String file1Contents = readFileToString(file1); 1.494 + String file2Contents = readFileToString(file2); 1.495 + numTestsRun++; 1.496 + if (file1Contents.trim().compareTo(file2Contents.trim()) == 0) { 1.497 + System.out.println("Diff successful: " + file1 + ", " + file2); 1.498 + numTestsPassed++; 1.499 + return true; 1.500 + } else if (throwErrorIFNoMatch) { 1.501 + throw new Error("Diff failed: " + file1 + ", " + file2); 1.502 + } else { 1.503 + return false; 1.504 + } 1.505 + } 1.506 + 1.507 + /** 1.508 + * Search for the string in the given file and return true 1.509 + * if the string was found. 1.510 + * If exactNewlineMatch is false, newlines will be normalized 1.511 + * before the comparison. 1.512 + * 1.513 + * @param fileString the contents of the file to search through 1.514 + * @param stringToFind the string to search for 1.515 + * @return true if the string was found 1.516 + */ 1.517 + private boolean findString(String fileString, String stringToFind) { 1.518 + if (exactNewlineMatch) { 1.519 + return fileString.indexOf(stringToFind) >= 0; 1.520 + } else { 1.521 + return fileString.replace(NL, "\n").indexOf(stringToFind.replace(NL, "\n")) >= 0; 1.522 + } 1.523 + } 1.524 + 1.525 + 1.526 + /** 1.527 + * Return the standard output. 1.528 + * @return the standard output 1.529 + */ 1.530 + public String getStandardOutput() { 1.531 + return standardOut.toString(); 1.532 + } 1.533 + 1.534 + /** 1.535 + * Return the error output. 1.536 + * @return the error output 1.537 + */ 1.538 + public String getErrorOutput() { 1.539 + return errors.getBuffer().toString(); 1.540 + } 1.541 + 1.542 + /** 1.543 + * Return the notice output. 1.544 + * @return the notice output 1.545 + */ 1.546 + public String getNoticeOutput() { 1.547 + return notices.getBuffer().toString(); 1.548 + } 1.549 + 1.550 + /** 1.551 + * Return the warning output. 1.552 + * @return the warning output 1.553 + */ 1.554 + public String getWarningOutput() { 1.555 + return warnings.getBuffer().toString(); 1.556 + } 1.557 + 1.558 + /** 1.559 + * A utility to copy a directory from one place to another. 1.560 + * We may possibly want to move this to our doclet toolkit in 1.561 + * the near future and maintain it from there. 1.562 + * 1.563 + * @param targetDir the directory to copy. 1.564 + * @param destDir the destination to copy the directory to. 1.565 + */ 1.566 + public static void copyDir(String targetDir, String destDir) { 1.567 + if (targetDir.endsWith("SCCS")) { 1.568 + return; 1.569 + } 1.570 + try { 1.571 + File targetDirObj = new File(targetDir); 1.572 + File destDirParentObj = new File(destDir); 1.573 + File destDirObj = new File(destDirParentObj, targetDirObj.getName()); 1.574 + if (! destDirParentObj.exists()) { 1.575 + destDirParentObj.mkdir(); 1.576 + } 1.577 + if (! destDirObj.exists()) { 1.578 + destDirObj.mkdir(); 1.579 + } 1.580 + String[] files = targetDirObj.list(); 1.581 + for (int i = 0; i < files.length; i++) { 1.582 + File srcFile = new File(targetDirObj, files[i]); 1.583 + File destFile = new File(destDirObj, files[i]); 1.584 + if (srcFile.isFile()) { 1.585 + System.out.println("Copying " + srcFile + " to " + destFile); 1.586 + copyFile(destFile, srcFile); 1.587 + } else if(srcFile.isDirectory()) { 1.588 + copyDir(srcFile.getAbsolutePath(), destDirObj.getAbsolutePath()); 1.589 + } 1.590 + } 1.591 + } catch (IOException exc) { 1.592 + throw new Error("Could not copy " + targetDir + " to " + destDir); 1.593 + } 1.594 + } 1.595 + 1.596 + /** 1.597 + * Copy source file to destination file. 1.598 + * 1.599 + * @throws SecurityException 1.600 + * @throws IOException 1.601 + */ 1.602 + public static void copyFile(File destfile, File srcfile) 1.603 + throws IOException { 1.604 + byte[] bytearr = new byte[512]; 1.605 + int len = 0; 1.606 + FileInputStream input = new FileInputStream(srcfile); 1.607 + File destDir = destfile.getParentFile(); 1.608 + destDir.mkdirs(); 1.609 + FileOutputStream output = new FileOutputStream(destfile); 1.610 + try { 1.611 + while ((len = input.read(bytearr)) != -1) { 1.612 + output.write(bytearr, 0, len); 1.613 + } 1.614 + } catch (FileNotFoundException exc) { 1.615 + } catch (SecurityException exc) { 1.616 + } finally { 1.617 + input.close(); 1.618 + output.close(); 1.619 + } 1.620 + } 1.621 +}