/* * @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(); } }