com.eleybourn.bookcatalogue.backup.tar.TarBackupWriter.java Source code

Java tutorial

Introduction

Here is the source code for com.eleybourn.bookcatalogue.backup.tar.TarBackupWriter.java

Source

/*
 * @copyright 2013 Philip Warner
 * @license GNU General Public License
 * 
 * This file is part of Book Catalogue.
 *
 * Book Catalogue 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.
 *
 * Book Catalogue 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 Book Catalogue.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.eleybourn.bookcatalogue.backup.tar;

import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
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.OutputStreamWriter;

import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;

import android.content.SharedPreferences;

import com.eleybourn.bookcatalogue.backup.BackupContainer;
import com.eleybourn.bookcatalogue.backup.BackupInfo;
import com.eleybourn.bookcatalogue.backup.BackupUtils;
import com.eleybourn.bookcatalogue.backup.BackupWriterAbstract;
import com.eleybourn.bookcatalogue.booklist.BooklistStyle;
import com.eleybourn.bookcatalogue.database.SerializationUtils;

/**
 * Implementation of TAR-specific writer functions
 * 
 * @author pjw
 */
public class TarBackupWriter extends BackupWriterAbstract {
    private final TarBackupContainer mContainer;
    private TarArchiveOutputStream mOutput;
    private int mStyleCounter = 0;

    /**
     * Constructor
     * 
     * @param container      Parent
     * @throws IOException
     */
    public TarBackupWriter(TarBackupContainer container) throws IOException {
        mContainer = container;
        // Open the archive for writing
        FileOutputStream out = new FileOutputStream(container.getFile());
        mOutput = new TarArchiveOutputStream(out);
    }

    /** 
     * Accessor
     */
    @Override
    public BackupContainer getContainer() {
        return mContainer;
    }

    /**
     * Save the books export file
     */
    @Override
    public void putBooks(File books) throws IOException {
        TarArchiveEntry entry = new TarArchiveEntry(new File(TarBackupContainer.BOOKS_FILE));
        entry.setModTime(books.lastModified());
        entry.setSize(books.length());
        mOutput.putArchiveEntry(entry);
        FileInputStream in = new FileInputStream(books);
        streamToArchive(in);
    }

    /**
     * Save a cover file
     */
    @Override
    public void putCoverFile(File source) throws IOException {
        TarArchiveEntry entry = new TarArchiveEntry(source.getName());
        entry.setModTime(source.lastModified());
        entry.setSize(source.length());
        mOutput.putArchiveEntry(entry);
        FileInputStream in = new FileInputStream(source);
        streamToArchive(in);
    }

    /**
     * Save the INFO data
     */
    @Override
    public void putInfo(BackupInfo info) throws IOException {
        ByteArrayOutputStream infoData = new ByteArrayOutputStream();
        BufferedWriter infoOut = new BufferedWriter(new OutputStreamWriter(infoData, TarBackupContainer.UTF8),
                TarBackupContainer.BUFFER_SIZE);
        BackupUtils.bundleToXml(infoOut, info.getBundle());
        infoOut.close();
        bytesToArchive(TarBackupContainer.INFO_FILE, infoData.toByteArray());
    }

    /**
     * Save a Booklist style. We save them with increasing suffix counters to ensure uniqueness
     */
    @Override
    public void putBooklistStyle(BooklistStyle style) throws IOException {
        // Turn the object into a byte array
        byte[] blob = SerializationUtils.serializeObject(style);
        mStyleCounter++;
        bytesToArchive(TarBackupContainer.STYLE_PREFIX + mStyleCounter, blob);
    }

    /**
     * Save the preferences.
     * 
     * It would be nice to support groups (ie. more than one preference name), but ... we don't need it.
     */
    @Override
    public void putPreferences(SharedPreferences prefs) throws IOException {
        // Turn the preferences into an XML file in a byte array
        ByteArrayOutputStream infoData = new ByteArrayOutputStream();
        BufferedWriter infoOut = new BufferedWriter(new OutputStreamWriter(infoData, TarBackupContainer.UTF8),
                TarBackupContainer.BUFFER_SIZE);
        BackupUtils.preferencesToXml(infoOut, prefs);
        infoOut.close();
        // Save them
        bytesToArchive(TarBackupContainer.PREFERENCES, infoData.toByteArray());
    }

    /**
     * Utility routine to send the contents of a stream to the current archive entry
     * 
     * @param in         Stream to be saved
     * 
     * @throws IOException
     */
    private void streamToArchive(InputStream in) throws IOException {
        try {
            byte[] buffer = new byte[TarBackupContainer.BUFFER_SIZE];
            while (true) {
                int cnt = in.read(buffer);
                if (cnt <= 0)
                    break;
                mOutput.write(buffer, 0, cnt);
            }
        } finally {
            try {
                in.close();
            } finally {
            }
            try {
                mOutput.closeArchiveEntry();
            } finally {
            }
        }

    }

    /**
     * Utility routine to save the passed bytes to an entry with the passed name
     * 
     * @param name      name of "file" in archive
     * @param bytes      bytes to write
     * 
     * @throws IOException
     */
    private void bytesToArchive(String name, byte[] bytes) throws IOException {
        TarArchiveEntry entry = new TarArchiveEntry(name);
        entry.setSize(bytes.length);
        mOutput.putArchiveEntry(entry);
        InputStream in = new ByteArrayInputStream(bytes);
        streamToArchive(in);
    }

    /**
     * Cleanup
     */
    @Override
    public void close() throws IOException {
        super.close();
        mOutput.close();
    }
}