org.ajax4jsf.webapp.CacheContent.java Source code

Java tutorial

Introduction

Here is the source code for org.ajax4jsf.webapp.CacheContent.java

Source

/**
 * License Agreement.
 *
 * Rich Faces - Natural Ajax for Java Server Faces (JSF)
 *
 * Copyright (C) 2007 Exadel, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1 as published by the Free Software Foundation.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
 */

package org.ajax4jsf.webapp;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Serializable;
import java.io.Writer;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import org.ajax4jsf.io.FastBufferOutputStream;
import org.ajax4jsf.io.FastBufferWriter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * @author shura (latest modification by $Author: alexsmirnov $)
 * @version $Revision: 1.1.2.1 $ $Date: 2007/01/09 18:58:20 $
 * 
 */
public class CacheContent implements Serializable {
    /**
     * 
     */
    private static final long serialVersionUID = 8120940486890871177L;

    private static final Log _log = LogFactory.getLog(CacheContent.class);

    // private transient ByteArrayOutputStream outputStream ;
    private transient FastBufferOutputStream outputStream;

    private transient FastBufferWriter stringOutputWriter;

    private transient PrintWriter servletWriter;

    private transient ServletOutputStream servletStream;

    // content to send.
    private byte[] content = null;

    private String writerContent = null;

    boolean filledOutputStream = false;

    boolean filledOutputWriter = false;

    private Map<String, Object> headers = new HashMap<String, Object>();

    private String contentType;

    private Integer contentLength;

    /**
     * Send saved content to http responce
     * 
     * @param response
     * @throws IOException
     */
    public void send(HttpServletResponse response) throws IOException {
        if (filledOutputStream) {
            OutputStream out = response.getOutputStream();
            if (content != null) {
                out.write(content);
            } else {
                this.outputStream.writeTo(out);
            }
            // out.flush();
            // out.close();
        } else if (filledOutputWriter) {
            Writer out = response.getWriter();
            if (null != writerContent) {
                out.write(writerContent);
            } else {
                stringOutputWriter.writeTo(out);
            }
            // out.flush();
            // out.close();
        }
    }

    /**
     * Send saved headers to http responce.
     * 
     * @param response
     */
    public void sendHeaders(HttpServletResponse response) {
        // set real content-length.
        // / if (null != content) {
        int realContentLength = 0;
        if (filledOutputStream) {
            if (null != content && content.length > 0) {
                realContentLength = content.length;
            } else if (null != outputStream && outputStream.getLength() > 0) {
                realContentLength = outputStream.getLength();
            }
        } // TODO - calculate content-lenght for writer ?

        if (realContentLength <= 0 && contentLength != null) {
            realContentLength = contentLength.intValue();
        }

        for (Iterator<Entry<String, Object>> iter = headers.entrySet().iterator(); iter.hasNext();) {
            Entry<String, Object> element = iter.next();
            String header = (String) element.getKey();
            Object headerValue = element.getValue();
            try {
                if (headerValue instanceof Long) {
                    Long time = (Long) headerValue;
                    response.setDateHeader(header, time.longValue());
                } else if (headerValue instanceof Integer) {
                    Integer value = (Integer) headerValue;
                    // Check real content length.
                    if ("Content-Length".equals(header)) {
                        if (realContentLength <= 0) {
                            realContentLength = value.intValue();
                        } else {
                            //do nothing
                        }
                    } else {
                        response.setIntHeader(header, value.intValue());
                    }
                } else {
                    // Don't send "chunked" transfer-encoding type with real content-length
                    if (!(realContentLength > 0 && "Transfer-Encoding".equals(header)
                            && "chunked".equals(headerValue))) {
                        response.setHeader(header, (String) headerValue);
                    }
                }

            } catch (Exception e) {
                _log.error("Error set response header " + header + "for value " + headerValue, e);
            }
            if (realContentLength > 0) {
                response.setContentLength(realContentLength);
            }
            if (null != contentType) {
                response.setContentType(this.contentType);
            }
        }
    }

    public void setDateHeader(String name, long value) {
        // Expires not stored in cache - must be re-calculated for every
        // response.
        if (!"Expires".equals(name)) {
            headers.put(name, new Long(value));
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.ajax4jsf.framework.resource.ResourceContext#setHeader(java.lang.String,
     *      java.lang.String)
     */
    public void setHeader(String name, String value) {
        headers.put(name, value);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.ajax4jsf.framework.resource.ResourceContext#setIntHeader(java.lang.String,
     *      int)
     */
    public void setIntHeader(String name, int value) {
        headers.put(name, new Integer(value));
    }

    /**
     * Create UNIX command 'tee' like stream - send all data to servlet
     * 
     * @param responseStream
     * @return
     */
    public OutputStream getOutputStream() {
        if (null == servletStream) {
            outputStream = new FastBufferOutputStream(1024);
            servletStream = new ServletOutputStream() {

                /*
                 * (non-Javadoc)
                 * 
                 * @see java.io.OutputStream#close()
                 */
                public void close() throws IOException {
                    filledOutputStream = true;
                    // / content = outputStream.toByteArray();
                    content = null;
                }

                /*
                 * (non-Javadoc)
                 * 
                 * @see java.io.OutputStream#flush()
                 */
                public void flush() throws IOException {
                }

                /*
                 * (non-Javadoc)
                 * 
                 * @see java.io.OutputStream#write(byte[], int, int)
                 */
                public void write(byte[] b, int off, int len) throws IOException {
                    outputStream.write(b, off, len);
                }

                /*
                 * (non-Javadoc)
                 * 
                 * @see java.io.OutputStream#write(byte[])
                 */
                public void write(byte[] b) throws IOException {
                    outputStream.write(b);
                }

                public void write(int b) throws IOException {
                    outputStream.write(b);
                }

            };
        }
        return servletStream;
    }

    public PrintWriter getWriter() {
        if (null == servletWriter) {
            stringOutputWriter = new FastBufferWriter(1024);
            Writer out = new Writer() {

                public void write(char[] cbuf, int off, int len) throws IOException {
                    stringOutputWriter.write(cbuf, off, len);
                }

                public void flush() throws IOException {
                }

                public void close() throws IOException {
                    // / writerContent = stringOutputWriter.toString();
                    filledOutputWriter = true;
                    writerContent = null;
                }

            };
            servletWriter = new PrintWriter(out);
        }
        return servletWriter;
    }

    public void setContentType(String contentType) {
        this.contentType = contentType;

    }

    /**
     * @return Returns the contentType.
     */
    public String getContentType() {
        return contentType;
    }

    private void writeObject(java.io.ObjectOutputStream s) throws IOException {
        if (filledOutputStream) {
            if (outputStream != null) {
                content = outputStream.toByteArray();
            }
        } else if (filledOutputWriter) {
            if (stringOutputWriter != null) {
                char[] cs = stringOutputWriter.toCharArray();
                writerContent = new String(cs);
            }
        }
        s.defaultWriteObject();
    }

    /**
     * Flush used output writer/stream, to fix https://jira.jboss.org/jira/browse/RF-4017
     * @param response
     * @throws IOException
     */
    public void flush(HttpServletResponse response) throws IOException {
        if (filledOutputStream) {
            OutputStream out = response.getOutputStream();
            out.flush();
        } else if (filledOutputWriter) {
            Writer out = response.getWriter();
            out.flush();
        }
    }

    public int getContentLength() {
        if (contentLength == null) {
            throw new IllegalStateException("Content length hasn't been set yet!");
        }

        return contentLength.intValue();
    }

    public void setContentLength(int contentLength) {
        this.contentLength = contentLength;
    }
}