Package com.salas.bb.core

Source Code of com.salas.bb.core.Backups$FilesLastModTimeComparator

// BlogBridge -- RSS feed reader, manager, and web based service
// Copyright (C) 2002-2006 by R. Pito Salas
//
// 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.
//
// 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, write to the Free Software Foundation, Inc., 59 Temple Place,
// Suite 330, Boston, MA 02111-1307 USA
//
// Contact: R. Pito Salas
// mailto:pitosalas@users.sourceforge.net
// More information: about BlogBridge
// http://www.blogbridge.com
// http://sourceforge.net/projects/blogbridge
//
// $Id: Backups.java,v 1.7 2006/05/30 10:31:15 spyromus Exp $
//

package com.salas.bb.core;

import com.salas.bb.domain.*;
import com.salas.bb.utils.opml.Converter;
import com.salas.bb.utils.i18n.Strings;
import com.salas.bbutilities.opml.export.Exporter;

import java.io.File;
import java.io.IOException;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.util.*;
import java.text.SimpleDateFormat;

import org.jdom.output.XMLOutputter;
import org.jdom.Document;

/**
* <p>Backups manager, which saves the OPML backup on demand and controls the population of
* backups in the working directory.</p>
*
* <p>The backups directory and number of last backups to keep are input parameters.</p>
*
* <p>The name of backup file is controlled with <code>FILENAME_FORMAT</code> property.
* At the present moment the names will look like: <code>~2005-05-31_142501.opml</code>
* which corresponds to: <code>31 May 2005, 14:25:01</code>.</p>
*
* <p>The manager utilitizes the same functionality as Synchronization module, meaning
* that the contents of synchronization and backup OPML are completely identical.</p>
*/
public final class Backups
{
    private static final SimpleDateFormat FILENAME_FORMAT =
        new SimpleDateFormat("'~'yyyy-MM-dd_HHmmss'.opml'");

    private static final String FILENAME_PATTERN =
        "^~[0-9]{4}-[0-9]{2}-[0-9]{2}_[0-9]{6}\\.opml$";

    /**
     * The title of the main OPML outline.
     */
    private static final String OPML_TITLE = "BlogBridge Backup";

    private final int   lastBackupsToKeep;
    private final File  backupsDir;

    /**
     * Initializes backups saver with directory and limit value.
     *
     * @param aBackupsDir           directory to save backups to. If it is not present yet
     *                              it will be created during saving.
     * @param aLastBackupsToKeep    number of backup files to keep (greater than 0). The old
     *                              backup files will be removed.
     *
     * @throws NullPointerException if backups directory isn't told.
     * @throws IllegalArgumentException if last backups to keep is not positive value.
     */
    public Backups(File aBackupsDir, int aLastBackupsToKeep)
    {
        if (aBackupsDir == null) throw new NullPointerException(Strings.error("backup.directory.is.unspecified"));
        if (aLastBackupsToKeep <= 0) throw new IllegalArgumentException(Strings.error("backup.non.positive.limit"));

        backupsDir = aBackupsDir;
        lastBackupsToKeep = aLastBackupsToKeep;
    }

    /**
     * Stores the guides set as OPML in backups folder. If backups folder doesn't exist,
     * it will be created. If this backup will overjump the limitation of backups to keep,
     * the last backups will be removed. Empty guides sets are also allowed.
     *
     * @param set guides set to store.
     *
     * @throws NullPointerException if the set isn't specified.
     */
    public void saveBackup(GuidesSet set)
        throws IOException
    {
        initBackupsDir();
        storeSet(set);
        rotateBackups();
    }

    /**
     * Creates backup directory if the last doesn't exist yet.
     *
     * @throws IOException if creation has failed.
     */
    private void initBackupsDir()
        throws IOException
    {
        if (!backupsDir.exists())
        {
            if (!backupsDir.mkdir()) throw new IOException(Strings.error("backup.failed.to.create.backup.directory"));
        }
    }

    /**
     * Exports the set to OPML and writes to backup file, which name is created from
     * current data and time.
     *
     * @param set   set to export.
     *
     * @throws IOException if output operation fails.
     */
    private void storeSet(GuidesSet set)
        throws IOException
    {
        com.salas.bbutilities.opml.export.Exporter exporter = new Exporter(true);
        Document doc = exporter.export(Converter.convertToOPML(set, OPML_TITLE));

        writeBackupToFile(doc, new File(backupsDir, createBackupFileName()));
    }

    /**
     * Writes backup OPML data to the file.
     *
     * @param aBackupOPMLDocument   exported OPML document.
     * @param aBackupFile           backup file.
     *
     * @throws IOException if output operation fails.
     */
    private static void writeBackupToFile(Document aBackupOPMLDocument, File aBackupFile)
        throws IOException
    {
        FileOutputStream fos = new FileOutputStream(aBackupFile);
        XMLOutputter xo = new XMLOutputter();
        xo.output(aBackupOPMLDocument, fos);
        fos.close();
    }

    /**
     * Creates name of the backup file from current date and time.
     *
     * @return backup file name.
     */
    private String createBackupFileName()
    {
        return FILENAME_FORMAT.format(new Date());
    }

    /**
     * Analyzes the list of backup files and removes oldest which are overjumping the
     * specified number of backups to keep.
     */
    private void rotateBackups()
    {
        File[] backupFiles = backupsDir.listFiles(new BackupFilenameFilter());
        Collection filesToRemove = chooseBackupsToRemove(backupFiles);

        Iterator it = filesToRemove.iterator();
        while (it.hasNext())
        {
            File backupFile = (File)it.next();
            backupFile.delete();
        }
    }

    /**
     * Selects the files from the list which have jumped over the limitation.
     *
     * @param aBackupFiles backup files.
     *
     * @return collection of files to remove.
     */
    private Collection chooseBackupsToRemove(File[] aBackupFiles)
    {
        List backupsToRemove = new ArrayList();

        if (aBackupFiles.length > lastBackupsToKeep)
        {
            SortedSet sortedBackupFiles = new TreeSet(new FilesLastModTimeComparator());
            sortedBackupFiles.addAll(Arrays.asList(aBackupFiles));

            int toRemove = aBackupFiles.length - lastBackupsToKeep;
            Iterator it = sortedBackupFiles.iterator();
            while (toRemove > 0 && it.hasNext())
            {
                Object backupFile = it.next();
                backupsToRemove.add(backupFile);
                toRemove--;
            }
        }

        return backupsToRemove;
    }

    /**
     * Compares files by their modification times.
     */
    private static class FilesLastModTimeComparator implements Comparator
    {
        public int compare(Object o1, Object o2)
        {
            long modTime1 = ((File)o1).lastModified();
            long modTime2 = ((File)o2).lastModified();

            return modTime1 > modTime2 ? 1 : modTime1 < modTime2 ? -1 : 0;
        }
    }
    /**
     * Filter for backup files.
     */
    private static class BackupFilenameFilter implements FilenameFilter
    {
        public boolean accept(File dir, String name)
        {
            return name != null && name.matches(FILENAME_PATTERN);
        }
    }
}
TOP

Related Classes of com.salas.bb.core.Backups$FilesLastModTimeComparator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.