📄 cmsflexresponse.java
字号:
/*
* File : $Source: /usr/local/cvs/opencms/src/org/opencms/flex/CmsFlexResponse.java,v $
* Date : $Date: 2006/03/27 14:52:35 $
* Version: $Revision: 1.42 $
*
* This library is part of OpenCms -
* the Open Source Content Mananagement System
*
* Copyright (c) 2005 Alkacon Software GmbH (http://www.alkacon.com)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* 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.
*
* For further information about Alkacon Software GmbH, please see the
* company website: http://www.alkacon.com
*
* For further information about OpenCms, please see the
* project website: http://www.opencms.org
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.opencms.flex;
import org.opencms.main.CmsIllegalArgumentException;
import org.opencms.main.CmsLog;
import org.opencms.util.CmsDateUtil;
import org.opencms.util.CmsRequestUtil;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import org.apache.commons.logging.Log;
/**
* Wrapper class for a HttpServletResponse, required in order to process JSPs from the OpenCms VFS.<p>
*
* This class wrapps the standard HttpServletResponse so that it's output can be delivered to
* the CmsFlexCache.<p>
*
* @author Alexander Kandzior
*
* @version $Revision: 1.42 $
*
* @since 6.0.0
*/
public class CmsFlexResponse extends HttpServletResponseWrapper {
/**
* Wrapped implementation of the ServletOutputStream.<p>
*
* This implementation writes to an internal buffer and optionally to another
* output stream at the same time.
* It should be fully transparent to the standard ServletOutputStream.<p>
*/
private class CmsServletOutputStream extends ServletOutputStream {
/** The optional output stream to write to. */
private ServletOutputStream m_servletStream;
/** The internal stream buffer. */
private ByteArrayOutputStream m_stream;
/**
* Constructor that must be used if the stream should write
* only to a buffer.<p>
*/
public CmsServletOutputStream() {
m_servletStream = null;
clear();
}
/**
* Constructor that must be used if the stream should write
* to a buffer and to another stream at the same time.<p>
*
* @param servletStream The stream to write to
*/
public CmsServletOutputStream(ServletOutputStream servletStream) {
m_servletStream = servletStream;
clear();
}
/**
* Clears the buffer by initializing the buffer with a new stream.<p>
*/
public void clear() {
m_stream = new java.io.ByteArrayOutputStream(1024);
}
/**
* @see java.io.OutputStream#close()
*/
public void close() throws IOException {
if (m_stream != null) {
m_stream.close();
}
if (m_servletStream != null) {
m_servletStream.close();
}
super.close();
}
/**
* @see java.io.OutputStream#flush()
*/
public void flush() throws IOException {
if (LOG.isDebugEnabled()) {
LOG.debug(Messages.get().getBundle().key(Messages.LOG_FLEXRESPONSE_FLUSHED_1, m_servletStream));
}
if (m_servletStream != null) {
m_servletStream.flush();
}
}
/**
* Provides access to the bytes cached in the buffer.<p>
*
* @return the cached bytes from the buffer
*/
public byte[] getBytes() {
return m_stream.toByteArray();
}
/**
* @see java.io.OutputStream#write(byte[], int, int)
*/
public void write(byte[] b, int off, int len) throws IOException {
m_stream.write(b, off, len);
if (m_servletStream != null) {
m_servletStream.write(b, off, len);
}
}
/**
* @see java.io.OutputStream#write(int)
*/
public void write(int b) throws IOException {
m_stream.write(b);
if (m_servletStream != null) {
m_servletStream.write(b);
}
}
/**
* Writes an array of bytes only to the included servlet stream,
* not to the buffer.<p>
*
* @param b The bytes to write to the stream
* @throws IOException In case the write() operation on the included servlet stream raises one
*/
public void writeToServletStream(byte[] b) throws IOException {
if (m_servletStream != null) {
m_servletStream.write(b);
}
}
}
/** The cache delimiter char. */
public static final char FLEX_CACHE_DELIMITER = (char)0;
/** Static string to indicate a header is "set" in the header maps. */
public static final String SET_HEADER = "[setHeader]";
/** The log object for this class. */
protected static final Log LOG = CmsLog.getLog(CmsFlexResponse.class);
/** Map to save response headers belonging to a single include call in .*/
private Map m_bufferHeaders;
/** String to hold a buffered redirect target. */
private String m_bufferRedirect;
/** Byte array used for "cached leafs" optimization. */
private byte[] m_cacheBytes;
/** The cached entry that is constructed from this response. */
private CmsFlexCacheEntry m_cachedEntry;
/** Indicates if caching is required, will always be true if m_writeOnlyToBuffer is true. */
private boolean m_cachingRequired;
/** The CmsFlexController for this response. */
private CmsFlexController m_controller;
/** The encoding to use for the response. */
private String m_encoding;
/** Map to save all response headers (including sub-elements) in. */
private Map m_headers;
/** A list of include calls that origin from this page, i.e. these are sub elements of this element. */
private List m_includeList;
/** A list of parameters that belong to the include calls. */
private List m_includeListParameters;
/** Indicates if this element is currently in include mode, i.e. processing a sub-element. */
private boolean m_includeMode;
/** A list of results from the inclusions, needed because of JSP buffering. */
private List m_includeResults;
/** Flag to indicate if this is the top level element or an included sub - element. */
private boolean m_isTopElement;
/** The CmsFlexCacheKey for this response. */
private CmsFlexCacheKey m_key;
/** A special wrapper class for a ServletOutputStream. */
private CmsFlexResponse.CmsServletOutputStream m_out;
/** Indicates that parent stream is writing only in the buffer. */
private boolean m_parentWritesOnlyToBuffer;
/** The wrapped ServletResponse. */
private HttpServletResponse m_res;
/** Indicates if this response is suspended (probably because of a redirect). */
private boolean m_suspended;
/** State bit indicating whether content type has been set, type may only be set once according to spec. */
private boolean m_typeSet;
/** Indicates that the OutputStream m_out should write ONLY in the buffer. */
private boolean m_writeOnlyToBuffer;
/** A printwriter that writes in the m_out stream. */
private java.io.PrintWriter m_writer;
/**
* Constructor for the CmsFlexResponse,
* this variation one is usually used to wrap responses for further include calls in OpenCms.<p>
*
* @param res the CmsFlexResponse to wrap
* @param controller the controller to use
*/
public CmsFlexResponse(HttpServletResponse res, CmsFlexController controller) {
super(res);
m_res = res;
m_controller = controller;
m_encoding = controller.getCurrentResponse().getEncoding();
m_isTopElement = controller.getCurrentResponse().isTopElement();
m_parentWritesOnlyToBuffer = controller.getCurrentResponse().hasIncludeList() && !controller.isForwardMode();
setOnlyBuffering(m_parentWritesOnlyToBuffer);
m_headers = new HashMap(16);
m_bufferHeaders = new HashMap(8);
}
/**
* Constructor for the CmsFlexResponse,
* this variation is usually used for the "top" response.<p>
*
* @param res the HttpServletResponse to wrap
* @param controller the controller to use
* @param streaming indicates if streaming should be enabled or not
* @param isTopElement indicates if this is the top element of an include cascade
*/
public CmsFlexResponse(
HttpServletResponse res,
CmsFlexController controller,
boolean streaming,
boolean isTopElement) {
super(res);
m_res = res;
m_controller = controller;
m_encoding = controller.getCmsObject().getRequestContext().getEncoding();
m_isTopElement = isTopElement;
m_parentWritesOnlyToBuffer = !streaming && !controller.isForwardMode();
setOnlyBuffering(m_parentWritesOnlyToBuffer);
m_headers = new HashMap(16);
m_bufferHeaders = new HashMap(8);
}
/**
* Process the headers stored in the provided map and add them to the response.<p>
*
* @param headers the headers to add
* @param res the resonse to add the headers to
*/
public static void processHeaders(Map headers, HttpServletResponse res) {
if (headers != null) {
Iterator i = headers.keySet().iterator();
while (i.hasNext()) {
String key = (String)i.next();
List l = (List)headers.get(key);
for (int j = 0; j < l.size(); j++) {
if ((j == 0) && (((String)l.get(0)).startsWith(SET_HEADER))) {
String s = (String)l.get(0);
res.setHeader(key, s.substring(SET_HEADER.length()));
} else {
res.addHeader(key, (String)l.get(j));
}
}
}
}
}
/**
* Method overloaded from the standard HttpServletRequest API.<p>
*
* Cookies must be set directly as a header, otherwise they might not be set
* in the super class.<p>
*
* @see javax.servlet.http.HttpServletResponseWrapper#addCookie(javax.servlet.http.Cookie)
*/
public void addCookie(Cookie cookie) {
if (cookie == null) {
throw new CmsIllegalArgumentException(Messages.get().container(Messages.ERR_ADD_COOKIE_0));
}
StringBuffer header = new StringBuffer(128);
// name and value
header.append(cookie.getName());
header.append('=');
header.append(cookie.getValue());
// add version 1 / RFC 2109 specific information
if (cookie.getVersion() == 1) {
header.append("; Version=1");
// comment
if (cookie.getComment() != null) {
header.append("; Comment=");
header.append(cookie.getComment());
}
}
// domain
if (cookie.getDomain() != null) {
header.append("; Domain=");
header.append(cookie.getDomain());
}
// max-age / expires
if (cookie.getMaxAge() >= 0) {
if (cookie.getVersion() == 0) {
// old Netscape format
header.append("; Expires=");
long time;
if (cookie.getMaxAge() == 0) {
time = 10000L;
} else {
time = System.currentTimeMillis() + (cookie.getMaxAge() * 1000L);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -