View Javadoc

1   package com.atlassian.core.spool;
2   
3   import java.io.*;
4   
5   /**
6    * This specialisation of DeferredFileOutputStream may be configured with a FileFactory so that files are only created
7    * once the deferred threshold is reached. getInputStream() returns a SpoolFileInputStream to read the result,
8    * which means that the deferred file will be deleted once the input stream is closed.
9    */
10  public class DeferredSpoolFileOutputStream extends DeferredFileOutputStream
11  {
12      private FileFactory fileFactory = DefaultSpoolFileFactory.getInstance();
13      private boolean unspooling = false;
14  
15      /**
16       * Create a new DeferredSpoolFileOutputStream with the specified threshold and deferred file
17       * @see #DeferredFileOutputStream(int, File)
18       */
19      public DeferredSpoolFileOutputStream(int threshold, File outputFile)
20      {
21          super(threshold, outputFile);
22      }
23  
24      /**
25       * Create a new DeferredSpoolFileOutputStream with the specified threshold and file factory. The file factory
26       * will only be used when the threshold is reached, so you can defer the creation of files until they are necessary
27       * @param threshold
28       * @param fileFactory Factory to use when the deferred file must be created
29       */
30      public DeferredSpoolFileOutputStream(int threshold, FileFactory fileFactory)
31      {
32          super(threshold, null);
33          this.fileFactory = fileFactory;
34      }
35  
36      /**
37       * @return True if the stream has been closed
38       */
39      public boolean isClosed()
40      {
41          return closed;
42      }
43  
44      /**
45       *
46       * @return True if getInputStream() has been called already
47       */
48      public boolean isUnspooling()
49      {
50          return unspooling;
51      }
52  
53      protected void thresholdReached() throws IOException
54      {
55          if (outputFile == null)
56              outputFile = fileFactory.createNewFile();
57          super.thresholdReached();
58      }
59  
60      /**
61       * Return an input stream of the written data. This method may only be called once and only once the output stream
62       * has been closed.
63       *
64       * @return A InputStream - If the deferred stream has been written to disk, a SpoolFileInputStream will be returned
65       * and the deferred file will be deleted when this stream is closed.
66       * @throws IOException If the output stream is not closed or an input stream has already been returned
67       */
68      public InputStream getInputStream() throws IOException
69      {
70          if (!isClosed())
71              throw new IOException("Output stream not closed");
72  
73          if (isUnspooling())
74              throw new IOException("Stream is already being unspooled");
75  
76          InputStream spoolStream;
77  
78          if (isInMemory())
79              spoolStream = new ByteArrayInputStream(getData());
80          else
81              try
82              {
83                  spoolStream = new SpoolFileInputStream(getFile());
84              }
85              catch (FileNotFoundException ex)
86              {
87                  throw new IOException("Deferred file does not exist");
88              }
89  
90          unspooling = true;
91          return spoolStream;
92      }
93  }