| /* |
| * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0, |
| * or the Eclipse Distribution License v. 1.0 which is available at |
| * http://www.eclipse.org/org/documents/edl-v10.php. |
| * |
| * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause |
| */ |
| |
| // Contributors: |
| // Oracle - initial API and implementation from Oracle TopLink |
| package org.eclipse.persistence.tools.file; |
| |
| import java.io.ByteArrayOutputStream; |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.FileOutputStream; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.OutputStream; |
| import java.util.Objects; |
| import java.util.Vector; |
| import java.util.jar.JarEntry; |
| import java.util.jar.JarOutputStream; |
| import java.util.jar.Manifest; |
| import java.util.zip.CRC32; |
| import java.util.zip.ZipEntry; |
| |
| import org.eclipse.persistence.internal.helper.Helper; |
| import org.eclipse.persistence.logging.AbstractSessionLog; |
| import org.eclipse.persistence.logging.SessionLog; |
| |
| /** |
| * INTERNAL: |
| * |
| * <b>Purpose</b>: Provide common file I/O utilities |
| * @author Steven Vo |
| * @since TopLink 4.5 |
| */ |
| public final class FileUtil { |
| |
| private FileUtil() { |
| } |
| |
| /* Copy file to another file or copy content of a directory to another directory |
| * |
| * @inputPath: path to a file or directory |
| * @outputPath: path to a file or directory |
| * @filteredExtensions: filter files that end with specified strings i.e {".java", ".class", ".xml"} |
| */ |
| public static void copy(String inputPath, String outputPath, String[] filteredExtensions) throws IOException { |
| File inputPathFile = new File(inputPath); |
| |
| if (!inputPathFile.exists()) { |
| return; |
| } |
| |
| File outputPathFile = new File(outputPath); |
| |
| if (!outputPathFile.exists()) { |
| if (outputPathFile.isDirectory()) { |
| if (!outputPathFile.mkdirs()) { |
| AbstractSessionLog.getLog().log(SessionLog.FINE, SessionLog.MISC, |
| "Cannot create directory '{0}'", new Object[] {outputPathFile}, false); |
| } |
| } else { |
| if (!outputPathFile.getParentFile().mkdirs()) { |
| AbstractSessionLog.getLog().log(SessionLog.FINE, SessionLog.MISC, |
| "Cannot create directory '{0}'", new Object[] {outputPathFile}, false); |
| } |
| } |
| } |
| |
| Vector files = findFiles(inputPath, filteredExtensions); |
| |
| for (int i = 0; i < files.size(); i++) { |
| File in = (File)files.elementAt(i); |
| |
| String outFilePath = in.getAbsolutePath().substring(inputPath.length()); |
| outFilePath = outputPath + File.separator + outFilePath; |
| |
| File out = new File(outFilePath); |
| File parent = new File(out.getParent()); |
| |
| if (!parent.exists()) { |
| if (!parent.mkdirs()) { |
| AbstractSessionLog.getLog().log(SessionLog.FINE, SessionLog.MISC, |
| "Cannot create directory '{0}'", new Object[] {outputPathFile}, false); |
| } |
| } |
| |
| copy(new FileInputStream(in), new FileOutputStream(out)); |
| } |
| } |
| |
| /* Copy an input stream to an output stream |
| * |
| * @in: input stream |
| * @out: output stream |
| */ |
| public static void copy(InputStream in, OutputStream out) throws IOException { |
| try (InputStream i = in; OutputStream o = out) { |
| byte[] buffer = new byte[512]; |
| while (true) { |
| int bytesRead = i.read(buffer); |
| if (bytesRead == -1) { |
| break; |
| } |
| |
| o.write(buffer, 0, bytesRead); |
| } |
| } |
| } |
| |
| /* Jar a given directory |
| * |
| * @jarFileName: path of the output jar |
| * @jarDirectory: path to the input directory |
| * @filteredExtensions: filter files that end with specified strings i.e {".java", ".class", ".xml"} |
| */ |
| public static void createJarFromDirectory(String jarFileName, String jarDirectory, String[] filtertedExtensions) throws IOException { |
| File directory = new File(jarDirectory); |
| if (!directory.exists()) { |
| return; |
| } |
| |
| File jar = new File(jarFileName); |
| if (!jar.exists()) { |
| if (!jar.getParentFile().mkdirs()) { |
| AbstractSessionLog.getLog().log(SessionLog.FINE, SessionLog.MISC, |
| "Cannot create directory '{0}'", new Object[] {jar.getParentFile()}, false); |
| } |
| } |
| JarOutputStream jarOut = null; |
| try { |
| jarOut = new JarOutputStream(new FileOutputStream(jar), new Manifest()); |
| Vector files = findFiles(jarDirectory, filtertedExtensions); |
| |
| for (int i = 0; i < files.size(); i++) { |
| File file = (File)files.elementAt(i); |
| |
| String relativePathToDirectory = file.getAbsolutePath().substring(directory.getAbsolutePath().length() + 1); |
| String entryName = relativePathToDirectory.replace('\\', '/'); |
| |
| FileInputStream inStream = null; |
| ByteArrayOutputStream byteStream = null; |
| |
| try { |
| inStream = new FileInputStream(file); |
| byteStream = new ByteArrayOutputStream(); |
| |
| int length = 0; |
| byte[] buffer = new byte[1024]; |
| while ((length = inStream.read(buffer)) > 0) { |
| byteStream.write(buffer, 0, length); |
| } |
| byte[] arr = byteStream.toByteArray(); |
| |
| JarEntry meta = new JarEntry(entryName); |
| jarOut.putNextEntry(meta); |
| meta.setSize(arr.length); |
| meta.setCompressedSize(arr.length); |
| CRC32 crc = new CRC32(); |
| crc.update(arr); |
| meta.setCrc(crc.getValue()); |
| meta.setMethod(ZipEntry.STORED); |
| jarOut.write(arr, 0, arr.length); |
| jarOut.closeEntry(); |
| } finally { |
| Helper.close(byteStream); |
| Helper.close(inStream); |
| } |
| } |
| } finally { |
| Helper.close(jarOut); |
| } |
| } |
| |
| /* |
| * Return vector of all Files contained in a path. |
| * |
| * @filteredExtensions: filter files that end with specified strings i.e {".java", ".class", ".xml"} |
| * If filteredExtensions == null or empty then then return all instances of File contained in the directory and its sub directories |
| * @Path: a directory path or a file path. |
| * If it's file path then return a single instance of File |
| * If it's directory path then return all instances of File contained in the directory and its sub directories |
| */ |
| public static Vector findFiles(String path, String[] filteredExtensions) { |
| Vector files = new Vector(); |
| |
| findFilesHelper(new File(path), filteredExtensions, files); |
| return files; |
| } |
| |
| /* |
| * INTERNAL: traverse the directory to find all files with filtered extensions. The result is passed |
| * around for each recursive call |
| */ |
| private static void findFilesHelper(File file, String[] filteredExtensions, Vector result) { |
| if (!file.exists()) { |
| return; |
| } |
| |
| if (file.isDirectory()) { |
| String[] entries = file.list(); |
| |
| if (entries != null) { |
| for (int i = 0; i < entries.length; i++) { |
| findFilesHelper(new File(file, entries[i]), filteredExtensions, result); |
| } |
| } |
| } else { |
| // add everything if no filtered extension |
| if ((filteredExtensions == null) || (filteredExtensions.length == 0)) { |
| result.addElement(file); |
| return; |
| } |
| |
| // add only filtered extensions |
| for (int i = 0; i < filteredExtensions.length; i++) { |
| if (file.getName().endsWith(filteredExtensions[i])) { |
| result.addElement(file); |
| return; |
| } |
| } |
| } |
| } |
| |
| /* |
| * Delete a file or directory |
| * |
| * @File: directory or file |
| */ |
| public static void delete(File file) { |
| Objects.requireNonNull(file); |
| if (!file.exists()) { |
| return; |
| } |
| |
| if (file.isDirectory()) { |
| String[] entries = file.list(); |
| |
| if (entries == null || entries.length == 0) { |
| if (!file.delete()) { |
| AbstractSessionLog.getLog().log(SessionLog.FINE, SessionLog.MISC, |
| "Cannot delete file '{0}'.", new Object[] {file}, false); |
| } |
| |
| } else { |
| for (int i = 0; i < entries.length; i++) { |
| delete(new File(file, entries[i])); |
| } |
| |
| // delete directory after its containing files were deleted |
| String[] content = file.list(); |
| if (content == null || content.length == 0) { |
| if (!file.delete()) { |
| AbstractSessionLog.getLog().log(SessionLog.FINE, SessionLog.MISC, |
| "Cannot delete file '{0}'.", new Object[] {file}, false); |
| } |
| } |
| } |
| } else { |
| if (!file.delete()) { |
| AbstractSessionLog.getLog().log(SessionLog.FINE, SessionLog.MISC, |
| "Cannot delete file '{0}'.", new Object[] {file}, false); |
| } |
| } |
| } |
| } |