net.pictulog.otgdb.task.BackupTask.java Source code

Java tutorial

Introduction

Here is the source code for net.pictulog.otgdb.task.BackupTask.java

Source

/**
 * This file is part of OTGDiskBackup.
 * <p/>
 * Copyright 2005-2009 Red Hat, Inc.  All rights reserved.
 * <p/>
 * 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 2 of the License, or
 * (at your option) any later version.
 * <p/>
 * 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.
 * <p/>
 * 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 net.pictulog.otgdb.task;

import android.util.Log;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

import de.waldheinz.fs.FsDirectory;
import de.waldheinz.fs.FsDirectoryEntry;
import de.waldheinz.fs.FsFile;

/**
 * This class will simply walk the whole tree and copy the file from the source
 * to the destination folder.
 *
 * @author rostskadat
 */
public class BackupTask extends AbstractTask<Void, Integer, List<String>> {

    private final FsDirectory srcDir;
    private final File destDir;
    private final List<String> extensions;
    private final boolean overwrite;
    private final boolean delete;
    private final BackupTaskListener listener;

    private Stack<List<String>> fileToDelete = new Stack<List<String>>();
    private List<String> failedToBackup = new ArrayList<String>();
    private int currentFile = 0;

    public BackupTask(BackupTaskListener listener, FsDirectory srcDir, File destDir, List<String> extensions,
            boolean delete, boolean overwrite) {
        this.listener = listener;
        this.srcDir = srcDir;
        this.destDir = destDir;
        this.extensions = extensions;
        this.delete = delete;
        this.overwrite = overwrite;
    }

    @Override
    protected List<String> doInBackground(Void... params) {
        List<String> failedToBackup = null;
        try {
            if (!destDir.exists()) {
                Log.e("BackupTask", "Dest dir '" + destDir.getPath() + "' does not exists or is not writtable");
            } else {
                Log.i("BackupTask", "Backup from " + srcDir.toString() + " -> " + destDir.toString());
                failedToBackup = backupFiles();
                Log.i("BackupTask", "Backup complete");
            }
        } catch (Exception e) {
            // Souldn't be raised...
            Log.e("BackupTask", e.getMessage(), e);
        }
        return failedToBackup;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        listener.onBackupStart();
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
        listener.onBackupProgressUpdate(values);
    }

    @Override
    protected void onPostExecute(List<String> failedToBackup) {
        super.onPostExecute(failedToBackup);
        if (failedToBackup == null || failedToBackup.isEmpty()) {
            listener.onBackupReady();
        } else {
            listener.onBackupFailed(failedToBackup);
        }
    }

    private List<String> backupFiles() {
        try {
            walkFileTree(srcDir, destDir);
            return failedToBackup;
        } catch (Exception e) {
            // Souldn't be raised...
            Log.e("BackupTask", e.getMessage(), e);
        }
        return null;
    }

    @Override
    protected void visitFile(FsDirectoryEntry file, File targetDirectory) throws IOException {
        if (file == null || !file.isFile()) {
            throw new IllegalArgumentException("entry must be an existing file");
        }
        if (targetDirectory == null || !targetDirectory.exists() || !targetDirectory.isDirectory()
                || !targetDirectory.canWrite()) {
            throw new IllegalArgumentException(
                    "targetDirectory '" + targetDirectory + "' must be an existing writable directory");
        }
        String entryName = file.getName();
        String extensionUpper = FilenameUtils.getExtension(entryName).toUpperCase();
        String extensionLower = FilenameUtils.getExtension(entryName).toLowerCase();
        if (!extensions.isEmpty() && !extensions.contains(extensionUpper) && !extensions.contains(extensionLower)) {
            return;
        }
        if (copyFile(file.getFile(), new File(targetDirectory, entryName))) {
            if (delete) {
                fileToDelete.peek().add(entryName);
            }
        } else {
            failedToBackup.add(entryName);
        }
    }

    @Override
    protected void preVisitDirectory(FsDirectoryEntry directory, File targetDirectory) throws IOException {
        if (!targetDirectory.exists()) {
            if (!targetDirectory.mkdirs()) {
                Log.w("BackupTask", "Failed to create directory " + targetDirectory.getAbsolutePath());
            }
        }
        if (delete) {
            fileToDelete.push(new ArrayList<String>());
        }
    }

    @Override
    protected void postVisitDirectory(FsDirectoryEntry directory, File targetDirectory) throws IOException {
        if (delete) {
            List<String> toDeletes = fileToDelete.pop();
            for (String toDelete : toDeletes) {
                directory.getDirectory().remove(toDelete);
            }
        }
    }

    private boolean copyFile(FsFile srcFile, File destFile) {
        publishProgress(currentFile++);
        if (srcFile.isValid()) {
            ByteBuffer buffer = ByteBuffer.allocate((int) srcFile.getLength());
            if (destFile.exists() && !overwrite) {
                return true;
            }
            OutputStream fos = null;
            try {
                fos = new FileOutputStream(destFile);
                srcFile.read(0, buffer);
                fos.write(buffer.array());
                fos.flush();
                return true;
            } catch (IOException e) {
                Log.e("BackupTask", e.getMessage(), e);
            } finally {
                IOUtils.closeQuietly(fos);
            }
        }
        return false;
    }

}