Java tutorial
/********************************************************************************* * Ephesoft is a Intelligent Document Capture and Mailroom Automation program * developed by Ephesoft, Inc. Copyright (C) 2015 Ephesoft Inc. * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU Affero General Public License version 3 as published by the * Free Software Foundation with the addition of the following permission added * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK * IN WHICH THE COPYRIGHT IS OWNED BY EPHESOFT, EPHESOFT DISCLAIMS THE WARRANTY * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more * details. * * You should have received a copy of the GNU Affero General Public License along with * this program; if not, see http://www.gnu.org/licenses or write to the Free * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA. * * You can contact Ephesoft, Inc. headquarters at 111 Academy Way, * Irvine, CA 92617, USA. or at email address info@ephesoft.com. * * The interactive user interfaces in modified source and object code versions * of this program must display Appropriate Legal Notices, as required under * Section 5 of the GNU Affero General Public License version 3. * * In accordance with Section 7(b) of the GNU Affero General Public License version 3, * these Appropriate Legal Notices must retain the display of the "Ephesoft" logo. * If the display of the logo is not reasonably feasible for * technical reasons, the Appropriate Legal Notices must display the words * "Powered by Ephesoft". ********************************************************************************/ package com.ephesoft.dcma.util; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.Closeable; import java.io.File; import java.io.FileFilter; import java.io.FileInputStream; import java.io.FilenameFilter; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.Reader; import java.security.GeneralSecurityException; import java.security.KeyStore; import java.util.ArrayList; import java.util.Arrays; import java.util.Enumeration; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Stack; import java.util.StringTokenizer; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipOutputStream; import org.apache.commons.io.IOUtils; import org.apache.commons.io.filefilter.AgeFileFilter; import org.apache.tools.ant.Project; import org.apache.tools.ant.taskdefs.Expand; import org.jdom.input.SAXBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.itextpdf.text.io.FileChannelRandomAccessSource; import com.itextpdf.text.pdf.RandomAccessFileOrArray; /** * This class is a utility file consisting of various APIs related to different functions that can be performed with a file. * * @author Ephesoft * @version 1.0 * */ public class FileUtils implements IUtilCommonConstants { /** * Logger for logging the messages. */ private static final Logger LOGGER = LoggerFactory.getLogger(FileUtils.class); /** * DEFAULT_LOCALE {@link Locale} the default locale. */ private static final Locale DEFAULT_LOCALE = Locale.getDefault(); /** * BUFFER_SIZE the buffer size. */ private static final int BUFFER_SIZE = 4096; /** * One minute time interval constant */ private static final long ONE_MINUTE = 60000L; /** * Ten Seconds time interval constant */ private static final long TEN_SECONDS = 10000L; /** * Constant for time period of one seconds. */ private static final int ONE_SECOND = 1000; /** * Constant for time period of one minute. */ private static final long WAITING_TIME = 60000L; /** * Constant for Zip file retry count. */ private static final int RETRY_COUNT = 3; /** * Constant for Sleep period */ private static final long SLEEP_PERIOD = 200l; /** * This method deletes a given directory with its content. * * @param srcPath * @return true if successful false other wise. */ public static boolean deleteDirectoryAndContents(final File srcPath) { final String files[] = srcPath.list(); boolean folderDelete = true; if (files != null) { for (int index = 0; index < files.length; index++) { final String sFilePath = srcPath.getPath() + File.separator + files[index]; final File fFilePath = new File(sFilePath); folderDelete = folderDelete & fFilePath.delete(); } } folderDelete = folderDelete & srcPath.delete(); return folderDelete; } /** * This method zips the contents of Directory specified into a zip file whose name is provided. * * @param dir * @param zipfile * @throws IOException * @throws IllegalArgumentException */ public static void zipDirectory(final String dir, final String zipfile, final boolean excludeBatchXml) throws IOException, IllegalArgumentException { // Check that the directory is a directory, and get its contents final File directory = new File(dir); if (!directory.isDirectory()) { throw new IllegalArgumentException("Not a directory: " + dir); } final String[] entries = directory.list(); final byte[] buffer = new byte[4096]; // Create a buffer for copying int bytesRead; final ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipfile)); for (int index = 0; index < entries.length; index++) { if (excludeBatchXml && entries[index].contains(IUtilCommonConstants.BATCH_XML)) { continue; } final File file = new File(directory, entries[index]); if (file.isDirectory()) { continue;// Ignore directory } final FileInputStream input = new FileInputStream(file); // Stream to read file final ZipEntry entry = new ZipEntry(file.getName()); // Make a ZipEntry out.putNextEntry(entry); // Store entry bytesRead = input.read(buffer); while (bytesRead != -1) { out.write(buffer, 0, bytesRead); bytesRead = input.read(buffer); } if (input != null) { input.close(); } } if (out != null) { out.close(); } } /** * API to zip list of files to a desired file. Operation aborted if any file is invalid or a directory. * * @param filePaths {@link List}< {@link String}> * @param outputFilePath {@link String} * @throws IOException */ public static void zipMultipleFiles(final List<String> filePaths, final String outputFilePath) throws IOException { LOGGER.info("Zipping files to " + outputFilePath + ".zip file"); final File outputFile = new File(outputFilePath); if (outputFile.exists()) { LOGGER.info(outputFilePath + " file already exists. Deleting existing and creating a new file."); outputFile.delete(); } final byte[] buffer = new byte[4096]; // Create a buffer for copying int bytesRead; ZipOutputStream out = null; FileInputStream input = null; try { out = new ZipOutputStream(new FileOutputStream(outputFilePath)); for (final String filePath : filePaths) { LOGGER.info("Writing file " + filePath + " into zip file."); final File file = new File(filePath); if (!file.exists() || file.isDirectory()) { throw new Exception("Invalid file: " + file.getAbsolutePath() + ". Either file does not exists or it is a directory."); } input = new FileInputStream(file); // Stream to read file final ZipEntry entry = new ZipEntry(file.getName()); // Make a ZipEntry out.putNextEntry(entry); // Store entry bytesRead = input.read(buffer); while (bytesRead != -1) { out.write(buffer, 0, bytesRead); bytesRead = input.read(buffer); } } } catch (final Exception e) { LOGGER.error("Exception occured while zipping file." + e.getMessage(), e); } finally { if (input != null) { input.close(); } if (out != null) { out.close(); } } } /** * This method deletes a given directory with its content. * * @param srcPath * @return true if successful false other wise. */ public static boolean deleteDirectoryAndContents(final String sSrcPath) { return deleteContents(sSrcPath, true); } /** * This method deletes a given directory with its content. * * @param srcPath * @return true if successful false other wise. */ public static boolean deleteContents(final String sSrcPath, final boolean folderDelete) { final File srcPath = new File(sSrcPath); boolean returnVal = folderDelete; if (null == srcPath || !srcPath.exists()) { returnVal = false; } else { final String files[] = srcPath.list(); if (files != null) { for (int index = 0; index < files.length; index++) { final String sFilePath = srcPath.getPath() + File.separator + files[index]; final File fFilePath = new File(sFilePath); returnVal = returnVal & fFilePath.delete(); } returnVal = returnVal & srcPath.delete(); } } return returnVal; } public static boolean deleteContentsOnly(final String srcPath) { boolean folderDelete = true; final File srcPathFile = new File(srcPath); if (null == srcPathFile || !srcPathFile.exists()) { folderDelete = false; } else { final String files[] = srcPathFile.list(); if (files != null) { for (int index = 0; index < files.length; index++) { final String sFilePath = srcPathFile.getPath() + File.separator + files[index]; final File fFilePath = new File(sFilePath); folderDelete = folderDelete & fFilePath.delete(); } } } return folderDelete; } /** * This method copies the src file to dest file. * * @param srcFile * @param destFile * @throws IOException */ public static void copyFile(final File srcFile, final File destFile) throws IOException { InputStream input = null; input = new FileInputStream(srcFile); // Check if destination file's parent directory exist, if not, try creating it, if unsuccessful throw an exception. File parentFile = destFile.getParentFile(); if ((null != parentFile) && (!parentFile.exists()) && (!parentFile.mkdirs())) { if (null != input) { input.close(); } throw new IOException("Destination '" + destFile + "' parent directory cannot be created"); } OutputStream out = null; out = new FileOutputStream(destFile); final byte[] buf = new byte[1024]; int len = input.read(buf); while (len > 0) { out.write(buf, 0, len); len = input.read(buf); } if (input != null) { input.close(); } if (out != null) { out.close(); } } /** * This methods copies a directory with all its files. * * @param srcPath * @param dstPath * @throws IOException */ public static void copyDirectoryWithContents(final File srcPath, final File dstPath) throws IOException { if (srcPath.isDirectory()) { if (!dstPath.exists()) { dstPath.mkdir(); } final String[] files = srcPath.list(); if (files.length > 0) { Arrays.sort(files); for (int index = 0; index < files.length; index++) { copyDirectoryWithContents(new File(srcPath, files[index]), new File(dstPath, files[index])); } } } else { if (srcPath.exists()) { final InputStream input = new FileInputStream(srcPath); final OutputStream out = new FileOutputStream(dstPath); // Transfer bytes from in to out final byte[] buf = new byte[1024]; int len = input.read(buf); while (len > 0) { out.write(buf, 0, len); len = input.read(buf); } if (input != null) { input.close(); } if (out != null) { out.close(); } } } } /** * This methods copies a directory with all its files. * * @param srcPath * @param dstPath * @throws IOException */ public static void copyDirectoryWithContents(final String sSrcPath, final String sDstPath) throws IOException { final File srcPath = new File(sSrcPath); final File dstPath = new File(sDstPath); if (srcPath.isDirectory()) { if (!dstPath.exists()) { dstPath.mkdir(); } final String[] files = srcPath.list(); if (files.length > 0) { // Arrays.sort(files); for (int index = 0; index < files.length; index++) { copyDirectoryWithContents(new File(srcPath, files[index]), new File(dstPath, files[index])); } } } else { if (srcPath.exists()) { final InputStream input = new FileInputStream(srcPath); final OutputStream out = new FileOutputStream(dstPath); // Transfer bytes from in to out final byte[] buf = new byte[1024]; int len = input.read(buf); while (len > 0) { out.write(buf, 0, len); len = input.read(buf); } if (input != null) { input.close(); } if (out != null) { out.close(); } } } } public static void deleteAllXMLs(final String folderName) { final File file = new File(folderName); if (file.isDirectory()) { final File[] allFiles = file.listFiles(); for (int index = 0; index < allFiles.length; index++) { if (allFiles[index].getName().endsWith(EXTENSION_XML)) { allFiles[index].delete(); } } } } public static void deleteAllHocrFiles(final String folderName) { final File file = new File(folderName); if (file.isDirectory()) { final File[] allFiles = file.listFiles(); for (int index = 0; index < allFiles.length; index++) { if (allFiles[index].getName().endsWith(EXTENSION_HTML)) { allFiles[index].delete(); } } } } public static void copyAllXMLFiles(final String fromLoc, final String toLoc) { final File inputFolder = new File(fromLoc); final File outputFolder = new File(toLoc); final File[] inputFiles = inputFolder.listFiles(); for (int index = 0; index < inputFiles.length; index++) { if (inputFiles[index].getName().endsWith(EXTENSION_XML)) { FileReader input; FileWriter out; int character; try { input = new FileReader(inputFiles[index]); out = new FileWriter(outputFolder + File.separator + inputFiles[index].getName()); character = input.read(); while (character != -1) { out.write(character); character = input.read(); } if (input != null) { input.close(); } if (out != null) { out.close(); } } catch (final FileNotFoundException e) { LOGGER.error("Exception while reading files:" + e); } catch (final IOException e) { LOGGER.error("Exception while copying files:" + e); } } } } public static boolean checkHocrFileExist(final String folderLocation) { boolean returnValue = false; final File folderLoc = new File(folderLocation); final File[] allFiles = folderLoc.listFiles(); for (int index = 0; index < allFiles.length; index++) { if (allFiles[index].getName().endsWith(EXTENSION_HTML)) { returnValue = true; } } return returnValue; } /** * An utility method to update the properties file. * * @param propertyFile File * @param propertyMap Map<String, String> * @param comments String * @throws IOException If any of the parameter is null or input property file is not found. */ public static void updateProperty(final File propertyFile, final Map<String, String> propertyMap, final String comments) throws IOException { if (null == propertyFile || null == propertyMap || propertyMap.isEmpty()) { throw new IOException("propertyFile/propertyMap is null or empty."); } final String commentsToAdd = HASH_STRING + comments; FileInputStream fileInputStream = null; InputStreamReader inputStreamReader = null; BufferedReader bufferedReader = null; List<String> propertiesToWrite = null; try { fileInputStream = new FileInputStream(propertyFile); inputStreamReader = new InputStreamReader(fileInputStream); bufferedReader = new BufferedReader(inputStreamReader); propertiesToWrite = new ArrayList<String>(); propertiesToWrite.add(commentsToAdd); processPropertyFile(propertyMap, bufferedReader, propertiesToWrite); } finally { if (bufferedReader != null) { try { bufferedReader.close(); } catch (final IOException exception) { LOGGER.error("Exception occured while closing bufferedReader :" + exception); } } if (inputStreamReader != null) { try { inputStreamReader.close(); } catch (final IOException exception) { LOGGER.error("Exception while closing input stream :" + exception); } } } writeToPropertyFile(propertyFile, propertiesToWrite); } /** * API to write a list of Strings to a property file. * * @param propertyFile {@link File} * @param propertiesToWrite {@link List} * @throws IOException */ private static void writeToPropertyFile(final File propertyFile, final List<String> propertiesToWrite) throws IOException { FileWriter fileWriter = null; BufferedWriter bufferedWriter = null; try { fileWriter = new FileWriter(propertyFile, false); bufferedWriter = new BufferedWriter(fileWriter); for (final String lineToWrite : propertiesToWrite) { bufferedWriter.write(lineToWrite); bufferedWriter.newLine(); } } finally { if (bufferedWriter != null) { try { bufferedWriter.close(); } catch (final IOException exception) { LOGGER.error("Exception occured while closing bufferedWriter : " + exception); } } if (fileWriter != null) { try { fileWriter.close(); } catch (final IOException exception) { LOGGER.error("Exception occured while closing fileWriter : " + exception); } } } } /** * API to process A property file and add all properties along with comment to list. * * @param propertyMap {@link Map} * @param bufferedReader {@link BufferedReader} * @param propertiesToWrite {@link List} * @throws IOException */ private static void processPropertyFile(final Map<String, String> propertyMap, final BufferedReader bufferedReader, final List<String> propertiesToWrite) throws IOException { String strLine = null; String key = null; String value = null; while ((strLine = bufferedReader.readLine()) != null) { strLine = strLine.trim(); if (strLine.startsWith(HASH_STRING)) { propertiesToWrite.add(strLine); } else { final int indexOfDelimeter = strLine.indexOf(EQUAL_TO); if (indexOfDelimeter > 0) { key = strLine.substring(0, indexOfDelimeter).trim(); final StringBuilder lineToWrite = new StringBuilder(key); lineToWrite.append(EQUAL_TO); value = propertyMap.get(key); if (value != null) { lineToWrite.append(value); } else { lineToWrite.append(strLine.substring(indexOfDelimeter + 1)); } propertiesToWrite.add(lineToWrite.toString()); } } } } public static String getAbsoluteFilePath(final String pathname) { assert pathname != null : "Path name is Null, pathname : " + pathname; final File file = new File(pathname); return file.getAbsolutePath(); } public static String changeFileExtension(final String fileName, final String extension) { LOGGER.info("Changing extension of file " + fileName + " to " + extension); final int indexOfDot = fileName.lastIndexOf(IUtilCommonConstants.DOT); final String existingFileName = fileName.substring(0, indexOfDot); final StringBuilder fileNameBuilder = new StringBuilder(); fileNameBuilder.append(existingFileName); fileNameBuilder.append(IUtilCommonConstants.DOT); fileNameBuilder.append(extension); return fileNameBuilder.toString(); } /** * This method zips the contents of Directory specified into a zip file whose name is provided. * * @param dir2zip {@link String} directory to be zipped * @param zout {@link ZipOutputStream} zip output stream for the zip file * @param dir2zipName {@link String} directory name for the zip file * @throws IOException throws {@link IOException} if error occurs while creating zip file */ public static void zipDirectory(final String dir2zip, final ZipOutputStream zout, final String dir2zipName) throws IOException { final File srcDir = new File(dir2zip); final List<String> fileList = listDirectory(srcDir); for (final String fileName : fileList) { final File file = new File(srcDir.getParent(), fileName); String zipName = fileName; if (File.separatorChar != FORWARD_SLASH) { zipName = fileName.replace(File.separatorChar, FORWARD_SLASH); } zipName = zipName.substring( zipName.indexOf(dir2zipName + BACKWARD_SLASH) + 1 + (dir2zipName + BACKWARD_SLASH).length()); ZipEntry zipEntry; if (file.isFile()) { zipEntry = new ZipEntry(zipName); zipEntry.setTime(file.lastModified()); zout.putNextEntry(zipEntry); final FileInputStream fin = new FileInputStream(file); final byte[] buffer = new byte[4096]; for (int n; (n = fin.read(buffer)) > 0;) { zout.write(buffer, 0, n); } if (fin != null) { fin.close(); } } else { zipEntry = new ZipEntry(zipName + FORWARD_SLASH); zipEntry.setTime(file.lastModified()); zout.putNextEntry(zipEntry); } } if (zout != null) { zout.close(); } } public static List<String> listDirectory(final File directory) throws IOException { return listDirectory(directory, true); } public static List<String> listDirectory(final File directory, final boolean includingDirectory) throws IOException { final Stack<String> stack = new Stack<String>(); final List<String> list = new ArrayList<String>(); // If it's a file, just return itself if (directory.isFile()) { if (directory.canRead()) { list.add(directory.getName()); } } else { // Traverse the directory in width-first manner, no-recursively final String root = directory.getParent(); stack.push(directory.getName()); while (!stack.empty()) { final String current = (String) stack.pop(); final File curDir = new File(root, current); final String[] fileList = curDir.list(); if (fileList != null) { for (final String entry : fileList) { final File file = new File(curDir, entry); if (file.isFile()) { if (file.canRead()) { list.add(current + File.separator + entry); } else { throw new IOException("Can't read file: " + file.getPath()); } } else if (file.isDirectory()) { if (includingDirectory) { list.add(current + File.separator + entry); } stack.push(current + File.separator + file.getName()); } else { throw new IOException("Unknown entry: " + file.getPath()); } } } } } return list; } /** * This method deletes a given directory with its content. * * @param srcPath */ public static void deleteDirectoryAndContentsRecursive(final File srcPath, final boolean deleteSrcDir) { if (srcPath.exists()) { final File[] files = srcPath.listFiles(); if (files != null) { for (int index = 0; index < files.length; index++) { if (files[index].isDirectory()) { deleteDirectoryAndContentsRecursive(files[index], true); } files[index].delete(); } } } if (deleteSrcDir) { srcPath.delete(); } } public static void deleteDirectoryAndContentsRecursive(final File srcPath) { deleteDirectoryAndContentsRecursive(srcPath, true); } /** * This method unzips a given directory with its content. * * @param zipFilepath * @param destinationDir */ public static void unzip(final File zipFile, final String destinationDir) { final File destinationFile = new File(destinationDir); if (destinationFile.exists()) { destinationFile.delete(); } final class Expander extends Expand { private static final String UNZIP = "unzip"; public Expander() { super(); setProject(new Project()); getProject().init(); setTaskType(UNZIP); setTaskName(UNZIP); } } final Expander expander = new Expander(); expander.setSrc(zipFile); expander.setDest(destinationFile); expander.execute(); } public static String getFileNameOfTypeFromFolder(final String dirLocation, final String fileExtOrFolderName) { String fileOrFolderName = EMPTY_STRING; final File[] listFiles = new File(dirLocation).listFiles(); if (listFiles != null) { for (int index = 0; index < listFiles.length; index++) { if (listFiles[index].getName().toLowerCase(Locale.getDefault()) .indexOf(fileExtOrFolderName.toLowerCase(Locale.getDefault())) > -1) { fileOrFolderName = listFiles[index].getPath(); break; } } } return fileOrFolderName; } public static void createThreadPoolLockFile(final String batchInstanceIdentifier, final String lockFolderPath, final String pluginFolderName) throws IOException { final File lockFolder = new File(lockFolderPath); if (!lockFolder.exists()) { lockFolder.mkdir(); } final File _lockFile = new File(lockFolderPath + File.separator + pluginFolderName); final boolean isCreateSuccess = _lockFile.createNewFile(); if (!isCreateSuccess) { LOGGER.error("Unable to create lock file for threadpool for pluginName:" + pluginFolderName); } } public static void deleteThreadPoolLockFile(final String batchInstanceIdentifier, final String lockFolderPath, final String pluginFolderName) throws IOException { final File _lockFile = new File(lockFolderPath + File.separator + pluginFolderName); final boolean isDeleteSuccess = _lockFile.delete(); if (!isDeleteSuccess) { LOGGER.error("Unable to delete lock file for threadpool for pluginName:" + pluginFolderName); } } public static boolean moveDirectoryAndContents(final String sourceDirPath, final String destDirPath) { boolean success = true; final File sourceDir = new File(sourceDirPath); final File destDir = new File(destDirPath); if (sourceDir.exists() && destDir.exists()) { // delete the directory if it already exists deleteDirectoryAndContentsRecursive(destDir); success = sourceDir.renameTo(destDir); } return success; } public static void deleteSelectedFilesFromDirectory(final String directoryPath, final List<String> filesList) { final File directory = new File(directoryPath); if (directory != null && directory.exists()) { for (final File file : directory.listFiles()) { if (filesList == null || filesList.isEmpty() || !filesList.contains(file.getName())) { file.delete(); } } } } /** * This API is creating file if not exists. * * @param filePath {@link String} * @return isFileCreated */ public static boolean createFile(final String filePath) { boolean isFileCreated = false; final File file = new File(filePath); if (file.exists()) { isFileCreated = true; } else { try { isFileCreated = file.createNewFile(); } catch (final IOException e) { LOGGER.error("Unable to create file" + e.getMessage(), e); } } return isFileCreated; } /** * This method append the src file to dest file. * * @param srcFile * @param destFile * @throws Exception */ public static void appendFile(final File srcFile, final File destFile) throws Exception { InputStream in = null; in = new FileInputStream(srcFile); final FileOutputStream out = new FileOutputStream(destFile, true); final byte[] buf = new byte[1024]; int len; while ((len = in.read(buf)) > 0) { out.write(buf, 0, len); } if (in != null) { in.close(); } if (out != null) { out.close(); } } /** * This API merging the input files into single output file. * * @param srcFiles {@link String} * @param destFile {@link String} * @return */ public static boolean mergeFilesIntoSingleFile(final List<String> srcFiles, final String destFile) throws Exception { final boolean isFileMerged = false; final File outputFile = new File(destFile); for (final String string : srcFiles) { final File inputFile = new File(string); appendFile(inputFile, outputFile); } return isFileMerged; } public static OutputStream getOutputStreamFromZip(final String zipName, final String fileName) throws FileNotFoundException, IOException { ZipOutputStream stream = null; stream = new ZipOutputStream(new FileOutputStream(new File(zipName + ZIP_FILE_EXT))); final ZipEntry zipEntry = new ZipEntry(fileName); stream.putNextEntry(zipEntry); return stream; } /** * Returns input stream from specified zip file. * * @param zipName {@link String} * @param fileName {@link String} * * @return input stream from specified zip file. */ public static InputStream getInputStreamFromZip(final String zipName, final String fileName) throws FileNotFoundException, IOException { // Apache Utility is used in case of Unix operating system. In case of // all other operating system use Java utility. InputStream in = null; boolean status = false; int retryCount = 1; // introducing retry mechanism for zip exception while (!status && retryCount <= RETRY_COUNT) { try { if (OSUtil.isUnix()) { final org.apache.tools.zip.ZipFile zipFile = new org.apache.tools.zip.ZipFile( EphesoftStringUtil.concatenate(zipName, ZIP_FILE_EXT)); in = zipFile.getInputStream(zipFile.getEntry(fileName)); } else { final ZipFile zipFile = new ZipFile(EphesoftStringUtil.concatenate(zipName, ZIP_FILE_EXT)); in = zipFile.getInputStream(zipFile.getEntry(fileName)); } status = true; } catch (java.util.zip.ZipException zipException) { status = false; if (retryCount++ < RETRY_COUNT) { LOGGER.info("ZipException encountered during reading the file. Retrying again", zipException); } else { LOGGER.error( "ZipException encountered during reading the file. Even after retrying 3 times error is not rectified. Please restart batch again if it go into error", zipException); } try { Thread.sleep(SLEEP_PERIOD); } catch (InterruptedException e) { LOGGER.error( "Thread interrupted while calling sleep method in fileUtil(getInputStreamFromZip)"); } } } return in; } public static boolean isZipFileExists(final String zipFilePath) { final File f = new File(zipFilePath + ZIP_FILE_EXT); return f.exists(); } /** * This method returns the updated file name if file with same already exists in the parent folder. * * @param fileName {@link String} * @param parentFolder {@link File} * * * @return updated file name. */ public static String getUpdatedFileNameForDuplicateFile(final String fileName, final File parentFolder) { String updatedFileName = fileName; int fileCount = -1; StringBuilder stringBuilder = new StringBuilder(); boolean fileExists = new File(parentFolder, updatedFileName).exists(); final int indexOfSeperator = fileName.lastIndexOf(IUtilCommonConstants.DOT); final String onlyFileName = fileName.substring(0, indexOfSeperator); final String onlyExtension = fileName.substring(indexOfSeperator); while (fileExists) { fileCount++; stringBuilder = new StringBuilder(); stringBuilder.append(onlyFileName); stringBuilder.append(IUtilCommonConstants.UNDER_SCORE); stringBuilder.append(fileCount); stringBuilder.append(onlyExtension); updatedFileName = stringBuilder.toString(); fileExists = new File(parentFolder, updatedFileName).exists(); } return updatedFileName; } /** * This method returns the updated file name if file with same already exists in the parent folder. * * @param fileName {@link String} * @param parentFolder {@link File} * @param fileCount {@link Integer} Specifies the count to be appended in the file name if file with same name already exists. * (Initially -1 is passed when method is called first time for a file) * @return */ public static String getUpdatedFileNameForDuplicateFile(final String fileName, final File parentFolder, final int fileCount, final String extension) { String updatedFileName = null; if (fileCount < 0) { updatedFileName = fileName; } else { updatedFileName = fileName + '_' + fileCount; } if (new File(parentFolder, updatedFileName + extension).exists()) { updatedFileName = getUpdatedFileNameForDuplicateFile(fileName, parentFolder, fileCount + 1, extension); } else { return updatedFileName; } return updatedFileName; } /** * This method checks if the file with specific filer name already exists in the the parent folder. * * @param fileName {@link String} name of the file to be searched. If null returns false. * @param parentFolder {@link File} folder in which file is to be searched. If null or if is not a directory,returns false. * @return true if the file exists, else false. */ public static boolean isFileExists(final String fileName, final File parentFolder) { LOGGER.info("checking if file with name " + fileName + " exists in folder " + parentFolder); boolean fileExists = false; if (parentFolder != null && parentFolder.isDirectory()) { LOGGER.info("Parent folder is a directory."); final File[] files = parentFolder.listFiles(new FileExistenceFilter(fileName)); fileExists = null != files && files.length > 0; } return fileExists; } /** * This method checks if the file with specific filer name already exists in the the parent folder. * * @param fileName {@link String} * @param parentFolder {@link File} * @return */ // public static boolean isFileExists(String fileName, File parentFolder) { // return isFileExists(fileName, parentFolder, false); // } public static boolean cleanUpDirectory(final File srcPath) { boolean isDeleted = true; if (srcPath.exists()) { final File[] files = srcPath.listFiles(); if (files != null) { for (int index = 0; index < files.length; index++) { if (files[index].isDirectory()) { isDeleted &= cleanUpDirectory(files[index]); } isDeleted &= files[index].delete(); } } } isDeleted &= srcPath.delete(); return isDeleted; } public static String createOSIndependentPath(final String path) { final StringTokenizer t = new StringTokenizer(path, "/\\"); final StringBuffer OSIndependentfilePath = new StringBuffer(); boolean isFirst = true; while (t.hasMoreTokens()) { if (!isFirst) { OSIndependentfilePath.append(File.separator); } OSIndependentfilePath.append(t.nextToken()); isFirst = false; } return OSIndependentfilePath.toString(); } /** * This API moves file from source path to destination path by creating destination path if it does not exists. * * @param sourcePath source path of file to be moved * @param destinationPath destination path where file has to be moved * @return operation success * @throws Exception error occurred while copying file from source to destination path */ public static boolean moveFile(final String sourcePath, final String destinationPath) throws Exception { boolean success = false; if (null != sourcePath && null != destinationPath) { final File sourceFile = new File(sourcePath); final File destinationFile = new File(destinationPath); // Delete the file if already exists if (destinationFile.exists()) { deleteDirectoryAndContentsRecursive(destinationFile, true); } // Create directories for destination path if (destinationFile.getParentFile() != null) { destinationFile.getParentFile().mkdirs(); } // Moving file from source path to destination path // REMOVED file.renameTo() implementation as it was environment dependent. And at times does not succeed. /* * if (sourceFile.exists() && sourceFile.canWrite()) { success = sourceFile.renameTo(destinationFile); if (success) { * LOGGER.info("Successfully changed the source file at " + sourceFile.getCanonicalPath() + " to " + * destinationFile.getCanonicalPath()); } } */ // Copy file from source to destination path when the source file cannot be deleted if (!success && sourceFile.exists() && sourceFile.canWrite()) { LOGGER.info("Copying the folder from " + sourceFile.getCanonicalPath() + " to " + destinationFile.getCanonicalPath()); if (sourceFile.isDirectory()) { copyDirectoryWithContents(sourceFile, destinationFile); } else { copyFile(sourceFile, destinationFile); } // Upon successful copy of the file to destination, now deleting it. forceDelete(sourceFile); success = true; } } return success; } /** * This method checks whether the given file is a directory or file. * * @param folderDetail - file to be checked * @return */ public static boolean checkForFile(final String filePath) { boolean isFile = false; if (null != filePath) { final File file = new File(filePath); isFile = !file.isDirectory(); } return isFile; } /** * Method to replace invalid characters from file name {fileName} by the replace character specified by admin. * * @param fileName name of the file from which invalid characters are to be replaced. * @param invalidChars array of invalid characters which are to be replaced. * @return */ public static String replaceInvalidFileChars(final String fileName) { String finalReplaceChar = IUtilCommonConstants.UNDER_SCORE; final String[] invalidChars = IUtilCommonConstants.INVALID_FILE_EXTENSIONS .split(IUtilCommonConstants.INVALID_CHAR_SEPARATOR); LOGGER.info("Entering removeInvalidFileChars method"); String updatedFileName = fileName; if (fileName != null && !fileName.isEmpty() && invalidChars != null && invalidChars.length > 0) { if (finalReplaceChar == null || finalReplaceChar.isEmpty()) { LOGGER.info("Replace character not specified. Using default character '-' as a replace character."); finalReplaceChar = DEFAULT_REPLACE_CHAR; } for (final String invalidChar : invalidChars) { if (finalReplaceChar.equals(invalidChar)) { LOGGER.info( "Replace character not specified or an invalid character. Using default character '-' as a replace character."); finalReplaceChar = DEFAULT_REPLACE_CHAR; } updatedFileName = updatedFileName.replace(invalidChar, finalReplaceChar); } } LOGGER.info("Exiting removeInvalidFileChars method"); return updatedFileName; } /** * API to check whether two file names are equal or not. File extensions are ignored while comparing the file names. * * @param fileName1 {@link String} file name to be compared * @param fileName2 {@link String} file name to be compared * @return return true if file names are equal, false otherwise; */ public static boolean compareFileNames(final String fileName1, final String fileName2) { LOGGER.debug(EphesoftStringUtil.concatenate("Comaring file names fileName1 = ", fileName1, " fileName2 = ", fileName2)); boolean isEqual = false; if (fileName1 != null || fileName2 != null) { int indexOf = fileName1.lastIndexOf(IUtilCommonConstants.DOT); indexOf = indexOf == -1 ? fileName1.length() : indexOf; final String localOldFileName = fileName1.substring(0, indexOf); indexOf = fileName2.lastIndexOf(IUtilCommonConstants.DOT); indexOf = indexOf == -1 ? fileName1.length() : indexOf; final String localImageName = fileName2.substring(0, indexOf); isEqual = localImageName.equalsIgnoreCase(localOldFileName); } LOGGER.debug(EphesoftStringUtil.concatenate("Are file names equal = ", isEqual)); return isEqual; } /** * This API is used to validate a file's entension against a set of valid extensions. * * @param fileName {@link String} * @param supportedExtensions {@link String}[] * @return */ public static boolean isFileExtensionValid(final String fileName, final String... supportedExtensions) { LOGGER.info("Checking validation on file with name " + fileName); final String attachmentExtension = fileName.substring(fileName.lastIndexOf(IUtilCommonConstants.DOT) + 1); boolean isFileValid = false; for (int i = 0; i < supportedExtensions.length; i++) { if (attachmentExtension.equalsIgnoreCase(supportedExtensions[i])) { isFileValid = true; break; } } if (isFileValid) { LOGGER.info("File " + fileName + " does not belong to " + supportedExtensions + " file type."); } else { LOGGER.info("File " + fileName + " is valid "); } return isFileValid; } /** * This API is used write the content of an Input Stream to a given file. Method will not close the input stream object. That must * be closed by the calling method. * * @param saveFile {@link File} * @param inputStream {@link InputStream} * @return Size of buffer * @throws FileNotFoundException * @throws IOException */ public static int writeFileViaStream(final File saveFile, final InputStream inputStream) throws FileNotFoundException, IOException { BufferedOutputStream bos = null; int ret = 0, count = 0; if (saveFile != null && inputStream != null) { try { bos = new BufferedOutputStream(new FileOutputStream(saveFile)); final byte[] buff = new byte[2048]; ret = inputStream.read(buff); while (ret > 0) { bos.write(buff, 0, ret); count += ret; ret = inputStream.read(buff); } } finally { try { if (bos != null) { bos.close(); } if (inputStream != null) { inputStream.close(); } } catch (final IOException ioe) { LOGGER.error("Error while closing the stream.", ioe); } } } return count; } /** * This API unzips files in specified destination directory. Destination directory is created if it doesn't exist. If destination * directory passed is null, zip will be extracted in its parent directory. * * @param zipFile {@link File} Zip File to be unzipped. * @param destinationDir {@link String} Directory where file is to be unzipped. * @throws IOException * @throws FileNotFoundException */ public static void unzipFiles(final File fSourceZip, final String destinationDir) throws FileNotFoundException, IOException { String finalDestinationDir = destinationDir; LOGGER.info("Extracting zip file = " + fSourceZip.getAbsolutePath()); BufferedInputStream bis = null; FileOutputStream fos = null; BufferedOutputStream bos = null; ZipFile zipFile = null; if (null == fSourceZip || !isFileExtensionValid(fSourceZip.getName().toLowerCase(DEFAULT_LOCALE), "zip")) { LOGGER.info("File is either null or not a valid zip file. File passed = " + fSourceZip); } else { // Create destination directory if it doesn't exists try { if (null == finalDestinationDir) { finalDestinationDir = fSourceZip.getParent(); LOGGER.info( "destination Directory null, extracting files to directory = " + finalDestinationDir); } final File destDir = new File(finalDestinationDir); if (!destDir.exists()) { destDir.mkdir(); LOGGER.info("destination directory " + finalDestinationDir + " created"); } zipFile = new ZipFile(fSourceZip); // Extract entries from zip file final Enumeration<? extends ZipEntry> zipEntry = zipFile.entries(); while (zipEntry.hasMoreElements()) { final ZipEntry entry = (ZipEntry) zipEntry.nextElement(); if (entry != null) { final String outputFileName = entry.getName(); // if the entry is directory, leave it. if (entry.isDirectory() || isFileExtensionValid(outputFileName.toLowerCase(DEFAULT_LOCALE), "zip")) { LOGGER.info( "Cann't import entry within zip file. Entry is either a directory or a zip file. Entry : " + outputFileName); continue; } else { File destinationFilePath = new File(finalDestinationDir, outputFileName); final String newFileName = updateFileName(destinationFilePath.getName(), finalDestinationDir); destinationFilePath = new File(finalDestinationDir, newFileName); LOGGER.info("Extracting file = " + outputFileName); // Get the InputStream for current entry of the zip file using getInputStream(Entry entry) method. bis = new BufferedInputStream(zipFile.getInputStream(entry)); // read the current entry from the zip file, extract it and write the extracted file. fos = new FileOutputStream(destinationFilePath); bos = new BufferedOutputStream(fos, 1024); int data; final byte buffer[] = new byte[1024]; boolean endOfFile = (data = bis.read(buffer, 0, 1024)) != -1; while (endOfFile) { bos.write(buffer, 0, data); endOfFile = (data = bis.read(buffer, 0, 1024)) != -1; } bos.flush(); } } } } finally { try { LOGGER.info("Closing input and ouput streams..."); // flush the output stream and close it. if (bos != null) { bos.flush(); bos.close(); } // close the input stream. if (bis != null) { bis.close(); } if (null != zipFile) { zipFile.close(); } } catch (final Exception e) { LOGGER.info("Error occurred while closing the stream for extracting zip file....", e); } } } } private static String updateFileName(final String fileName, final String folderPath) { String finalFileName = fileName; if (fileName != null) { int extensionIndex = fileName.indexOf(IUtilCommonConstants.DOT); extensionIndex = extensionIndex == -1 ? fileName.length() : extensionIndex; final File parentFile = new File(folderPath); LOGGER.info("Updating file name if any file with the same name exists. File : " + fileName); finalFileName = getUpdatedFileNameForDuplicateFile(fileName.substring(0, extensionIndex), parentFile, -1, fileName.substring(extensionIndex)) + fileName.substring(extensionIndex); LOGGER.info("Updated file name : " + finalFileName); } return finalFileName; } /** * This method copies the contents of one folder into another. * * @param originalFolder the folder to copy * @param copiedFolder the folder to store the copied content * @throws IOException */ public static void copyFolder(final File originalFolder, final File copiedFolder) throws IOException { if (copiedFolder.exists()) { copiedFolder.delete(); } copiedFolder.mkdirs(); if (originalFolder.isDirectory()) { final String[] folderList = originalFolder.list(); Arrays.sort(folderList); for (final String folderName : folderList) { FileUtils.copyDirectoryWithContents(new File(originalFolder, folderName), new File(copiedFolder, folderName)); } } } /** * This method zips the contents of Directory specified into a zip file whose name is provided. * * @param dir2zip {@link String} the directory to zip * @param zout {@link ZipOutputStream} the zip stream * @throws IOException */ public static void zipDirectoryWithFullName(final String dir2zip, final ZipOutputStream zout) throws IOException { final File srcDir = new File(dir2zip); final List<String> fileList = FileUtils.listDirectory(srcDir); for (final String fileName : fileList) { final File file = new File(srcDir.getParent(), fileName); String zipName = fileName; if (File.separatorChar != FORWARD_SLASH) { zipName = fileName.replace(File.separatorChar, FORWARD_SLASH); } ZipEntry zipEntry; if (file.isFile()) { zipEntry = new ZipEntry(zipName); zipEntry.setTime(file.lastModified()); zout.putNextEntry(zipEntry); final FileInputStream fin = new FileInputStream(file); final byte[] buffer = new byte[BUFFER_SIZE]; for (int n; (n = fin.read(buffer)) > 0;) { zout.write(buffer, 0, n); } if (fin != null) { fin.close(); } } else { zipEntry = new ZipEntry(zipName + FORWARD_SLASH); zipEntry.setTime(file.lastModified()); zout.putNextEntry(zipEntry); } } if (zout != null) { zout.close(); } } /** * This method zip the multiple files. * * @param dir2zip {@link String} The directory in which file need to zip. * @param zout {@link ZipOutputStream} The zipoutput stream. * @param fileExtension {@link String} The extension of file which need to zip. * @throws {@link IOException} */ public static void zipMultipleFiles(final String dir2zip, final ZipOutputStream zout, final String fileExtension) throws IOException { final File srcDir = new File(dir2zip); if (srcDir.exists()) { final List<String> fileList = listDirectory(srcDir); for (final String fileName : fileList) { final File file = new File(srcDir.getParent(), fileName); String zipName = fileName; if (File.separatorChar != FORWARD_SLASH) { zipName = fileName.replace(File.separatorChar, FORWARD_SLASH); } ZipEntry zipEntry; if (file.isFile()) { zipEntry = new ZipEntry(zipName); zipEntry.setTime(file.lastModified()); zout.putNextEntry(zipEntry); final FileInputStream fin = new FileInputStream(file); final byte[] buffer = new byte[INITIAL_SIZE]; int bytesRead; bytesRead = fin.read(buffer); while (bytesRead != -1) { zout.write(buffer, 0, bytesRead); bytesRead = fin.read(buffer); } if (fin != null) { fin.close(); } } else { zipEntry = new ZipEntry(zipName + FORWARD_SLASH); zipEntry.setTime(file.lastModified()); zout.putNextEntry(zipEntry); } } if (zout != null) { zout.close(); } } else { LOGGER.error("Source folder doesn't exist."); } } /** * Deletes a file. If file is a directory, deletes it and all sub-directories. * <p> * The difference between File.delete() and this method are: * <ul> * <li>A directory to be deleted does not have to be empty.</li> * <li><code>{@link IUtilCommonConstants}.DELETE_RETRY_INDEX</code> count of maximum attempts will be made to delete the file</li> * <li>An error log will be logged for each unsuccessful attempt to delete the file, but no exception will be thrown.</li> * </ul> * * Must only be used if the files to be deleted can be left behind in case the deletion is unsuccessful. * * @param fileToBeDeleted file or directory to be deleted. * @return boolean, true if the file deletion was successful, false otherwise. */ public static boolean forceDelete(final File fileToBeDeleted) { boolean isFolderDeleted = false; if (fileToBeDeleted != null) { final String fileAbsolutePath = fileToBeDeleted.getAbsolutePath(); if (fileToBeDeleted.exists()) { LOGGER.info(EphesoftStringUtil.concatenate("Trying to delete ", fileAbsolutePath)); for (int retryIndex = 0; retryIndex < IUtilCommonConstants.DELETE_RETRY_MAX_COUNT; retryIndex++) { try { org.apache.commons.io.FileUtils.forceDelete(fileToBeDeleted); isFolderDeleted = true; break; } catch (final IOException e) { LOGGER.error(EphesoftStringUtil.concatenate(fileAbsolutePath, " folder could not be deleted in ", (retryIndex + 1), " attempt(s). Max ", IUtilCommonConstants.DELETE_RETRY_MAX_COUNT, " tries.")); } } } else { LOGGER.error(EphesoftStringUtil.concatenate("The file/folder ", fileAbsolutePath, " does not exist. So cannot be deleted.")); } } else { LOGGER.error("File object is null. Escaping the delete functionality."); } return isFolderDeleted; } /** * Waits for a folder to be modified completely. * * @param folderToCheck directory to be monitored for modification. * @param timeoutLimit for folder-modification. */ public static void waitForFolderModification(final File folderToCheck, final long timeoutLimit) { if (null != folderToCheck && folderToCheck.isDirectory() && timeoutLimit > 0) { final long startTimeWaitCopyOperation = System.currentTimeMillis(); // Wait for folder to be copied completely while (isFolderModification(folderToCheck, ONE_MINUTE) && (System.currentTimeMillis() - startTimeWaitCopyOperation) < timeoutLimit) { try { Thread.sleep(TEN_SECONDS); } catch (final InterruptedException exception) { LOGGER.error(EphesoftStringUtil.concatenate("interrupted exception occured. ", exception.getMessage())); } } } } /** * Checks whether folder is modified or not within the specified duration. * * @param folderToCheck {@link File}- folder to be checked * @param waitingDuration {@link Long}- time duration for folder modification * @return {@link Boolean}- <code>true</code> if folder has been modified within the specified duration, else <code>false</code> */ public static boolean isFolderModification(final File folderToCheck, final long waitingDuration) { boolean isFolderModified = false; if (null != folderToCheck && waitingDuration >= 0) { if (folderToCheck.exists() && ((System.currentTimeMillis() - folderToCheck.lastModified()) < waitingDuration)) { isFolderModified = true; LOGGER.debug(EphesoftStringUtil.concatenate(folderToCheck.getAbsolutePath(), " is not modified since last minute. So now this folder will be sent for batch processing.")); } } return isFolderModified; } /** * This method checks whether the given directory is empty or not. * * @param directoryPath - dir to be checked * @return */ public static boolean checkForEmptyDirectory(final String directoryPath) { boolean isEmpty = false; if (null != directoryPath) { final File file = new File(directoryPath); if (!file.exists()) { file.mkdirs(); isEmpty = true; } else { final File[] listOfFiles = file.listFiles(); if ((listOfFiles != null && listOfFiles.length <= 0)) { isEmpty = true; } } } return isEmpty; } /** * Creates backup of oldFile on the backUpFilePath and replaces oldFile with newFile. * * @param {@link String} oldFilePath whose backup is to be created. * @param {@link String} backUpFilePath backup file path. * @param {@link String} newFilePath file path of new file to be copied in place. * @return boolean true if operation is successful false otherwise. */ public static boolean backupAndCopyFile(final String oldFilePath, final String backUpFilePath, final String newFilePath) { LOGGER.debug(EphesoftStringUtil.concatenate("Inside backupAndCopyFile method. oldFilePath is ", oldFilePath, " ,backUpFilePath is ", backUpFilePath, " and newFilePath is ", newFilePath)); boolean isBackUpCreated = false; if (!(EphesoftStringUtil.isNullOrEmpty(oldFilePath) || EphesoftStringUtil.isNullOrEmpty(backUpFilePath) || EphesoftStringUtil.isNullOrEmpty(newFilePath))) { try { final File newFile = new File(newFilePath); if (newFile.exists()) { final File oldFile = new File(oldFilePath); final boolean backupSuccess = FileUtils.moveFile(oldFilePath, backUpFilePath); if (backupSuccess) { LOGGER.debug(EphesoftStringUtil.concatenate(oldFilePath, " backed up successfully to ", backUpFilePath)); } else { LOGGER.debug(EphesoftStringUtil.concatenate("Unable to create backup of file ", oldFilePath, " to ", backUpFilePath, " as file ", oldFilePath, "does not exist. Copying new file without creating backup.")); } FileUtils.copyFile(newFile, oldFile); isBackUpCreated = true; } else { LOGGER.error(EphesoftStringUtil.concatenate("File is not present at path: ", newFilePath)); } } catch (final Exception exception) { LOGGER.error(EphesoftStringUtil.concatenate("Unable to create backup of file ", oldFilePath, "backUpFilePath is ", backUpFilePath, " and new file path is ", newFilePath, exception.getMessage()), exception); } } return isBackUpCreated; } /** * Writes text to specified file. * * @param {@link File} fileName name of file where write operation is to be perform. * @param {@link String} textToWrite text to be written in specified file. * @param {@link boolean} appendText flag to decide whether overwrite or append specified text. * */ public static void writeTextToFile(final File gsArgumentFile, final String textToWrite, final boolean appendText) { LOGGER.debug(EphesoftStringUtil.concatenate("Writing text : ", textToWrite, " to file ", gsArgumentFile.getAbsolutePath())); if (null != gsArgumentFile && !EphesoftStringUtil.isNullOrEmpty(textToWrite)) { BufferedWriter bufferedWriter = null; try { bufferedWriter = new BufferedWriter(new FileWriter(gsArgumentFile, appendText)); bufferedWriter.write(textToWrite); LOGGER.debug(EphesoftStringUtil.concatenate("Text : ", textToWrite, " is written to file ", gsArgumentFile.getAbsolutePath(), " successfully.")); } catch (final IOException exception) { LOGGER.error(EphesoftStringUtil.concatenate("Exception occured while writing content to file ", gsArgumentFile.getAbsolutePath()), exception); } finally { try { if (null != bufferedWriter) { bufferedWriter.close(); } } catch (final IOException exception) { LOGGER.error("Exception occured while closing stream. Exception is ", exception); } } } else { LOGGER.error(EphesoftStringUtil.concatenate( "Invalid parameter are specified for operation. Unable to perform any processing.")); } } /** * Checks if the file whose path is passed as a parameter is used by another process or not. In case parameter is passed as NULL or * empty <code>true</code> is returned. * * <p> * It internally uses apache {@link org.apache.commons.io.FileUtils} <code>touch</code>> method. This method will wait for 1 minute * for the file to be released by another process otherwise it return <code>true</code>. * * @param file {@link File} File to be checked for locking. * @return true if file is locked otherwise false. */ public static boolean isFileLocked(final File file) { boolean isFileLocked = true; String filePath = null; // changes with respect to ticket 2692: invalid batch xml creation in report-data folder for import multipage plugin. if (null != file && file.exists()) { filePath = file.getAbsolutePath(); LOGGER.debug(EphesoftStringUtil.concatenate("Checking for file lock on: ", filePath)); long startTime = System.currentTimeMillis(); // Check and wait for 1 minute for the release of file if it is // locked while (isFileLocked && (System.currentTimeMillis() - startTime) < WAITING_TIME) { try { org.apache.commons.io.FileUtils.touch(file); isFileLocked = false; } catch (final IOException ioException) { // Wait for 1 second and check again if the file is released try { Thread.sleep(ONE_SECOND); } catch (final InterruptedException interruptedException) { // Do nothing } isFileLocked = true; } } } LOGGER.debug(EphesoftStringUtil.concatenate("Status of file: ", filePath, " locked is: ", isFileLocked)); return isFileLocked; } /** * This method renames a folder given its original path and new path as parameter. * * @param originalPath {@link String} value containing path of original folder. * @param newPath {@link String} value containing path of new folder which will replace old folder. * @return returns the status of operation as boolean value. */ public static boolean renameFolder(final String originalPath, final String newPath) { boolean renameSuccessful = false; LOGGER.debug( EphesoftStringUtil.concatenate("Original path is : ", originalPath, " New Path is : ", newPath)); if (originalPath == null) { LOGGER.error("Path of Original folder is null"); } else if (newPath == null) { LOGGER.error("Path of new folder is null"); } else { final File originalFolder = new File(originalPath); renameSuccessful = originalFolder.renameTo(new File(newPath)); // Update the UNC folder name in the file system. if (renameSuccessful) { LOGGER.info("Moving of Directory and its contents of original path folder is successful"); } else { LOGGER.error("Moving of Directory and its contents of original path folder is failed"); } } return renameSuccessful; } /** * Checks if any file exists with the file path passed. * * @param inputFilePath {@link String} Absolute Path of file whose existence is to be checked. * @return Returns true if file exists otherwise false. */ public static boolean isFileExists(final String inputFilePath) { boolean isFileExists = false; if (!EphesoftStringUtil.isNullOrEmpty(inputFilePath)) { File file = new File(inputFilePath); isFileExists = file.exists(); } return isFileExists; } /** * Gets the file extension for the file. * * @param imagePath {@link String} absolute file path */ public static String getFileExtension(final String imagePath) { String fileExtension = null; if (!EphesoftStringUtil.isNullOrEmpty(imagePath)) { int extensionIndex = imagePath.lastIndexOf(IUtilCommonConstants.DOT); if (extensionIndex != -1) { fileExtension = imagePath.substring(extensionIndex + 1); } } return fileExtension; } /** * Closes the com.itextpdf.text.pdf.RandomAccessFileOrArray. * * @param randomAccessFile {@link com.itextpdf.text.pdf.RandomAccessFileOrArray} com.itextpdf.text.pdf.RandomAccessFileOrArray to * be closed */ public static void closeStream(final RandomAccessFileOrArray randomAccessFile) { try { if (randomAccessFile != null) { randomAccessFile.close(); } } catch (IOException ioException) { LOGGER.error("Error occurred while closing RandomAccessFileOrArray.", ioException); } } /** * Closes the reader stream. * * @param reader {@link java.io.Reader} to be closed */ public static void closeStream(final Reader reader) { IOUtils.closeQuietly(reader); } /** * Creates the key store file at the path <code> keyStoreFilePath </code> which is secured by the <code>password</code> and stores * the Key store in to the file. * * @param keyStoreFilePath {@link String} absolute/Relative path to the key store file * @param password char[] password by which the file is secured * @param store {@link KeyStore} that protects the key store file * @return boolean true if file is created , otherwise false. * @throws GeneralSecurityException when key store key could not be stored * @throws IOException when could not update the file / store the contents of key store at the path */ public static boolean createKeyStoreFile(final String keyStoreFilePath, final char[] password, final KeyStore store) throws GeneralSecurityException, IOException { FileOutputStream keyStoreStream = null; boolean fileCreated = false; try { if (store != null && !EphesoftStringUtil.isNullOrEmpty(keyStoreFilePath) && password != null) { File keyStoreFile = new File(keyStoreFilePath); File parentFile = keyStoreFile.getParentFile(); parentFile.mkdirs(); keyStoreStream = new FileOutputStream(keyStoreFilePath); store.store(keyStoreStream, password); fileCreated = true; } } finally { IOUtils.closeQuietly(keyStoreStream); } return fileCreated; } /** * Checks whether the fileToSearch exists under the parent Directory. If the parent file is a directory and the file to search * exist under the directory then it returns true else returns false. * * @param parentDirectoryPath {@link String} Relative or absolute path to the parent directory * @param fileToSearchPath {@link String} file to locate if is under the parent directory or not. * @return true if the file exists under the parent directory else false. */ public static boolean isUnderDirectory(final String parentDirectoryPath, final String fileToSearchPath) { boolean isUnderDirectory = false; if (!EphesoftStringUtil.isNullOrEmpty(parentDirectoryPath) && !EphesoftStringUtil.isNullOrEmpty(fileToSearchPath)) { File parentDirectory = new File(parentDirectoryPath); File subFolderFile = new File(fileToSearchPath); if (parentDirectory.isDirectory() && subFolderFile.exists()) { String parentFileAbsolutePath = parentDirectory.getAbsolutePath(); String subFolderFileAbsolutePath = parentDirectory.getAbsolutePath(); isUnderDirectory = subFolderFileAbsolutePath.startsWith(parentFileAbsolutePath); } } return isUnderDirectory; } /** * Creates JDOM document from a given xml. * * @param xmlFilePath the xml file path * @return JDOM document for given xml file */ public static org.jdom.Document createJDOMDocumentFromXML(final String xmlFilePath) { LOGGER.info(EphesoftStringUtil.concatenate("Entering create document from xml ", xmlFilePath)); org.jdom.Document document = null; try { SAXBuilder sb = new SAXBuilder(); document = sb.build(xmlFilePath); } catch (FileNotFoundException fileNotFoundException) { LOGGER.error(EphesoftStringUtil.concatenate("File not found = ", xmlFilePath, fileNotFoundException.getMessage())); } catch (Exception exception) { LOGGER.error(EphesoftStringUtil.concatenate("Exception occured while creating document from xml = ", xmlFilePath, exception.getMessage())); } LOGGER.info("Exiting create document from xml"); return document; } private FileUtils() { // private constructor added to make the class non-instantiable. } /** * This method deletes a given directory with its content without throwing exceptions. Implementation of apache FileUtils method * deleteQuietly. * * @param srcFile {@link File} the file to be deleted along with its contents. * @return boolean true if deletion successful, false otherwise. */ public static boolean deleteQuietly(final File srcFile) { boolean deletionSuccessful = false; if (srcFile == null) { deletionSuccessful = false; } try { if (srcFile.isDirectory()) { deleteDirectoryAndContentsRecursive(srcFile); } else { deletionSuccessful = srcFile.delete(); } } catch (Exception ignored) { deletionSuccessful = false; } return deletionSuccessful; } /** * Closes the Closeable resource. * * @param closeable {@link Closeable} to be closed. */ public static void closeResource(final Closeable closeable) { IOUtils.closeQuietly(closeable); } /** * Closes the FileChannelRandomAccessSource. * * @param fileChannelRandomAccessSource {@link com.itextpdf.text.io.FileChannelRandomAccessSource} to be closed. */ public static void closeFileChannelRandomAccessSource( final FileChannelRandomAccessSource fileChannelRandomAccessSource) { try { if (null != fileChannelRandomAccessSource) { fileChannelRandomAccessSource.close(); } } catch (final IOException e) { LOGGER.error(EphesoftStringUtil.concatenate( "Exception occured while closing fileChannelRandomAccessSource ", e.getMessage(), e)); } } /** * Deletes files of specified file type from folder. * * @param folderPath Absolute path of the folder * @param fileExtension extension for files to be deleted */ public static void deleteFileOfType(final String folderPath, final String fileExtension) { if (!EphesoftStringUtil.isNullOrEmpty(folderPath)) { File directory = new File(folderPath); if (directory.isDirectory() && directory.exists()) { File[] fileList = directory.listFiles(new FilenameFilter() { @Override public boolean accept(File dir, String name) { return name.toLowerCase().endsWith(fileExtension.toLowerCase()); } }); for (File file : fileList) { file.delete(); } } } } /** * Returns a list of all the valid file names in a directory that match the regex pattern * * @param filePath path of the folder location from where the files will be picked * * @return list of all file names that match the regex */ public static List<String> getFileNamesWithRegexMatch(final String filePath, final String regexPattern) { List<String> fileNameList = new ArrayList<String>(); if (EphesoftStringUtil.isNullOrEmpty(regexPattern) || EphesoftStringUtil.isNullOrEmpty(filePath)) { LOGGER.info("File path or regex pattern is null or blank"); } else { File folderPath = new File(filePath); File[] listOfFiles = folderPath.listFiles(); for (File file : listOfFiles) { if (file.getName().matches(regexPattern)) { fileNameList.add(file.getName()); } } } return fileNameList; } /** * returs a list of file names without extension from a directory that match a particular pattern * * @param filePath * @param regexPattern * @return */ public static List<String> getFileNamesWithRegexMatchWithoutExtension(final String filePath, final String regexPattern) { List<String> fileNameList = new ArrayList<String>(); if (EphesoftStringUtil.isNullOrEmpty(regexPattern) || EphesoftStringUtil.isNullOrEmpty(filePath)) { LOGGER.info("File path or regex pattern is null or blank"); } else { File folderPath = new File(filePath); File[] listOfFiles = folderPath.listFiles(); for (File file : listOfFiles) { if (file.getName().matches(regexPattern)) { fileNameList.add(org.apache.commons.io.FilenameUtils.removeExtension(file.getName())); } } } return fileNameList; } /** * Checks if is directory has all valid extension files. * * @param tempUnZipDir the temp un zip dir * @param serializationExt the serialization ext * @return true, if is directory has all valid extension files */ public static boolean isDirectoryHasAllValidExtensionFiles(String tempUnZipDir, String serializationExt) { boolean isValid = true; File folderPath = new File(tempUnZipDir); if (folderPath.isDirectory()) { File[] listOfFiles = folderPath.listFiles(); if (listOfFiles.length > 0) { for (File file : listOfFiles) { if (file.isDirectory() || !isFileExtensionValid(file.getAbsolutePath(), serializationExt)) { isValid = false; break; } } } else { isValid = false; } } else { isValid = false; } return isValid; } /** * * Deletes files from the directory comparing modified time with cutoff in milliseconds * * @param file * @param cutoff * @param acceptOlder * @return */ public static void deleteAgedFile(File file, long cutoff, boolean acceptOlder) { deleteFiles(file, new AgeFileFilter(cutoff, acceptOlder)); } /** * Deletes files from the folder with the specified filter * * @param directory * @param fileFilter */ public static void deleteFiles(File directory, FileFilter fileFilter) { File[] files = directory.listFiles(fileFilter); List<String> deletedFiles = new ArrayList<String>(files.length); for (File file : files) { if (file.isDirectory()) { FileUtils.deleteDirectoryAndContentsRecursive(file); } else { file.delete(); } deletedFiles.add(file.getName()); } LOGGER.info(EphesoftStringUtil.concatenate(deletedFiles, " files deleted from directory ", directory)); } /** * Returns recursive count of specified file extensions present inside specified directory on the basis of recursive flag. * * @param directoryPath {@link String} to be searched for file count. * @param {@link String[]} extensions has file extensions to be searched in directory. * @param recursive flag to perform file search recursively. * @return count of specified file extensions */ public static int getFileCountOfTypeFromDirectory(final String directoryPath, final String[] extensions, final boolean recursive) { LOGGER.info("Executing getFileCountOfTypeFromDirectory API."); int filesCount = 0; if (!EphesoftStringUtil.isNullOrEmpty(directoryPath) && null != extensions) { LOGGER.info(EphesoftStringUtil.concatenate("Executing getFileCountOfTypeFromDirectory for directory : ", directoryPath, ". Files extension to be searched are : ", Arrays.toString(extensions), " and recursive flag is : ", recursive)); filesCount = org.apache.commons.io.FileUtils.listFiles(new File(directoryPath), extensions, recursive) .size(); LOGGER.info(EphesoftStringUtil.concatenate("Total ", filesCount, " are present in directory that matches specified extentions.")); } else { LOGGER.error( "Either specified directory or extension is invalid. Please make sure correct arguments are specified."); } LOGGER.info("Executed getFileCountOfTypeFromDirectory API."); return filesCount; } }