| /* |
| * Copyright (C) 2015 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.apkzlib.zip; |
| |
| import com.android.apkzlib.utils.IOExceptionRunnable; |
| import java.io.IOException; |
| import javax.annotation.Nonnull; |
| import javax.annotation.Nullable; |
| |
| /** |
| * An extension of a {@link ZFile}. Extensions are notified when files are open, updated, closed and |
| * when files are added or removed from the zip. These notifications are received after the zip |
| * has been updated in memory for open, when files are added or removed and when the zip has been |
| * updated on disk or closed. |
| * <p> |
| * An extension is also notified before the file is updated, allowing it to modify the file before |
| * the update happens. If it does, then all extensions are notified of the changes on the zip file. |
| * Because the order of the notifications is preserved, all extensions are notified in the same |
| * order. For example, if two extensions E1 and E2 are registered and they both add a file at |
| * update time, this would be the flow: |
| * <ul> |
| * <li>E1 receives {@code beforeUpdate} notification.</li> |
| * <li>E1 adds file F1 to the zip (notifying the addition is suspended because another |
| * notification is in progress).</li> |
| * <li>E2 receives {@code beforeUpdate} notification.</li> |
| * <li>E2 adds file F2 to the zip (notifying the addition is suspended because another |
| * notification is in progress).</li> |
| * <li>E1 is notified F1 was added.</li> |
| * <li>E2 is notified F1 was added.</li> |
| * <li>E1 is notified F2 was added.</li> |
| * <li>E2 is notified F2 was added.</li> |
| * <li>(zip file is updated on disk)</li> |
| * <li>E1 is notified the zip was updated.</li> |
| * <li>E2 is notified the zip was updated.</li> |
| * </ul> |
| * <p> |
| * An extension should not modify the zip file when notified of changes. If allowed, this would |
| * break event notification order in case multiple extensions are registered with the zip file. |
| * To allow performing changes to the zip file, all notification method return a |
| * {@code IOExceptionRunnable} that is invoked when {@link ZFile} has finished notifying all |
| * extensions. |
| */ |
| public abstract class ZFileExtension { |
| |
| /** |
| * The zip file has been open and the zip's contents have been read. The default implementation |
| * does nothing and returns {@code null}. |
| * |
| * @return an optional runnable to run when notification of all listeners has ended |
| * @throws IOException failed to process the event |
| */ |
| @Nullable |
| public IOExceptionRunnable open() throws IOException { |
| return null; |
| } |
| |
| /** |
| * The zip will be updated. This method allows the extension to register changes to the zip |
| * file before the file is written. The default implementation does nothing and returns |
| * {@code null}. |
| * <p> |
| * After this notification is received, the extension will receive further |
| * {@link #added(StoredEntry, StoredEntry)} and {@link #removed(StoredEntry)} notifications if |
| * it or other extensions add or remove files before update. |
| * <p> |
| * When no more files are updated, the {@link #entriesWritten()} notification is sent. |
| * |
| * @return an optional runnable to run when notification of all listeners has ended |
| * @throws IOException failed to process the event |
| */ |
| @Nullable |
| public IOExceptionRunnable beforeUpdate() throws IOException { |
| return null; |
| } |
| |
| /** |
| * This notification is sent when all entries have been written in the file but the central |
| * directory and the EOCD have not yet been written. No entries should be added, removed or |
| * updated during this notification. If this method forces an update of either the central |
| * directory or EOCD, then this method will be invoked again for all extensions with the new |
| * central directory and EOCD. |
| * <p> |
| * After this notification, {@link #updated()} is sent. |
| * |
| * @throws IOException failed to process the event |
| */ |
| public void entriesWritten() throws IOException { |
| } |
| |
| /** |
| * The zip file has been updated on disk. The default implementation does nothing. |
| * |
| * @throws IOException failed to perform update tasks |
| */ |
| public void updated() throws IOException { |
| } |
| |
| /** |
| * The zip file has been closed. Note that if {@link ZFile#close()} requires that the zip file |
| * be updated (because it had in-memory changes), {@link #updated()} will be called before |
| * this method. The default implementation does nothing. |
| */ |
| public void closed() { |
| } |
| |
| /** |
| * A new entry has been added to the zip, possibly replacing an entry in there. The |
| * default implementation does nothing and returns {@code null}. |
| * |
| * @param entry the entry that was added |
| * @param replaced the entry that was replaced, if any |
| * @return an optional runnable to run when notification of all listeners has ended |
| */ |
| @Nullable |
| public IOExceptionRunnable added(@Nonnull StoredEntry entry, @Nullable StoredEntry replaced) { |
| return null; |
| } |
| |
| /** |
| * An entry has been removed from the zip. This method is not invoked for entries that have |
| * been replaced. Those entries are notified using <em>replaced</em> in |
| * {@link #added(StoredEntry, StoredEntry)}. The default implementation does nothing and |
| * returns {@code null}. |
| * |
| * @param entry the entry that was deleted |
| * @return an optional runnable to run when notification of all listeners has ended |
| */ |
| @Nullable |
| public IOExceptionRunnable removed(@Nonnull StoredEntry entry) { |
| return null; |
| } |
| } |