Struts源码之OgnlValueStack
public class OgnlValueStack implements Serializable, ValueStack, ClearableValueStack, MemberAccessValueStack { public static final String THROW_EXCEPTION_ON_FAILURE = OgnlValueStack.class.getName() + ".throwExceptionOnFailure"; private static final long serialVersionUID = 370737852934925530L; private static final String MAP_IDENTIFIER_KEY = "com.opensymphony.xwork2.util.OgnlValueStack.MAP_IDENTIFIER_KEY"; private static final Logger LOG = LoggerFactory.getLogger(OgnlValueStack.class); CompoundRoot root; transient Map<String, Object> context; Class defaultType; Map<Object, Object> overrides; transient OgnlUtil ognlUtil; transient SecurityMemberAccess securityMemberAccess; private boolean devMode; private boolean logMissingProperties; protected OgnlValueStack(XWorkConverter xworkConverter, CompoundRootAccessor accessor, TextProvider prov, boolean allowStaticAccess) { setRoot(xworkConverter, accessor, new CompoundRoot(), allowStaticAccess); push(prov); } protected OgnlValueStack(ValueStack vs, XWorkConverter xworkConverter, CompoundRootAccessor accessor, boolean allowStaticAccess) { setRoot(xworkConverter, accessor, new CompoundRoot(vs.getRoot()), allowStaticAccess); } @Inject public void setOgnlUtil(OgnlUtil ognlUtil) { this.ognlUtil = ognlUtil; } protected void setRoot(XWorkConverter xworkConverter, CompoundRootAccessor accessor, CompoundRoot compoundRoot, boolean allowStaticMethodAccess) { this.root = compoundRoot; this.securityMemberAccess = new SecurityMemberAccess(allowStaticMethodAccess); this.context = Ognl.createDefaultContext(this.root, accessor, new OgnlTypeConverterWrapper(xworkConverter), securityMemberAccess); context.put(VALUE_STACK, this); Ognl.setClassResolver(context, accessor); ((OgnlContext) context).setTraceEvaluations(false); ((OgnlContext) context).setKeepLastEvaluation(false); } @Inject(XWorkConstants.DEV_MODE) public void setDevMode(String mode) { devMode = "true".equalsIgnoreCase(mode); } @Inject(value = "logMissingProperties", required = false) public void setLogMissingProperties(String logMissingProperties) { this.logMissingProperties = "true".equalsIgnoreCase(logMissingProperties); } /** * @see com.opensymphony.xwork2.util.ValueStack#getContext() */ public Map<String, Object> getContext() { return context; } /** * @see com.opensymphony.xwork2.util.ValueStack#setDefaultType(java.lang.Class) */ public void setDefaultType(Class defaultType) { this.defaultType = defaultType; } /** * @see com.opensymphony.xwork2.util.ValueStack#setExprOverrides(java.util.Map) */ public void setExprOverrides(Map<Object, Object> overrides) { if (this.overrides == null) { this.overrides = overrides; } else { this.overrides.putAll(overrides); } } /** * @see com.opensymphony.xwork2.util.ValueStack#getExprOverrides() */ public Map<Object, Object> getExprOverrides() { return this.overrides; } /** * @see com.opensymphony.xwork2.util.ValueStack#getRoot() */ public CompoundRoot getRoot() { return root; } /** * @see com.opensymphony.xwork2.util.ValueStack#setParameter(String, Object) */ public void setParameter(String expr, Object value) { setValue(expr, value, devMode, false); } /** /** * @see com.opensymphony.xwork2.util.ValueStack#setValue(java.lang.String, java.lang.Object) */ public void setValue(String expr, Object value) { setValue(expr, value, devMode); } /** * @see com.opensymphony.xwork2.util.ValueStack#setValue(java.lang.String, java.lang.Object, boolean) */ public void setValue(String expr, Object value, boolean throwExceptionOnFailure) { setValue(expr, value, throwExceptionOnFailure, true); } private void setValue(String expr, Object value, boolean throwExceptionOnFailure, boolean evalExpression) { Map<String, Object> context = getContext(); try { trySetValue(expr, value, throwExceptionOnFailure, context, evalExpression); } catch (OgnlException e) { handleOgnlException(expr, value, throwExceptionOnFailure, e); } catch (RuntimeException re) { //XW-281 handleRuntimeException(expr, value, throwExceptionOnFailure, re); } finally { cleanUpContext(context); } } private void trySetValue(String expr, Object value, boolean throwExceptionOnFailure, Map<String, Object> context, boolean evalExpression) throws OgnlException { context.put(XWorkConverter.CONVERSION_PROPERTY_FULLNAME, expr); context.put(REPORT_ERRORS_ON_NO_PROP, (throwExceptionOnFailure) ? Boolean.TRUE : Boolean.FALSE); ognlUtil.setValue(expr, context, root, value, evalExpression); } private void cleanUpContext(Map<String, Object> context) { ReflectionContextState.clear(context); context.remove(XWorkConverter.CONVERSION_PROPERTY_FULLNAME); context.remove(REPORT_ERRORS_ON_NO_PROP); } private void handleRuntimeException(String expr, Object value, boolean throwExceptionOnFailure, RuntimeException re) { if (throwExceptionOnFailure) { String message = ErrorMessageBuilder.create() .errorSettingExpressionWithValue(expr, value) .build(); throw new XWorkException(message, re); } else { if (LOG.isWarnEnabled()) { LOG.warn("Error setting value", re); } } } private void handleOgnlException(String expr, Object value, boolean throwExceptionOnFailure, OgnlException e) { String msg = "Error setting expression '" + expr + "' with value '" + value + "'"; if (LOG.isWarnEnabled()) { LOG.warn(msg, e); } if (throwExceptionOnFailure) { throw new XWorkException(msg, e); } } /** * @see com.opensymphony.xwork2.util.ValueStack#findString(java.lang.String) */ public String findString(String expr) { return (String) findValue(expr, String.class); } public String findString(String expr, boolean throwExceptionOnFailure) { return (String) findValue(expr, String.class, throwExceptionOnFailure); } /** * @see com.opensymphony.xwork2.util.ValueStack#findValue(java.lang.String) */ public Object findValue(String expr, boolean throwExceptionOnFailure) { try { setupExceptionOnFailure(throwExceptionOnFailure); return tryFindValueWhenExpressionIsNotNull(expr); } catch (OgnlException e) { return handleOgnlException(expr, throwExceptionOnFailure, e); } catch (Exception e) { return handleOtherException(expr, throwExceptionOnFailure, e); } finally { ReflectionContextState.clear(context); } } private void setupExceptionOnFailure(boolean throwExceptionOnFailure) { if (throwExceptionOnFailure) { context.put(THROW_EXCEPTION_ON_FAILURE, true); } } private Object tryFindValueWhenExpressionIsNotNull(String expr) throws OgnlException { if (expr == null) { return null; } return tryFindValue(expr); } private Object handleOtherException(String expr, boolean throwExceptionOnFailure, Exception e) { logLookupFailure(expr, e); if (throwExceptionOnFailure) throw new XWorkException(e); return findInContext(expr); } private Object tryFindValue(String expr) throws OgnlException { Object value; expr = lookupForOverrides(expr); if (defaultType != null) { value = findValue(expr, defaultType); } else { value = getValueUsingOgnl(expr); if (value == null) { value = findInContext(expr); } } return value; } private String lookupForOverrides(String expr) { if ((overrides != null) && overrides.containsKey(expr)) { expr = (String) overrides.get(expr); } return expr; } private Object getValueUsingOgnl(String expr) throws OgnlException { try { return ognlUtil.getValue(expr, context, root); } finally { context.remove(THROW_EXCEPTION_ON_FAILURE); } } public Object findValue(String expr) { return findValue(expr, false); } /** * @see com.opensymphony.xwork2.util.ValueStack#findValue(java.lang.String, java.lang.Class) */ public Object findValue(String expr, Class asType, boolean throwExceptionOnFailure) { try { setupExceptionOnFailure(throwExceptionOnFailure); return tryFindValueWhenExpressionIsNotNull(expr, asType); } catch (OgnlException e) { return handleOgnlException(expr, throwExceptionOnFailure, e); } catch (Exception e) { return handleOtherException(expr, throwExceptionOnFailure, e); } finally { ReflectionContextState.clear(context); } } private Object tryFindValueWhenExpressionIsNotNull(String expr, Class asType) throws OgnlException { if (expr == null) { return null; } return tryFindValue(expr, asType); } private Object handleOgnlException(String expr, boolean throwExceptionOnFailure, OgnlException e) { Object ret = findInContext(expr); if (ret == null) { if (shouldLogNoSuchPropertyWarning(e)) { LOG.warn("Could not find property [" + ((NoSuchPropertyException) e).getName() + "]"); } if (throwExceptionOnFailure) { throw new XWorkException(e); } } return ret; } private boolean shouldLogNoSuchPropertyWarning(OgnlException e) { return e instanceof NoSuchPropertyException && devMode && logMissingProperties; } private Object tryFindValue(String expr, Class asType) throws OgnlException { Object value = null; try { expr = lookupForOverrides(expr); value = getValue(expr, asType); if (value == null) { value = findInContext(expr); } } finally { context.remove(THROW_EXCEPTION_ON_FAILURE); } return value; } private Object getValue(String expr, Class asType) throws OgnlException { return ognlUtil.getValue(expr, context, root, asType); } private Object findInContext(String name) { return getContext().get(name); } public Object findValue(String expr, Class asType) { return findValue(expr, asType, false); } /** * Log a failed lookup, being more verbose when devMode=true. * * @param expr The failed expression * @param e The thrown exception. */ private void logLookupFailure(String expr, Exception e) { String msg = LoggerUtils.format("Caught an exception while evaluating expression '#0' against value stack", expr); if (devMode && LOG.isWarnEnabled()) { LOG.warn(msg, e); LOG.warn("NOTE: Previous warning message was issued due to devMode set to true."); } else if (LOG.isDebugEnabled()) { LOG.debug(msg, e); } } /** * @see com.opensymphony.xwork2.util.ValueStack#peek() */ public Object peek() { return root.peek(); } /** * @see com.opensymphony.xwork2.util.ValueStack#pop() */ public Object pop() { return root.pop(); } /** * @see com.opensymphony.xwork2.util.ValueStack#push(java.lang.Object) */ public void push(Object o) { root.push(o); } /** * @see com.opensymphony.xwork2.util.ValueStack#set(java.lang.String, java.lang.Object) */ public void set(String key, Object o) { //set basically is backed by a Map pushed on the stack with a key being put on the map and the Object being the value Map setMap = retrieveSetMap(); setMap.put(key, o); } private Map retrieveSetMap() { Map setMap; Object topObj = peek(); if (shouldUseOldMap(topObj)) { setMap = (Map) topObj; } else { setMap = new HashMap(); setMap.put(MAP_IDENTIFIER_KEY, ""); push(setMap); } return setMap; } /** * check if this is a Map put on the stack for setting if so just use the old map (reduces waste) */ private boolean shouldUseOldMap(Object topObj) { return topObj instanceof Map && ((Map) topObj).get(MAP_IDENTIFIER_KEY) != null; } /** * @see com.opensymphony.xwork2.util.ValueStack#size() */ public int size() { return root.size(); } private Object readResolve() { // TODO: this should be done better ActionContext ac = ActionContext.getContext(); Container cont = ac.getContainer(); XWorkConverter xworkConverter = cont.getInstance(XWorkConverter.class); CompoundRootAccessor accessor = (CompoundRootAccessor) cont.getInstance(PropertyAccessor.class, CompoundRoot.class.getName()); TextProvider prov = cont.getInstance(TextProvider.class, "system"); boolean allow = "true".equals(cont.getInstance(String.class, "allowStaticMethodAccess")); OgnlValueStack aStack = new OgnlValueStack(xworkConverter, accessor, prov, allow); aStack.setOgnlUtil(cont.getInstance(OgnlUtil.class)); aStack.setRoot(xworkConverter, accessor, this.root, allow); return aStack; } public void clearContextValues() { //this is an OGNL ValueStack so the context will be an OgnlContext //it would be better to make context of type OgnlContext ((OgnlContext) context).getValues().clear(); } public void setAcceptProperties(Set<Pattern> acceptedProperties) { securityMemberAccess.setAcceptProperties(acceptedProperties); } public void setPropertiesJudge(PropertiesJudge judge) { securityMemberAccess.setPropertiesJudge(judge); } public void setExcludeProperties(Set<Pattern> excludeProperties) { securityMemberAccess.setExcludeProperties(excludeProperties); } }
Struts源码之OgnlValueStack的更多相关文章
- 将struts源码导入eclipse
预制条件和spring源码导入eclipse中一样,下面直接给出导入eclipse的步骤. 步骤: 1. 下载struts相应版本的源码 http://struts.apache.org/downlo ...
- myeclipse 跟踪struts 源码失败
解决办法: 找到工程jar包所在的位置,点击右键:properties 点击external folder 找到 这个包下的src文件夹 导入之后, 源码会变色
- Struts源码之ValueStack
/** * ValueStack allows multiple beans to be pushed in and dynamic EL expressions to be evaluated ag ...
- 如何阅读Java源码 阅读java的真实体会
刚才在论坛不经意间,看到有关源码阅读的帖子.回想自己前几年,阅读源码那种兴奋和成就感(1),不禁又有一种激动. 源码阅读,我觉得最核心有三点:技术基础+强烈的求知欲+耐心. 说到技术基础,我打个比 ...
- 如何阅读Java源码
刚才在论坛不经意间,看到有关源码阅读的帖子.回想自己前几年,阅读源码那种兴奋和成就感(1),不禁又有一种激动.源码阅读,我觉得最核心有三点:技术基础+强烈的求知欲+耐心. 说到技术基础,我打个比方吧, ...
- Java 源码学习线路————_先JDK工具包集合_再core包,也就是String、StringBuffer等_Java IO类库
http://www.iteye.com/topic/1113732 原则网址 Java源码初接触 如果你进行过一年左右的开发,喜欢用eclipse的debug功能.好了,你现在就有阅读源码的技术基础 ...
- [收藏] Java源码阅读的真实体会
收藏自http://www.iteye.com/topic/1113732 刚才在论坛不经意间,看到有关源码阅读的帖子.回想自己前几年,阅读源码那种兴奋和成就感(1),不禁又有一种激动. 源码阅读,我 ...
- Java源码阅读的真实体会(一种学习思路)
Java源码阅读的真实体会(一种学习思路) 刚才在论坛不经意间,看到有关源码阅读的帖子.回想自己前几年,阅读源码那种兴奋和成就感(1),不禁又有一种激动. 源码阅读,我觉得最核心有三点:技术基础+强烈 ...
- Java源码阅读的真实体会(一种学习思路)【转】
Java源码阅读的真实体会(一种学习思路) 刚才在论坛不经意间,看到有关源码阅读的帖子.回想自己前几年,阅读源码那种兴奋和成就感(1),不禁又有一种激动. 源码阅读,我觉得最核心有三点:技术基础+ ...
随机推荐
- Mysql创建、删除用户、用户管理等相关:转载http://www.cnblogs.com/fly1988happy/archive/2011/12/15/2288554.html
MySql中添加用户,新建数据库,用户授权,删除用户,修改密码(注意每行后边都跟个;表示一个命令语句结束): 1.新建用户 登录MYSQL: @>mysql -u root -p @>密码 ...
- tomcat启动批处理——catalina.bat
这个批处理才是tomcat服务器启动跟关闭的核心脚本.其中包括....(各种变量),此节将详细讲解这个批处理的逻辑. 先看看第一部分脚本: ****************************** ...
- qq安全原理
故事总要有缘由,那么这个故事的缘由就是,当我以前写了一个获取其它进程密码框密码的时候(前几篇博客中有描述),我抱着试一试的心情去试探了一下能不能得到 QQ 的密码,当我抓到密码框的句柄,然后输入给程序 ...
- JSP简单隔行变色和日期格式化
以前好像在找,都没找到简单点的,所以后面就自己写了一个,感觉超级简单又好理解,分享给大家 <%@ page language="java" import="java ...
- Gazebo機器人仿真學習探索筆記(五)環境模型
環境模型構建可以通過向其中添加模型實現,待之後補充,比較有趣的是建築物模型, 可以編輯多層樓層和房間,加入樓梯,窗戶和牆壁等,具體可以參考附錄,等有空再補充. 起伏地形環境構建可以參考之前內容:在Ga ...
- 择天记OL体验截图
- Android原生嵌入React Native
1.首先集成的项目目录 我使用的是直接按照react-native init Project 的格式来导入的,也就是说,我的Android项目目录是跟node_modules是在一个目录下的. 我们i ...
- ROS_Kinetic_05 ROS基础内容(二)
ROS_Kinetic_05 ROS基础内容(二) 1. ROS节点node 官网教程:http://wiki.ros.org/cn/ROS/Tutorials/UnderstandingNodes ...
- OpenCL异构计算资料收集
Easy OpenCL with Python 原文 http://www.drdobbs.com/open-source/easy-opencl-with-python/240162614 ...
- (NO.00003)iOS游戏简单的机器人投射游戏成形记(六)
为什么要将手臂移动的代码单独放在一个方法中? 其实这里是多次重构之后的版本.原来的移动代码是放在touchMoved方法里的.后来发现除了触摸手臂移动方式外,还要实现触摸屏幕移动手臂这第二种方式. 所 ...