View Javadoc

1   /*
2    * $Id: TransformPerRequestInChunksPolicy.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.PipedOutputStream;
14  import java.util.concurrent.Semaphore;
15  
16  /**
17   * A {@link TransformPolicy} that copies the requested transformed bytes in chunks
18   * into the {@link PipedOutputStream}.
19   */
20  public class TransformPerRequestInChunksPolicy extends AbstractTransformPolicy
21  {
22  
23      private Semaphore writeSemaphore;
24      private long chunkSize;
25      private long bytesActuallyRequested;
26  
27      public TransformPerRequestInChunksPolicy(long chunkSize)
28      {
29          this.writeSemaphore = new Semaphore(1);
30          this.chunkSize = chunkSize;
31          this.bytesActuallyRequested = 0;
32      }
33  
34      /**
35       * {@inheritDoc}
36       */
37      @Override
38      public void readRequest(long length)
39      {
40          this.bytesActuallyRequested = this.bytesActuallyRequested + length;
41          super.readRequest(length);
42          this.writeSemaphore.release();
43      }
44  
45      /**
46       * {@inheritDoc}
47       */
48      @Override
49      public void release()
50      {
51          this.writeSemaphore.release();
52          super.release();
53      }
54  
55      /**
56       * {@inheritDoc}
57       */
58      @Override
59      protected Thread getCopyingThread()
60      {
61          return new PerRequestWork();
62      }
63  
64      private class PerRequestWork extends TransformerWork
65      {
66          @Override
67          protected void execute() throws Exception
68          {
69              getTransformer().initialize(getInputStream().getOut());
70  
71              boolean finishWriting = false;
72              while (!finishWriting && !isClosed)
73              {
74                  writeSemaphore.acquire();
75  
76                  /**
77                   * Assuming one thread is reading the input stream (which is reasonable)
78                   * and the state of the reading thread which should be delayed at this point
79                   * it is safe to manipulate getBytesRequested() as I'm the only thread accessing the object
80                   */
81                  long requested = bytesActuallyRequested;
82                  long updatedRequest = (long) (Math.ceil((double)requested / (double)chunkSize) * chunkSize);
83                  getBytesRequested().set(updatedRequest);
84  
85                  finishWriting = getTransformer().write(getInputStream().getOut(), getBytesRequested());
86              }
87          }
88      }
89  }