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.file;
020
021 import java.io.IOException;
022 import java.io.OutputStream;
023
024 /**
025 * <code>AbstractRWArchiveFile</code> represents a read-write archive file. This class is abstract and implemented by
026 * all read-write archive files.
027 * In addition to the read-only operations defined by {@link com.mucommander.file.AbstractArchiveFile}, it provides
028 * abstract methods for adding and deleting entries from the archive.
029 *
030 * The {@link #isWritableArchive()} method impletemented by this class always returns <code>true</code>. However,
031 * write operations may not always be available depending on the underlying file (e.g. if random file access is
032 * required). In that case, {@link #isWritableArchive()} should be overridden to return <code>true</code> only when
033 * write operations are available.
034 *
035 * @author Maxence Bernard
036 */
037 public abstract class AbstractRWArchiveFile extends AbstractArchiveFile {
038
039 /**
040 * Creates an AbstractRWArchiveFile on top of the given file.
041 *
042 * @param file the file on top of which to create the archive
043 */
044 protected AbstractRWArchiveFile(AbstractFile file) {
045 super(file);
046 }
047
048
049 ////////////////////////////////////////
050 // AbstractArchiveFile implementation //
051 ////////////////////////////////////////
052
053 /**
054 * Returns <code>true</code>: <code>AbstractRWArchiveFile</code> implementations are capable of adding or deleting
055 * entries. This method should be overridden if the implementation is capable of providing write access only under
056 * certain conditions, for example if it requires random access to the proxied archive file which may not
057 * always be available depending on the udnderlying file. If that is the case, this method should return
058 * <code>true</code> only when all conditions for providing write operations are met.
059 *
060 * @return true
061 */
062 public boolean isWritableArchive() {
063 return true;
064 }
065
066
067 //////////////////////
068 // Abstract methods //
069 //////////////////////
070
071 /**
072 * Adds the given entry to the archive and returns an <code>OutputStream</code> to write the entry's contents
073 * if the entry is a regular file, <code>null</code> if the entry is a directory.
074 * Throws an <code>IOException</code> if the entry already exists in the archive or if an I/O error occurs.
075 *
076 * @param entry the entry to add to the archive
077 * @return an OutputStream to write the entry's contents if the entry is a regular file, null if the entry is a directory
078 * @throws IOException if the entry already exists in the archive or if an I/O error occurs
079 */
080 public abstract OutputStream addEntry(ArchiveEntry entry) throws IOException;
081
082 /**
083 * Deletes the specified entry from the archive. Throws an <code>IOException</code> if the entry doesn't exist
084 * in the archive or if an I/O error occurs.
085 *
086 * @param entry the entry to delete from the archive
087 * @throws IOException if the entry doesn't exist in the archive or if an I/O error occurs
088 */
089 public abstract void deleteEntry(ArchiveEntry entry) throws IOException;
090
091 /**
092 * Updates the specified entry in the archive with the attributes containted in the {@link ArchiveEntry} object.
093 * Throws an <code>IOException</code> if the entry doesn't exist in the archive or if an I/O error occurs.
094 *
095 * <p>This methods can be used to update the entry's date and permissions for instance.</p>
096 *
097 * @param entry the entry to update in the archive
098 * @throws IOException if the entry doesn't exist in the archive or if an I/O error occurs
099 */
100 public abstract void updateEntry(ArchiveEntry entry) throws IOException;
101
102 /**
103 * Processes the archive file to leave it in an optimal form. This method should be called after a writable archive
104 * has been modified (entries added or removed).
105 *
106 * <p>The actual effect of this method on the archive file depends on the kind of archive. It may be implemented
107 * as a no-op if there is no use for it.
108 * To illustrate, in the case of a {@link com.mucommander.file.impl.zip.ZipArchiveFile}, this method removes chunks
109 * of free space that are left when entries are deleted.</p>
110 *
111 * @throws IOException if an I/O error occurs
112 */
113 public abstract void optimizeArchive() throws IOException;
114 }