001: // THIS SOFTWARE IS PROVIDED BY SOFTARIS PTY.LTD. AND OTHER METABOSS
002: // CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
003: // BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
004: // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SOFTARIS PTY.LTD.
005: // OR OTHER METABOSS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
006: // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
007: // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
008: // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
009: // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
010: // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
011: // EVEN IF SOFTARIS PTY.LTD. OR OTHER METABOSS CONTRIBUTORS ARE ADVISED OF THE
012: // POSSIBILITY OF SUCH DAMAGE.
013: //
014: // Copyright 2000-2005 © Softaris Pty.Ltd. All Rights Reserved.
015: package com.metaboss.util;
016:
017: import java.io.File;
018: import java.io.FileFilter;
019: import java.io.FileNotFoundException;
020: import java.io.IOException;
021: import java.util.ArrayList;
022:
023: /** Set of useful utilites */
024: public class DirectoryUtils {
025: /** Trims tree of directories excluding specified directory. Trimming means deleting the directories without any contents. */
026: public static void trimDirectoryTree(String pTreeRootDirectoryPath)
027: throws FileNotFoundException, IOException {
028: String[] lAllChildDirectories = listAllChildDirectoriesInDirectory(pTreeRootDirectoryPath);
029: for (int i = 0; i < lAllChildDirectories.length; i++) {
030: String lChildDirectoryPath = lAllChildDirectories[i];
031: // Call this method recursively to trim possible subdirectories
032: trimDirectoryTree(lChildDirectoryPath);
033: // Delete this child itself if it is empty
034: File lChildDirectory = new File(lChildDirectoryPath);
035: String[] lGrandChildren = lChildDirectory.list();
036: if (lGrandChildren == null || lGrandChildren.length == 0)
037: lChildDirectory.delete();
038: }
039: }
040:
041: /** This utility method is almost the same as File.createTempFile() method, with the only difference is
042: * that it creates directory and not a file. */
043: public static File createTempDir(String pPrefix, String pSuffix)
044: throws IOException {
045: File lTempFile = File.createTempFile(pPrefix, pSuffix);
046: lTempFile.delete();
047: lTempFile.mkdirs();
048: return lTempFile;
049: }
050:
051: /** Copies contents of the from directory (excluding directory itself) to
052: * the destination directory (again excluding directory itself).
053: * Same files get overwritten */
054: public static void copyDirectory(String pFromDirectoryPath,
055: String pToDirectoryPath) throws FileNotFoundException,
056: IOException {
057: File lFromDirectory = new File(pFromDirectoryPath);
058: if (lFromDirectory.exists() == false
059: || lFromDirectory.isDirectory() == false)
060: throw new FileNotFoundException(pFromDirectoryPath
061: + " does not exists. Unable to copy");
062: File lToDirectory = new File(pToDirectoryPath);
063: if (lToDirectory.exists() == false
064: || lToDirectory.isDirectory() == false)
065: throw new FileNotFoundException(pToDirectoryPath
066: + " does not exists. Unable to copy");
067: // First deal with files
068: String[] lAllFiles = listAllFilesInDirectory(lFromDirectory
069: .getAbsolutePath(), new FileFilter() {
070: public boolean accept(File pPathname) {
071: return pPathname.isFile();
072: }
073: });
074: int lFromDirectoryNameLength = lFromDirectory.getAbsolutePath()
075: .length();
076: for (int i = 0; i < lAllFiles.length; i++) {
077: String lAbsoluteFromFileName = lAllFiles[i];
078: String lAbsoluteToFileName = lToDirectory.getAbsolutePath()
079: + lAbsoluteFromFileName
080: .substring(lFromDirectoryNameLength);
081: FileUtils.copyFile(lAbsoluteFromFileName,
082: lAbsoluteToFileName);
083: }
084: // Now deal with subdirectories
085: String[] lAllDirectories = listAllChildDirectoriesInDirectory(lFromDirectory
086: .getAbsolutePath());
087: for (int i = 0; i < lAllDirectories.length; i++) {
088: String lAbsoluteFromDirectoryName = lAllDirectories[i];
089: String lAbsoluteToDirectoryName = lToDirectory
090: .getAbsolutePath()
091: + lAbsoluteFromDirectoryName
092: .substring(lFromDirectoryNameLength);
093: ensureThereIsDirectory(lAbsoluteToDirectoryName);
094: copyDirectory(lAbsoluteFromDirectoryName,
095: lAbsoluteToDirectoryName);
096: }
097: }
098:
099: /** Makes sure that the clean directory exists and accessible
100: * cleans up contents of the existing directory if necessary
101: */
102: public static void ensureNewCleanDirectory(String pDirectoryPath)
103: throws IOException {
104: File lDirectory = new File(pDirectoryPath);
105: if (lDirectory.exists())
106: deleteAllDirectoryContents(lDirectory);
107: else
108: lDirectory.mkdirs();
109: }
110:
111: /** Makes sure that the directory without files exists and accessible.
112: * Cleans up contents of the existing directory if necessary. This version
113: * does not touch any subdirectories. Use ensureNewCleanDirectory() if you wish to
114: * ensure that totally clean director exists.
115: */
116: public static void ensureNewNoFilesDirectory(String pDirectoryPath)
117: throws IOException {
118: File lDirectory = new File(pDirectoryPath);
119: if (lDirectory.exists())
120: deleteAllFilesInTheDirectory(lDirectory);
121: else
122: lDirectory.mkdirs();
123: }
124:
125: /** Makes sure that the directory exists and accessible
126: * creates directory if necesary
127: */
128: public static void ensureThereIsDirectory(String pDirectoryPath) {
129: File lDirectory = new File(pDirectoryPath);
130: if (!lDirectory.exists())
131: lDirectory.mkdirs();
132: }
133:
134: /** Deletes all contents of the specified directory including directory itself */
135: public static void deleteDirectory(File pDirectory)
136: throws IOException {
137: if (!pDirectory.isDirectory())
138: throw new IllegalArgumentException(pDirectory
139: .getAbsolutePath()
140: + " is not a directory");
141: deleteAllDirectoryContents(pDirectory);
142: if (!pDirectory.delete())
143: throw new IOException("Unable to delete directory. "
144: + pDirectory.getAbsolutePath());
145: }
146:
147: /** Deletes all contents of the specified directory including directory itself.
148: * Does not fail if directory does not exist - just exist gracefully */
149: public static void deleteDirectoryIfExists(File pDirectory)
150: throws IOException {
151: if (pDirectory.exists())
152: deleteDirectory(pDirectory);
153: }
154:
155: /** Deletes all contents of the specified directory including subdirectories, but excluding the directory itself */
156: public static void deleteAllDirectoryContents(File pDirectory)
157: throws IOException {
158: if (!pDirectory.isDirectory())
159: throw new IllegalArgumentException(pDirectory
160: .getAbsolutePath()
161: + " is not a directory");
162: File[] lContainedFiles = pDirectory.listFiles();
163: if (lContainedFiles != null && lContainedFiles.length > 0) {
164: for (int i = 0; i < lContainedFiles.length; i++) {
165: if (lContainedFiles[i].isDirectory())
166: deleteAllDirectoryContents(lContainedFiles[i]);
167: if (!lContainedFiles[i].delete())
168: throw new IOException("Unable to delete file. "
169: + lContainedFiles[i].getAbsolutePath());
170: }
171: }
172: }
173:
174: /** Deletes all files in the specified directory. This excludes any subdirectories */
175: public static void deleteAllFilesInTheDirectory(File pDirectory)
176: throws IOException {
177: if (!pDirectory.isDirectory())
178: throw new IllegalArgumentException(pDirectory
179: .getAbsolutePath()
180: + " is not a directory");
181: File[] lContainedFiles = pDirectory.listFiles();
182: if (lContainedFiles != null && lContainedFiles.length > 0) {
183: for (int i = 0; i < lContainedFiles.length; i++) {
184: if (lContainedFiles[i].isFile()) {
185: if (!lContainedFiles[i].delete())
186: throw new IOException("Unable to delete file. "
187: + lContainedFiles[i].getAbsolutePath());
188: }
189: }
190: }
191: }
192:
193: /** Returns true if specified path can be deleted.
194: * @param pPathToDelete file or directory to test
195: * @return true if path is not present or can be removed. For directory
196: * being able to remove means that all it's contents are writeable including subdirectories */
197: public static boolean canDelete(File pPathToDelete) {
198: if (!pPathToDelete.exists())
199: return true; // Not present - can be removed
200: if (!pPathToDelete.canWrite())
201: return false; // Present and is not writeable - can not be removed
202: if (pPathToDelete.isFile())
203: return true; // Writeable file can be deleted
204: File[] lContainedFiles = pPathToDelete.listFiles();
205: if (lContainedFiles != null && lContainedFiles.length > 0) {
206: for (int i = 0; i < lContainedFiles.length; i++) {
207: if (!canDelete(lContainedFiles[i]))
208: return false; // One of the contained files can not be deleted
209: }
210: }
211: return true; // Passed all tests
212: }
213:
214: /** Returns true if specified path can be created.
215: * @param pPathToCreate file or directory to test
216: * @return true if path is not present and can be created */
217: public static boolean canCreate(File pPathToCreate) {
218: // Convert to absolute path
219: pPathToCreate = pPathToCreate.getAbsoluteFile();
220: if (pPathToCreate.exists())
221: return false; // Already present - can not be created
222: File lParent = pPathToCreate.getParentFile();
223: if (lParent == null)
224: return false; // No parent - can not create
225: if (!lParent.exists())
226: return canCreate(lParent); // Parent does not exists see if we can create parent
227: return lParent.canWrite();
228: }
229:
230: /** Lists all files contained in the directory and possibly subdirectories, which are
231: * satisfying given file filter. Note that subdirectories will onbly be considered if file filter accepts them
232: * @return array of strings with each element being an absolute path to the file contained in the directory */
233: public static String[] listAllFilesInDirectory(
234: String pDirectoryAbsolutePath, FileFilter pFilter)
235: throws FileNotFoundException {
236: File lDirectoryToAnalyse = new File(pDirectoryAbsolutePath);
237: if ((!lDirectoryToAnalyse.exists())
238: || (!lDirectoryToAnalyse.canRead()))
239: throw new FileNotFoundException(lDirectoryToAnalyse
240: + " does not exist or is not accessible");
241: if (!lDirectoryToAnalyse.isDirectory())
242: throw new FileNotFoundException(lDirectoryToAnalyse
243: + " is not a directory");
244: ArrayList lDir = new ArrayList();
245: File[] lFiles = lDirectoryToAnalyse.listFiles(pFilter);
246: if (lFiles != null && lFiles.length > 0) {
247: for (int i = 0; i < lFiles.length; i++) {
248: if (lFiles[i].isDirectory())
249: lDir.addAll(java.util.Arrays
250: .asList(listAllFilesInDirectory(lFiles[i]
251: .getAbsolutePath(), pFilter)));
252: else
253: lDir.add(lFiles[i].getAbsolutePath());
254: }
255: }
256: return (String[]) lDir.toArray(new String[lDir.size()]);
257: }
258:
259: /** Lists all files contained in the directory and all subdirectories in no particular order
260: * @return array of strings with each element being an absolute path to the file contained in the directory */
261: public static String[] listAllFilesInDirectory(
262: String pDirectoryAbsolutePath) throws FileNotFoundException {
263: return listAllFilesInDirectory(pDirectoryAbsolutePath,
264: new FileFilter() {
265: public boolean accept(File pPathname) {
266: return true;
267: }
268: });
269: }
270:
271: /** Lists all direct child directories contained in the directory
272: * @return array of strings with each element being an absolute path to the child directory of the specified directory */
273: public static String[] listAllChildDirectoriesInDirectory(
274: String pDirectoryAbsolutePath) throws FileNotFoundException {
275: File lDirectoryToAnalyse = new File(pDirectoryAbsolutePath);
276: if ((!lDirectoryToAnalyse.exists())
277: || (!lDirectoryToAnalyse.canRead()))
278: throw new FileNotFoundException(lDirectoryToAnalyse
279: + " does not exist or is not accessible");
280: if (!lDirectoryToAnalyse.isDirectory())
281: throw new FileNotFoundException(lDirectoryToAnalyse
282: + " is not a directory");
283: ArrayList lDir = new ArrayList();
284: File[] lFiles = lDirectoryToAnalyse.listFiles();
285: if (lFiles != null && lFiles.length > 0) {
286: for (int i = 0; i < lFiles.length; i++) {
287: File lFile = lFiles[i];
288: if (lFile.isDirectory())
289: lDir.add(lFile.getAbsolutePath());
290: }
291: }
292: return (String[]) lDir.toArray(new String[lDir.size()]);
293: }
294:
295: /** Lists all descendant directories (on any level) contained in the directory
296: * @return array of strings with each element being an absolute path to the descendant directory of the specified directory */
297: public static String[] listAllDescendantDirectoriesInDirectory(
298: String pDirectoryAbsolutePath) throws FileNotFoundException {
299: File lDirectoryToAnalyse = new File(pDirectoryAbsolutePath);
300: if ((!lDirectoryToAnalyse.exists())
301: || (!lDirectoryToAnalyse.canRead()))
302: throw new FileNotFoundException(lDirectoryToAnalyse
303: + " does not exist or is not accessible");
304: if (!lDirectoryToAnalyse.isDirectory())
305: throw new FileNotFoundException(lDirectoryToAnalyse
306: + " is not a directory");
307: ArrayList lDir = new ArrayList();
308: File[] lFiles = lDirectoryToAnalyse.listFiles();
309: if (lFiles != null && lFiles.length > 0) {
310: for (int i = 0; i < lFiles.length; i++) {
311: File lFile = lFiles[i];
312: if (lFile.isDirectory()) {
313: // Add itself and call same routine recursively to add descendants of this directory
314: String lAbsolutePath = lFile.getAbsolutePath();
315: lDir.add(lAbsolutePath);
316: lDir
317: .addAll(java.util.Arrays
318: .asList(listAllDescendantDirectoriesInDirectory(lAbsolutePath)));
319: }
320: }
321: }
322: return (String[]) lDir.toArray(new String[lDir.size()]);
323: }
324:
325: /** Generates the ful path for the unique temporary directory */
326: public static String getUniqueTempDirectoryAbsolutePath() {
327: // Derive the base directory where compilation will take place
328: String lTmpDir = System.getProperty("java.io.tmpdir");
329: String lBaseDir = lTmpDir;
330: if (!lBaseDir.endsWith("\\"))
331: lBaseDir += "\\";
332: // randomise millis for the uniqueness of the actual directory
333: long lCurrMillis = System.currentTimeMillis();
334: lBaseDir += "metaboss"
335: + "_"
336: + Long
337: .toHexString((long) (Math.random() * lCurrMillis))
338: + "_" + Long.toHexString(lCurrMillis);
339: return lBaseDir;
340: }
341:
342: /** Lists all directories contained in the directory and all subdirectories which
343: * have its last name equal to the given one. List is in no particular order.
344: * Search will stop at the first match and not go any deeper. So if there is a directory
345: * ......\name\.....\name only to level directory will be returned
346: * @param pRootDirectoryAbsolutePath the absolute path to the directory to start search from
347: * @param pNameToLookFor the name to match
348: * @return array of strings with each element being an absolute path to the directory matching the criteria */
349: public static String[] listAllDirectoriesWithName(
350: String pRootDirectoryAbsolutePath, String pNameToLookFor)
351: throws FileNotFoundException {
352: File lDirectoryToAnalyse = new File(pRootDirectoryAbsolutePath);
353: if ((!lDirectoryToAnalyse.exists())
354: || (!lDirectoryToAnalyse.canRead()))
355: throw new FileNotFoundException(lDirectoryToAnalyse
356: + " does not exist or is not accessible");
357: if (!lDirectoryToAnalyse.isDirectory())
358: throw new FileNotFoundException(lDirectoryToAnalyse
359: + " is not a directory");
360: ArrayList lDir = new ArrayList();
361: File[] lFiles = lDirectoryToAnalyse.listFiles();
362: if (lFiles != null && lFiles.length > 0) {
363: for (int i = 0; i < lFiles.length; i++) {
364: if (lFiles[i].isDirectory()) {
365: if (lFiles[i].getName().equals(pNameToLookFor))
366: lDir.add(lFiles[i].getAbsolutePath());
367: else
368: lDir.addAll(java.util.Arrays
369: .asList(listAllDirectoriesWithName(
370: lFiles[i].getAbsolutePath(),
371: pNameToLookFor)));
372: }
373: }
374: }
375: return (String[]) lDir.toArray(new String[lDir.size()]);
376: }
377: }
|