From c04d2db80f7db575ce12dfefccfcc2007fef1f80 Mon Sep 17 00:00:00 2001 From: hns Date: Tue, 27 Mar 2007 12:53:28 +0000 Subject: [PATCH] * Implement res.pushBuffer(StringBuffer) and res.popBuffer() to get StringBuffers in and out of the res buffer stack. This is needed for efficiently implementing the method described in http://dev.helma.org/wiki/Handler+for+rendered+skins/ --- src/helma/framework/ResponseBean.java | 27 +++++++++++++++---- src/helma/framework/ResponseTrans.java | 36 ++++++++++++++++---------- src/helma/framework/core/Skin.java | 17 ++++++------ 3 files changed, 54 insertions(+), 26 deletions(-) diff --git a/src/helma/framework/ResponseBean.java b/src/helma/framework/ResponseBean.java index 6c11fd17..c90781ef 100644 --- a/src/helma/framework/ResponseBean.java +++ b/src/helma/framework/ResponseBean.java @@ -471,7 +471,7 @@ public class ResponseBean implements Serializable { * writes will be redirected to this buffer. */ public void push() { - res.pushStringBuffer(); + res.pushBuffer(null); } /** @@ -481,23 +481,40 @@ public class ResponseBean implements Serializable { * @return ... */ public String pop() { - return res.popStringBuffer(); + return res.popString(); } /** * Old version for push() kept for compatibility + * @deprecated */ public void pushStringBuffer() { - res.pushStringBuffer(); + res.pushBuffer(null); } /** * Old version for pop() kept for compatibility - * + * @deprecated * @return ... */ public String popStringBuffer() { - return res.popStringBuffer(); + return res.popString(); + } + + /** + * Push a string buffer on the response object. All further + * writes will be redirected to this buffer. + * @param buffer the string buffer + */ + public void pushBuffer(StringBuffer buffer) { + res.pushBuffer(buffer); + } + + /** + * Pops the current response buffer without converting it to a string + */ + public StringBuffer popBuffer() { + return res.popBuffer(); } /** diff --git a/src/helma/framework/ResponseTrans.java b/src/helma/framework/ResponseTrans.java index cd386d37..64c0bc00 100644 --- a/src/helma/framework/ResponseTrans.java +++ b/src/helma/framework/ResponseTrans.java @@ -199,10 +199,13 @@ public final class ResponseTrans extends Writer implements Serializable { } /** - * This is called before a skin is rendered as string (renderSkinAsString) to redirect the output - * to a new string buffer. + * This is called before a skin is rendered as string + * (renderSkinAsString) to redirect the output to a new + * string buffer. + * @param buf the StringBuffer to use, or null + * @return the new StringBuffer instance */ - public synchronized void pushStringBuffer() { + public synchronized StringBuffer pushBuffer(StringBuffer buf) { if (buffers == null) { buffers = new Stack(); } @@ -211,33 +214,40 @@ public final class ResponseTrans extends Writer implements Serializable { buffers.push(buffer); } - if (cachedBuffer != null) { + if (buf != null) { + buffer = buf; + } else if (cachedBuffer != null) { buffer = cachedBuffer; cachedBuffer = null; } else { buffer = new StringBuffer(64); } + return buffer; } /** * Returns the content of the current string buffer and switches back to the previos one. */ - public synchronized String popStringBuffer() { + public synchronized String popString() { + StringBuffer buf = popBuffer(); + String str = buf.toString(); + // store stringbuffer for later reuse + buf.setLength(0); + cachedBuffer = buf; + return str; + } + + public synchronized StringBuffer popBuffer() { if (buffer == null) { throw new RuntimeException("Can't pop string buffer: buffer is null"); } else if (buffers == null) { throw new RuntimeException("Can't pop string buffer: buffer stack is empty"); } - - String str = buffer.toString(); - - buffer.setLength(0); - cachedBuffer = buffer; - + // get local reference + StringBuffer buf = buffer; // restore the previous buffer, which may be null buffer = buffers.empty() ? null : (StringBuffer) buffers.pop(); - - return str; + return buf; } /** diff --git a/src/helma/framework/core/Skin.java b/src/helma/framework/core/Skin.java index 3745c8cf..1af27756 100644 --- a/src/helma/framework/core/Skin.java +++ b/src/helma/framework/core/Skin.java @@ -226,11 +226,11 @@ public final class Skin { throws RedirectException, UnsupportedEncodingException { String result = ""; ResponseTrans res = reval.getResponse(); - res.pushStringBuffer(); + res.pushBuffer(null); try { render(reval, thisObject, paramObject); } finally { - result = res.popStringBuffer(); + result = res.popString(); } return result; } @@ -657,14 +657,12 @@ public final class Skin { } else { if (handler == HANDLER_RESPONSE) { // some special handling for response handler - if ("message".equals(propName)) { + if ("message".equals(propName)) value = reval.getResponse().getMessage(); - } else if ("error".equals(propName)) { + else if ("error".equals(propName)) value = reval.getResponse().getError(); - } - if (value != null) { + if (value != null) return filter(reval, value, thisObject, handlerCache); - } } // display error message unless silent failmode is on if ((handlerObject == null || !engine.hasProperty(handlerObject, propName)) @@ -1018,8 +1016,11 @@ public final class Skin { } } +/** + * Exception type for unhandled macros + */ class MacroUnhandledException extends Exception { MacroUnhandledException(String name) { super(name); } -} \ No newline at end of file +}