View Javadoc
1   /*
2    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
3    * The software in this package is published under the terms of the CPAL v1.0
4    * license, a copy of which has been included with this distribution in the
5    * LICENSE.txt file.
6    */
7   package org.mule.module.pgp;
8   
9   import java.io.IOException;
10  import java.io.InputStream;
11  import java.io.PipedInputStream;
12  import java.io.PipedOutputStream;
13  
14  import org.apache.commons.lang.Validate;
15  
16  /**
17   * A {@link LazyTransformedInputStream} represents an {@link InputStream} that
18   * has been transformed when someone needs to read from it.
19   * 
20   * Internally, the {@link LazyTransformedInputStream} has a pipe that is written by an
21   * {@link StreamTransformer} according to a {@link TransformPolicy}.
22   * 
23   * The {@link LazyTransformedInputStream} uses a separate thread for writing on the pipe
24   * and delays it destruction till this {@link InputStream} is closed of finalized. In this way
25   * we avoid any problems with broken pipes.
26   */
27  public class LazyTransformedInputStream extends InputStream
28  {
29      private PipedInputStream in;
30      private PipedOutputStream out;
31      private TransformPolicy transformPolicy;
32      private StreamTransformer transformer;
33      
34      public LazyTransformedInputStream(TransformPolicy transformPolicy, StreamTransformer transformer) throws IOException
35      {
36          Validate.notNull(transformPolicy, "The transformPolicy should not be null");
37          Validate.notNull(transformer, "The transformer should not be null");
38  
39          this.in = new PipedInputStream();
40          this.out = new PipedOutputStream(this.in);
41          this.transformPolicy = transformPolicy;
42          this.transformer = transformer;
43          this.transformPolicy.initialize(this);
44      }
45  
46      @Override
47      public int available() throws IOException
48      {
49          this.transformPolicy.readRequest(100);
50          return this.in.available();
51      }
52  
53      @Override
54      public void close() throws IOException
55      {
56          this.in.close();
57          this.transformPolicy.release();
58      }
59      
60      @Override
61      protected void finalize() throws Throwable
62      {
63          this.transformPolicy.release();
64      }
65      
66      @Override
67      public synchronized void mark(int readlimit)
68      {
69          this.in.mark(readlimit);
70      }
71  
72      @Override
73      public boolean markSupported()
74      {
75          return this.in.markSupported();
76      }
77  
78      @Override
79      public int read() throws IOException
80      {
81          this.transformPolicy.readRequest(1);
82          return this.in.read();
83      }
84  
85      @Override
86      public int read(byte[] b, int off, int len) throws IOException
87      {
88          this.transformPolicy.readRequest(len);
89          return this.in.read(b, off, len);
90      }
91  
92      @Override
93      public int read(byte[] b) throws IOException
94      {
95          this.transformPolicy.readRequest(b.length);
96          return this.in.read(b);
97      }
98  
99      @Override
100     public synchronized void reset() throws IOException
101     {
102         this.in.reset();
103     }
104 
105     @Override
106     public long skip(long n) throws IOException
107     {
108         this.transformPolicy.readRequest(n);
109         return this.in.skip(n);
110     }
111 
112     PipedOutputStream getOut()
113     {
114         return out;
115     }
116     
117     StreamTransformer getTransformer()
118     {
119         return transformer;
120     }
121 }