com.reprezen.genflow.api.util.FileUtils Maven / Gradle / Ivy
/*******************************************************************************
* Copyright © 2013, 2016 Modelsolv, Inc.
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains the property
* of ModelSolv, Inc. See the file license.html in the root directory of
* this project for further information.
*******************************************************************************/
package com.reprezen.genflow.api.util;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.regex.Pattern;
import com.google.common.collect.Lists;
import com.google.common.io.Files;
import com.reprezen.genflow.api.GenerationException;
/**
* @author Konstantin Zaitsev
* @date May 29, 2015
*/
public final class FileUtils {
// prevent instantiation
private FileUtils() {
}
/**
* Copies resources from JAR file to specified location. Used class to lookup
* JAR file location.
*
* @param codeBase class to lookup JAR file location
* @param source source path in JAR
* @param target target location in local file system
* @throws IOException
* @throws URISyntaxException
*/
public static List copyResources(Class> codeBase, String source, File target) throws Exception {
URL codeLocation = null;
File codeSource = null;
try {
codeLocation = codeBase.getProtectionDomain().getCodeSource().getLocation();
codeSource = new File(codeLocation.toURI());
} catch (URISyntaxException e) {
// bug in code locations located in plugin bundles - URL incorrectly includes
// bare spaces, so above fails, but this should work OK.
codeSource = new File(codeLocation.getPath());
}
return copyResources(codeSource, source, target);
}
/**
* Copies resources from JAR file to specified location.
*
* @param codeSource code source location (usually a JAR file, in dev it may be
* a classes directory)
* @param source source path in JAR
* @param target target location in local file system
* @throws IOException
*/
public static List copyResources(File codeSource, String source, File target) throws Exception {
if (codeSource.isFile()) {
return copyJarResources(codeSource, source, target);
} else {
// Unlikely except in dev environment
return copyFileResources(new File(codeSource, source), target);
}
}
public static List copyJarResources(File jarFile, String source, File target) throws IOException {
List result = Lists.newArrayList();
// resolve "." and ".." compoents. We prefix with "/" and remove afterward, in
// order to preventing resolving relative to current working directory in
// filesystem (e.g. "../foo" would do that)
source = new File("/" + source).getCanonicalPath().replaceAll(Pattern.quote(File.separator), "/");
if (source.contains("/")) {
// skip initial slash and (on windows) device letter) for matching with jar file
// entries
source = source.substring(source.indexOf('/') + 1);
}
if (source.startsWith(".." + "/"))
{
throw new IOException("Invalid relative static resource path - no parent path component to absorb '..'");
}
String prefix = source.equals(".") ? "" : source + "/";
try (JarFile jar = new JarFile(jarFile)) {
final Enumeration entries = jar.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
String name = entry.getName();
if (name.equals(source)) {
result.add(copyJarEntry(jar, entry, target));
} else if (name.startsWith(prefix) && !entry.isDirectory()) {
File outputFile = new File(target, entry.getName().substring(prefix.length()));
result.add(copyJarEntry(jar, entry, outputFile));
}
}
}
return result;
}
private static File copyJarEntry(JarFile jar, JarEntry entry, File output) throws IOException {
if (isDirectory(output)) {
output = new File(output, new File(entry.getName()).getName());
}
try (InputStream in = jar.getInputStream(entry)) {
Files.createParentDirs(output);
if (!output.exists() || output.lastModified() != entry.getTime()) {
// Safe to use: copyInputStreamToFile in Apache Commons IO since v.2.0
org.apache.commons.io.FileUtils.copyInputStreamToFile(in, output);
output.setLastModified(entry.getTime());
}
return output;
}
}
public static List copyFileResources(File source, File target) throws Exception {
if (!source.exists()) {
throw new GenerationException(
"Static resource copying: the source folder does not exist: " + source.getPath());
}
if (source.isDirectory()) {
return copyDirectory(source, target);
} else {
return Collections.singletonList(copyFile(source, target));
}
}
private static File copyFile(File sourceFile, File output) throws IOException {
if (isDirectory(output)) {
output = new File(output, sourceFile.getName());
}
if (!output.exists() || output.lastModified() != sourceFile.lastModified()) {
Files.createParentDirs(output);
Files.copy(sourceFile, output);
output.setLastModified(sourceFile.lastModified());
}
return output;
}
private static boolean isDirectory(File file) {
if (file.exists()) {
return file.isDirectory();
} else {
return file.getPath().endsWith("/");
}
}
private static List copyDirectory(File source, File target) throws IOException {
List result = Lists.newArrayList();
File[] filesInDirectory = source.listFiles();
for (File file : filesInDirectory) {
if (file.isFile()) {
File outputFile = new File(target, file.getName());
result.add(copyFile(file, outputFile));
} else {
result.addAll(copyDirectory(file, new File(target, file.getName())));
}
}
return result;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy