Permalink
Browse files

New ResponseBuffer API

  • Loading branch information...
1 parent a743cd4 commit 2425de3f2f4cf86f082cfefde7e31a3d3647cddc @lincolnthree lincolnthree committed Aug 20, 2012
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2012 <a href="mailto:lincolnbaxter@gmail.com">Lincoln Baxter, III</a>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.ocpsoft.rewrite.servlet.config.response;
+
+import java.nio.charset.Charset;
+
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * Holds contents of the fully completed {@link HttpServletResponse}.
+ *
+ * @author <a href="mailto:lincolnbaxter@gmail.com">Lincoln Baxter, III</a>
+ */
+public interface ResponseBuffer
+{
+ /**
+ * Get the contents of this buffer.
+ */
+ public byte[] getContents();
+
+ /**
+ * Set the contents of this buffer.
+ */
+ public void setContents(byte[] contents);
+
+ /**
+ * Get the {@link Charset} with which response output is encoded.
+ */
+ public Charset getCharset();
+
+ /**
+ * Set the {@link Charset} with which response output will be encoded.
+ */
+ public void setCharset(Charset charset);
+}
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2012 <a href="mailto:lincolnbaxter@gmail.com">Lincoln Baxter, III</a>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.ocpsoft.rewrite.servlet.config.response;
+
+import javax.servlet.ServletResponse;
+
+import org.ocpsoft.rewrite.servlet.http.event.HttpServletRewrite;
+
+/**
+ * An intercepter that operates on the fully buffered {@link ServletResponse#getOutputStream()} before flushing to the
+ * client, once the control of the application has been returned to Rewrite.
+ *
+ * @author <a href="mailto:lincolnbaxter@gmail.com">Lincoln Baxter, III</a>
+ */
+public interface ResponseInterceptor
+{
+ /**
+ * Perform modifications on the fully buffered {@link ServletResponse#getOutputStream()} contents.
+ */
+ void intercept(HttpServletRewrite event, ResponseBuffer buffer, ResponseInterceptorChain chain);
+}
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2012 <a href="mailto:lincolnbaxter@gmail.com">Lincoln Baxter, III</a>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.ocpsoft.rewrite.servlet.config.response;
+
+import org.ocpsoft.rewrite.servlet.http.event.HttpServletRewrite;
+
+/**
+ * Chain responsible for controlling interception of {@link ResponseInterceptor} instances.
+ *
+ * @author <a href="mailto:lincolnbaxter@gmail.com">Lincoln Baxter, III</a>
+ */
+public interface ResponseInterceptorChain
+{
+ /**
+ * Invoke the next {@link ResponseInterceptor} in the chain. When no more registered {@link ResponseInterceptor}
+ * instances exist, this method simply returns control back to the calling {@link ResponseInterceptor}.
+ */
+ void next(HttpServletRewrite event, ResponseBuffer buffer, ResponseInterceptorChain chain);
+}
@@ -1,20 +0,0 @@
-package org.ocpsoft.rewrite.servlet.config;
-
-import java.io.InputStream;
-
-import javax.servlet.ServletResponse;
-
-/**
- * A piece of work to be done on the fully buffered {@link ServletResponse#getOutputStream()} before flushing to the
- * client, once the control of the application has been returned to Rewrite.
- *
- * @author <a href="mailto:lincolnbaxter@gmail.com">Lincoln Baxter, III</a>
- *
- */
-public interface OutputBuffer
-{
- /**
- * Perform any manipulation of the fully buffered {@link ServletResponse#getOutputStream()} contents.
- */
- InputStream execute(InputStream input);
-}
@@ -21,6 +21,7 @@
import javax.servlet.http.HttpServletResponse;
import org.ocpsoft.rewrite.context.EvaluationContext;
+import org.ocpsoft.rewrite.servlet.config.response.ResponseInterceptor;
import org.ocpsoft.rewrite.servlet.http.event.HttpServletRewrite;
import org.ocpsoft.rewrite.servlet.impl.HttpRewriteWrappedResponse;
@@ -32,21 +33,21 @@
public abstract class Response extends HttpOperation
{
/**
- * Add the given {@link OutputBuffer} instances to the current {@link ServletResponse}. This will activate response
+ * Add the given {@link ResponseInterceptor} instances to the current {@link ServletResponse}. This will activate response
* buffering on the current {@link ServletRequest} - meaning that generated output will not be sent to the client
- * until the entire request has completed and all registered {@link OutputBuffer} instances have been executed.
+ * until the entire request has completed and all registered {@link ResponseInterceptor} instances have been executed.
*
* @param bufferedResponseToLowercase2
*
* @throws IllegalStateException When output has already been written to the client.
*/
- public static Response withOutputBufferedBy(final OutputBuffer... buffers) throws IllegalStateException
+ public static Response withOutputInterceptedBy(final ResponseInterceptor... buffers) throws IllegalStateException
{
return new Response() {
@Override
public void performHttp(HttpServletRewrite event, EvaluationContext context)
{
- for (OutputBuffer buffer : buffers) {
+ for (ResponseInterceptor buffer : buffers) {
HttpRewriteWrappedResponse.getInstance(event.getRequest()).addBufferStage(buffer);
}
}
@@ -81,7 +81,7 @@ protected Join(final String pattern)
}
/**
- * The outward facing URL path to which this {@link Join} will apply.
+ * The client-facing URL path to which this {@link Join} will apply.
*/
public static IJoin path(final String pattern)
{
@@ -0,0 +1,48 @@
+package org.ocpsoft.rewrite.servlet.impl;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.ocpsoft.rewrite.servlet.event.BaseRewrite;
+import org.ocpsoft.rewrite.servlet.http.event.HttpServletRewrite;
+
+public class HttpBufferRewriteImpl extends BaseRewrite<HttpServletRequest, HttpServletResponse> implements HttpServletRewrite
+{
+ private HttpInboundRewriteImpl delegate;
+
+ public HttpBufferRewriteImpl(HttpServletRequest request, HttpServletResponse response)
+ {
+ super(request, response);
+ this.delegate = new HttpInboundRewriteImpl(request, response);
+ }
+
+ @Override
+ public String getContextPath()
+ {
+ return delegate.getContextPath();
+ }
+
+ @Override
+ public String getRequestPath()
+ {
+ return delegate.getRequestPath();
+ }
+
+ @Override
+ public String getRequestQueryString()
+ {
+ return delegate.getRequestQueryString();
+ }
+
+ @Override
+ public String getRequestQueryStringSeparator()
+ {
+ return delegate.getRequestQueryStringSeparator();
+ }
+
+ @Override
+ public String getURL()
+ {
+ return delegate.getURL();
+ }
+}
@@ -1,5 +1,5 @@
/*
- * Copyright 2011 <a href="mailto:lincolnbaxter@gmail.com">Lincoln Baxter, III</a>
+ * Copyright 2012 <a href="mailto:lincolnbaxter@gmail.com">Lincoln Baxter, III</a>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,13 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.ocpsoft.rewrite.servlet.impl;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
-import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
@@ -41,7 +39,8 @@
import org.ocpsoft.rewrite.event.Rewrite;
import org.ocpsoft.rewrite.exception.RewriteException;
import org.ocpsoft.rewrite.servlet.RewriteLifecycleContext;
-import org.ocpsoft.rewrite.servlet.config.OutputBuffer;
+import org.ocpsoft.rewrite.servlet.config.response.ResponseBuffer;
+import org.ocpsoft.rewrite.servlet.config.response.ResponseInterceptor;
import org.ocpsoft.rewrite.servlet.event.BaseRewrite.Flow;
import org.ocpsoft.rewrite.servlet.http.event.HttpOutboundServletRewrite;
import org.ocpsoft.rewrite.servlet.spi.RewriteLifecycleListener;
@@ -73,25 +72,25 @@ public HttpRewriteWrappedResponse(final HttpServletRequest request, final HttpSe
/*
* Buffering Facilities
*/
- private ByteArrayOutputStream stream = new ByteArrayOutputStream();
- private PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(stream,
+ private ByteArrayOutputStream responseOutputBuffer = new ByteArrayOutputStream();
+ private PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(responseOutputBuffer,
Charset.forName(getCharacterEncoding())), true);
- private List<OutputBuffer> bufferedStages = new ArrayList<OutputBuffer>();
+ private List<ResponseInterceptor> responseInterceptors = new ArrayList<ResponseInterceptor>();
private boolean buffersLocked = false;
public boolean isBufferingActive()
{
- return !bufferedStages.isEmpty();
+ return !responseInterceptors.isEmpty();
}
- public void addBufferStage(OutputBuffer stage) throws IllegalStateException
+ public void addBufferStage(ResponseInterceptor stage) throws IllegalStateException
{
if (areBuffersLocked())
{
throw new IllegalStateException(
"Cannot add output buffers to Response once request processing has been passed to the application.");
}
- this.bufferedStages.add(stage);
+ this.responseInterceptors.add(stage);
}
private boolean areBuffersLocked()
@@ -109,16 +108,18 @@ public void flushBufferedStreams()
if (isBufferingActive())
{
try {
- InputStream result = new ByteArrayInputStream(stream.toByteArray());
- for (OutputBuffer stage : bufferedStages) {
- result = stage.execute(result);
- }
- Streams.copy(result, super.getOutputStream());
+ ResponseBuffer buffer = new ResponseBufferImpl(responseOutputBuffer.toByteArray(), Charset.forName(getCharacterEncoding()));
+ new ResponseInterceptorChainImpl(responseInterceptors).begin(new HttpBufferRewriteImpl(request, this), buffer);
+
+ if (!Charset.forName(getCharacterEncoding()).equals(buffer.getCharset()))
+ setCharacterEncoding(buffer.getCharset().name());
+
+ Streams.copy(new ByteArrayInputStream(buffer.getContents()), super.getOutputStream());
if (printWriter != null) {
printWriter.close();
}
- if (stream != null) {
- stream.close();
+ if (responseOutputBuffer != null) {
+ responseOutputBuffer.close();
}
}
catch (IOException e) {
@@ -134,7 +135,7 @@ public String toString()
if (isBufferingActive())
{
try {
- return stream.toString(getCharacterEncoding());
+ return responseOutputBuffer.toString(getCharacterEncoding());
}
catch (UnsupportedEncodingException e) {
throw new RewriteException("Response accepted invalid character encoding " + getCharacterEncoding(), e);
@@ -163,7 +164,7 @@ public PrintWriter getWriter()
public ServletOutputStream getOutputStream()
{
if (isBufferingActive())
- return new ByteArrayServletOutputStream(stream);
+ return new ByteArrayServletOutputStream(responseOutputBuffer);
else
try {
lockBuffers();
@@ -189,7 +190,7 @@ public void setContentLength(int contentLength)
public void flushBuffer() throws IOException
{
if (isBufferingActive())
- stream.flush();
+ responseOutputBuffer.flush();
else
{
lockBuffers();
@@ -450,14 +451,14 @@ public boolean isCommitted()
@Override
public void reset()
{
- stream.reset();
+ responseOutputBuffer.reset();
super.reset();
}
@Override
public void resetBuffer()
{
- stream.reset();
+ responseOutputBuffer.reset();
super.resetBuffer();
}
Oops, something went wrong.

0 comments on commit 2425de3

Please sign in to comment.