You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by dk...@apache.org on 2013/06/24 17:25:02 UTC
svn commit: r1496093 - in /sling/trunk/bundles/scripting/jsp-taglib/src/main:
java/org/apache/sling/scripting/jsp/taglib/IncludeTagHandler.java
resources/META-INF/sling.tld
Author: dklco
Date: Mon Jun 24 15:25:02 2013
New Revision: 1496093
URL: http://svn.apache.org/r1496093
Log:
Fixing SLING-2834: adding support for var and scope variables for including the results of a response into a JSP variable
Modified:
sling/trunk/bundles/scripting/jsp-taglib/src/main/java/org/apache/sling/scripting/jsp/taglib/IncludeTagHandler.java
sling/trunk/bundles/scripting/jsp-taglib/src/main/resources/META-INF/sling.tld
Modified: sling/trunk/bundles/scripting/jsp-taglib/src/main/java/org/apache/sling/scripting/jsp/taglib/IncludeTagHandler.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/scripting/jsp-taglib/src/main/java/org/apache/sling/scripting/jsp/taglib/IncludeTagHandler.java?rev=1496093&r1=1496092&r2=1496093&view=diff
==============================================================================
--- sling/trunk/bundles/scripting/jsp-taglib/src/main/java/org/apache/sling/scripting/jsp/taglib/IncludeTagHandler.java (original)
+++ sling/trunk/bundles/scripting/jsp-taglib/src/main/java/org/apache/sling/scripting/jsp/taglib/IncludeTagHandler.java Mon Jun 24 15:25:02 2013
@@ -16,15 +16,23 @@
*/
package org.apache.sling.scripting.jsp.taglib;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpServletResponseWrapper;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.BodyContent;
+import org.apache.tika.io.IOUtils;
+
/**
* The <code>IncludeTagHandler</code> implements the
* <code><sling:include></code> custom tag.
@@ -35,6 +43,8 @@ public class IncludeTagHandler extends A
/** flush argument */
private boolean flush = false;
+ private String var = null;
+ private Integer scope = PageContext.PAGE_SCOPE;
protected void dispatch(RequestDispatcher dispatcher,
ServletRequest request, ServletResponse response)
@@ -45,8 +55,22 @@ public class IncludeTagHandler extends A
// might throw an IOException of course
pageContext.getOut().flush();
}
-
- dispatcher.include(request, response);
+ if (var == null) {
+ dispatcher.include(request, response);
+ } else {
+ String encoding = response.getCharacterEncoding();
+ BufferedServletOutputStream bsops = new BufferedServletOutputStream(encoding);
+ try{
+ CaptureResponseWrapper wrapper = new CaptureResponseWrapper((HttpServletResponse) response, bsops);
+ dispatcher.include(request, wrapper);
+ if (! wrapper.isBinaryResponse()) {
+ wrapper.flushBuffer();
+ pageContext.setAttribute(var, bsops.getBuffer(), scope);
+ }
+ }finally{
+ IOUtils.closeQuietly(bsops);
+ }
+ }
}
public void setPageContext(PageContext pageContext) {
@@ -54,10 +78,174 @@ public class IncludeTagHandler extends A
// init local fields, since tag might be reused
flush = false;
+ this.var = null;
+ this.scope = PageContext.PAGE_SCOPE;
}
public void setFlush(boolean flush) {
this.flush = flush;
}
-
+
+ public void setVar(String var) {
+ if (var != null && var.trim().length() > 0) {
+ this.var = var;
+ }
+ }
+
+ // for tag attribute
+ public void setScope(String scope) {
+ this.scope = validScope(scope);
+ }
+
+ /**
+ * Gets the int code for a valid scope, must be one of 'page', 'request',
+ * 'session' or 'application'. If an invalid or no scope is specified page
+ * scope is returned.
+ *
+ * @param scope
+ * @return
+ */
+ private Integer validScope(String scope) {
+ scope = (scope != null && scope.trim().length() > 0 ? scope.trim()
+ .toUpperCase() : null);
+ if (scope == null) {
+ return PageContext.PAGE_SCOPE;
+ }
+
+ String[] scopes = { "PAGE", "REQUEST", "SESSION", "APPLICATION" };
+ Integer[] iaScopes = { PageContext.PAGE_SCOPE,
+ PageContext.REQUEST_SCOPE, PageContext.SESSION_SCOPE,
+ PageContext.APPLICATION_SCOPE };
+
+ for (int ndx = 0, len = scopes.length; ndx < len; ndx++) {
+ if (scopes[ndx].equals(scope)) {
+ return iaScopes[ndx];
+ }
+ }
+ return PageContext.PAGE_SCOPE;
+ }
+
+ /**
+ * Extends the HttpServletResponse to wrap the response and capture the results.
+ */
+ private static final class CaptureResponseWrapper extends HttpServletResponseWrapper {
+ private final String encoding;
+ private final ServletOutputStream ops;
+ private boolean isBinaryResponse = false;
+ private PrintWriter writer = null;
+
+ /**
+ * Construct a new CaptureResponseWrapper.
+ *
+ * @param response
+ * the response to wrap
+ * @param ops
+ * the output stream to write to
+ */
+ CaptureResponseWrapper(HttpServletResponse response,
+ ServletOutputStream ops) {
+ super(response);
+ this.encoding = response.getCharacterEncoding();
+ this.ops = ops;
+ }
+
+ /**
+ * Returns true if the response is binary.
+ *
+ * @return
+ */
+ public boolean isBinaryResponse() {
+ return isBinaryResponse;
+ }
+
+
+ /*
+ * (non-Javadoc)
+ * @see javax.servlet.ServletResponseWrapper#flushBuffer()
+ */
+ @Override
+ public void flushBuffer() throws IOException {
+ if (isBinaryResponse()) {
+ getResponse().getOutputStream().flush();
+ } else {
+ writer.flush();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see javax.servlet.ServletResponseWrapper#getOutputStream()
+ */
+ @Override
+ public ServletOutputStream getOutputStream() throws IOException {
+ if (writer != null) {
+ throw new IOException("'getWriter()' has already been invoked for a character data response.");
+ }
+ isBinaryResponse = true;
+ return getResponse().getOutputStream();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see javax.servlet.ServletResponseWrapper#getWriter()
+ */
+ @Override
+ public PrintWriter getWriter() throws IOException {
+ if (writer != null) {
+ return writer;
+ }
+ if (isBinaryResponse) {
+ throw new IOException("'getOutputStream()' has already been invoked for a binary data response.");
+ }
+ writer = new PrintWriter(new OutputStreamWriter(ops, encoding));
+ return writer;
+ }
+
+ }
+
+ /**
+ * Extends the ServletOutputStream to capture the results into a byte array.
+ */
+ private static final class BufferedServletOutputStream extends ServletOutputStream {
+ private final ByteArrayOutputStream baops = new ByteArrayOutputStream();
+ private final String encoding;
+
+ /**
+ * Constructs a new BufferedServletOutputStream.
+ *
+ * @param encoding the encoding string
+ */
+ public BufferedServletOutputStream(String encoding) {
+ this.encoding = encoding;
+ }
+
+ /**
+ * Gets the byte buffer as a string.
+ *
+ * @return the byte buffer
+ * @throws IOException
+ */
+ public String getBuffer() throws IOException {
+ return baops.toString(encoding);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see java.io.OutputStream#close()
+ */
+ @Override
+ public void close() throws IOException {
+ baops.reset();
+ super.close();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see java.io.OutputStream#write(int)
+ */
+ @Override
+ public void write(int b) throws IOException {
+ baops.write(b);
+ }
+ }
}
Modified: sling/trunk/bundles/scripting/jsp-taglib/src/main/resources/META-INF/sling.tld
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/scripting/jsp-taglib/src/main/resources/META-INF/sling.tld?rev=1496093&r1=1496092&r2=1496093&view=diff
==============================================================================
--- sling/trunk/bundles/scripting/jsp-taglib/src/main/resources/META-INF/sling.tld (original)
+++ sling/trunk/bundles/scripting/jsp-taglib/src/main/resources/META-INF/sling.tld Mon Jun 24 15:25:02 2013
@@ -176,6 +176,24 @@
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
+ <attribute>
+ <description>
+ If var is specified, what scope to store the variable in
+ </description>
+ <name>scope</name>
+ <required>false</required>
+ <rtexprvalue>false</rtexprvalue>
+ <type>String</type>
+ </attribute>
+ <attribute>
+ <description>
+ Variable name to store the resulting markup into
+ </description>
+ <name>var</name>
+ <required>false</required>
+ <rtexprvalue>false</rtexprvalue>
+ <type>String</type>
+ </attribute>
</tag>
<tag>