View Javadoc

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