Adding interface to implement the content received by a remote data source cache - OnDataSend.

I am creating a proxy server that content received from internent cache and the need arose to save to a file.
What I did was create an interface that shares the data sent to a callback and enables you to create this cache.

Exemplifying how would the proxy server:

```
    @Override
    public Response serve(String uri, Method method, Map<String, String> header, Map<String, String> parms, Map<String, String> files) {
        String targetUrl = Encoder.decode(parms.get(QUERY_URL));
        if (DEBUG) Log.d(TAG, String.format("Loading (%s)", targetUrl));

        String fileName = Encoder.decode(parms.get(QUERY_FILE));
        if (DEBUG) Log.d(TAG, String.format("FILE (%s)", fileName));

        Response response = new Response();
        Stream stream = new Stream(0);

        if (!hasItemInCache(fileName)){
            try {
                stream = doDownload(targetUrl, fileName, response, header);
            } catch (Exception e){
                if (DEBUG) e.printStackTrace();
                return new Response(Response.Status.INTERNAL_ERROR, MIME_PLAINTEXT,
                    String.valueOf(e.getMessage()));
            }
        } else {
            SimpleDiskCache.InputStreamEntry cacheItem = getCacheItem(fileName);
            stream.setInputStream(cacheItem.getInputStream());

            Map<String, Serializable> cacheData = cacheItem.getMetadata();
            MetaData meta = (MetaData) cacheData.get(CACHE_KEY);

            long fileSize = meta.getFileSize();
            stream.setCode(200); // OK
            try {
                if (stream.is.available() < (fileSize-10)){
                    try {
                        stream = doDownload(targetUrl, fileName, response, header);
                    } catch (Exception e){
                        if (DEBUG) e.printStackTrace();
                        return new Response(Response.Status.INTERNAL_ERROR, MIME_PLAINTEXT,
                                String.valueOf(e.getMessage()));
                    } finally {
                        Util.close(stream.is);
                        cacheItem.close();
                    }
                } else {
                    stream.setCached(true);
                }
            } catch (IOException e){
                if (DEBUG) e.printStackTrace();
            }
        }
        Response.Status status = Response.Status.lookup(stream.code);
        response.setStatus(status);

        response.setData(new BufferedInputStream(stream.is));
        response.setMimeType(header.get(Header.CONTENT_TYPE));
        response.setChunkedTransfer(true);

        if (DEBUG) Log.d(TAG, String.format("File(%s) cached:%s", fileName, stream.cached));

        // Interface implemented and assigned to the request (allows access to data sent).
        final Stream _stream = stream;
        response.setOnDataSend(new OnDataSend(){
            @Override
            public void onSend(byte[] buffer, int length) {
                if (_stream.os != null && !_stream.cached){
                    try {
                        _stream.os.write(buffer, 0, length);
                    } catch (IOException e) {
                        if (DEBUG) e.printStackTrace();
                    }
                }
            @Override
             public void onStopSend() {
                  try {
                      _stream.os.close();
                  } catch (IOException e) {
                      if (DEBUG) e.printStackTrace();
                  }
              }
            }
        });
        if (DEBUG) Log.d(TAG, String.format("Code[%d] Status[%s]", stream.code, status));
        return response;
    }
```

Without this interface is virtually impossible to create any cached content.