001/*
002 * The contents of this file are subject to the license and copyright
003 * detailed in the LICENSE and NOTICE files at the root of the source
004 * tree.
005 */
006package org.fcrepo.auth.webac;
007
008import java.io.BufferedReader;
009import java.io.ByteArrayInputStream;
010import java.io.IOException;
011import java.io.InputStreamReader;
012
013import javax.servlet.ReadListener;
014import javax.servlet.ServletInputStream;
015import javax.servlet.ServletRequest;
016import javax.servlet.http.HttpServletRequest;
017import javax.servlet.http.HttpServletRequestWrapper;
018
019import org.apache.commons.io.IOUtils;
020
021/**
022 * An extension of HttpServletRequestWrapper that caches the InputStream as
023 * byte array and overrides the getInputStream to return a new InputStream
024 * object each time based on the cached byte array.
025 * 
026 * @author mohideen
027 */
028public class CachedHttpRequest extends HttpServletRequestWrapper {
029
030    private byte[] cachedContent;
031
032    private BufferedReader reader;
033
034    /**
035     * Create a new CachedSparqlRequest for the given servlet request.
036     * @param request the original servlet request
037     */
038    public CachedHttpRequest(final ServletRequest request) {
039        super((HttpServletRequest) request);
040    }
041
042    @Override
043    public ServletInputStream getInputStream() throws IOException {
044        if (getRequest().getInputStream() != null) {
045            if (this.cachedContent == null) {
046                this.cachedContent = IOUtils.toByteArray(getRequest().getInputStream());
047            }
048            return new CustomServletInputStream(cachedContent);
049        }
050        return null;
051    }
052
053    @Override
054    public BufferedReader getReader() throws IOException {
055        if (this.reader == null) {
056            this.reader = new BufferedReader(new InputStreamReader(getInputStream(),
057                    getCharacterEncoding()));
058        }
059        return this.reader;
060    }
061
062    private static class CustomServletInputStream extends ServletInputStream {
063
064        private final ByteArrayInputStream buffer;
065
066        public CustomServletInputStream(final byte[] contents) {
067            this.buffer = new ByteArrayInputStream(contents);
068        }
069
070        @Override
071        public int read() {
072            return buffer.read();
073        }
074
075        @Override
076        public boolean isFinished() {
077            return buffer.available() == 0;
078        }
079
080        @Override
081        public boolean isReady() {
082            return true;
083        }
084
085        @Override
086        public void setReadListener(final ReadListener listener) {
087            throw new RuntimeException("Not implemented");
088        }
089    }
090}