Source Code Cross Referenced for ExpressionEvaluationUtils.java in  » J2EE » spring-framework-2.5 » org » springframework » web » util » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » J2EE » spring framework 2.5 » org.springframework.web.util 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2002-2007 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.util;
018:
019:        import java.util.Collections;
020:        import java.util.HashMap;
021:        import java.util.Map;
022:
023:        import javax.servlet.ServletContext;
024:        import javax.servlet.jsp.JspException;
025:        import javax.servlet.jsp.PageContext;
026:        import javax.servlet.jsp.el.ELException;
027:        import javax.servlet.jsp.el.Expression;
028:
029:        import org.apache.commons.logging.Log;
030:        import org.apache.commons.logging.LogFactory;
031:        import org.apache.taglibs.standard.lang.support.ExpressionEvaluatorManager;
032:
033:        import org.springframework.util.Assert;
034:        import org.springframework.util.ClassUtils;
035:
036:        /**
037:         * Convenience methods for transparent access to JSP 2.0's built-in
038:         * {@link javax.servlet.jsp.el.ExpressionEvaluator} or the standalone
039:         * {@link org.apache.taglibs.standard.lang.support.ExpressionEvaluatorManager}
040:         * of Jakarta's JSTL implementation.
041:         *
042:         * <p>Automatically detects JSP 2.0 or Jakarta JSTL, preferring the JSP 2.0
043:         * mechanism if available. Also detects the JSP 2.0 API being present but
044:         * the runtime JSP engine not actually supporting JSP 2.0, falling back to
045:         * the Jakarta JSTL in this case. Throws an exception when encountering actual
046:         * EL expressions if neither JSP 2.0 nor the Jakarta JSTL is available.
047:         *
048:         * <p>In the case of JSP 2.0, this class will by default use standard
049:         * <code>evaluate</code> calls. If your application server happens to be
050:         * inefficient in that respect, consider setting Spring's "cacheJspExpressions"
051:         * context-param in <code>web.xml</code> to "true", which will use
052:         * <code>parseExpression</code> calls with cached Expression objects instead.
053:         *
054:         * <p>The evaluation methods check if the value contains "${" before
055:         * invoking the EL evaluator, treating the value as "normal" expression
056:         * (i.e. a literal String value) else.
057:         *
058:         * <p>Note: The evaluation methods do not have a runtime dependency on
059:         * JSP 2.0 or on Jakarta's JSTL implementation, as long as they are not
060:         * asked to process actual EL expressions. This allows for using EL-aware
061:         * tags with Java-based JSP expressions instead, for example.
062:         *
063:         * @author Juergen Hoeller
064:         * @author Alef Arendsen
065:         * @since 11.07.2003
066:         * @see javax.servlet.jsp.el.ExpressionEvaluator#evaluate
067:         * @see javax.servlet.jsp.el.ExpressionEvaluator#parseExpression
068:         * @see org.apache.taglibs.standard.lang.support.ExpressionEvaluatorManager
069:         */
070:        public abstract class ExpressionEvaluationUtils {
071:
072:            /**
073:             * JSP 2.0 expression cache parameter at the servlet context level
074:             * (i.e. a context-param in <code>web.xml</code>): "cacheJspExpressions".
075:             */
076:            public static final String EXPRESSION_CACHE_CONTEXT_PARAM = "cacheJspExpressions";
077:
078:            public static final String EXPRESSION_PREFIX = "${";
079:
080:            public static final String EXPRESSION_SUFFIX = "}";
081:
082:            private static final String EXPRESSION_CACHE_FLAG_CONTEXT_ATTR = ExpressionEvaluationUtils.class
083:                    .getName()
084:                    + ".CACHE_JSP_EXPRESSIONS";
085:
086:            private static final String EXPRESSION_CACHE_MAP_CONTEXT_ATTR = ExpressionEvaluationUtils.class
087:                    .getName()
088:                    + ".JSP_EXPRESSION_CACHE";
089:
090:            private static final String JSP_20_CLASS_NAME = "javax.servlet.jsp.el.ExpressionEvaluator";
091:
092:            private static final String JAKARTA_JSTL_CLASS_NAME = "org.apache.taglibs.standard.lang.support.ExpressionEvaluatorManager";
093:
094:            private static final Log logger = LogFactory
095:                    .getLog(ExpressionEvaluationUtils.class);
096:
097:            private static ExpressionEvaluationHelper helper;
098:
099:            static {
100:                ClassLoader cl = ExpressionEvaluationUtils.class
101:                        .getClassLoader();
102:                if (ClassUtils.isPresent(JSP_20_CLASS_NAME, cl)) {
103:                    logger.debug("Found JSP 2.0 ExpressionEvaluator");
104:                    if (ClassUtils.isPresent(JAKARTA_JSTL_CLASS_NAME, cl)) {
105:                        logger
106:                                .debug("Found Jakarta JSTL ExpressionEvaluatorManager");
107:                        helper = new Jsp20ExpressionEvaluationHelper(
108:                                new JakartaExpressionEvaluationHelper());
109:                    } else {
110:                        helper = new Jsp20ExpressionEvaluationHelper(
111:                                new NoExpressionEvaluationHelper());
112:                    }
113:                } else if (ClassUtils.isPresent(JAKARTA_JSTL_CLASS_NAME, cl)) {
114:                    logger
115:                            .debug("Found Jakarta JSTL ExpressionEvaluatorManager");
116:                    helper = new JakartaExpressionEvaluationHelper();
117:                } else {
118:                    logger.debug("JSP expression evaluation not available");
119:                    helper = new NoExpressionEvaluationHelper();
120:                }
121:            }
122:
123:            /**
124:             * Check if the given expression value is an EL expression.
125:             * @param value the expression to check
126:             * @return <code>true</code> if the expression is an EL expression,
127:             * <code>false</code> otherwise
128:             */
129:            public static boolean isExpressionLanguage(String value) {
130:                return (value != null && value.indexOf(EXPRESSION_PREFIX) != -1);
131:            }
132:
133:            /**
134:             * Evaluate the given expression (be it EL or a literal String value)
135:             * to an Object of a given type,
136:             * @param attrName name of the attribute (typically a JSP tag attribute)
137:             * @param attrValue value of the attribute
138:             * @param resultClass class that the result should have (String, Integer, Boolean)
139:             * @param pageContext current JSP PageContext
140:             * @return the result of the evaluation
141:             * @throws JspException in case of parsing errors, also in case of type mismatch
142:             * if the passed-in literal value is not an EL expression and not assignable to
143:             * the result class
144:             */
145:            public static Object evaluate(String attrName, String attrValue,
146:                    Class resultClass, PageContext pageContext)
147:                    throws JspException {
148:
149:                if (isExpressionLanguage(attrValue)) {
150:                    return doEvaluate(attrName, attrValue, resultClass,
151:                            pageContext);
152:                } else if (attrValue != null && resultClass != null
153:                        && !resultClass.isInstance(attrValue)) {
154:                    throw new JspException("Attribute value \"" + attrValue
155:                            + "\" is neither a JSP EL expression nor "
156:                            + "assignable to result class ["
157:                            + resultClass.getName() + "]");
158:                } else {
159:                    return attrValue;
160:                }
161:            }
162:
163:            /**
164:             * Evaluate the given expression (be it EL or a literal String value) to an Object.
165:             * @param attrName name of the attribute (typically a JSP tag attribute)
166:             * @param attrValue value of the attribute
167:             * @param pageContext current JSP PageContext
168:             * @return the result of the evaluation
169:             * @throws JspException in case of parsing errors
170:             */
171:            public static Object evaluate(String attrName, String attrValue,
172:                    PageContext pageContext) throws JspException {
173:
174:                if (isExpressionLanguage(attrValue)) {
175:                    return doEvaluate(attrName, attrValue, Object.class,
176:                            pageContext);
177:                } else {
178:                    return attrValue;
179:                }
180:            }
181:
182:            /**
183:             * Evaluate the given expression (be it EL or a literal String value) to a String.
184:             * @param attrName name of the attribute (typically a JSP tag attribute)
185:             * @param attrValue value of the attribute
186:             * @param pageContext current JSP PageContext
187:             * @return the result of the evaluation
188:             * @throws JspException in case of parsing errors
189:             */
190:            public static String evaluateString(String attrName,
191:                    String attrValue, PageContext pageContext)
192:                    throws JspException {
193:
194:                if (isExpressionLanguage(attrValue)) {
195:                    return (String) doEvaluate(attrName, attrValue,
196:                            String.class, pageContext);
197:                } else {
198:                    return attrValue;
199:                }
200:            }
201:
202:            /**
203:             * Evaluate the given expression (be it EL or a literal String value) to an integer.
204:             * @param attrName name of the attribute (typically a JSP tag attribute)
205:             * @param attrValue value of the attribute
206:             * @param pageContext current JSP PageContext
207:             * @return the result of the evaluation
208:             * @throws JspException in case of parsing errors
209:             */
210:            public static int evaluateInteger(String attrName,
211:                    String attrValue, PageContext pageContext)
212:                    throws JspException {
213:
214:                if (isExpressionLanguage(attrValue)) {
215:                    return ((Integer) doEvaluate(attrName, attrValue,
216:                            Integer.class, pageContext)).intValue();
217:                } else {
218:                    return Integer.parseInt(attrValue);
219:                }
220:            }
221:
222:            /**
223:             * Evaluate the given expression (be it EL or a literal String value) to a boolean.
224:             * @param attrName name of the attribute (typically a JSP tag attribute)
225:             * @param attrValue value of the attribute
226:             * @param pageContext current JSP PageContext
227:             * @return the result of the evaluation
228:             * @throws JspException in case of parsing errors
229:             */
230:            public static boolean evaluateBoolean(String attrName,
231:                    String attrValue, PageContext pageContext)
232:                    throws JspException {
233:
234:                if (isExpressionLanguage(attrValue)) {
235:                    return ((Boolean) doEvaluate(attrName, attrValue,
236:                            Boolean.class, pageContext)).booleanValue();
237:                } else {
238:                    return Boolean.valueOf(attrValue).booleanValue();
239:                }
240:            }
241:
242:            /**
243:             * Actually evaluate the given expression (be it EL or a literal String value)
244:             * to an Object of a given type. Supports concatenated expressions,
245:             * for example: "${var1}text${var2}"
246:             * @param attrName name of the attribute
247:             * @param attrValue value of the attribute
248:             * @param resultClass class that the result should have
249:             * @param pageContext current JSP PageContext
250:             * @return the result of the evaluation
251:             * @throws JspException in case of parsing errors
252:             */
253:            private static Object doEvaluate(String attrName, String attrValue,
254:                    Class resultClass, PageContext pageContext)
255:                    throws JspException {
256:
257:                Assert.notNull(attrValue, "Attribute value must not be null");
258:                Assert.notNull(resultClass, "Result class must not be null");
259:                Assert.notNull(pageContext, "PageContext must not be null");
260:
261:                if (resultClass.isAssignableFrom(String.class)) {
262:                    StringBuffer resultValue = null;
263:                    int exprPrefixIndex = -1;
264:                    int exprSuffixIndex = 0;
265:                    do {
266:                        exprPrefixIndex = attrValue.indexOf(EXPRESSION_PREFIX,
267:                                exprSuffixIndex);
268:                        if (exprPrefixIndex != -1) {
269:                            int prevExprSuffixIndex = exprSuffixIndex;
270:                            exprSuffixIndex = attrValue.indexOf(
271:                                    EXPRESSION_SUFFIX, exprPrefixIndex
272:                                            + EXPRESSION_PREFIX.length());
273:                            String expr = null;
274:                            if (exprSuffixIndex != -1) {
275:                                exprSuffixIndex += EXPRESSION_SUFFIX.length();
276:                                expr = attrValue.substring(exprPrefixIndex,
277:                                        exprSuffixIndex);
278:                            } else {
279:                                expr = attrValue.substring(exprPrefixIndex);
280:                            }
281:                            if (expr.length() == attrValue.length()) {
282:                                // A single expression without static prefix or suffix ->
283:                                // parse it with the specified result class rather than String.
284:                                return helper.evaluate(attrName, attrValue,
285:                                        resultClass, pageContext);
286:                            } else {
287:                                // We actually need to concatenate partial expressions into a String.
288:                                if (resultValue == null) {
289:                                    resultValue = new StringBuffer();
290:                                }
291:                                resultValue.append(attrValue.substring(
292:                                        prevExprSuffixIndex, exprPrefixIndex));
293:                                resultValue.append(helper.evaluate(attrName,
294:                                        expr, String.class, pageContext));
295:                            }
296:                        } else {
297:                            if (resultValue == null) {
298:                                resultValue = new StringBuffer();
299:                            }
300:                            resultValue.append(attrValue
301:                                    .substring(exprSuffixIndex));
302:                        }
303:                    } while (exprPrefixIndex != -1 && exprSuffixIndex != -1);
304:                    return resultValue.toString();
305:                }
306:
307:                else {
308:                    return helper.evaluate(attrName, attrValue, resultClass,
309:                            pageContext);
310:                }
311:            }
312:
313:            /**
314:             * Determine whether JSP 2.0 expressions are supposed to be cached
315:             * and return the corresponding cache Map, or <code>null</code> if
316:             * caching is not enabled.
317:             * @param pageContext current JSP PageContext
318:             * @return the cache Map, or <code>null</code> if caching is disabled
319:             */
320:            private static Map getJspExpressionCache(PageContext pageContext) {
321:                ServletContext servletContext = pageContext.getServletContext();
322:                Map cacheMap = (Map) servletContext
323:                        .getAttribute(EXPRESSION_CACHE_MAP_CONTEXT_ATTR);
324:                if (cacheMap == null) {
325:                    Boolean cacheFlag = (Boolean) servletContext
326:                            .getAttribute(EXPRESSION_CACHE_FLAG_CONTEXT_ATTR);
327:                    if (cacheFlag == null) {
328:                        cacheFlag = Boolean
329:                                .valueOf(servletContext
330:                                        .getInitParameter(EXPRESSION_CACHE_CONTEXT_PARAM));
331:                        servletContext.setAttribute(
332:                                EXPRESSION_CACHE_FLAG_CONTEXT_ATTR, cacheFlag);
333:                    }
334:                    if (cacheFlag.booleanValue()) {
335:                        cacheMap = Collections.synchronizedMap(new HashMap());
336:                        servletContext.setAttribute(
337:                                EXPRESSION_CACHE_MAP_CONTEXT_ATTR, cacheMap);
338:                    }
339:                }
340:                return cacheMap;
341:            }
342:
343:            /**
344:             * Internal interface for evaluating a JSP EL expression.
345:             */
346:            private static interface ExpressionEvaluationHelper {
347:
348:                public Object evaluate(String attrName, String attrValue,
349:                        Class resultClass, PageContext pageContext)
350:                        throws JspException;
351:            }
352:
353:            /**
354:             * Fallback ExpressionEvaluationHelper:
355:             * always throws an exception in case of an actual EL expression.
356:             */
357:            private static class NoExpressionEvaluationHelper implements 
358:                    ExpressionEvaluationHelper {
359:
360:                public Object evaluate(String attrName, String attrValue,
361:                        Class resultClass, PageContext pageContext)
362:                        throws JspException {
363:
364:                    throw new JspException(
365:                            "Neither JSP 2.0 nor Jakarta JSTL available - cannot parse JSP EL expression \""
366:                                    + attrValue + "\"");
367:                }
368:            }
369:
370:            /**
371:             * Actual invocation of the Jakarta ExpressionEvaluatorManager.
372:             * In separate inner class to avoid runtime dependency on Jakarta's
373:             * JSTL implementation, for evaluation of non-EL expressions.
374:             */
375:            private static class JakartaExpressionEvaluationHelper implements 
376:                    ExpressionEvaluationHelper {
377:
378:                public Object evaluate(String attrName, String attrValue,
379:                        Class resultClass, PageContext pageContext)
380:                        throws JspException {
381:
382:                    return ExpressionEvaluatorManager.evaluate(attrName,
383:                            attrValue, resultClass, pageContext);
384:                }
385:            }
386:
387:            /**
388:             * Actual invocation of the JSP 2.0 ExpressionEvaluator.
389:             * In separate inner class to avoid runtime dependency on JSP 2.0,
390:             * for evaluation of non-EL expressions.
391:             */
392:            private static class Jsp20ExpressionEvaluationHelper implements 
393:                    ExpressionEvaluationHelper {
394:
395:                private final ExpressionEvaluationHelper fallback;
396:
397:                private boolean fallbackNecessary = false;
398:
399:                public Jsp20ExpressionEvaluationHelper(
400:                        ExpressionEvaluationHelper fallback) {
401:                    this .fallback = fallback;
402:                }
403:
404:                public Object evaluate(String attrName, String attrValue,
405:                        Class resultClass, PageContext pageContext)
406:                        throws JspException {
407:
408:                    if (isFallbackNecessary()) {
409:                        return this .fallback.evaluate(attrName, attrValue,
410:                                resultClass, pageContext);
411:                    }
412:
413:                    try {
414:                        Map expressionCache = getJspExpressionCache(pageContext);
415:                        if (expressionCache != null) {
416:                            // We are supposed to explicitly create and cache JSP Expression objects.
417:                            ExpressionCacheKey cacheKey = new ExpressionCacheKey(
418:                                    attrValue, resultClass);
419:                            Expression expr = (Expression) expressionCache
420:                                    .get(cacheKey);
421:                            if (expr == null) {
422:                                expr = pageContext.getExpressionEvaluator()
423:                                        .parseExpression(attrValue,
424:                                                resultClass, null);
425:                                expressionCache.put(cacheKey, expr);
426:                            }
427:                            return expr.evaluate(pageContext
428:                                    .getVariableResolver());
429:                        } else {
430:                            // We're simply calling the JSP 2.0 evaluate method straight away.
431:                            return pageContext.getExpressionEvaluator()
432:                                    .evaluate(attrValue, resultClass,
433:                                            pageContext.getVariableResolver(),
434:                                            null);
435:                        }
436:                    } catch (ELException ex) {
437:                        throw new JspException(
438:                                "Parsing of JSP EL expression \"" + attrValue
439:                                        + "\" failed", ex);
440:                    } catch (LinkageError err) {
441:                        logger
442:                                .debug(
443:                                        "JSP 2.0 ExpressionEvaluator API present but not implemented - using fallback",
444:                                        err);
445:                        setFallbackNecessary();
446:                        return this .fallback.evaluate(attrName, attrValue,
447:                                resultClass, pageContext);
448:                    }
449:                }
450:
451:                private synchronized boolean isFallbackNecessary() {
452:                    return this .fallbackNecessary;
453:                }
454:
455:                private synchronized void setFallbackNecessary() {
456:                    this .fallbackNecessary = true;
457:                }
458:            }
459:
460:            /**
461:             * Cache key class for JSP 2.0 Expression objects.
462:             */
463:            private static class ExpressionCacheKey {
464:
465:                private final String value;
466:                private final Class resultClass;
467:                private final int hashCode;
468:
469:                public ExpressionCacheKey(String value, Class resultClass) {
470:                    this .value = value;
471:                    this .resultClass = resultClass;
472:                    this .hashCode = this .value.hashCode() * 29
473:                            + this .resultClass.hashCode();
474:                }
475:
476:                public boolean equals(Object obj) {
477:                    if (!(obj instanceof  ExpressionCacheKey)) {
478:                        return false;
479:                    }
480:                    ExpressionCacheKey other = (ExpressionCacheKey) obj;
481:                    return (this .value.equals(other.value) && this .resultClass
482:                            .equals(other.resultClass));
483:                }
484:
485:                public int hashCode() {
486:                    return this.hashCode;
487:                }
488:            }
489:
490:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.