ContextResponseWrapper.java
package sk.iway.iwcm.system.context;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Locale;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import sk.iway.iwcm.Constants;
import sk.iway.iwcm.Logger;
import sk.iway.iwcm.SetCharacterEncodingFilter;
import sk.iway.iwcm.Tools;
/**
* ContextResponseWrapper.java - wrapper pre moznost fungovania WebJETu v inom ako ROOT contexte (napr. /wj7)
* Povodne riesene pre TatraBanku projekt RaiffeisenBank
*
*@Title webjet7
*@Company Interway s.r.o. (www.interway.sk)
*@Copyright Interway s.r.o. (c) 2001-2012
*@author $Author: jeeff jeeff $
*@version $Revision: 1.3 $
*@created Date: 20.7.2012 9:12:24
*@modified $Date: 2004/08/16 06:26:11 $
*/
public class ContextResponseWrapper extends HttpServletResponseWrapper
{
PrintWriter writer;
private StringWriter strWriter;
private String redirectURL = null;
HttpServletResponse origResponse;
HttpServletRequest origRequest;
ContextResponseStream outputStream = null;
boolean debug = false;
List<Cookie> cookies = null;
public void writeResponseToOriginalOutput(HttpServletRequest req, boolean removeContextPath) throws IOException
{
if (debug) Logger.debug(ContextResponseWrapper.class, "writeResponseToOriginalOutput, contentType="+getContentType()+" os="+outputStream);
if (getContentType()!=null && (getContentType().startsWith("text") || outputStream == null || getContentType().indexOf("x-javascript")!=-1 || getContentType().indexOf("application/javascript")!=-1))
{
if (debug) Logger.debug(ContextResponseWrapper.class, "writeResponseToOriginalOutput, budem replacovat");
String htmlCode;
if (outputStream != null)
{
htmlCode = outputStream.getBaos().toString(SetCharacterEncodingFilter.getEncoding());
}
else
{
htmlCode = strWriter.getBuffer().toString();
}
writeResponseToOriginalOutput(req, htmlCode, removeContextPath);
}
else if (outputStream != null && outputStream.getBaos()!=null)
{
if (debug) Logger.debug(ContextResponseWrapper.class, "writeResponseToOriginalOutput, zapisujem priamo");
origResponse.getOutputStream().write(outputStream.getBaos().toByteArray());
}
}
/**
* Zapise HTML kod na povodny vystup s testom na moznost gzip kompresie
* @param req
* @param htmlCode
* @throws IOException
*/
private void writeResponseToOriginalOutput(HttpServletRequest req, String htmlCode, boolean removeContextPath) throws IOException
{
//zapis vystup
String outputCode;
if (removeContextPath == false)
{
outputCode = ContextFilter.addContextPath(req.getContextPath(), htmlCode);
}
else
{
outputCode = ContextFilter.removeContextPath(Constants.getString("contextPathAdmin"), htmlCode);
}
//TODO: toto treba ratat ako poset bytov, co pre UTF-8 nie je length
//byte bytes[] = outputCode.getBytes(SetCharacterEncodingFilter.getEncoding());
//origResponse.reset();
//origResponse.setContentLength(bytes.length);
/*
if (outputCode.length() < 100000)
{
if (debug) Logger.debug(ContextResponseWrapper.class, "setting buffer to size: "+(outputCode.length()+5000));
origResponse.setBufferSize(outputCode.length()+5000);
}
*/
//String output2 = ""+outputCode;
int length = outputCode.getBytes(SetCharacterEncodingFilter.getEncoding()).length;
origResponse.setContentLength(length);
//origResponse.setHeader("Content-Length", String.valueOf(output2.getBytes("utf-8").length));
//origResponse.setHeader("CLutf", String.valueOf(output2.getBytes("utf-8").length));
//origResponse.setHeader("CL2", String.valueOf(outputCode.length()));
//origResponse.setHeader("CL3", String.valueOf(outputCode.getBytes("").length));
//origResponse.setHeader("CL4", String.valueOf(outputCode.getBytes().length));
if (Tools.isNotEmpty(outputCode))
{
if (debug) Logger.debug(ContextResponseWrapper.class, "writing data, size="+outputCode.length());
origResponse.getWriter().write(outputCode);
}
//origResponse.getOutputStream().write(bytes);
}
@Override
public void sendRedirect(String url) throws IOException
{
if (debug) Logger.println(this,"--> send redirect: "+url);
redirectURL = url;
//super.sendRedirect(url);
}
@Override
public void addCookie(Cookie c)
{
if (debug) Logger.debug(this,"add cookie: " + c.getName()+" path="+c.getPath()+" value="+c.getValue());
if (cookies != null) cookies.add(c);
}
// ----------------------------------------------------------- Constructors
/**
* Construct a new response wrapper according to the specified parameters.
*
* @param response The servlet response we are wrapping
*/
public ContextResponseWrapper(HttpServletResponse response,HttpServletRequest request)
{
super(response);
debug = Constants.getBoolean("contextPathDebug");
origResponse = response;
//baos = new ByteArrayOutputStream();
strWriter = new StringWriter();
writer = new PrintWriter(strWriter);
origRequest = request;
cookies = new ArrayList<>();
}
/**
* Swallow any attempt to flush the response buffer.
*/
@Override
public void flushBuffer() throws IOException {
if (debug) Logger.debug(this,"--> FLUSH BUFFER");
}
/**
* Return a PrintWriter that can be used to accumulate the response data
* for the included resource.
*
* @exception IOException if an I/O error occurs
*/
@Override
public PrintWriter getWriter() throws IOException {
return (writer);
}
@Override
public void setBufferSize(int bufferSize)
{
try
{
super.setBufferSize(bufferSize);
}
catch (Exception e)
{
}
}
public String getRedirectURL()
{
return redirectURL;
}
private ContextResponseStream createOutputStream()
{
try
{
return new ContextResponseStream(origResponse);
}
catch (Exception e)
{
sk.iway.iwcm.Logger.error(e);
}
return null;
}
@Override
public ServletOutputStream getOutputStream() throws IOException
{
if (outputStream == null) outputStream = createOutputStream();
return (outputStream);
}
//setStatus implementation
protected int statusCode = 0;
protected String statusMessage = null;
@Override
@SuppressWarnings("deprecation")
public void setStatus(int sc, String sm)
{
super.setStatus(sc, sm);
statusCode = sc;
statusMessage = sm;
}
@Override
public void setStatus(int sc)
{
super.setStatus(sc);
statusCode = sc;
}
public int getStatusCode()
{
return statusCode;
}
public String getStatusMessage()
{
return statusMessage;
}
//setCharacterEncoding implementation
protected String characterEncoding = null;
@Override
public void setCharacterEncoding(String charset)
{
if (debug) Logger.debug(ContextResponseWrapper.class, "setCharacterEncoding:"+charset);
super.setCharacterEncoding(charset);
characterEncoding = charset;
}
@Override
public String getCharacterEncoding()
{
if (debug) Logger.debug(ContextResponseWrapper.class, "getCharacterEncoding: "+characterEncoding+" vs "+super.getCharacterEncoding());
if (characterEncoding == null) return super.getCharacterEncoding();
return characterEncoding;
}
//setContentType implementation
protected String contentType = null;
@Override
public void setContentType(String type)
{
if ("text/html".equalsIgnoreCase(type))
{
type = "text/html; charset="+SetCharacterEncodingFilter.getEncoding();
}
if (debug) Logger.debug(ContextResponseWrapper.class, "setContentType="+type);
super.setContentType(type);
//jeeff:tato kontrola je tu kvoli nejakej haluze, ze sa setContentType vola viac krat a niekedy konci nespravne ako text/css (netusim preco)
if (contentType == null || type.indexOf("; charset=")!=-1 || type.indexOf("application/")!=-1 || type.indexOf("image/")!=-1)
{
if (debug) Logger.debug(ContextResponseWrapper.class, "setting contentType="+type);
contentType = type;
super.setContentType(type);
}
}
@Override
public String getContentType()
{
if ("text/html".equalsIgnoreCase(contentType))
{
contentType = "text/html; charset="+SetCharacterEncodingFilter.getEncoding();
}
if (debug) Logger.debug(ContextResponseWrapper.class, "getContentType="+contentType);
return contentType;
}
//setLocale implementation
Locale locale = null;
@Override
public void setLocale(Locale loc)
{
super.setLocale(loc);
locale = loc;
}
@Override
public Locale getLocale()
{
if (locale == null) return super.getLocale();
return locale;
}
//sendError implementation
protected int errorCode=0;
protected String errorMessage=null;
@Override
public void sendError(int sc, String msg) throws IOException
{
errorCode = sc;
errorMessage = msg;
//super.sendError(sc, msg);
}
@Override
public void sendError(int sc) throws IOException
{
errorCode = sc;
//super.sendError(sc);
}
public int getErrorCode()
{
return errorCode;
}
public String getErrorMessage()
{
return errorMessage;
}
//setHeader implementation
protected java.util.Hashtable<String, String> headers = null;
@Override
public void setHeader(String name, String value)
{
if (debug) Logger.debug(ContextResponseWrapper.class, "setHeader: name="+name+" value="+value);
if (headers == null) headers = new Hashtable<>();
headers.put(name, value);
super.setHeader(name, value);
if ("content-type".equalsIgnoreCase(name))
{
setContentType(value);
}
}
@Override
public String getHeader(String name)
{
if (debug) Logger.debug(ContextResponseWrapper.class, "getHeader: "+name);
if (headers == null) return null;
return headers.get(name);
}
@Override
public void addHeader(String name, String value)
{
if (debug) Logger.debug(ContextResponseWrapper.class, "addHeader: name="+name+" value="+value);
if (headers == null) headers = new Hashtable<>();
headers.put(name, value);
super.addHeader(name, value);
}
@Override
public void addIntHeader(String name, int value)
{
if (debug) Logger.debug(ContextResponseWrapper.class, "addIntHeader: name="+name+" value="+value);
if (headers == null) headers = new Hashtable<>();
headers.put(name, String.valueOf(value));
super.addIntHeader(name, value);
}
@Override
public void setIntHeader(String name, int value)
{
if (debug) Logger.debug(ContextResponseWrapper.class, "setIntHeader: name="+name+" value="+value);
if (headers == null) headers = new Hashtable<>();
headers.put(name, String.valueOf(value));
super.setIntHeader(name, value);
}
public List<Cookie> getCookies()
{
return cookies;
}
}