1 package com.atlassian.core.spool;
2
3 import java.io.InputStream;
4 import java.io.IOException;
5
6 /**
7 * Spool that delegates to the overThresholdSpool immediately if InputStream::available() is greater than the threshold
8 * of the secondary Thresholding spool. This avoids needless spooling of data into memory from InputStreams with large
9 * amounts of initial data available
10 */
11 public class SmartSpool implements ThresholdingSpool
12 {
13 private Spool overThresholdSpool = new BufferedFileSpool();
14 private ThresholdingSpool thresholdingSpool = new DeferredSpool();
15
16 public void setThresholdBytes(int bytes)
17 {
18 thresholdingSpool.setThresholdBytes(bytes);
19 }
20
21 public int getThresholdBytes()
22 {
23 return thresholdingSpool.getThresholdBytes();
24 }
25
26 public InputStream spool(InputStream is) throws IOException
27 {
28 // This stream has more bytes than we are willing to spool in memory. Write it straight to the overflow spool
29 if (is.available() > getThresholdBytes())
30 return overThresholdSpool.spool(is);
31
32 // The input stream MAY have more than we are prepared to spool in memory.
33 // (InputStream::available() only has to return the number of bytes that can be read *without blocking*
34 // The thresholding spool should sort this out.
35 return thresholdingSpool.spool(is);
36 }
37
38 /**
39 * Set the spooling strategy to use when InputStream::available is greater than the threshold of the configured
40 * ThresholdingSpool
41 * @param overThresholdSpool
42 */
43 public void setOverThresholdSpool(Spool overThresholdSpool)
44 {
45 this.overThresholdSpool = overThresholdSpool;
46 }
47
48 /**
49 * Set the spooling strategy that will be used when InputStream::available() is less than or equal to
50 * the value of the strategy's threshold.
51 * @param thresholdingSpool
52 */
53 public void setThresholdingSpool(ThresholdingSpool thresholdingSpool)
54 {
55 this.thresholdingSpool = thresholdingSpool;
56 }
57 }