Skip to content

Commit 6390e89

Browse files
author
Keith Donald
committed
eval tag tidying
1 parent 117b138 commit 6390e89

File tree

6 files changed

+205
-50
lines changed

6 files changed

+205
-50
lines changed

org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
import org.springframework.validation.Validator;
3939
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
4040
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
41+
import org.springframework.web.servlet.handler.ConversionServiceHandlerInterceptor;
42+
import org.springframework.web.servlet.handler.MappedInterceptor;
4143
import org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter;
4244
import org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping;
4345

@@ -94,28 +96,42 @@ public BeanDefinition parse(Element element, ParserContext parserContext) {
9496
annMappingDef.getPropertyValues().add("order", 0);
9597
String annMappingName = parserContext.getReaderContext().registerWithGeneratedName(annMappingDef);
9698

99+
RuntimeBeanReference conversionService = getConversionService(element, source, parserContext);
100+
RuntimeBeanReference validator = getValidator(element, source, parserContext);
101+
97102
RootBeanDefinition bindingDef = new RootBeanDefinition(ConfigurableWebBindingInitializer.class);
98103
bindingDef.setSource(source);
99104
bindingDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
100-
bindingDef.getPropertyValues().add("conversionService", getConversionService(element, source, parserContext));
101-
bindingDef.getPropertyValues().add("validator", getValidator(element, source, parserContext));
105+
bindingDef.getPropertyValues().add("conversionService", conversionService);
106+
bindingDef.getPropertyValues().add("validator", validator);
102107

103108
RootBeanDefinition annAdapterDef = new RootBeanDefinition(AnnotationMethodHandlerAdapter.class);
104109
annAdapterDef.setSource(source);
105110
annAdapterDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
106111
annAdapterDef.getPropertyValues().add("webBindingInitializer", bindingDef);
107112
annAdapterDef.getPropertyValues().add("messageConverters", getMessageConverters(source));
108-
String adapterName = parserContext.getReaderContext().registerWithGeneratedName(annAdapterDef);
113+
String annAdapterName = parserContext.getReaderContext().registerWithGeneratedName(annAdapterDef);
114+
115+
RootBeanDefinition csInterceptorDef = new RootBeanDefinition(ConversionServiceHandlerInterceptor.class);
116+
csInterceptorDef.setSource(source);
117+
csInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, conversionService);
118+
RootBeanDefinition mappedCsInterceptorDef = new RootBeanDefinition(MappedInterceptor.class);
119+
mappedCsInterceptorDef.setSource(source);
120+
mappedCsInterceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
121+
mappedCsInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, (Object) null);
122+
mappedCsInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(1, csInterceptorDef);
123+
String mappedInterceptorName = parserContext.getReaderContext().registerWithGeneratedName(mappedCsInterceptorDef);
109124

110125
parserContext.registerComponent(new BeanComponentDefinition(annMappingDef, annMappingName));
111-
parserContext.registerComponent(new BeanComponentDefinition(annAdapterDef, adapterName));
126+
parserContext.registerComponent(new BeanComponentDefinition(annAdapterDef, annAdapterName));
127+
parserContext.registerComponent(new BeanComponentDefinition(mappedCsInterceptorDef, mappedInterceptorName));
112128
parserContext.popAndRegisterContainingComponent();
113129

114130
return null;
115131
}
116132

117133

118-
private Object getConversionService(Element element, Object source, ParserContext parserContext) {
134+
private RuntimeBeanReference getConversionService(Element element, Object source, ParserContext parserContext) {
119135
if (element.hasAttribute("conversion-service")) {
120136
return new RuntimeBeanReference(element.getAttribute("conversion-service"));
121137
}
@@ -129,7 +145,7 @@ private Object getConversionService(Element element, Object source, ParserContex
129145
}
130146
}
131147

132-
private Object getValidator(Element element, Object source, ParserContext parserContext) {
148+
private RuntimeBeanReference getValidator(Element element, Object source, ParserContext parserContext) {
133149
if (element.hasAttribute("validator")) {
134150
return new RuntimeBeanReference(element.getAttribute("validator"));
135151
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* Copyright 2002-2008 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.handler;
18+
19+
import java.io.IOException;
20+
21+
import javax.servlet.ServletException;
22+
import javax.servlet.http.HttpServletRequest;
23+
import javax.servlet.http.HttpServletResponse;
24+
25+
import org.springframework.core.convert.ConversionService;
26+
import org.springframework.util.Assert;
27+
28+
/**
29+
* Interceptor that places the configured {@link ConversionService} in request scope so it's available during request processing.
30+
* Mainly for use within JSP tags such as the spring:eval tag.
31+
* The request attribute name is "org.springframework.core.convert.ConversionService", the value of ConversionService.class.getName();
32+
* @author Keith Donald
33+
* @since 3.0.1
34+
*/
35+
public class ConversionServiceHandlerInterceptor extends HandlerInterceptorAdapter {
36+
37+
private final ConversionService conversionService;
38+
39+
/**
40+
* Creates a new {@link ConversionServiceHandlerInterceptor}.
41+
* @param conversionService the conversion service to export to request scope when this interceptor is invoked.
42+
*/
43+
public ConversionServiceHandlerInterceptor(ConversionService conversionService) {
44+
Assert.notNull(conversionService, "The ConversionService may not be null");
45+
this.conversionService = conversionService;
46+
}
47+
48+
@Override
49+
public final boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
50+
throws ServletException, IOException {
51+
request.setAttribute(ConversionService.class.getName(), this.conversionService);
52+
return true;
53+
}
54+
55+
}

org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/tags/EvalTag.java

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import javax.servlet.jsp.JspException;
2222
import javax.servlet.jsp.PageContext;
23+
import javax.servlet.jsp.el.ELException;
2324

2425
import org.springframework.beans.BeansException;
2526
import org.springframework.core.convert.ConversionService;
@@ -110,7 +111,8 @@ public int doEndTag() throws JspException {
110111
}
111112
}
112113
else {
113-
pageContext.setAttribute(var, expression.getValue(context), scope);
114+
Object result = expression.getValue(context);
115+
pageContext.setAttribute(var, result, scope);
114116
}
115117
return EVAL_PAGE;
116118
}
@@ -127,7 +129,7 @@ private EvaluationContext createEvaluationContext() {
127129

128130
private ConversionService getConversionService() {
129131
try {
130-
return (ConversionService) this.pageContext.getRequest().getAttribute("org.springframework.core.convert.ConversionService");
132+
return (ConversionService) this.pageContext.getRequest().getAttribute(ConversionService.class.getName());
131133
} catch (BeansException e) {
132134
return null;
133135
}
@@ -147,19 +149,19 @@ public Class<?>[] getSpecificTargetClasses() {
147149

148150
public boolean canRead(EvaluationContext context, Object target,
149151
String name) throws AccessException {
150-
if (name.equals("pageContext")) {
152+
Object implicitVar = resolveImplicitVariable(name);
153+
if (implicitVar != null) {
151154
return true;
152155
}
153-
// TODO support all other JSP implicit variables defined at http://java.sun.com/javaee/6/docs/api/javax/servlet/jsp/el/ImplicitObjectELResolver.html
154156
return this.pageContext.findAttribute(name) != null;
155157
}
156158

157159
public TypedValue read(EvaluationContext context, Object target,
158160
String name) throws AccessException {
159-
if (name.equals("pageContext")) {
160-
return new TypedValue(this.pageContext);
161+
Object implicitVar = resolveImplicitVariable(name);
162+
if (implicitVar != null) {
163+
return new TypedValue(implicitVar);
161164
}
162-
// TODO support all other JSP implicit variables defined at http://java.sun.com/javaee/6/docs/api/javax/servlet/jsp/el/ImplicitObjectELResolver.html
163165
return new TypedValue(this.pageContext.findAttribute(name));
164166
}
165167

@@ -173,6 +175,14 @@ public void write(EvaluationContext context, Object target,
173175
throw new UnsupportedOperationException();
174176
}
175177

178+
private Object resolveImplicitVariable(String name) throws AccessException {
179+
try {
180+
return this.pageContext.getVariableResolver().resolveVariable(name);
181+
} catch (ELException e) {
182+
throw new AccessException("Unexpected exception occurred accessing '" + name + "' as an implicit variable", e);
183+
}
184+
}
185+
176186
}
177187

178188
}

org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockPageContext.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,15 @@ public ELContext getELContext() {
294294
}
295295

296296
public VariableResolver getVariableResolver() {
297-
return null;
297+
return new VariableResolver() {
298+
public Object resolveVariable(String pName) throws ELException {
299+
if (pName.equals("pageContext")) {
300+
return this;
301+
} else {
302+
return null;
303+
}
304+
}
305+
};
298306
}
299307

300308
public HttpSession getSession() {

0 commit comments

Comments
 (0)