Author: cziegeler Date: Wed Feb 3 14:24:09 2010 New Revision: 906062 URL: http://svn.apache.org/viewvc?rev=906062&view=rev Log: Wrap output stream and print writer to catch close() calls
Modified: sling/whiteboard/portal/container/src/main/java/org/apache/sling/portal/container/internal/PortletMimeResponseContextImpl.java Modified: sling/whiteboard/portal/container/src/main/java/org/apache/sling/portal/container/internal/PortletMimeResponseContextImpl.java URL: http://svn.apache.org/viewvc/sling/whiteboard/portal/container/src/main/java/org/apache/sling/portal/container/internal/PortletMimeResponseContextImpl.java?rev=906062&r1=906061&r2=906062&view=diff ============================================================================== --- sling/whiteboard/portal/container/src/main/java/org/apache/sling/portal/container/internal/PortletMimeResponseContextImpl.java (original) +++ sling/whiteboard/portal/container/src/main/java/org/apache/sling/portal/container/internal/PortletMimeResponseContextImpl.java Wed Feb 3 14:24:09 2010 @@ -31,6 +31,8 @@ import org.apache.pluto.container.PortletURLProvider.TYPE; import org.apache.pluto.container.util.PrintWriterServletOutputStream; import org.apache.sling.portal.container.SlingPortletContainer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * @version $Id$ @@ -40,54 +42,45 @@ extends PortletResponseContextImpl implements PortletMimeResponseContext { - private static class CacheControlImpl implements CacheControl - { + /** The logger. */ + private final static Logger LOGGER = LoggerFactory.getLogger(PortletMimeResponseContextImpl.class); + + private static class CacheControlImpl implements CacheControl { + private String eTag; private int expirationTime; private boolean publicScope; private boolean cachedContent; - public CacheControlImpl() - { - } - - public boolean useCachedContent() - { + public boolean useCachedContent() { return cachedContent; } - public String getETag() - { + public String getETag() { return this.eTag; } - public int getExpirationTime() - { + public int getExpirationTime() { return expirationTime; } - public boolean isPublicScope() - { + public boolean isPublicScope() { return publicScope; } - public void setETag(String eTag) - { + public void setETag(String eTag) { this.eTag = eTag; } - public void setExpirationTime(int expirationTime) - { + public void setExpirationTime(int expirationTime) { this.expirationTime = expirationTime; } - public void setPublicScope(boolean publicScope) - { + public void setPublicScope(boolean publicScope) { this.publicScope = publicScope; } - public void setUseCachedContent(boolean cachedContent) - { + public void setUseCachedContent(boolean cachedContent) { this.cachedContent = cachedContent; } } @@ -96,123 +89,152 @@ private OutputStream outputStream; public PortletMimeResponseContextImpl(SlingPortletContainer container, HttpServletRequest containerRequest, - HttpServletResponse containerResponse, PortletWindow window) - { + HttpServletResponse containerResponse, PortletWindow window) { super(container, containerRequest, containerResponse, window); } - public void close() - { + public void close() { cacheControl = null; outputStream = null; super.close(); } - public void flushBuffer() throws IOException - { - if (!isClosed()) - { + public void flushBuffer() throws IOException { + if (!isClosed()) { getServletResponse().flushBuffer(); } } - public int getBufferSize() - { + public int getBufferSize() { return getServletResponse().getBufferSize(); } - public CacheControl getCacheControl() - { - if (isClosed()) - { + public CacheControl getCacheControl() { + if (isClosed()) { return null; } - if (cacheControl == null) - { + if (cacheControl == null) { cacheControl = new CacheControlImpl(); } return cacheControl; } - public String getCharacterEncoding() - { + public String getCharacterEncoding() { return isClosed() ? null : getServletResponse().getCharacterEncoding(); } - public String getContentType() - { + public String getContentType() { return isClosed() ? null : getServletResponse().getContentType(); } - public Locale getLocale() - { + public Locale getLocale() { return isClosed() ? null : getServletResponse().getLocale(); } - public OutputStream getOutputStream() throws IOException, IllegalStateException - { - if (isClosed()) - { + public OutputStream getOutputStream() throws IOException, IllegalStateException { + if (isClosed()) { return null; } - if (outputStream == null) - { - try - { + if (outputStream == null) { + try { outputStream = getServletResponse().getOutputStream(); - } - catch (IllegalStateException e) - { + } catch (IllegalStateException e) { // handle situation where underlying ServletResponse its getWriter() // has been called already anyway: return a wrapped PrintWriter in that case outputStream = new PrintWriterServletOutputStream(getServletResponse().getWriter(), getServletResponse().getCharacterEncoding()); } } - return outputStream; + return new SecureOutputStream(outputStream); } - public PrintWriter getWriter() throws IOException, IllegalStateException - { - return isClosed() ? null : getServletResponse().getWriter(); + public PrintWriter getWriter() throws IOException, IllegalStateException { + return isClosed() ? null : new SecurePrinterWriter(getServletResponse().getWriter()); } - public boolean isCommitted() - { + public boolean isCommitted() { return getServletResponse().isCommitted(); } - public void reset() - { + public void reset() { getServletResponse().reset(); } - public void resetBuffer() - { - if (!isClosed()) - { + public void resetBuffer() { + if (!isClosed()) { getServletResponse().resetBuffer(); } } - public void setBufferSize(int size) - { - if (!isClosed()) - { + public void setBufferSize(int size) { + if (!isClosed()) { getServletResponse().setBufferSize(size); } } - public void setContentType(String contentType) - { - if (!isClosed()) - { + public void setContentType(String contentType) { + if (!isClosed()) { getServletResponse().setContentType(contentType); } } - public PortletURLProvider getPortletURLProvider(TYPE type) - { + public PortletURLProvider getPortletURLProvider(TYPE type) { return isClosed() ? null : new PortletURLProviderImpl(getPortalURL(), type, getPortletWindow()); } + + + public final static class SecurePrinterWriter extends PrintWriter { + + public SecurePrinterWriter(final PrintWriter delegatee) { + super(delegatee); + } + + @Override + public void close() { + this.flush(); + // log a warning + final Exception e = new IllegalStateException(); + LOGGER.warn("Portlet should not call PrintWriter.close()!", e); + } + } + + public final static class SecureOutputStream extends OutputStream { + + private final OutputStream delegatee; + + public SecureOutputStream(final OutputStream delegatee) { + this.delegatee = delegatee; + } + + @Override + public void flush() throws IOException { + this.delegatee.flush(); + } + + @Override + public void write(byte[] b, int off, int len) throws IOException { + // TODO Auto-generated method stub + this.delegatee.write(b, off, len); + } + + @Override + public void write(byte[] b) throws IOException { + // TODO Auto-generated method stub + this.delegatee.write(b); + } + + @Override + public void write(int b) throws IOException { + this.delegatee.write(b); + } + + @Override + public void close() throws IOException { + this.delegatee.flush(); + // log a warning + final Exception e = new IllegalStateException(); + LOGGER.warn("Portlet should not call OutputStream.close()!", e); + } + + } }