1
+ /*
2
+ * Copyright 2002-2009 the original author or authors.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ package org .springframework .web .servlet .tags ;
18
+
19
+ import java .io .IOException ;
20
+
21
+ import javax .servlet .jsp .JspException ;
22
+ import javax .servlet .jsp .PageContext ;
23
+
24
+ import org .springframework .beans .BeansException ;
25
+ import org .springframework .core .convert .ConversionService ;
26
+ import org .springframework .expression .AccessException ;
27
+ import org .springframework .expression .EvaluationContext ;
28
+ import org .springframework .expression .Expression ;
29
+ import org .springframework .expression .ExpressionParser ;
30
+ import org .springframework .expression .PropertyAccessor ;
31
+ import org .springframework .expression .TypedValue ;
32
+ import org .springframework .expression .spel .standard .SpelExpressionParser ;
33
+ import org .springframework .expression .spel .support .StandardEvaluationContext ;
34
+ import org .springframework .expression .spel .support .StandardTypeConverter ;
35
+ import org .springframework .web .util .ExpressionEvaluationUtils ;
36
+ import org .springframework .web .util .HtmlUtils ;
37
+ import org .springframework .web .util .JavaScriptUtils ;
38
+ import org .springframework .web .util .TagUtils ;
39
+
40
+ /**
41
+ * JSP tag for evaluating expressions with the Spring Expression Language (SpEL).
42
+ * Supports the standard JSP evaluation context consisting of implicit variables and scoped attributes.
43
+ *
44
+ * @author Keith Donald
45
+ * @since 3.0.1
46
+ */
47
+ public class EvalTag extends HtmlEscapingAwareTag {
48
+
49
+ private ExpressionParser expressionParser ;
50
+
51
+ private String expression ;
52
+
53
+ private String var ;
54
+
55
+ private int scope = PageContext .PAGE_SCOPE ;
56
+
57
+ private boolean javaScriptEscape = false ;
58
+
59
+ /**
60
+ * Set the expression to evaluate.
61
+ */
62
+ public void setExpression (String expression ) {
63
+ this .expression = expression ;
64
+ }
65
+
66
+ /**
67
+ * Set the variable name to expose the evaluation result under.
68
+ * Defaults to rendering the result to the current JspWriter
69
+ */
70
+ public void setVar (String var ) {
71
+ this .var = var ;
72
+ }
73
+
74
+ /**
75
+ * Set the scope to export the evaluation result to.
76
+ * This attribute has no meaning unless var is also defined.
77
+ */
78
+ public void setScope (String scope ) {
79
+ this .scope = TagUtils .getScope (scope );
80
+ }
81
+
82
+ /**
83
+ * Set JavaScript escaping for this tag, as boolean value.
84
+ * Default is "false".
85
+ */
86
+ public void setJavaScriptEscape (String javaScriptEscape ) throws JspException {
87
+ this .javaScriptEscape =
88
+ ExpressionEvaluationUtils .evaluateBoolean ("javaScriptEscape" , javaScriptEscape , this .pageContext );
89
+ }
90
+
91
+ @ Override
92
+ public int doStartTagInternal () throws JspException {
93
+ this .expressionParser = new SpelExpressionParser ();
94
+ return EVAL_BODY_INCLUDE ;
95
+ }
96
+
97
+ @ Override
98
+ public int doEndTag () throws JspException {
99
+ Expression expression = this .expressionParser .parseExpression (this .expression );
100
+ EvaluationContext context = createEvaluationContext ();
101
+ if (this .var == null ) {
102
+ // print the url to the writer
103
+ try {
104
+ String result = expression .getValue (context , String .class );
105
+ result = isHtmlEscape () ? HtmlUtils .htmlEscape (result ) : result ;
106
+ result = this .javaScriptEscape ? JavaScriptUtils .javaScriptEscape (result ) : result ;
107
+ pageContext .getOut ().print (result );
108
+ }
109
+ catch (IOException e ) {
110
+ throw new JspException (e );
111
+ }
112
+ }
113
+ else {
114
+ // store the url as a variable
115
+ pageContext .setAttribute (var , expression .getValue (context ), scope );
116
+ }
117
+ return EVAL_PAGE ;
118
+ }
119
+
120
+ private EvaluationContext createEvaluationContext () {
121
+ StandardEvaluationContext context = new StandardEvaluationContext ();
122
+ context .addPropertyAccessor (new JspPropertyAccessor (this .pageContext ));
123
+ ConversionService conversionService = getConversionService ();
124
+ if (conversionService != null ) {
125
+ context .setTypeConverter (new StandardTypeConverter ());
126
+ }
127
+ return context ;
128
+ }
129
+
130
+ private ConversionService getConversionService () {
131
+ try {
132
+ // TODO replace this with a call to RequestContext that is not brittle
133
+ return getRequestContext ().getWebApplicationContext ().getBean ("conversionService" , ConversionService .class );
134
+ } catch (BeansException e ) {
135
+ return null ;
136
+ }
137
+ }
138
+
139
+ private static class JspPropertyAccessor implements PropertyAccessor {
140
+
141
+ private PageContext pageContext ;
142
+
143
+ public JspPropertyAccessor (PageContext pageContext ) {
144
+ this .pageContext = pageContext ;
145
+ }
146
+
147
+ public Class <?>[] getSpecificTargetClasses () {
148
+ return null ;
149
+ }
150
+
151
+ public boolean canRead (EvaluationContext context , Object target ,
152
+ String name ) throws AccessException {
153
+ if (name .equals ("pageContext" )) {
154
+ return true ;
155
+ }
156
+ // TODO support all other JSP implicit variables defined at http://java.sun.com/javaee/6/docs/api/javax/servlet/jsp/el/ImplicitObjectELResolver.html
157
+ return this .pageContext .findAttribute (name ) != null ;
158
+ }
159
+
160
+ public TypedValue read (EvaluationContext context , Object target ,
161
+ String name ) throws AccessException {
162
+ if (name .equals ("pageContext" )) {
163
+ return new TypedValue (this .pageContext );
164
+ }
165
+ // TODO support all other JSP implicit variables defined at http://java.sun.com/javaee/6/docs/api/javax/servlet/jsp/el/ImplicitObjectELResolver.html
166
+ return new TypedValue (this .pageContext .findAttribute (name ));
167
+ }
168
+
169
+ public boolean canWrite (EvaluationContext context , Object target ,
170
+ String name ) throws AccessException {
171
+ return false ;
172
+ }
173
+
174
+ public void write (EvaluationContext context , Object target ,
175
+ String name , Object newValue ) throws AccessException {
176
+ throw new UnsupportedOperationException ();
177
+ }
178
+
179
+ }
180
+
181
+ }
0 commit comments