X-Git-Url: http://wamblee.org/gitweb/?a=blobdiff_plain;f=support%2Fgeneral%2Fsrc%2Ftest%2Fjava%2Forg%2Fwamblee%2Fio%2FFileSystemUtils.java;fp=support%2Fgeneral%2Fsrc%2Ftest%2Fjava%2Forg%2Fwamblee%2Fio%2FFileSystemUtils.java;h=ad3b4e208d27e51960b18c41ed93c939353da2a9;hb=32a62ca2c752e33a7873ac868a7a1f289caedcd4;hp=0000000000000000000000000000000000000000;hpb=d2bdf4e813c6a3964958c87b2ce56eaadf8a1f0a;p=utils diff --git a/support/general/src/test/java/org/wamblee/io/FileSystemUtils.java b/support/general/src/test/java/org/wamblee/io/FileSystemUtils.java new file mode 100644 index 00000000..ad3b4e20 --- /dev/null +++ b/support/general/src/test/java/org/wamblee/io/FileSystemUtils.java @@ -0,0 +1,369 @@ +/* + * Copyright 2006 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.wamblee.io; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.net.URL; +import java.net.URLDecoder; +import java.nio.MappedByteBuffer; +import java.nio.channels.FileChannel; +import java.security.CodeSource; + +import junit.framework.Assert; +import junit.framework.TestCase; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * File system utilities. + * + * @author Erik Brakkee + */ +public final class FileSystemUtils { + + private static final Log LOG = LogFactory.getLog(FileSystemUtils.class); + + /** + * Test output directory relative to the sub project. + */ + private static final String TEST_OUTPUT_DIR = "../target/testoutput"; + + /** + * Test input directory relative to the sub project. + */ + private static final String TEST_INPUT_DIR = "../src/test/resources"; + + /* + * Disabled. + * + */ + private FileSystemUtils() { + // Empty + } + + /** + * Deletes a directory recursively. The test case will fail if the directory + * does not exist or if deletion fails. + * + * @param aDir + * Directory to delete. + */ + public static void deleteDirRecursively(String aDir) { + deleteDirRecursively(new File(aDir)); + } + + /** + * Deletes a directory recursively. See {@link #deleteDirRecursively}. + * + * @param aDir + * Directory. + */ + public static void deleteDirRecursively(File aDir) { + TestCase.assertTrue(aDir.isDirectory()); + + for (File file : aDir.listFiles()) { + if (file.isDirectory()) { + deleteDirRecursively(file); + } else { + delete(file); + } + } + + delete(aDir); + } + + /** + * Deletes a file or directory. The test case will fail if the file or + * directory does not exist or if deletion fails. Deletion of a non-empty + * directory will always fail. + * + * @param aFile + * File or directory to delete. + */ + public static void delete(File aFile) { + TestCase.assertTrue(aFile.delete()); + } + + /** + * Gets a path relative to a sub project. This utility should be used to + * easily access file paths within a subproject without requiring any + * specific Eclipse configuration. + * + * @param aRelativePath + * Relative path. + * @param aTestClass + * Test class. + */ + public static File getPath(String aRelativePath, Class aTestClass) { + CodeSource source = aTestClass.getProtectionDomain().getCodeSource(); + if (source == null) { + LOG.warn("Could not obtain path for '" + aRelativePath + + "' for class " + aTestClass + + ", using relative path as is"); + return new File(aRelativePath); + } + URL location = source.getLocation(); + String protocol = location.getProtocol(); + if (!protocol.equals("file")) { + LOG.warn("protocol is not 'file': " + location); + return new File(aRelativePath); + } + + String path = location.getPath(); + try { + path = URLDecoder.decode(location.getPath(), "UTF-8"); + } catch (UnsupportedEncodingException e) { + // ignore it.. just don't decode + LOG.warn("Decoding path failed: '" + location.getPath() + "'", e); + } + + return new File(new File(path).getParentFile(), aRelativePath); + } + + /** + * Ensures that a directory hierarchy exists (recursively if needed). If it + * is not possible to create the directory, then the test case will fail. + * + * @param aDir + * Directory to create. + */ + public static void createDir(File aDir) { + if (aDir.exists() && !aDir.isDirectory()) { + TestCase.fail("'" + aDir + + "' already exists and is not a directory"); + } + if (aDir.exists()) { + return; + } + createDir(aDir.getParentFile()); + TestCase.assertTrue("Could not create '" + aDir + "'", aDir.mkdir()); + } + + /** + * Creates a file in a directory. + * @param aDir Directory path. Will be created if it does not exist. + * @param aName Filename. + * @param aContents Contents. + */ + public static void createFile(File aDir, String aName, InputStream aContents) { + createDir(aDir); + try { + OutputStream os = new FileOutputStream(new File(aDir, aName)); + copyStream(aContents, os); + } catch (IOException e) { + e.printStackTrace(); + TestCase.fail(e.getMessage()); + } + } + + /** + * Gets the test output directory for a specific test class. + * + * @param aTestClass + * Test class. + * @return Test output directory. + */ + public static File getTestOutputDir(Class aTestClass) { + File file = getPath(TEST_OUTPUT_DIR, aTestClass); + String className = aTestClass.getName(); + String classRelPath = className.replaceAll("\\.", "/"); + return new File(file, classRelPath); + } + + /** + * Gets the test input directory for a specific test class. + * + * @param aTestClass + * Test class. + * @return Test input directory. + */ + public static File getTestInputDir(Class aTestClass) { + File file = getPath(TEST_INPUT_DIR, aTestClass); + String packageName = aTestClass.getPackage().getName(); + String packagePath = packageName.replaceAll("\\.", "/"); + return new File(file, packagePath); + } + + /** + * Creates a directory hierarchy for the output directory of a test class if + * needed. + * + * @param aTestClass + * Test class + * @return Test directory. + */ + public static File createTestOutputDir(Class aTestClass) { + File file = getTestOutputDir(aTestClass); + createDir(file); + return file; + } + + /** + * Gets a test output file name. This returns a File object representing the + * output file and ensures that the directory where the file will be created + * already exists. + * + * @param aName + * Name of the file. + * @param aTestClass + * Test class. + * @return File. + */ + public static File getTestOutputFile(String aName, Class aTestClass) { + File file = new File(getTestOutputDir(aTestClass), aName); + createDir(file.getParentFile()); + return file; + } + + public static String read(InputStream aIs) throws IOException { + try { + StringBuffer buffer = new StringBuffer(); + int c; + while ((c = aIs.read()) != -1) { + buffer.append((char) c); + } + return buffer.toString(); + } finally { + aIs.close(); + } + } + + /** + * Copies an input stream to an output stream. + * + * @param aIs + * Input stream. + * @param aOs + * Output stream. + */ + public static void copyStream(InputStream aIs, OutputStream aOs) { + try { + int c; + while ((c = aIs.read()) != -1) { + aOs.write(c); + } + aIs.close(); + aOs.close(); + } catch (IOException e) { + e.printStackTrace(); + Assert.fail(e.getMessage()); + } + } + + /** + * Recursively copy a directory. + * + * @param aSrc + * Source directory + * @param aTarget + * Target directory. + */ + public static void copyDir(File aSrc, File aTarget) { + Assert.assertTrue(aSrc.isDirectory()); + Assert.assertTrue(!aTarget.exists()); + + aTarget.mkdirs(); + + File[] files = aSrc.listFiles(); + for (int i = 0; i < files.length; i++) { + File file = files[i]; + if (file.isDirectory()) { + if (!file.getName().equals(".svn")) { + copyDir(new File(aSrc, file.getName()), new File(aTarget, + file.getName())); + } + } else { + copyFile(file, new File(aTarget, file.getName())); + } + } + } + + /** + * Copy a file. If copying fails then the testcase will fail. + * + * @param aSrc + * Source file. + * @param aTarget + * Target file. + */ + public static void copyFile(File aSrc, File aTarget) { + + try { + FileInputStream fis = new FileInputStream(aSrc); + FileOutputStream fos = new FileOutputStream(aTarget); + FileChannel fcin = fis.getChannel(); + FileChannel fcout = fos.getChannel(); + + // map input file + + MappedByteBuffer mbb = fcin.map(FileChannel.MapMode.READ_ONLY, 0, + fcin.size()); + + // do the file copy + fcout.write(mbb); + + // finish up + + fcin.close(); + fcout.close(); + fis.close(); + fos.close(); + } catch (IOException e) { + Assert.assertTrue("Copying file " + aSrc.getPath() + " to " + + aTarget.getPath() + " failed.", false); + } + } + + /** + * Remove all files within a given directory including the directory itself. + * This only attempts to remove regular files and not directories within the + * directory. If the directory contains a nested directory, the deletion + * will fail. The test case will fail if this fails. + * + * @param aDir + * Directory to remove. + */ + public static void deleteDir(File aDir) { + cleanDir(aDir); + delete(aDir); + } + + /** + * Remove all regular files within a given directory. + * + * @param outputDirName + */ + public static void cleanDir(File aDir) { + if (!aDir.exists()) { + return; // nothing to do. + } + File[] entries = aDir.listFiles(); + for (int i = 0; i < entries.length; i++) { + File file = entries[i]; + if (file.isFile()) { + Assert.assertTrue("Could not delete " + entries[i].getPath(), + entries[i].delete()); + } + } + } +}