package com.yoursway.utils;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Maps.newHashMap;
import static com.yoursway.utils.relativepath.Pathes.relativePath;
import static java.util.Collections.emptyList;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import com.yoursway.utils.relativepath.RelativePath;
public class YsFileUtils {
public static final String UTF8_ENCODING = "utf-8";
public static Object readAsObject(File source) throws IOException, ClassNotFoundException {
FileInputStream in = new FileInputStream(source);
try {
ObjectInputStream oi = new ObjectInputStream(in);
return oi.readObject();
} finally {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void writeObject(Object object, File file) throws IOException {
FileOutputStream out = new FileOutputStream(file);
try {
writeObject(object, out);
} finally {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void writeObject(Object object, OutputStream out) throws IOException {
ObjectOutputStream oo = new ObjectOutputStream(out);
oo.writeObject(object);
oo.flush();
}
public static String readAsString(File source) throws IOException {
return readAsString(source, UTF8_ENCODING);
}
public static String readAsString(File source, String encoding) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
loadFromFile(source, baos);
byte[] bytes = baos.toByteArray();
return new String(bytes, encoding);
}
public static String readAsStringAndClose(InputStream source) throws IOException {
try {
return readAsString(source, UTF8_ENCODING);
} finally {
source.close();
}
}
public static String readAsString(InputStream source) throws IOException {
return readAsString(source, UTF8_ENCODING);
}
public static String readAsString(InputStream source, String encoding) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
transfer(source, baos);
byte[] bytes = baos.toByteArray();
return new String(bytes, encoding);
}
public static void writeString(File destination, String data) throws IOException {
writeString(destination, data, UTF8_ENCODING);
}
public static void writeString(File destination, String data, String encoding) throws IOException {
writeBytes(destination, data.getBytes(encoding));
}
public static void writeBytes(File destination, byte[] data) throws IOException {
saveToFile(new ByteArrayInputStream(data), destination);
}
public static void writeStringAndClose(OutputStream destination, String data) throws IOException {
try {
writeString(destination, data, UTF8_ENCODING);
} finally {
destination.close();
}
}
public static void writeString(OutputStream destination, String data) throws IOException {
writeString(destination, data, UTF8_ENCODING);
}
public static void writeString(OutputStream destination, String data, String encoding) throws IOException {
writeBytes(destination, data.getBytes(encoding));
}
public static void writeBytes(OutputStream destination, byte[] data) throws IOException {
transfer(new ByteArrayInputStream(data), destination);
}
public static void cp_r(File source, File destinationParentFolder) throws IOException {
List<File> e = emptyList();
cp_r_exclude(source, destinationParentFolder, e);
}
public static void cp_r_exclude(File source, File destinationParentFolder, Collection<File> excluded)
throws IOException {
destinationParentFolder.mkdirs();
cp_r_(source, destinationParentFolder, excluded);
}
/**
* Prereq: <code>destinationParentFolder</code> exists.
*
* @param excluded
*/
private static void cp_r_(File source, File destinationParentFolder, Collection<File> excluded)
throws IOException {
if (excluded.contains(source))
return;
if (!source.isDirectory()) {
fileCopy(source, new File(destinationParentFolder, source.getName()));
} else {
File childrenDestination = new File(destinationParentFolder, source.getName());
cp_r_children(source, childrenDestination, excluded);
}
}
public static void cp_r_children(File source, File childrenDestination) throws IOException {
List<File> e = emptyList();
cp_r_children(source, childrenDestination, e);
}
public static void cp_r_children(File source, File childrenDestination, Collection<File> excluded)
throws IOException {
childrenDestination.mkdirs();
File[] children = source.listFiles();
if (children != null)
for (File child : children)
cp_r_(child, childrenDestination, excluded);
}
public static void fileCopy(File src, File dst) throws IOException {
InputStream in = new FileInputStream(src);
try {
saveToFile(in, dst);
} finally {
in.close();
}
}
public static void download(URL url, File dst) throws IOException {
InputStream in = url.openStream();
try {
saveToFile(in, dst);
} finally {
in.close();
}
}
public static void saveToFile(InputStream in, File dst) throws FileNotFoundException, IOException {
OutputStream out = new FileOutputStream(dst);
try {
transfer(in, out);
} finally {
out.close();
}
}
public static void loadFromFile(File src, OutputStream out) throws FileNotFoundException, IOException {
InputStream in = new FileInputStream(src);
try {
transfer(in, out);
} finally {
in.close();
}
}
public static void transfer(InputStream in, OutputStream out) throws IOException {
byte[] buf = new byte[1024 * 1024];
int len;
while ((len = in.read(buf)) > 0)
out.write(buf, 0, len);
}
public static void transfer(InputStream in, OutputStream out, int maxBytes) throws IOException {
byte[] buf = new byte[maxBytes];
int done = 0;
int len;
while (done < maxBytes && (len = in.read(buf)) > 0) {
out.write(buf, 0, len);
done += len;
}
}
public static File createTempFolder(String prefix, String suffix) throws IOException {
File file;
do {
file = File.createTempFile(prefix, suffix);
file.delete();
} while (!file.mkdir());
return file;
}
public static File findLatestOsgiBundle(File folder, String bundleName) {
return chooseLatestVersion(findOsgiBundles(folder, bundleName));
}
public static File chooseLatestVersion(Collection<File> jars) {
List<File> jarsList = newArrayList(jars);
if (jarsList.isEmpty())
return null;
Collections.sort(jarsList, YsStrings.toStringComparator(YsStrings.getNaturalComparatorAscii()));
return jarsList.get(jarsList.size() - 1);
}
public static Collection<File> findOsgiBundles(File folder, String bundleName) {
Collection<File> result = newArrayList();
File[] files = folder.listFiles();
if (files != null)
for (File file : files)
addPluginIfMatches(file, bundleName, result);
return result;
}
public static void addPluginIfMatches(File folderOrJar, String bundleName, Collection<File> result) {
String name = folderOrJar.getName();
if (folderOrJar.isFile()) {
if (name.equals(bundleName + ".jar") || name.startsWith(bundleName + "_")
&& name.endsWith(".jar"))
result.add(folderOrJar);
} else {
if (name.equals(bundleName) || name.startsWith(bundleName + "_"))
result.add(folderOrJar);
}
}
public static File urlToFileWithProtocolCheck(URL url) {
if (!url.getProtocol().equals("file"))
throw new IllegalArgumentException("URL is not a file: " + url);
return new File(url.getPath());
}
public static void deleteFile(File file) {
if (file.exists() && !file.delete())
throw new RuntimeException("Cannot delete file " + file);
}
public static void deleteRecursively(File directory) {
File[] children = directory.listFiles();
if (children != null) {
for (File child : children)
if (child.isDirectory())
deleteRecursively(child);
else
deleteFile(child);
if (!directory.delete())
throw new RuntimeException("Cannot delete directory " + directory);
}
}
public static void zipFolderContents(File folder, File zip) throws IOException {
zip(zip, newArrayList(new ZipRoot(folder, "")));
}
public static void zip(File zip, Collection<ZipRoot> roots) throws IOException {
FileOutputStream fout = new FileOutputStream(zip);
ZipOutputStream out = new ZipOutputStream(fout);
try {
for (ZipRoot root : roots)
zipChildren(root.folder(), root.prefix(), out);
} finally {
out.close();
}
}
public static void zipChildren(File folder, String prefix, ZipOutputStream out) throws IOException {
File[] files = folder.listFiles();
if (files == null)
return;
for (File file : files) {
if (file.isFile()) {
String name = prefix + file.getName();
ZipEntry entry = new ZipEntry(name);
entry.setTime(file.lastModified());
out.putNextEntry(entry);
loadFromFile(file, out);
out.closeEntry();
} else if (file.isDirectory()) {
zipChildren(file, prefix + file.getName() + "/", out);
}
}
}
public static void rewriteZipBasic(File source, OutputStream outf, Map<String, InputStream> overrides)
throws IOException {
InputStream inf = new FileInputStream(source);
try {
rewriteZipBasic(inf, outf, overrides);
} finally {
inf.close();
}
}
public static void rewriteZip(File source, OutputStream outf, Map<String, StreamFilter> overrides)
throws IOException {
InputStream inf = new FileInputStream(source);
try {
rewriteZip(inf, outf, overrides);
} finally {
inf.close();
}
}
public static void rewriteZipBasic(InputStream source, OutputStream outf,
Map<String, InputStream> overrides) throws IOException {
Map<String, StreamFilter> data = newHashMap();
for (Map.Entry<String, InputStream> entry : overrides.entrySet())
data.put(entry.getKey(), new CopyFromStreamFilter(entry.getValue()));
rewriteZip(source, outf, data);
}
public static void rewriteZip(InputStream source, OutputStream outf, Map<String, StreamFilter> rewrites)
throws IOException {
Map<String, StreamFilter> rewritesRemaining = newHashMap(rewrites);
ZipInputStream in = new ZipInputStream(source);
ZipOutputStream out = new ZipOutputStream(outf);
ZipEntry entry;
while (null != (entry = in.getNextEntry())) {
String name = entry.getName();
StreamFilter filter = rewritesRemaining.remove(name);
if (filter == null) {
out.putNextEntry(entry);
transfer(in, out);
} else {
ZipEntry newEntry = new ZipEntry(name);
newEntry.setTime(entry.getTime());
out.putNextEntry(newEntry);
filter.process(in, out);
}
}
for (Map.Entry<String, StreamFilter> item : rewritesRemaining.entrySet()) {
out.putNextEntry(new ZipEntry(item.getKey()));
item.getValue().process(new ByteArrayInputStream(new byte[0]), out);
}
out.finish();
}
public static String readFileOrZipAsString(File directoryOrArchive, String relativePath)
throws IOException {
return readFileOrZipAsString(directoryOrArchive, relativePath, UTF8_ENCODING);
}
public static String readFileOrZipAsString(File directoryOrArchive, String relativePath, String encoding)
throws IOException {
byte[] bytes = readFileOrZipAsBytes(directoryOrArchive, relativePath);
return new String(bytes, encoding);
}
public static byte[] readFileOrZipAsBytes(File directoryOrArchive, String relativePath)
throws IOException {
InputStream in = openFileOrZip(directoryOrArchive, relativePath);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
transfer(in, baos);
byte[] bytes = baos.toByteArray();
return bytes;
}
public static InputStream openFileOrZip(File directoryOrArchive, String relativePath) throws IOException {
if (directoryOrArchive.isDirectory()) {
return new FileInputStream(new File(directoryOrArchive, relativePath));
} else {
ZipFile file = new ZipFile(directoryOrArchive);
ZipEntry entry = file.getEntry(relativePath);
if (entry == null)
throw new IOException("Entry " + relativePath + " not found in " + directoryOrArchive);
InputStream in = file.getInputStream(entry);
return new DelegatingZipClosingInputStream(in, file);
}
}
public static RelativePath calculateRelativePath(File root, File path) {
return calculateRelativePath_(root, path, relativePath(""));
}
private static RelativePath calculateRelativePath_(File root, File path, RelativePath currentPath) {
if (root == null)
return null;
if (root.equals(path))
return currentPath;
return calculateRelativePath_(root, path.getParentFile(), relativePath(path.getName()).append(
currentPath));
}
/**
* @deprecated Use {@link YsPathUtils#joinPath(String,String)} instead
*/
@Deprecated
public static String joinPath(String a, String b) {
return YsPathUtils.joinPath(a, b);
}
public static boolean isBogusFile(String name) {
return Pattern.compile("^([._](git|svn|darcs)|CVS|\\.DS_Store)$").matcher(name).find();
}
public static boolean isSameFile(File first, File second) {
try {
first = first.getCanonicalFile();
} catch (IOException e) {
first = first.getAbsoluteFile();
}
try {
second = second.getCanonicalFile();
} catch (IOException e) {
second = second.getAbsoluteFile();
}
return first.equals(second);
}
}