001    /*
002     * This file is part of muCommander, http://www.mucommander.com
003     * Copyright (C) 2002-2008 Maxence Bernard
004     *
005     * muCommander is free software; you can redistribute it and/or modify
006     * it under the terms of the GNU General Public License as published by
007     * the Free Software Foundation; either version 3 of the License, or
008     * (at your option) any later version.
009     *
010     * muCommander is distributed in the hope that it will be useful,
011     * but WITHOUT ANY WARRANTY; without even the implied warranty of
012     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013     * GNU General Public License for more details.
014     *
015     * You should have received a copy of the GNU General Public License
016     * along with this program.  If not, see <http://www.gnu.org/licenses/>.
017     */
018    
019    package com.mucommander.io;
020    
021    import com.mucommander.file.AbstractFile;
022    import com.mucommander.file.FileFactory;
023    import com.mucommander.file.FileURL;
024    
025    import java.io.File;
026    import java.io.FilterInputStream;
027    import java.io.IOException;
028    import java.io.InputStream;
029    
030    /**
031     * Opens an input stream on a file that has been saved by {@link com.mucommander.io.BackupOutputStream}.
032     * <p>
033     * This class' role is to choose which of the original or backup file should be read in order to ensure
034     * that the data is not corrupt.
035     * </p>
036     * @see com.mucommander.io.BackupOutputStream
037     * @author Nicolas Rinaudo
038     */
039    public class BackupInputStream extends FilterInputStream implements BackupConstants {
040        // - Initialisation ---------------------------------------------------------
041        // --------------------------------------------------------------------------
042        /**
043         * Opens a backup input stream on the specified file.
044         * @param     file        file to open for reading.
045         * @exception IOException thrown if any IO related error occurs.
046         */
047        public BackupInputStream(File file) throws IOException {super(getInputStream(FileFactory.getFile(file.getAbsolutePath())));}
048    
049        /**
050         * Opens a backup input stream on the specified file.
051         * @param     path        path to the file to open for reading.
052         * @exception IOException thrown if any IO related error occurs.
053         */
054        public BackupInputStream(String path) throws IOException {super(getInputStream(FileFactory.getFile((new File(path)).getAbsolutePath())));}
055    
056        /**
057         * Opens a backup input stream on the specified file.
058         * @param     file        file to open for reading.
059         * @exception IOException thrown if any IO related error occurs.
060         */
061        public BackupInputStream(AbstractFile file) throws IOException {super(getInputStream(file));}
062    
063        /**
064         * Opens a stream on the right file.
065         * <p>
066         * If a backup file is found, and is bigger than the target file, then it will be used.
067         * </p>
068         * @param     file        file on which to open an input stream.
069         * @return                a stream on the right file.
070         * @exception IOException thrown if any IO related error occurs.
071         */
072        private static InputStream getInputStream(AbstractFile file) throws IOException {
073            AbstractFile backup;
074            FileURL test;
075    
076            test = (FileURL)file.getURL().clone();
077            test.setPath(test.getPath() + BACKUP_SUFFIX);
078    
079            // Checks whether the backup file is a better choice than the target one.
080            backup = FileFactory.getFile(test);
081            if(backup != null && backup.exists() && (file.getSize() < backup.getSize()))
082                return backup.getInputStream();
083    
084            // Opens a stream on the target file.
085            return file.getInputStream();
086        }
087    }