View Javadoc

1   /* ObjectPlusFilesInputStream
2   *
3   * $Id: ObjectPlusFilesInputStream.java 4646 2006-09-22 17:23:04Z paul_jack $
4   *
5   * Created on Apr 28, 2004
6   *
7   * Copyright (C) 2004 Internet Archive.
8   *
9   * This file is part of the Heritrix web crawler (crawler.archive.org).
10  *
11  * Heritrix is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser Public License as published by
13  * the Free Software Foundation; either version 2.1 of the License, or
14  * any later version.
15  *
16  * Heritrix is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU Lesser Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser Public License
22  * along with Heritrix; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24  */
25  package org.archive.io;
26  
27  import java.io.File;
28  import java.io.IOException;
29  import java.io.InputStream;
30  import java.io.ObjectInputStream;
31  import java.util.Iterator;
32  import java.util.LinkedList;
33  
34  import org.archive.util.FileUtils;
35  
36  
37  /***
38   * Enhanced ObjectOutputStream with support for restoring
39   * files that had been saved, in parallel with object
40   * serialization.
41   *
42   * @author gojomo
43   *
44   */
45  public class ObjectPlusFilesInputStream extends ObjectInputStream {
46      LinkedList<File> auxiliaryDirectoryStack = new LinkedList<File>();
47      LinkedList<Runnable> postRestoreTasks = new LinkedList<Runnable>();
48  
49      /***
50       * Instantiate over the given stream and using the supplied
51       * auxiliary storage directory.
52       *
53       * @param in
54       * @param storeDir
55       * @throws IOException
56       */
57      public ObjectPlusFilesInputStream(InputStream in, File storeDir)
58      throws IOException {
59          super(in);
60          auxiliaryDirectoryStack.addFirst(storeDir);
61      }
62  
63      /***
64       * Push another default storage directory for use
65       * until popped.
66       *
67       * @param dir
68       */
69      public void pushAuxiliaryDirectory(String dir) {
70          auxiliaryDirectoryStack.
71              addFirst(new File(getAuxiliaryDirectory(), dir));
72      }
73  
74      /***
75       * Discard the top auxiliary directory.
76       */
77      public void popAuxiliaryDirectory() {
78          auxiliaryDirectoryStack.removeFirst();
79      }
80  
81      /***
82       * Return the top auxiliary directory, from
83       * which saved files are restored.
84       *
85       * @return Auxillary directory.
86       */
87      public File getAuxiliaryDirectory() {
88          return (File)auxiliaryDirectoryStack.getFirst();
89      }
90  
91      /***
92       * Restore a file from storage, using the name and length
93       * info on the serialization stream and the file from the
94       * current auxiliary directory, to the given File.
95       *
96       * @param destination
97       * @throws IOException
98       */
99      public void restoreFile(File destination) throws IOException {
100         String nameAsStored = readUTF();
101         long lengthAtStoreTime = readLong();
102         File storedFile = new File(getAuxiliaryDirectory(),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(),nameAsStored);
118         File destination = new File(directory,nameAsStored);
119         FileUtils.copyFile(storedFile, destination, lengthAtStoreTime);
120     }
121 
122     /***
123      * Register a task to be done when the ObjectPlusFilesInputStream
124      * is closed.
125      *
126      * @param task
127      */
128     public void registerFinishTask(Runnable task) {
129         postRestoreTasks.addFirst(task);
130     }
131 
132     private void doFinishTasks() {
133     	Iterator iter = postRestoreTasks.iterator();
134     	while(iter.hasNext()) {
135     		((Runnable)iter.next()).run();
136         }
137     }
138 
139     /***
140      * In addition to default, do any registered cleanup tasks.
141      *
142      * @see java.io.InputStream#close()
143      */
144     public void close() throws IOException {
145         super.close();
146         doFinishTasks();
147     }
148 }