JavadocTester.java revision 173:fdfed22db054
198944Sobrien/*
298944Sobrien * Copyright 2002-2008 Sun Microsystems, Inc.  All Rights Reserved.
398944Sobrien * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
498944Sobrien *
598944Sobrien * This code is free software; you can redistribute it and/or modify it
698944Sobrien * under the terms of the GNU General Public License version 2 only, as
798944Sobrien * published by the Free Software Foundation.
898944Sobrien *
998944Sobrien * This code is distributed in the hope that it will be useful, but WITHOUT
1098944Sobrien * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1198944Sobrien * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1298944Sobrien * version 2 for more details (a copy is included in the LICENSE file that
1398944Sobrien * accompanied this code).
1498944Sobrien *
1598944Sobrien * You should have received a copy of the GNU General Public License version
1698944Sobrien * 2 along with this work; if not, write to the Free Software Foundation,
1798944Sobrien * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1898944Sobrien *
1998944Sobrien * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
2098944Sobrien * CA 95054 USA or visit www.sun.com if you need additional information or
2198944Sobrien * have any questions.
2298944Sobrien */
2398944Sobrien
2498944Sobrienimport com.sun.javadoc.*;
2598944Sobrienimport java.util.*;
2698944Sobrienimport java.io.*;
2798944Sobrien
2898944Sobrien
2998944Sobrien/**
30130803Smarcel * Runs javadoc and then runs regression tests on the resulting output.
3198944Sobrien * This class currently contains three tests:
3298944Sobrien * <ul>
3398944Sobrien * <li> String search: Reads each file, complete with newlines,
3498944Sobrien *      into a string.  Lets you search for strings that contain
3598944Sobrien *      newlines.  String matching is case-sensitive.
3698944Sobrien *      You can run javadoc multiple times with different arguments,
3798944Sobrien *      generating output into different destination directories, and
3898944Sobrien *      then perform a different array of tests on each one.
3998944Sobrien *      To do this, the run method accepts a test array for testing
4098944Sobrien *      that a string is found, and a negated test array for testing
4198944Sobrien *      that a string is not found.
4298944Sobrien * <li> Run diffs: Iterate through the list of given file pairs
4398944Sobrien *      and diff the pairs.
4498944Sobrien * <li> Check exit code: Check the exit code of Javadoc and
4598944Sobrien *      record whether the test passed or failed.
4698944Sobrien * </ul>
4798944Sobrien *
4898944Sobrien * @author Doug Kramer
4998944Sobrien * @author Jamie Ho
5098944Sobrien * @since 1.4.2
5198944Sobrien */
5298944Sobrienpublic abstract class JavadocTester {
5398944Sobrien
5498944Sobrien    protected static final String FS = System.getProperty("file.separator");
5598944Sobrien    protected static final String PS = System.getProperty("path.separator");
5698944Sobrien    protected static final String NL = System.getProperty("line.separator");
5798944Sobrien    protected static final String SRC_DIR = System.getProperty("test.src", ".");
5898944Sobrien    protected static final String JAVA_VERSION = System.getProperty("java.version");
5998944Sobrien    protected static final String[][] NO_TEST = new String[][] {};
6098944Sobrien
6198944Sobrien    /**
6298944Sobrien     * Use this as the file name in the test array when you want to search
6398944Sobrien     * for a string in the error output.
6498944Sobrien     */
6598944Sobrien    public static final String ERROR_OUTPUT = "ERROR_OUTPUT";
6698944Sobrien
6798944Sobrien    /**
6898944Sobrien     * Use this as the file name in the test array when you want to search
6998944Sobrien     * for a string in the notice output.
7098944Sobrien     */
7198944Sobrien    public static final String NOTICE_OUTPUT = "NOTICE_OUTPUT";
7298944Sobrien
7398944Sobrien    /**
7498944Sobrien     * Use this as the file name in the test array when you want to search
7598944Sobrien     * for a string in the warning output.
7698944Sobrien     */
7798944Sobrien    public static final String WARNING_OUTPUT = "WARNING_OUTPUT";
7898944Sobrien
7998944Sobrien    /**
8098944Sobrien     * Use this as the file name in the test array when you want to search
8198944Sobrien     * for a string in standard output.
8298944Sobrien     */
8398944Sobrien    public static final String STANDARD_OUTPUT = "STANDARD_OUTPUT";
8498944Sobrien
8598944Sobrien    /**
8698944Sobrien     * The default doclet.
8798944Sobrien     */
8898944Sobrien    public static final String DEFAULT_DOCLET_CLASS = "com.sun.tools.doclets.formats.html.HtmlDoclet";
8998944Sobrien    public static final String DEFAULT_DOCLET_CLASS_OLD = "com.sun.tools.doclets.standard.Standard";
9098944Sobrien
9198944Sobrien    /**
9298944Sobrien     * The writer to write error messages.
9398944Sobrien     */
9498944Sobrien    public StringWriter errors;
9598944Sobrien
9698944Sobrien    /**
9798944Sobrien     * The writer to write notices.
9898944Sobrien     */
9998944Sobrien    public StringWriter notices;
10098944Sobrien
10198944Sobrien    /**
10298944Sobrien     * The writer to write warnings.
10398944Sobrien     */
10498944Sobrien    public StringWriter warnings;
10598944Sobrien
10698944Sobrien    /**
10798944Sobrien     * The buffer of warning output..
10898944Sobrien     */
10998944Sobrien    public StringBuffer standardOut;
11098944Sobrien
11198944Sobrien    /**
11298944Sobrien     * The current subtest number.
11398944Sobrien     */
11498944Sobrien    private static int numTestsRun = 0;
11598944Sobrien
11698944Sobrien    /**
11798944Sobrien     * The number of subtests passed.
11898944Sobrien     */
11998944Sobrien    private static int numTestsPassed = 0;
12098944Sobrien
12198944Sobrien    /**
12298944Sobrien     * The current run of javadoc
12398944Sobrien     */
12498944Sobrien    private static int javadocRunNum = 0;
12598944Sobrien
12698944Sobrien    /**
12798944Sobrien     * Construct a JavadocTester.
12898944Sobrien     */
12998944Sobrien    public JavadocTester() {
13098944Sobrien    }
13198944Sobrien
13298944Sobrien    /**
13398944Sobrien     * Return the bug id.
13498944Sobrien     * @return the bug id
13598944Sobrien     */
13698944Sobrien    public abstract String getBugId();
13798944Sobrien
13898944Sobrien    /**
13998944Sobrien     * Return the name of the bug.
14098944Sobrien     * @return the name of the bug
14198944Sobrien     */
14298944Sobrien    public abstract String getBugName();
14398944Sobrien
14498944Sobrien    /**
14598944Sobrien     * Execute the tests.
14698944Sobrien     *
14798944Sobrien     * @param tester           the tester to execute
14898944Sobrien     * @param args             the arguments to pass to Javadoc
14998944Sobrien     * @param testArray        the array of tests
15098944Sobrien     * @param negatedTestArray the array of negated tests
15198944Sobrien     * @return                 the return code for the execution of Javadoc
15298944Sobrien     */
15398944Sobrien    public static int run(JavadocTester tester, String[] args,
15498944Sobrien            String[][] testArray, String[][] negatedTestArray) {
15598944Sobrien        int returnCode = tester.runJavadoc(args);
15698944Sobrien        tester.runTestsOnHTML(testArray, negatedTestArray);
15798944Sobrien        return returnCode;
15898944Sobrien    }
15998944Sobrien
16098944Sobrien    /**
16198944Sobrien     * Execute Javadoc using the default doclet.
16298944Sobrien     *
16398944Sobrien     * @param args  the arguments to pass to Javadoc
16498944Sobrien     * @return      the return code from the execution of Javadoc
16598944Sobrien     */
16698944Sobrien    public int runJavadoc(String[] args) {
16798944Sobrien        float javaVersion = Float.parseFloat(JAVA_VERSION.substring(0,3));
16898944Sobrien        String docletClass = javaVersion < 1.5 ?
16998944Sobrien            DEFAULT_DOCLET_CLASS_OLD : DEFAULT_DOCLET_CLASS;
17098944Sobrien        return runJavadoc(docletClass, args);
17198944Sobrien    }
17298944Sobrien
17398944Sobrien
17498944Sobrien    /**
17598944Sobrien     * Execute Javadoc.
17698944Sobrien     *
17798944Sobrien     * @param docletClass the doclet being tested.
17898944Sobrien     * @param args  the arguments to pass to Javadoc
17998944Sobrien     * @return      the return code from the execution of Javadoc
18098944Sobrien     */
18198944Sobrien    public int runJavadoc(String docletClass, String[] args) {
18298944Sobrien        javadocRunNum++;
18398944Sobrien        if (javadocRunNum == 1) {
18498944Sobrien            System.out.println("\n" + "Running javadoc...");
18598944Sobrien        } else {
18698944Sobrien            System.out.println("\n" + "Running javadoc (run "
18798944Sobrien                                    + javadocRunNum + ")...");
18898944Sobrien        }
18998944Sobrien        initOutputBuffers();
19098944Sobrien
19198944Sobrien        ByteArrayOutputStream stdout = new ByteArrayOutputStream();
19298944Sobrien        PrintStream prev = System.out;
19398944Sobrien        System.setOut(new PrintStream(stdout));
19498944Sobrien        int returnCode = com.sun.tools.javadoc.Main.execute(
19598944Sobrien                getBugName(),
19698944Sobrien                new PrintWriter(errors, true),
19798944Sobrien                new PrintWriter(warnings, true),
19898944Sobrien                new PrintWriter(notices, true),
19998944Sobrien                docletClass,
20098944Sobrien                getClass().getClassLoader(),
20198944Sobrien                args);
20298944Sobrien        System.setOut(prev);
20398944Sobrien        standardOut = new StringBuffer(stdout.toString());
20498944Sobrien        printJavadocOutput();
20598944Sobrien        return returnCode;
20698944Sobrien    }
20798944Sobrien
208130803Smarcel    /**
209130803Smarcel     * Create new string writer buffers
210130803Smarcel     */
211130803Smarcel    private void initOutputBuffers() {
212130803Smarcel        errors   = new StringWriter();
213130803Smarcel        notices  = new StringWriter();
214130803Smarcel        warnings = new StringWriter();
215130803Smarcel    }
216130803Smarcel
217130803Smarcel    /**
218130803Smarcel     * Run array of tests on the resulting HTML.
219130803Smarcel     * This method accepts a testArray for testing that a string is found
220130803Smarcel     * and a negatedTestArray for testing that a string is not found.
221130803Smarcel     *
222130803Smarcel     * @param testArray         the array of tests
223130803Smarcel     * @param negatedTestArray  the array of negated tests
224130803Smarcel     */
225130803Smarcel    public void runTestsOnHTML(String[][] testArray, String[][] negatedTestArray) {
226130803Smarcel        runTestsOnHTML(testArray, false);
227130803Smarcel        runTestsOnHTML(negatedTestArray, true);
228130803Smarcel    }
229130803Smarcel
230130803Smarcel    /**
231130803Smarcel     * Run the array of tests on the resulting HTML.
232130803Smarcel     *
233130803Smarcel     * @param testArray the array of tests
234130803Smarcel     * @param isNegated true if test is negated; false otherwise
235130803Smarcel     */
236130803Smarcel    private void runTestsOnHTML(String[][] testArray , boolean isNegated) {
237130803Smarcel        for (int i = 0; i < testArray.length; i++) {
238130803Smarcel
239130803Smarcel            numTestsRun++;
240130803Smarcel
24198944Sobrien            System.out.print("Running subtest #" + numTestsRun + "... ");
242130803Smarcel
243130803Smarcel            // Get string to find
244130803Smarcel            String stringToFind = testArray[i][1];
245130803Smarcel
246130803Smarcel            // Read contents of file into a string
247130803Smarcel            String fileString;
248130803Smarcel            try {
249130803Smarcel                fileString = readFileToString(testArray[i][0]);
25098944Sobrien            } catch (Error e) {
251130803Smarcel                if (isNegated) {
25298944Sobrien                  numTestsPassed += 1;
25398944Sobrien                  System.out.println("Passed\n not found:\n"
25498944Sobrien                    + stringToFind + " in non-existent " + testArray[i][0] + "\n");
255130803Smarcel                  continue;
25698944Sobrien                }
25798944Sobrien                throw e;
258130803Smarcel            }
259130803Smarcel            // Find string in file's contents
26098944Sobrien            boolean isFound = findString(fileString, stringToFind);
26198944Sobrien            if ((isNegated && !isFound) || (!isNegated && isFound) ) {
26298944Sobrien                numTestsPassed += 1;
26398944Sobrien                System.out.println( "Passed" + "\n"
26498944Sobrien                                    + (isNegated ? "not found:" : "found:") + "\n"
26598944Sobrien                                    + stringToFind + " in " + testArray[i][0] + "\n");
26698944Sobrien            } else {
26798944Sobrien                System.out.println( "FAILED" + "\n"
268130803Smarcel                                    + "for bug " + getBugId()
269130803Smarcel                                    + " (" + getBugName() + ")" + "\n"
270130803Smarcel                                    + "when searching for:" + "\n"
271130803Smarcel                                    + stringToFind
272130803Smarcel                                    + " in " + testArray[i][0] + "\n");
27398944Sobrien            }
27498944Sobrien        }
27598944Sobrien    }
27698944Sobrien
27798944Sobrien    /**
27898944Sobrien     * Iterate through the list of given file pairs and diff each file.
27998944Sobrien     *
28098944Sobrien     * @param filePairs the pairs of files to diff.
28198944Sobrien     * @throws an Error is thrown if any differences are found between
28298944Sobrien     * file pairs.
28398944Sobrien     */
28498944Sobrien    public void runDiffs(String[][] filePairs) throws Error {
28598944Sobrien        runDiffs(filePairs, true);
28698944Sobrien    }
28798944Sobrien
288130803Smarcel    /**
289130803Smarcel     * Iterate through the list of given file pairs and diff each file.
29098944Sobrien     *
29198944Sobrien     * @param filePairs the pairs of files to diff.
29298944Sobrien     * @param throwErrorIFNoMatch flag to indicate whether or not to throw
29398944Sobrien     * an error if the files do not match.
29498944Sobrien     *
29598944Sobrien     * @throws an Error is thrown if any differences are found between
29698944Sobrien     * file pairs and throwErrorIFNoMatch is true.
297130803Smarcel     */
29898944Sobrien    public void runDiffs(String[][] filePairs, boolean throwErrorIfNoMatch) throws Error {
29998944Sobrien        for (int i = 0; i < filePairs.length; i++) {
30098944Sobrien            diff(filePairs[i][0], filePairs[i][1], throwErrorIfNoMatch);
30198944Sobrien        }
30298944Sobrien    }
30398944Sobrien
304130803Smarcel    /**
305130803Smarcel     * Check the exit code of Javadoc and record whether the test passed
306130803Smarcel     * or failed.
307130803Smarcel     *
30898944Sobrien     * @param expectedExitCode The exit code that is required for the test
30998944Sobrien     * to pass.
31098944Sobrien     * @param actualExitCode The actual exit code from the previous run of
31198944Sobrien     * Javadoc.
31298944Sobrien     */
31398944Sobrien    public void checkExitCode(int expectedExitCode, int actualExitCode) {
314130803Smarcel        numTestsRun++;
315130803Smarcel        if (expectedExitCode == actualExitCode) {
31698944Sobrien            System.out.println( "Passed" + "\n" + " got return code " +
31798944Sobrien                actualExitCode);
31898944Sobrien            numTestsPassed++;
31998944Sobrien        } else {
32098944Sobrien            System.out.println( "FAILED" + "\n" + "for bug " + getBugId()
32198944Sobrien                + " (" + getBugName() + ")" + "\n" + "Expected return code " +
32298944Sobrien                expectedExitCode + " but got " + actualExitCode);
32398944Sobrien        }
32498944Sobrien    }
32598944Sobrien
32698944Sobrien    /**
32798944Sobrien     * Print a summary of the test results.
32898944Sobrien     */
32998944Sobrien    protected void printSummary() {
33098944Sobrien        if ( numTestsRun != 0 && numTestsPassed == numTestsRun ) {
33198944Sobrien            // Test passed
332130803Smarcel            System.out.println("\n" + "All " + numTestsPassed
333130803Smarcel                                             + " subtests passed");
33498944Sobrien        } else {
33598944Sobrien            // Test failed
33698944Sobrien            throw new Error("\n" + (numTestsRun - numTestsPassed)
33798944Sobrien                                    + " of " + (numTestsRun)
33898944Sobrien                                    + " subtests failed for bug " + getBugId()
33998944Sobrien                                    + " (" + getBugName() + ")" + "\n");
34098944Sobrien        }
34198944Sobrien    }
34298944Sobrien
34398944Sobrien    /**
34498944Sobrien     * Print the output stored in the buffers.
34598944Sobrien     */
34698944Sobrien    protected void printJavadocOutput() {
34798944Sobrien        System.out.println(STANDARD_OUTPUT + " : \n" + getStandardOutput());
34898944Sobrien        System.err.println(ERROR_OUTPUT + " : \n" + getErrorOutput());
34998944Sobrien        System.err.println(WARNING_OUTPUT + " : \n" + getWarningOutput());
35098944Sobrien        System.out.println(NOTICE_OUTPUT + " : \n" + getNoticeOutput());
35198944Sobrien    }
35298944Sobrien
35398944Sobrien    /**
35498944Sobrien     * Read the file and return it as a string.
35598944Sobrien     *
35698944Sobrien     * @param fileName  the name of the file to read
35798944Sobrien     * @return          the file in string format
35898944Sobrien     */
35998944Sobrien    public String readFileToString(String fileName) throws Error {
36098944Sobrien        if (fileName.equals(ERROR_OUTPUT)) {
36198944Sobrien            return getErrorOutput();
36298944Sobrien        } else if (fileName.equals(NOTICE_OUTPUT)) {
36398944Sobrien            return getNoticeOutput();
36498944Sobrien        } else if (fileName.equals(WARNING_OUTPUT)) {
36598944Sobrien            return getWarningOutput();
36698944Sobrien        } else if (fileName.equals(STANDARD_OUTPUT)) {
36798944Sobrien            return getStandardOutput();
36898944Sobrien        }
36998944Sobrien        try {
37098944Sobrien            File file = new File(fileName);
37198944Sobrien            if ( !file.exists() ) {
37298944Sobrien                System.out.println("\n" + "FILE DOES NOT EXIST: " + fileName);
37398944Sobrien            }
37498944Sobrien            BufferedReader in = new BufferedReader(new FileReader(file));
37598944Sobrien
37698944Sobrien            // Create an array of characters the size of the file
37798944Sobrien            char[] allChars = new char[(int)file.length()];
37898944Sobrien
37998944Sobrien            // Read the characters into the allChars array
38098944Sobrien            in.read(allChars, 0, (int)file.length());
38198944Sobrien            in.close();
38298944Sobrien
38398944Sobrien            // Convert to a string
38498944Sobrien            String allCharsString = new String(allChars);
38598944Sobrien            return allCharsString;
38698944Sobrien        } catch (FileNotFoundException e) {
38798944Sobrien            System.err.println(e);
38898944Sobrien            throw new Error("File not found: " + fileName);
38998944Sobrien        } catch (IOException e) {
39098944Sobrien            System.err.println(e);
39198944Sobrien            throw new Error("Error reading file: " + fileName);
392130803Smarcel        }
393130803Smarcel    }
39498944Sobrien
39598944Sobrien    /**
39698944Sobrien     * Compare the two given files.
39798944Sobrien     *
39898944Sobrien     * @param file1 the first file to compare.
39998944Sobrien     * @param file2 the second file to compare.
40098944Sobrien     * @param throwErrorIFNoMatch flag to indicate whether or not to throw
40198944Sobrien     * an error if the files do not match.
40298944Sobrien     * @return true if the files are the same and false otherwise.
40398944Sobrien     */
40498944Sobrien    public boolean diff(String file1, String file2, boolean throwErrorIFNoMatch) throws Error {
40598944Sobrien        String file1Contents = readFileToString(file1);
40698944Sobrien        String file2Contents = readFileToString(file2);
40798944Sobrien        numTestsRun++;
40898944Sobrien        if (file1Contents.trim().compareTo(file2Contents.trim()) == 0) {
40998944Sobrien            System.out.println("Diff successful: " + file1 + ", " + file2);
41098944Sobrien            numTestsPassed++;
41198944Sobrien            return true;
41298944Sobrien        } else if (throwErrorIFNoMatch) {
41398944Sobrien            throw new Error("Diff failed: " + file1 + ", " + file2);
41498944Sobrien        } else {
41598944Sobrien            return false;
41698944Sobrien        }
41798944Sobrien    }
41898944Sobrien
41998944Sobrien    /**
42098944Sobrien     * Search for the string in the given file and return true
42198944Sobrien     * if the string was found.
42298944Sobrien     *
42398944Sobrien     * @param fileString    the contents of the file to search through
42498944Sobrien     * @param stringToFind  the string to search for
42598944Sobrien     * @return              true if the string was found
42698944Sobrien     */
42798944Sobrien    private boolean findString(String fileString, String stringToFind) {
42898944Sobrien        return fileString.indexOf(stringToFind) >= 0;
42998944Sobrien    }
43098944Sobrien
431130803Smarcel    /**
43298944Sobrien     * Return the standard output.
43398944Sobrien     * @return the standard output
434130803Smarcel     */
43598944Sobrien    public String getStandardOutput() {
43698944Sobrien        return standardOut.toString();
43798944Sobrien    }
43898944Sobrien
43998944Sobrien    /**
44098944Sobrien     * Return the error output.
44198944Sobrien     * @return the error output
44298944Sobrien     */
44398944Sobrien    public String getErrorOutput() {
44498944Sobrien        return errors.getBuffer().toString();
44598944Sobrien    }
44698944Sobrien
44798944Sobrien    /**
44898944Sobrien     * Return the notice output.
44998944Sobrien     * @return the notice output
45098944Sobrien     */
45198944Sobrien    public String getNoticeOutput() {
45298944Sobrien        return notices.getBuffer().toString();
45398944Sobrien    }
45498944Sobrien
45598944Sobrien    /**
45698944Sobrien     * Return the warning output.
45798944Sobrien     * @return the warning output
45898944Sobrien     */
45998944Sobrien    public String getWarningOutput() {
46098944Sobrien        return warnings.getBuffer().toString();
46198944Sobrien    }
46298944Sobrien
46398944Sobrien    /**
46498944Sobrien     * A utility to copy a directory from one place to another.
46598944Sobrien     * We may possibly want to move this to our doclet toolkit in
46698944Sobrien     * the near future and maintain it from there.
46798944Sobrien     *
46898944Sobrien     * @param targetDir the directory to copy.
46998944Sobrien     * @param destDir the destination to copy the directory to.
47098944Sobrien     */
47198944Sobrien    public static void copyDir(String targetDir, String destDir) {
47298944Sobrien        if (targetDir.endsWith("SCCS")) {
47398944Sobrien            return;
47498944Sobrien        }
47598944Sobrien        try {
47698944Sobrien            File targetDirObj = new File(targetDir);
47798944Sobrien            File destDirParentObj = new File(destDir);
47898944Sobrien            File destDirObj = new File(destDirParentObj, targetDirObj.getName());
47998944Sobrien            if (! destDirParentObj.exists()) {
48098944Sobrien                destDirParentObj.mkdir();
48198944Sobrien            }
48298944Sobrien            if (! destDirObj.exists()) {
48398944Sobrien                destDirObj.mkdir();
48498944Sobrien            }
48598944Sobrien            String[] files = targetDirObj.list();
48698944Sobrien            for (int i = 0; i < files.length; i++) {
48798944Sobrien                File srcFile = new File(targetDirObj, files[i]);
48898944Sobrien                File destFile = new File(destDirObj, files[i]);
48998944Sobrien                if (srcFile.isFile()) {
49098944Sobrien                    System.out.println("Copying " + srcFile + " to " + destFile);
49198944Sobrien                        copyFile(destFile, srcFile);
49298944Sobrien                } else if(srcFile.isDirectory()) {
49398944Sobrien                    copyDir(srcFile.getAbsolutePath(), destDirObj.getAbsolutePath());
49498944Sobrien                }
49598944Sobrien            }
49698944Sobrien        } catch (IOException exc) {
49798944Sobrien            throw new Error("Could not copy " + targetDir + " to " + destDir);
49898944Sobrien        }
49998944Sobrien    }
50098944Sobrien
50198944Sobrien    /**
50298944Sobrien     * Copy source file to destination file.
50398944Sobrien     *
50498944Sobrien     * @throws SecurityException
50598944Sobrien     * @throws IOException
50698944Sobrien     */
50798944Sobrien    public static void copyFile(File destfile, File srcfile)
50898944Sobrien        throws IOException {
50998944Sobrien        byte[] bytearr = new byte[512];
51098944Sobrien        int len = 0;
51198944Sobrien        FileInputStream input = new FileInputStream(srcfile);
51298944Sobrien        File destDir = destfile.getParentFile();
51398944Sobrien        destDir.mkdirs();
51498944Sobrien        FileOutputStream output = new FileOutputStream(destfile);
51598944Sobrien        try {
51698944Sobrien            while ((len = input.read(bytearr)) != -1) {
51798944Sobrien                output.write(bytearr, 0, len);
51898944Sobrien            }
51998944Sobrien        } catch (FileNotFoundException exc) {
52098944Sobrien        } catch (SecurityException exc) {
52198944Sobrien        } finally {
52298944Sobrien            input.close();
52398944Sobrien            output.close();
52498944Sobrien        }
52598944Sobrien    }
52698944Sobrien}
52798944Sobrien