001: /* ObjectPlusFilesInputStream
002: *
003: * $Id: ObjectPlusFilesInputStream.java 4646 2006-09-22 17:23:04Z paul_jack $
004: *
005: * Created on Apr 28, 2004
006: *
007: * Copyright (C) 2004 Internet Archive.
008: *
009: * This file is part of the Heritrix web crawler (crawler.archive.org).
010: *
011: * Heritrix is free software; you can redistribute it and/or modify
012: * it under the terms of the GNU Lesser Public License as published by
013: * the Free Software Foundation; either version 2.1 of the License, or
014: * any later version.
015: *
016: * Heritrix is distributed in the hope that it will be useful,
017: * but WITHOUT ANY WARRANTY; without even the implied warranty of
018: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
019: * GNU Lesser Public License for more details.
020: *
021: * You should have received a copy of the GNU Lesser Public License
022: * along with Heritrix; if not, write to the Free Software
023: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
024: */
025: package org.archive.io;
026:
027: import java.io.File;
028: import java.io.IOException;
029: import java.io.InputStream;
030: import java.io.ObjectInputStream;
031: import java.util.Iterator;
032: import java.util.LinkedList;
033:
034: import org.archive.util.FileUtils;
035:
036: /**
037: * Enhanced ObjectOutputStream with support for restoring
038: * files that had been saved, in parallel with object
039: * serialization.
040: *
041: * @author gojomo
042: *
043: */
044: public class ObjectPlusFilesInputStream extends ObjectInputStream {
045: LinkedList<File> auxiliaryDirectoryStack = new LinkedList<File>();
046: LinkedList<Runnable> postRestoreTasks = new LinkedList<Runnable>();
047:
048: /**
049: * Instantiate over the given stream and using the supplied
050: * auxiliary storage directory.
051: *
052: * @param in
053: * @param storeDir
054: * @throws IOException
055: */
056: public ObjectPlusFilesInputStream(InputStream in, File storeDir)
057: throws IOException {
058: super (in);
059: auxiliaryDirectoryStack.addFirst(storeDir);
060: }
061:
062: /**
063: * Push another default storage directory for use
064: * until popped.
065: *
066: * @param dir
067: */
068: public void pushAuxiliaryDirectory(String dir) {
069: auxiliaryDirectoryStack.addFirst(new File(
070: getAuxiliaryDirectory(), dir));
071: }
072:
073: /**
074: * Discard the top auxiliary directory.
075: */
076: public void popAuxiliaryDirectory() {
077: auxiliaryDirectoryStack.removeFirst();
078: }
079:
080: /**
081: * Return the top auxiliary directory, from
082: * which saved files are restored.
083: *
084: * @return Auxillary directory.
085: */
086: public File getAuxiliaryDirectory() {
087: return (File) auxiliaryDirectoryStack.getFirst();
088: }
089:
090: /**
091: * Restore a file from storage, using the name and length
092: * info on the serialization stream and the file from the
093: * current auxiliary directory, to the given File.
094: *
095: * @param destination
096: * @throws IOException
097: */
098: public void restoreFile(File destination) throws IOException {
099: String nameAsStored = readUTF();
100: long lengthAtStoreTime = readLong();
101: File storedFile = new File(getAuxiliaryDirectory(),
102: nameAsStored);
103: FileUtils.copyFile(storedFile, destination, lengthAtStoreTime);
104: }
105:
106: /**
107: * Restore a file from storage, using the name and length
108: * info on the serialization stream and the file from the
109: * current auxiliary directory, to the given File.
110: *
111: * @param directory
112: * @throws IOException
113: */
114: public void restoreFileTo(File directory) throws IOException {
115: String nameAsStored = readUTF();
116: long lengthAtStoreTime = readLong();
117: File storedFile = new File(getAuxiliaryDirectory(),
118: nameAsStored);
119: File destination = new File(directory, nameAsStored);
120: FileUtils.copyFile(storedFile, destination, lengthAtStoreTime);
121: }
122:
123: /**
124: * Register a task to be done when the ObjectPlusFilesInputStream
125: * is closed.
126: *
127: * @param task
128: */
129: public void registerFinishTask(Runnable task) {
130: postRestoreTasks.addFirst(task);
131: }
132:
133: private void doFinishTasks() {
134: Iterator iter = postRestoreTasks.iterator();
135: while (iter.hasNext()) {
136: ((Runnable) iter.next()).run();
137: }
138: }
139:
140: /**
141: * In addition to default, do any registered cleanup tasks.
142: *
143: * @see java.io.InputStream#close()
144: */
145: public void close() throws IOException {
146: super.close();
147: doFinishTasks();
148: }
149: }
|