3e36219d453d80d3a2125ee4d562356cb624693d
[utils] / support / src / test / java / org / wamblee / io / 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.io;
17
18 import java.io.File;
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.io.UnsupportedEncodingException;
22 import java.net.URL;
23 import java.net.URLDecoder;
24 import java.security.CodeSource;
25
26 import junit.framework.TestCase;
27
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30
31 /**
32  * File system utilities.
33  *
34  * @author Erik Brakkee
35  */
36 public final class FileSystemUtils {
37
38     private static final Log LOG = LogFactory.getLog(FileSystemUtils.class);
39
40     /**
41      * Test output directory relative to the sub project.
42      */
43     private static final String TEST_OUTPUT_DIR = "../target/testoutput";
44     
45     /**
46      * Test input directory relative to the sub project. 
47      */
48     private static final String TEST_INPUT_DIR = "../src/test/resources";
49
50     /*
51      * Disabled.
52      * 
53      */
54     private FileSystemUtils() {
55         // Empty
56     }
57
58     /**
59      * Deletes a directory recursively. The test case will fail if the directory
60      * does not exist or if deletion fails.
61      * 
62      * @param aDir
63      *            Directory to delete.
64      */
65     public static void deleteDirRecursively(String aDir) {
66         deleteDirRecursively(new File(aDir));
67     }
68
69     /**
70      * Deletes a directory recursively. See {@link #deleteDirRecursively}.
71      * 
72      * @param aDir
73      *            Directory.
74      */
75     public static void deleteDirRecursively(File aDir) {
76         TestCase.assertTrue(aDir.isDirectory());
77
78         for (File file : aDir.listFiles()) {
79             if (file.isDirectory()) {
80                 deleteDirRecursively(file);
81             } else {
82                 delete(file);
83             }
84         }
85
86         delete(aDir);
87     }
88
89     /**
90      * Deletes a file or directory. The test case will fail if the file or
91      * directory does not exist or if deletion fails. Deletion of a non-empty
92      * directory will always fail.
93      * 
94      * @param aFile
95      *            File or directory to delete.
96      */
97     public static void delete(File aFile) {
98         TestCase.assertTrue(aFile.delete());
99     }
100
101     /**
102      * Gets a path relative to a sub project. This utility should be used to
103      * easily access file paths within a subproject without requiring any
104      * specific Eclipse configuration.
105      * 
106      * @param aRelativePath
107      *            Relative path.
108      * @param aTestClass
109      *            Test class.
110      */
111     public static File getPath(String aRelativePath, Class aTestClass) {
112         CodeSource source = aTestClass.getProtectionDomain().getCodeSource();
113         if (source == null) {
114             LOG.warn("Could not obtain path for '" + aRelativePath
115                     + "' for class " + aTestClass
116                     + ", using relative path as is");
117             return new File(aRelativePath);
118         }
119         URL location = source.getLocation();
120         String protocol = location.getProtocol();
121         if (!protocol.equals("file")) {
122             LOG.warn("protocol is not 'file': " + location);
123             return new File(aRelativePath);
124         }
125
126         String path = location.getPath();
127         try {
128             path = URLDecoder.decode(location.getPath(), "UTF-8");
129         } catch (UnsupportedEncodingException e) {
130             // ignore it.. just don't decode
131             LOG.warn("Decoding path failed: '" + location.getPath() + "'", e );
132         }
133
134         return new File(new File(path).getParentFile(), aRelativePath);
135     }
136
137     /**
138      * Ensures that a directory hierarchy exists (recursively if needed). If it
139      * is not possible to create the directory, then the test case will fail.
140      * 
141      * @param aDir
142      *            Directory to create.
143      */
144     public static void createDir(File aDir) {
145         if (aDir.exists() && !aDir.isDirectory()) {
146             TestCase.fail("'" + aDir
147                     + "' already exists and is not a directory");
148         }
149         if (aDir.exists()) {
150             return;
151         }
152         createDir(aDir.getParentFile());
153         TestCase.assertTrue("Could not create '" + aDir + "'", aDir.mkdir());
154     }
155
156     /**
157      * Gets the test output directory for a specific test class.
158      * 
159      * @param aTestClass
160      *            Test class.
161      * @return Test output directory.
162      */
163     public static File getTestOutputDir(Class aTestClass) {
164         File file = getPath(TEST_OUTPUT_DIR, aTestClass);
165         String packageName = aTestClass.getPackage().getName();
166         String packagePath = packageName.replaceAll("\\.", "/");
167         return new File(file, packagePath);
168     }
169     
170     /**
171      * Gets the test input directory for a specific test class.
172      * 
173      * @param aTestClass
174      *            Test class.
175      * @return Test input directory.
176      */
177     public static File getTestInputDir(Class aTestClass) {
178         File file = getPath(TEST_INPUT_DIR, aTestClass);
179         String packageName = aTestClass.getPackage().getName();
180         String packagePath = packageName.replaceAll("\\.", "/");
181         return new File(file, packagePath);
182     }
183
184     /**
185      * Creates a directory hierarchy for the output directory of a test class if
186      * needed.
187      * 
188      * @param aTestClass
189      *            Test class
190      * @return Test directory.
191      */
192     public static File createTestOutputDir(Class aTestClass) {
193         File file = getTestOutputDir(aTestClass);
194         createDir(file);
195         return file;
196     }
197
198     /**
199      * Gets a test output file name. This returns a File object representing the
200      * output file and ensures that the directory where the file will be created
201      * already exists.
202      * 
203      * @param aName
204      *            Name of the file.
205      * @param aTestClass
206      *            Test class.
207      * @return File.
208      */
209     public static File getTestOutputFile(String aName, Class aTestClass) {
210         File file = new File(getTestOutputDir(aTestClass), aName);
211         createDir(file.getParentFile());
212         return file;
213     }
214
215     public static String read(InputStream aIs) throws IOException {
216         try {
217             StringBuffer buffer = new StringBuffer();
218             int c;
219             while ((c = aIs.read()) != -1) {
220                 buffer.append((char)c);
221             }
222             return buffer.toString();
223         } finally {
224             aIs.close();
225         }
226     }
227 }