/*
blizzy's Backup - Easy to use personal file backup application
Copyright (C) 2011-2012 Maik Schreiber
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.blizzy.backup;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.nio.file.Files;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.zip.Deflater;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.swt.widgets.Display;
import org.jooq.Record;
import de.blizzy.backup.database.Database;
import de.blizzy.backup.database.schema.Tables;
import de.blizzy.backup.vfs.IFolder;
public final class Utils {
public static interface IFileOrFolderEntry {
boolean isFolder() throws IOException;
IFileOrFolderEntry getParentFolder() throws IOException;
String getAbsolutePath();
String getName();
}
private static final String DIALOG_SECTION = BackupPlugin.ID + ".dialog"; //$NON-NLS-1$
private static final DateFormat BACKUP_PATH_FORMAT =
new SimpleDateFormat("yyyy'/'MM'/'dd'/'HHmm"); //$NON-NLS-1$
private Utils() {}
public static IDialogSettings getSection(String sectionId) {
IDialogSettings root = BackupPlugin.getDefault().getDialogSettings();
return getChildSection(getChildSection(root, DIALOG_SECTION), sectionId);
}
public static IDialogSettings getChildSection(IDialogSettings parent, String name) {
IDialogSettings section = parent.getSection(name);
if (section == null) {
section = parent.addNewSection(name);
}
return section;
}
public static String createBackupFilePath(String outputFolder) {
String datePath = BACKUP_PATH_FORMAT.format(new Date());
File folder = toBackupFile(datePath + "/dummy", outputFolder).getParentFile(); //$NON-NLS-1$
int maxIdx = getMaxBackupFileIndex(folder);
int newIdx = maxIdx + 1;
return datePath + "/" + toBackupFileName(newIdx); //$NON-NLS-1$
}
public static String createSampleBackupFilePath() {
return BACKUP_PATH_FORMAT.format(new Date()) + "/" + toBackupFileName(Integer.MAX_VALUE); //$NON-NLS-1$
}
public static File toBackupFile(String backupFilePath, String outputFolder) {
String[] parts = backupFilePath.split("/"); //$NON-NLS-1$
File result = new File(outputFolder);
for (String part : parts) {
result = new File(result, part);
}
return result;
}
public static boolean isBackupFolder(String folder) {
return StringUtils.isNotBlank(folder) && Database.containsDatabaseFolder(new File(folder));
}
static void runAsync(Display display, Runnable runnable) {
if (Display.findDisplay(Thread.currentThread()) != null) {
runnable.run();
} else if (!display.isDisposed()) {
display.asyncExec(runnable);
}
}
public static String getSimpleName(IFolder folder) {
String result = folder.getName();
if (StringUtils.isBlank(result)) {
result = folder.getAbsolutePath();
}
return result;
}
public static boolean isParent(IFolder parent, IFolder child) {
for (; child != null; child = child.getParentFolder()) {
if (parent.equals(child.getParentFolder())) {
return true;
}
}
return false;
}
public static void zipFile(File source, File target) throws IOException {
ZipOutputStream out = null;
try {
out = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(target)));
out.setLevel(Deflater.BEST_COMPRESSION);
ZipEntry entry = new ZipEntry(source.getName());
entry.setTime(source.lastModified());
out.putNextEntry(entry);
Files.copy(source.toPath(), out);
} finally {
IOUtils.closeQuietly(out);
}
}
public static File toCanonicalFile(File file) {
try {
return file.getCanonicalFile();
} catch (IOException e) {
// ignore
}
return file.getAbsoluteFile();
}
public static int findFileOrFolderEntryInBackup(IFileOrFolderEntry fileOrFolder, int backupId, Database database)
throws IOException {
if (fileOrFolder.isFolder()) {
// try to find folder as root folder
Record record = database.factory()
.select(Tables.ENTRIES.ID)
.from(Tables.ENTRIES)
.where(Tables.ENTRIES.NAME.equal(fileOrFolder.getAbsolutePath()), Tables.ENTRIES.PARENT_ID.isNull(),
Tables.ENTRIES.BACKUP_ID.equal(Integer.valueOf(backupId)))
.fetchAny();
if (record != null) {
return record.getValue(Tables.ENTRIES.ID).intValue();
}
}
// find entry in parent folder
IFileOrFolderEntry parentFolder = fileOrFolder.getParentFolder();
if (parentFolder != null) {
int parentFolderId = findFileOrFolderEntryInBackup(parentFolder, backupId, database);
if (parentFolderId > 0) {
Record record = database.factory()
.select(Tables.ENTRIES.ID)
.from(Tables.ENTRIES)
.where(Tables.ENTRIES.NAME.equal(fileOrFolder.getName()),
Tables.ENTRIES.PARENT_ID.equal(Integer.valueOf(parentFolderId)),
Tables.ENTRIES.BACKUP_ID.equal(Integer.valueOf(backupId)))
.fetchAny();
if (record != null) {
return record.getValue(Tables.ENTRIES.ID).intValue();
}
}
}
return -1;
}
public static int getMaxBackupFileIndex(File folder) {
if (folder.isDirectory()) {
List<String> files = Arrays.asList(folder.list(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.indexOf('-') < 0;
}
}));
if (!files.isEmpty()) {
Collections.sort(files, new Comparator<String>() {
@Override
public int compare(String f1, String f2) {
int idx1 = toBackupFileIndex(f1);
int idx2 = toBackupFileIndex(f2);
if (idx1 < idx2) {
return -1;
}
if (idx1 > idx2) {
return 1;
}
return 0;
}
});
return toBackupFileIndex(files.get(files.size() - 1));
}
}
return 0;
}
public static String toBackupFileName(int index) {
return Integer.toString(index, 36);
}
public static int toBackupFileIndex(String fileName) {
return Integer.parseInt(fileName, 36);
}
}