(no commit message)
[utils] / support / test / org / wamblee / test / FileSystemUtils.java
1 /*
2  * Copyright 2006 the original author or authors.
3  * 
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  * 
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  * 
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package org.wamblee.test;
17
18 import java.io.File;
19 import java.io.UnsupportedEncodingException;
20 import java.net.URL;
21 import java.net.URLDecoder;
22 import java.security.CodeSource;
23
24 import junit.framework.TestCase;
25
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28
29 /**
30  * File system utilities.
31  */
32 public final class FileSystemUtils {
33
34     private static final Log LOG = LogFactory.getLog(FileSystemUtils.class);
35
36     /**
37      * Test output directory relative to the sub project.
38      */
39     private static final String TEST_OUTPUT_DIR = "resources/testoutput";
40
41     /*
42      * Disabled.
43      * 
44      */
45     private FileSystemUtils() {
46         // Empty
47     }
48
49     /**
50      * Deletes a directory recursively. The test case will fail if the directory
51      * does not exist or if deletion fails.
52      * 
53      * @param aDir
54      *            Directory to delete.
55      */
56     public static void deleteDirRecursively(String aDir) {
57         deleteDirRecursively(new File(aDir));
58     }
59
60     /**
61      * Deletes a directory recursively. See {@link #deleteDirRecursively}.
62      * 
63      * @param aDir
64      *            Directory.
65      */
66     public static void deleteDirRecursively(File aDir) {
67         TestCase.assertTrue(aDir.isDirectory());
68
69         for (File file: aDir.listFiles()) {
70             if (file.isDirectory()) {
71                 deleteDirRecursively(file);
72             } else {
73                 delete(file);
74             }
75         }
76
77         delete(aDir);
78     }
79
80     /**
81      * Deletes a file or directory. The test case will fail if the file or
82      * directory does not exist or if deletion fails. Deletion of a non-empty
83      * directory will always fail.
84      * 
85      * @param aFile
86      *            File or directory to delete.
87      */
88     public static void delete(File aFile) {
89         TestCase.assertTrue(aFile.delete());
90     }
91
92     /**
93      * Gets a path relative to a sub project. This utility should be used to
94      * easily access file paths within a subproject without requiring any
95      * specific Eclipse configuration.
96      * 
97      * @param aRelativePath
98      *            Relative path.
99      * @param aTestClass
100      *            Test class.
101      */
102     public static File getPath(String aRelativePath, Class aTestClass) {
103         CodeSource source = aTestClass.getProtectionDomain().getCodeSource();
104         if (source == null) {
105             LOG.warn("Could not obtain path for '" + aRelativePath
106                     + "' for class " + aTestClass
107                     + ", using relative path as is");
108             return new File(aRelativePath);
109         }
110         URL location = source.getLocation();
111         String protocol = location.getProtocol();
112         if (!protocol.equals("file")) {
113             return new File(aRelativePath);
114         }
115
116         String path = location.getPath();
117         try {
118             path = URLDecoder.decode(location.getPath(), "UTF-8");
119         } catch (UnsupportedEncodingException e) {
120             // ignore it.. just don't decode
121         }
122
123         return new File(new File(path).getParentFile(), aRelativePath);
124     }
125
126     /**
127      * Ensures that a directory hierarchy exists (recursively if needed). If it
128      * is not possible to create the directory, then the test case will fail.
129      * 
130      * @param aDir
131      *            Directory to create.
132      */
133     public static void createDir(File aDir) {
134         if (aDir.exists() && !aDir.isDirectory()) {
135             TestCase.fail("'" + aDir
136                     + "' already exists and is not a directory");
137         }
138         if (aDir.exists()) {
139             return;
140         }
141         createDir(aDir.getParentFile());
142         TestCase.assertTrue("Could not create '" + aDir + "'", aDir.mkdir());
143     }
144
145     /**
146      * Gets the test output directory for a specific test class.
147      * 
148      * @param aTestClass
149      *            Test class.
150      * @return Test output directory.
151      */
152     public static File getTestOutputDir(Class aTestClass) {
153         File file = getPath(TEST_OUTPUT_DIR, aTestClass);
154         String packageName = aTestClass.getPackage().getName();
155         String packagePath = packageName.replaceAll("\\.", "/");
156         return new File(file, packagePath);
157     }
158
159     /**
160      * Creates a directory hierarchy for the output directory of a test class if
161      * needed.
162      * 
163      * @param aTestClass
164      *            Test class
165      * @return Test directory.
166      */
167     public static File createTestOutputDir(Class aTestClass) {
168         File file = getTestOutputDir(aTestClass);
169         createDir(file);
170         return file;
171     }
172
173     /**
174      * Gets a test output file name. This returns a File object representing the
175      * output file and ensures that the directory where the file will be created
176      * already exists.
177      * 
178      * @param aName
179      *            Name of the file.
180      * @param aTestClass
181      *            Test class.
182      * @return File.
183      */
184     public static File getTestOutputFile(String aName, Class aTestClass) {
185         File file = new File(getTestOutputDir(aTestClass), aName);
186         createDir(file.getParentFile());
187         return file;
188     }
189 }