001: /*
002: * Copyright 2002-2005 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.springframework.web.servlet.tags;
018:
019: import java.io.IOException;
020:
021: import javax.servlet.jsp.JspException;
022: import javax.servlet.jsp.tagext.BodyContent;
023: import javax.servlet.jsp.tagext.BodyTag;
024:
025: import org.springframework.web.util.ExpressionEvaluationUtils;
026: import org.springframework.web.util.HtmlUtils;
027: import org.springframework.web.util.JavaScriptUtils;
028:
029: /**
030: * Custom JSP tag to escape its enclosed body content,
031: * applying HTML escaping and/or JavaScript escaping.
032: *
033: * <p>Provides a "htmlEscape" property for explicitly specifying whether to
034: * apply HTML escaping. If not set, a page-level default (e.g. from the
035: * HtmlEscapeTag) or an application-wide default (the "defaultHtmlEscape"
036: * context-param in web.xml) is used.
037: *
038: * <p>Provides a "javaScriptEscape" property for specifying whether to apply
039: * JavaScript escaping. Can be combined with HTML escaping or used standalone.
040: *
041: * @author Juergen Hoeller
042: * @since 1.1.1
043: * @see org.springframework.web.util.HtmlUtils
044: * @see org.springframework.web.util.JavaScriptUtils
045: */
046: public class EscapeBodyTag extends HtmlEscapingAwareTag implements
047: BodyTag {
048:
049: private boolean javaScriptEscape = false;
050:
051: private BodyContent bodyContent;
052:
053: /**
054: * Set JavaScript escaping for this tag, as boolean value.
055: * Default is "false".
056: */
057: public void setJavaScriptEscape(String javaScriptEscape)
058: throws JspException {
059: this .javaScriptEscape = ExpressionEvaluationUtils
060: .evaluateBoolean("javaScriptEscape", javaScriptEscape,
061: pageContext);
062: }
063:
064: protected int doStartTagInternal() {
065: // do nothing
066: return EVAL_BODY_BUFFERED;
067: }
068:
069: public void doInitBody() {
070: // do nothing
071: }
072:
073: public void setBodyContent(BodyContent bodyContent) {
074: this .bodyContent = bodyContent;
075: }
076:
077: public int doAfterBody() throws JspException {
078: try {
079: String content = readBodyContent();
080: // HTML and/or JavaScript escape, if demanded
081: content = isHtmlEscape() ? HtmlUtils.htmlEscape(content)
082: : content;
083: content = this .javaScriptEscape ? JavaScriptUtils
084: .javaScriptEscape(content) : content;
085: writeBodyContent(content);
086: } catch (IOException ex) {
087: throw new JspException("Could not write escaped body", ex);
088: }
089: return (SKIP_BODY);
090: }
091:
092: /**
093: * Read the unescaped body content from the page.
094: * @return the original content
095: * @throws IOException if reading failed
096: */
097: protected String readBodyContent() throws IOException {
098: return this .bodyContent.getString();
099: }
100:
101: /**
102: * Write the escaped body content to the page.
103: * <p>Can be overridden in subclasses, e.g. for testing purposes.
104: * @param content the content to write
105: * @throws IOException if writing failed
106: */
107: protected void writeBodyContent(String content) throws IOException {
108: this.bodyContent.getEnclosingWriter().print(content);
109: }
110:
111: }
|