// THIS SOFTWARE IS PROVIDED BY SOFTARIS PTY.LTD. AND OTHER METABOSS
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
// BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SOFTARIS PTY.LTD.
// OR OTHER METABOSS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF SOFTARIS PTY.LTD. OR OTHER METABOSS CONTRIBUTORS ARE ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// Copyright 2000-2005 Softaris Pty.Ltd. All Rights Reserved.
package com.metaboss.util;
import java.io.File;
import java.io.FileFilter;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
/** Set of useful utilites */
public class DirectoryUtils
{
/** Trims tree of directories excluding specified directory. Trimming means deleting the directories without any contents. */
public static void trimDirectoryTree(String pTreeRootDirectoryPath) throws FileNotFoundException, IOException
{
String[] lAllChildDirectories = listAllChildDirectoriesInDirectory(pTreeRootDirectoryPath);
for (int i = 0; i < lAllChildDirectories.length; i++)
{
String lChildDirectoryPath = lAllChildDirectories[i];
// Call this method recursively to trim possible subdirectories
trimDirectoryTree(lChildDirectoryPath);
// Delete this child itself if it is empty
File lChildDirectory = new File(lChildDirectoryPath);
String[] lGrandChildren = lChildDirectory.list();
if (lGrandChildren == null || lGrandChildren.length == 0)
lChildDirectory.delete();
}
}
/** This utility method is almost the same as File.createTempFile() method, with the only difference is
* that it creates directory and not a file. */
public static File createTempDir(String pPrefix, String pSuffix) throws IOException
{
File lTempFile = File.createTempFile(pPrefix, pSuffix);
lTempFile.delete();
lTempFile.mkdirs();
return lTempFile;
}
/** Copies contents of the from directory (excluding directory itself) to
* the destination directory (again excluding directory itself).
* Same files get overwritten */
public static void copyDirectory(String pFromDirectoryPath, String pToDirectoryPath) throws FileNotFoundException, IOException
{
File lFromDirectory = new File(pFromDirectoryPath);
if (lFromDirectory.exists() == false || lFromDirectory.isDirectory() == false)
throw new FileNotFoundException(pFromDirectoryPath + " does not exists. Unable to copy");
File lToDirectory = new File(pToDirectoryPath);
if (lToDirectory.exists() == false || lToDirectory.isDirectory() == false)
throw new FileNotFoundException(pToDirectoryPath + " does not exists. Unable to copy");
// First deal with files
String[] lAllFiles = listAllFilesInDirectory(lFromDirectory.getAbsolutePath(), new FileFilter()
{
public boolean accept(File pPathname)
{
return pPathname.isFile();
}
});
int lFromDirectoryNameLength = lFromDirectory.getAbsolutePath().length();
for (int i = 0; i < lAllFiles.length; i++)
{
String lAbsoluteFromFileName = lAllFiles[i];
String lAbsoluteToFileName = lToDirectory.getAbsolutePath() + lAbsoluteFromFileName.substring(lFromDirectoryNameLength);
FileUtils.copyFile(lAbsoluteFromFileName,lAbsoluteToFileName);
}
// Now deal with subdirectories
String[] lAllDirectories = listAllChildDirectoriesInDirectory(lFromDirectory.getAbsolutePath());
for (int i = 0; i < lAllDirectories.length; i++)
{
String lAbsoluteFromDirectoryName = lAllDirectories[i];
String lAbsoluteToDirectoryName = lToDirectory.getAbsolutePath() + lAbsoluteFromDirectoryName.substring(lFromDirectoryNameLength);
ensureThereIsDirectory(lAbsoluteToDirectoryName);
copyDirectory(lAbsoluteFromDirectoryName, lAbsoluteToDirectoryName);
}
}
/** Makes sure that the clean directory exists and accessible
* cleans up contents of the existing directory if necessary
*/
public static void ensureNewCleanDirectory(String pDirectoryPath) throws IOException
{
File lDirectory = new File(pDirectoryPath);
if (lDirectory.exists())
deleteAllDirectoryContents(lDirectory);
else
lDirectory.mkdirs();
}
/** Makes sure that the directory without files exists and accessible.
* Cleans up contents of the existing directory if necessary. This version
* does not touch any subdirectories. Use ensureNewCleanDirectory() if you wish to
* ensure that totally clean director exists.
*/
public static void ensureNewNoFilesDirectory(String pDirectoryPath) throws IOException
{
File lDirectory = new File(pDirectoryPath);
if (lDirectory.exists())
deleteAllFilesInTheDirectory(lDirectory);
else
lDirectory.mkdirs();
}
/** Makes sure that the directory exists and accessible
* creates directory if necesary
*/
public static void ensureThereIsDirectory(String pDirectoryPath)
{
File lDirectory = new File(pDirectoryPath);
if (!lDirectory.exists())
lDirectory.mkdirs();
}
/** Deletes all contents of the specified directory including directory itself */
public static void deleteDirectory(File pDirectory) throws IOException
{
if (!pDirectory.isDirectory())
throw new IllegalArgumentException(pDirectory.getAbsolutePath() + " is not a directory");
deleteAllDirectoryContents(pDirectory);
if (!pDirectory.delete())
throw new IOException("Unable to delete directory. " + pDirectory.getAbsolutePath());
}
/** Deletes all contents of the specified directory including directory itself.
* Does not fail if directory does not exist - just exist gracefully */
public static void deleteDirectoryIfExists(File pDirectory) throws IOException
{
if (pDirectory.exists())
deleteDirectory(pDirectory);
}
/** Deletes all contents of the specified directory including subdirectories, but excluding the directory itself */
public static void deleteAllDirectoryContents(File pDirectory) throws IOException
{
if (!pDirectory.isDirectory())
throw new IllegalArgumentException(pDirectory.getAbsolutePath() + " is not a directory");
File [] lContainedFiles = pDirectory.listFiles();
if (lContainedFiles != null && lContainedFiles.length > 0)
{
for (int i = 0; i < lContainedFiles.length; i++)
{
if (lContainedFiles[i].isDirectory())
deleteAllDirectoryContents(lContainedFiles[i]);
if(!lContainedFiles[i].delete())
throw new IOException("Unable to delete file. " + lContainedFiles[i].getAbsolutePath());
}
}
}
/** Deletes all files in the specified directory. This excludes any subdirectories */
public static void deleteAllFilesInTheDirectory(File pDirectory) throws IOException
{
if (!pDirectory.isDirectory())
throw new IllegalArgumentException(pDirectory.getAbsolutePath() + " is not a directory");
File [] lContainedFiles = pDirectory.listFiles();
if (lContainedFiles != null && lContainedFiles.length > 0)
{
for (int i = 0; i < lContainedFiles.length; i++)
{
if (lContainedFiles[i].isFile())
{
if(!lContainedFiles[i].delete())
throw new IOException("Unable to delete file. " + lContainedFiles[i].getAbsolutePath());
}
}
}
}
/** Returns true if specified path can be deleted.
* @param pPathToDelete file or directory to test
* @return true if path is not present or can be removed. For directory
* being able to remove means that all it's contents are writeable including subdirectories */
public static boolean canDelete(File pPathToDelete)
{
if (!pPathToDelete.exists())
return true; // Not present - can be removed
if (!pPathToDelete.canWrite())
return false; // Present and is not writeable - can not be removed
if (pPathToDelete.isFile())
return true; // Writeable file can be deleted
File [] lContainedFiles = pPathToDelete.listFiles();
if (lContainedFiles != null && lContainedFiles.length > 0)
{
for (int i = 0; i < lContainedFiles.length; i++)
{
if (!canDelete(lContainedFiles[i]))
return false; // One of the contained files can not be deleted
}
}
return true; // Passed all tests
}
/** Returns true if specified path can be created.
* @param pPathToCreate file or directory to test
* @return true if path is not present and can be created */
public static boolean canCreate(File pPathToCreate)
{
// Convert to absolute path
pPathToCreate = pPathToCreate.getAbsoluteFile();
if (pPathToCreate.exists())
return false; // Already present - can not be created
File lParent = pPathToCreate.getParentFile();
if (lParent == null)
return false; // No parent - can not create
if (!lParent.exists())
return canCreate(lParent); // Parent does not exists see if we can create parent
return lParent.canWrite();
}
/** Lists all files contained in the directory and possibly subdirectories, which are
* satisfying given file filter. Note that subdirectories will onbly be considered if file filter accepts them
* @return array of strings with each element being an absolute path to the file contained in the directory */
public static String[] listAllFilesInDirectory(String pDirectoryAbsolutePath, FileFilter pFilter) throws FileNotFoundException
{
File lDirectoryToAnalyse = new File(pDirectoryAbsolutePath);
if ((!lDirectoryToAnalyse.exists()) || (!lDirectoryToAnalyse.canRead()))
throw new FileNotFoundException(lDirectoryToAnalyse + " does not exist or is not accessible");
if (!lDirectoryToAnalyse.isDirectory())
throw new FileNotFoundException(lDirectoryToAnalyse + " is not a directory");
ArrayList lDir = new ArrayList();
File[] lFiles = lDirectoryToAnalyse.listFiles(pFilter);
if (lFiles != null && lFiles.length > 0)
{
for (int i = 0; i < lFiles.length; i++)
{
if (lFiles[i].isDirectory())
lDir.addAll(java.util.Arrays.asList(listAllFilesInDirectory(lFiles[i].getAbsolutePath(), pFilter)));
else
lDir.add(lFiles[i].getAbsolutePath());
}
}
return (String[])lDir.toArray(new String[lDir.size()]);
}
/** Lists all files contained in the directory and all subdirectories in no particular order
* @return array of strings with each element being an absolute path to the file contained in the directory */
public static String[] listAllFilesInDirectory(String pDirectoryAbsolutePath) throws FileNotFoundException
{
return listAllFilesInDirectory(pDirectoryAbsolutePath, new FileFilter()
{
public boolean accept(File pPathname)
{
return true;
}
});
}
/** Lists all direct child directories contained in the directory
* @return array of strings with each element being an absolute path to the child directory of the specified directory */
public static String[] listAllChildDirectoriesInDirectory(String pDirectoryAbsolutePath) throws FileNotFoundException
{
File lDirectoryToAnalyse = new File(pDirectoryAbsolutePath);
if ((!lDirectoryToAnalyse.exists()) || (!lDirectoryToAnalyse.canRead()))
throw new FileNotFoundException(lDirectoryToAnalyse + " does not exist or is not accessible");
if (!lDirectoryToAnalyse.isDirectory())
throw new FileNotFoundException(lDirectoryToAnalyse + " is not a directory");
ArrayList lDir = new ArrayList();
File[] lFiles = lDirectoryToAnalyse.listFiles();
if (lFiles != null && lFiles.length > 0)
{
for (int i = 0; i < lFiles.length; i++)
{
File lFile = lFiles[i];
if (lFile.isDirectory())
lDir.add(lFile.getAbsolutePath());
}
}
return (String[])lDir.toArray(new String[lDir.size()]);
}
/** Lists all descendant directories (on any level) contained in the directory
* @return array of strings with each element being an absolute path to the descendant directory of the specified directory */
public static String[] listAllDescendantDirectoriesInDirectory(String pDirectoryAbsolutePath) throws FileNotFoundException
{
File lDirectoryToAnalyse = new File(pDirectoryAbsolutePath);
if ((!lDirectoryToAnalyse.exists()) || (!lDirectoryToAnalyse.canRead()))
throw new FileNotFoundException(lDirectoryToAnalyse + " does not exist or is not accessible");
if (!lDirectoryToAnalyse.isDirectory())
throw new FileNotFoundException(lDirectoryToAnalyse + " is not a directory");
ArrayList lDir = new ArrayList();
File[] lFiles = lDirectoryToAnalyse.listFiles();
if (lFiles != null && lFiles.length > 0)
{
for (int i = 0; i < lFiles.length; i++)
{
File lFile = lFiles[i];
if (lFile.isDirectory())
{
// Add itself and call same routine recursively to add descendants of this directory
String lAbsolutePath = lFile.getAbsolutePath();
lDir.add(lAbsolutePath);
lDir.addAll(java.util.Arrays.asList(listAllDescendantDirectoriesInDirectory(lAbsolutePath)));
}
}
}
return (String[])lDir.toArray(new String[lDir.size()]);
}
/** Generates the ful path for the unique temporary directory */
public static String getUniqueTempDirectoryAbsolutePath()
{
// Derive the base directory where compilation will take place
String lTmpDir = System.getProperty("java.io.tmpdir");
String lBaseDir = lTmpDir;
if (!lBaseDir.endsWith("\\"))
lBaseDir += "\\";
// randomise millis for the uniqueness of the actual directory
long lCurrMillis = System.currentTimeMillis();
lBaseDir += "metaboss" + "_" + Long.toHexString((long)(Math.random() * lCurrMillis)) + "_" + Long.toHexString(lCurrMillis);
return lBaseDir;
}
/** Lists all directories contained in the directory and all subdirectories which
* have its last name equal to the given one. List is in no particular order.
* Search will stop at the first match and not go any deeper. So if there is a directory
* ......\name\.....\name only to level directory will be returned
* @param pRootDirectoryAbsolutePath the absolute path to the directory to start search from
* @param pNameToLookFor the name to match
* @return array of strings with each element being an absolute path to the directory matching the criteria */
public static String[] listAllDirectoriesWithName(String pRootDirectoryAbsolutePath, String pNameToLookFor) throws FileNotFoundException
{
File lDirectoryToAnalyse = new File(pRootDirectoryAbsolutePath);
if ((!lDirectoryToAnalyse.exists()) || (!lDirectoryToAnalyse.canRead()))
throw new FileNotFoundException(lDirectoryToAnalyse + " does not exist or is not accessible");
if (!lDirectoryToAnalyse.isDirectory())
throw new FileNotFoundException(lDirectoryToAnalyse + " is not a directory");
ArrayList lDir = new ArrayList();
File[] lFiles = lDirectoryToAnalyse.listFiles();
if (lFiles != null && lFiles.length > 0)
{
for (int i = 0; i < lFiles.length; i++)
{
if (lFiles[i].isDirectory())
{
if (lFiles[i].getName().equals(pNameToLookFor))
lDir.add(lFiles[i].getAbsolutePath());
else
lDir.addAll(java.util.Arrays.asList(listAllDirectoriesWithName(lFiles[i].getAbsolutePath(),pNameToLookFor)));
}
}
}
return (String[])lDir.toArray(new String[lDir.size()]);
}
}
|