/* * JBoss, Home of Professional Open Source. * * See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing. * * See the AUTHORS.txt file distributed with this work for a full listing of individual contributors. */ package org.teiid.core.designer.util; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.util.ArrayList; import org.eclipse.core.resources.IResource; import org.teiid.core.designer.CoreModelerPlugin; import org.teiid.core.designer.TeiidDesignerException; import org.teiid.core.designer.util.OperationUtil.Unreliable; /** * @since 8.0 */ public class FileUtils { public interface Constants { char CURRENT_FOLDER_SYMBOL_CHAR = '.'; char DRIVE_SEPARATOR_CHAR = ':'; char FILE_EXTENSION_SEPARATOR_CHAR = '.'; char FILE_NAME_WILDCARD_CHAR = '*'; String CURRENT_FOLDER_SYMBOL = String.valueOf(CURRENT_FOLDER_SYMBOL_CHAR); String DRIVE_SEPARATOR = String.valueOf(DRIVE_SEPARATOR_CHAR); String FILE_EXTENSION_SEPARATOR = String.valueOf(FILE_EXTENSION_SEPARATOR_CHAR); String FILE_NAME_WILDCARD = String.valueOf(FILE_NAME_WILDCARD_CHAR); String PARENT_FOLDER_SYMBOL = ".."; //$NON-NLS-1$ } public static final char SEPARATOR = '/'; public static int DEFAULT_BUFFER_SIZE = 8092; public static String TEMP_DIRECTORY; public final static String JAVA_IO_TEMP_DIR = "java.io.tmpdir";//$NON-NLS-1$ private static final String TEMP_FILE = "delete.me"; //$NON-NLS-1$ private static final String TEMP_FILE_RENAMED = "delete.me.old"; //$NON-NLS-1$ public final static char[] SUFFIX_class = ".class".toCharArray(); //$NON-NLS-1$ public final static char[] SUFFIX_CLASS = ".CLASS".toCharArray(); //$NON-NLS-1$ public final static char[] SUFFIX_java = ".java".toCharArray(); //$NON-NLS-1$ public final static char[] SUFFIX_JAVA = ".JAVA".toCharArray(); //$NON-NLS-1$ public final static char[] SUFFIX_jar = ".jar".toCharArray(); //$NON-NLS-1$ public final static char[] SUFFIX_JAR = ".JAR".toCharArray(); //$NON-NLS-1$ public final static char[] SUFFIX_zip = ".zip".toCharArray(); //$NON-NLS-1$ public final static char[] SUFFIX_ZIP = ".ZIP".toCharArray(); //$NON-NLS-1$ static { final String tempDirPath = System.getProperty(JAVA_IO_TEMP_DIR); TEMP_DIRECTORY = (tempDirPath.endsWith(File.separator) ? tempDirPath : tempDirPath + File.separator); } /**<p> * Convert the specified file name to end with the specified extension if it doesn't already end with an extension. * </p> * @param name * The file name. * @param extension * The extension to append to the file name. * @return The file name with an extension. * @since 4.0 */ public static String toFileNameWithExtension(final String name, final String extension) { return toFileNameWithExtension(name, extension, false); } /**<p> * Convert the specified file name to end with the specified extension if it doesn't already end with an extension. If force * is true, the specified extension will be appended to the name if the name doesn't end with that particular extension. * </p> * @param name * The file name. * @param extension * The extension to append to the file name. * @param force * Indicates whether to force the specified extension as the extension of the file name. * @return The file name with an extension. * @since 4.0 */ public static String toFileNameWithExtension(final String name, final String extension, final boolean force) { if (name == null) { final String msg = CoreModelerPlugin.Util.getString("FileUtils.The_name_of_the_file_may_not_be_null"); //$NON-NLS-1$ throw new IllegalArgumentException(msg); } if (extension == null) { final String msg = CoreModelerPlugin.Util.getString("FileUtils.The_file_extension_may_not_be_null"); //$NON-NLS-1$ throw new IllegalArgumentException(msg); } if (name.endsWith(extension)) { return name; } if (!force && name.indexOf(Constants.FILE_EXTENSION_SEPARATOR_CHAR) >= 0) { return name; } final int nameLen = name.length() - 1; final int extLen = extension.length(); final boolean nameEndsWithExtChr = (nameLen >= 0 && name.charAt(nameLen) == Constants.FILE_EXTENSION_SEPARATOR_CHAR); final boolean extBeginsWithExtChr = (extLen > 0 && extension.charAt(0) == Constants.FILE_EXTENSION_SEPARATOR_CHAR); if (nameEndsWithExtChr && extBeginsWithExtChr) { return name.substring(0, nameLen) + extension; } if (!nameEndsWithExtChr && !extBeginsWithExtChr) { return name + Constants.FILE_EXTENSION_SEPARATOR + extension; } return name + extension; } /** * Determine whether the specified name is valid for a file or folder on the current file system. * @param newName the new name to be checked * @return true if the name is null or contains no invalid characters for a folder or file, or false otherwise */ public static boolean isFilenameValid(String newName) { return true; //TODO: just catch an exception when the file is accessed or created } /** * @param path * @return */ public static String getBaseFileNameWithoutExtension(String path) { return CoreStringUtil.getFirstToken(CoreStringUtil.getLastToken(path, "/"), "."); //$NON-NLS-1$ //$NON-NLS-2$ } /** * Obtains the file extension of the specified <code>File</code>. The extension is considered to be all the * characters after the last occurrence of {@link Constants#FILE_EXTENSION_SEPARATOR_CHAR} in the pathname * of the input. * @param theFile the file whose extension is being requested * @return the extension or <code>null</code> if not found * @since 4.2 */ public static String getExtension(File theFile) { return getExtension(theFile.getPath()); } /** * Obtains the file extension of the specified file name. The extension is considered to be all the * characters after the last occurrence of {@link Constants#FILE_EXTENSION_SEPARATOR_CHAR}. * @param theFileName the file whose extension is being requested * @return the extension or <code>null</code> if not found * @since 4.2 */ public static String getExtension(String theFileName) { String result = null; final int index = theFileName.lastIndexOf(Constants.FILE_EXTENSION_SEPARATOR_CHAR); // make sure extension char is found and is not the last char in the path if ((index != -1) && ((index + 1) != theFileName.length())) { result = theFileName.substring(index + 1); } return result; } /** * Returns true iff str.toLowerCase().endsWith(".jar") || str.toLowerCase().endsWith(".zip") * implementation is not creating extra strings. * @param name * @return */ public final static boolean isArchiveFileName(String name) { int nameLength = name == null ? 0 : name.length(); int suffixLength = SUFFIX_JAR.length; if (nameLength < suffixLength) return false; // try to match as JAR file for (int i = 0; i < suffixLength; i++) { char c = name.charAt(nameLength - i - 1); int suffixIndex = suffixLength - i - 1; if (c != SUFFIX_jar[suffixIndex] && c != SUFFIX_JAR[suffixIndex]) { // try to match as ZIP file suffixLength = SUFFIX_ZIP.length; if (nameLength < suffixLength) return false; for (int j = 0; j < suffixLength; j++) { c = name.charAt(nameLength - j - 1); suffixIndex = suffixLength - j - 1; if (c != SUFFIX_zip[suffixIndex] && c != SUFFIX_ZIP[suffixIndex]) return false; } return true; } } return true; } /** * Returns fileArray {@code ArrayList} of {@code File} objects that match a pattern in the specified directory. * @param pathToScan The path to look for the matching files * @param startWith The beginning portion of the file name * @param endsWith The ending portion of the file name (i.e. ".jar") * @return fileArray An ArrayList of * @since 8.5 */ public final static ArrayList<File> getFilesForPattern(String pathToScan, String startWith, String endsWith) { String target_file ; // fileThatYouWantToFilter File folderToScan = new File(pathToScan); File[] listOfFiles = folderToScan.listFiles(); ArrayList<File> list = new ArrayList(); for (File file:listOfFiles) { if (file.isFile()) { target_file = file.getName(); if (target_file.startsWith(startWith) && target_file.endsWith(endsWith)) { list.add(file); } } } return list; } /** * Copy a file. Overwrites the destination file if it exists. * @param fromFile * @param destDirectory * @param overwrite * * @param fromFileName * @param toFileName * @return * @throws IOException * @since 4.3 */ public static File copy(final File fromFile, final File destDirectory, final boolean overwrite) throws IOException { final File toFile = new File(destDirectory, fromFile.getName()); if (toFile.exists()) if (overwrite) toFile.delete(); else { final String msg = CoreModelerPlugin.Util.getString("FileUtils.File_already_exists", toFile.getName()); //$NON-NLS-1$ throw new IOException(msg); } if (!fromFile.exists()) throw new FileNotFoundException( CoreModelerPlugin.Util.getString("FileUtils.File_does_not_exist._1", fromFile.getName())); //$NON-NLS-1$ FileInputStream fis = null; try { fis = new FileInputStream(fromFile); write(fis, toFile); } finally { if (fis != null) fis.close(); } return toFile; } /** * @param source * @param destination * @throws Exception */ public static void copy(final File source, final OutputStream destination) throws Exception { OperationUtil.perform(new UnreliableCopy(source, destination)); } /** * @param source * @param destination * @throws Exception */ public static void copy(final InputStream source, final File destination) throws Exception { OperationUtil.perform(new UnreliableCopy(source, destination)); } /** * @param source * @param destination * @throws Exception */ public static void copy(final InputStream source, final OutputStream destination) throws Exception { final byte[] buf = new byte[DEFAULT_BUFFER_SIZE]; for (int len = source.read(buf); len >= 0; len = source.read(buf)) destination.write(buf, 0, len); } /** * Copy a file. Overwrites the destination file if it exists. * * @param fromFileName * @param toFileName * @throws IOException * @since 4.3 */ public static void copy(final String fromFileName, final String toFileName) throws IOException { copy(fromFileName, toFileName, true); } /** * Copy a file * * @param fromFileName * @param toFileName * @param overwrite whether to overwrite the destination file if it exists. * @throws IOException * @since 4.3 */ public static void copy(final String fromFileName, final String toFileName, final boolean overwrite) throws IOException { final File toFile = new File(toFileName); if (toFile.exists()) if (overwrite) toFile.delete(); else { final String msg = CoreModelerPlugin.Util.getString("FileUtils.File_already_exists", toFileName); //$NON-NLS-1$ throw new IOException(msg); } final File fromFile = new File(fromFileName); if (!fromFile.exists()) throw new FileNotFoundException( CoreModelerPlugin.Util.getString("FileUtils.File_does_not_exist._1", //$NON-NLS-1$ fromFileName)); FileInputStream fis = null; try { fis = new FileInputStream(fromFile); write(fis, toFileName); } finally { if (fis != null) fis.close(); } } /** * Copy recursively the <code>sourceDirectory</code> and all its contents to the <code>targetDirectory</code>. If * <code>targetDirectory</code> does not exist, it will be created. * * @param sourceDirectory The source directory to copy * @param targetDirectory The target directory to copy to * @param filter files to ignore * @throws Exception If the source directory does not exist. * @since 4.3 */ public static void copyDirectoriesRecursively(final File sourceDirectory, final File targetDirectory, final FilenameFilter filter) throws Exception { copyRecursively(sourceDirectory, targetDirectory, filter, true); } /** * Copy file from originating directory to the destination directory. * * @param orginDirectory * @param destDirectory * @param fileName * @throws Exception * @since 4.4 */ public static void copyFile(final String orginDirectory, final String destDirectory, final String fileName) throws Exception { copyFile(orginDirectory, fileName, destDirectory, fileName); } /** * Copy file from originating directory to the destination directory. * * @param orginDirectory * @param orginFileName * @param destDirectory * @param destFileName * @throws Exception * @since 4.4 */ public static void copyFile(final String orginDirectory, final String orginFileName, final String destDirectory, final String destFileName) throws Exception { FileUtils.copy(orginDirectory + File.separator + orginFileName, destDirectory + File.separator + destFileName); } /** * Copy recursively from the <code>sourceDirectory</code> all its contents to the <code>targetDirectory</code>. if * <code>includeSourceRoot<code> == <code>true</code>, copy <code>sourceDirectory</code> itself, else only copy * <code>sourceDirectory</code>'s contents. If <code>targetDirectory</code> does not exist, it will be created. * * @param sourceDirectory * @param targetDirectory * @param filter - files which should not be copied * @param includeSourceRoot * @throws FileNotFoundException * @throws Exception * @since 4.3 */ public static void copyRecursively(final File sourceDirectory, final File targetDirectory, final FilenameFilter filter, final boolean includeSourceRoot) throws FileNotFoundException, Exception { if (!sourceDirectory.exists()) throw new FileNotFoundException( CoreModelerPlugin.Util.getString("FileUtils.File_does_not_exist._1", //$NON-NLS-1$ sourceDirectory)); if (!sourceDirectory.isDirectory()) throw new FileNotFoundException( CoreModelerPlugin.Util.getString("FileUtils.Not_a_directory", //$NON-NLS-1$ sourceDirectory)); File targetDir = new File(targetDirectory.getAbsolutePath() + File.separatorChar + sourceDirectory.getName()); if (includeSourceRoot) // copy source directory targetDir.mkdir(); else // copy only source directory contents targetDir = new File(targetDirectory.getAbsolutePath() + File.separatorChar); File[] sourceFiles = null; if (filter != null) sourceFiles = sourceDirectory.listFiles(filter); else sourceFiles = sourceDirectory.listFiles(); for (final File srcFile : sourceFiles) if (srcFile.isDirectory()) { final File childTargetDir = new File(targetDir.getAbsolutePath()); copyRecursively(srcFile, childTargetDir, filter, true); } else copy(srcFile.getAbsolutePath(), targetDir.getAbsolutePath() + File.separatorChar + srcFile.getName()); } /** * Compute checksum for the given file. * * @param f The file for which checksum needs to be computed * @return The checksum * @throws Exception * @since 4.3 */ public static long getCheckSum(final File f) throws Exception { CoreArgCheck.isNotNull(f); FileInputStream is = null; try { is = new FileInputStream(f); return ChecksumUtil.computeChecksum(is).getValue(); } finally { if (is != null) try { is.close(); } catch (final IOException err1) { } } } /** * @param filename * @return */ public static String getFilenameWithoutExtension(final String filename) { if (filename == null || filename.length() == 0) return filename; final int extensionIndex = filename.lastIndexOf('.'); if (extensionIndex == -1) return filename; // not found if (extensionIndex == 0) return ""; //$NON-NLS-1$ return filename.substring(0, extensionIndex); } /** * @param theFileName * @return */ public static String normalizeFileName(final String theFileName) { if (theFileName == null) return null; if (theFileName.length() == 0) return theFileName; try { return URLDecoder.decode(theFileName, "UTF-8"); //$NON-NLS-1$ } catch (final UnsupportedEncodingException e) { return theFileName; } } /** * @param directory */ public static void removeChildrenRecursively(final File directory) { final File[] files = directory.listFiles(); if (files != null) for (final File file2 : files) { final File file = file2; if (file.isDirectory()) removeDirectoryAndChildren(file); else if (!file.delete()) file.deleteOnExit(); } } /** * @param directory */ public static void removeDirectoryAndChildren(final File directory) { removeChildrenRecursively(directory); if (!directory.delete()) directory.deleteOnExit(); } /** * Test whether it's possible to read and write files in the specified directory. * * @param dirPath Name of the directory to test * @throws TeiidDesignerException * @since 4.3 */ public static void testDirectoryPermissions(final String dirPath) throws TeiidDesignerException { // try to create a file final File tmpFile = new File(dirPath + File.separatorChar + TEMP_FILE); boolean success = false; try { success = tmpFile.createNewFile(); } catch (final IOException e) { } if (!success) { final String msg = CoreModelerPlugin.Util.getString("FileUtils.Unable_to_create_file_in", dirPath); //$NON-NLS-1$ throw new TeiidDesignerException(msg); } // test if file can be written to if (!tmpFile.canWrite()) { final String msg = CoreModelerPlugin.Util.getString("FileUtils.Unable_to_write_file_in", dirPath); //$NON-NLS-1$ throw new TeiidDesignerException(msg); } // test if file can be read if (!tmpFile.canRead()) { final String msg = CoreModelerPlugin.Util.getString("FileUtils.Unable_to_read_file_in", dirPath); //$NON-NLS-1$ throw new TeiidDesignerException(msg); } // test if file can be renamed final File newFile = new File(dirPath + File.separatorChar + TEMP_FILE_RENAMED); success = false; try { success = tmpFile.renameTo(newFile); } catch (final Exception e) { } if (!success) { final String msg = CoreModelerPlugin.Util.getString("FileUtils.Unable_to_rename_file_in", dirPath); //$NON-NLS-1$ throw new TeiidDesignerException(msg); } // test if file can be deleted success = false; try { success = newFile.delete(); } catch (final Exception e) { } if (!success) { final String msg = CoreModelerPlugin.Util.getString("FileUtils.Unable_to_delete_file_in", dirPath); //$NON-NLS-1$ throw new TeiidDesignerException(msg); } } /** * Write an InputStream to a file. * @param is * @param f * @throws IOException */ public static void write(final InputStream is, final File f) throws IOException { write(is, f, DEFAULT_BUFFER_SIZE); } /** * Write an InputStream to a file. * @param is * @param f * @param bufferSize * @throws IOException */ public static void write(final InputStream is, final File f, final int bufferSize) throws IOException { f.delete(); final File parentDir = f.getParentFile(); if (parentDir != null) parentDir.mkdirs(); FileOutputStream fio = null; BufferedOutputStream bos = null; try { fio = new FileOutputStream(f); bos = new BufferedOutputStream(fio); if (bufferSize > 0) { final byte[] buff = new byte[bufferSize]; int bytesRead; // Simple read/write loop. while (-1 != (bytesRead = is.read(buff, 0, buff.length))) bos.write(buff, 0, bytesRead); } bos.flush(); } finally { if (bos != null) bos.close(); if (fio != null) fio.close(); } } /** * Write an InputStream to a file. * @param is * @param fileName * @throws IOException */ public static void write(final InputStream is, final String fileName) throws IOException { final File f = new File(fileName); write(is, f); } /** * Write a byte array to a file. * @param data * @param fileName * @throws IOException */ public static void write(byte[] data, String fileName) throws IOException { ByteArrayInputStream bais = null; InputStream is = null; try { bais = new ByteArrayInputStream(data); is = new BufferedInputStream(bais); write(is, fileName); } finally { if (is != null) { is.close(); } if (bais != null) { bais.close(); } } } /** * Write a byte array to a file. * @param data * @param file * @throws IOException */ public static void write(byte[] data, File file) throws IOException { ByteArrayInputStream bais = null; InputStream is = null; try { bais = new ByteArrayInputStream(data); is = new BufferedInputStream(bais); write(is, file); } finally { if (is != null) { is.close(); } if (bais != null) { bais.close(); } } } private FileUtils() { } static class UnreliableCopy implements Unreliable { private File sourceFile; private InputStream source; private File destinationFile; private OutputStream destination; UnreliableCopy(final File source, final OutputStream destination) { sourceFile = source; this.destination = destination; } UnreliableCopy(final InputStream source, final File destination) { this.source = source; destinationFile = destination; } @Override public void doIfFails() { } @Override public void finallyDo() throws Exception { if (destinationFile != null) destination.close(); if (sourceFile != null) source.close(); } @Override public void tryToDo() throws Exception { if (source == null) source = new FileInputStream(sourceFile); if (destination == null) { final File folder = destinationFile.getParentFile(); if (folder != null) folder.mkdirs(); destination = new FileOutputStream(destinationFile); } copy(source, destination); } } /** * @param resource * @return the name of the resource without any extension */ public static String getNameWithoutExtension(IResource resource) { if (resource == null) return null; return resource.getFullPath().removeFileExtension().lastSegment(); } }