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),不禁又有一种激动. 源码阅读,我觉得最核心有三点:技术基础+ ...
随机推荐
- ORACLE异常(整理网上资料)
一.oracle预定义异常 命名的系统异常 产生原因 Oracle Error SQLCODE Value ACCESS_INTO_NULL 未定义对象 ORA-06530 -6530 CASE_N ...
- CoreText精彩文字轮廓绘制动画的一点改进
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 原文在: http://oleb.net/blog/2010/ ...
- SpriteKit中类似Cocos2D的CCActionSpawn并发方法GroupAction
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 我们知道在Cocos2D中对于并发Action的处理可以使用C ...
- springmvc文件上传和拦截器
文件上传 用到这两个包 配置视图解析器:springmvc配置文件配置 <!-- id必须要是"multipartResolver" --> <bean id=& ...
- 1.关于QT中的Graphics绘图,定时器,动画,将窗口中的内容打印到图片上,打印机,打印预览
1 新建项目 A 修改pro中的内容如下: HEADERS += \ MyWidget.h SOURCES += \ MyWidget.cpp QT += gui widgets prints ...
- Android初级教程:单击事件的传递机制初谈
以上仅是小试牛刀,后续有很多事件传递机制,继续探讨.
- UNIX网络编程——TCP/IP简介
一.ISO/OSI参考模型 OSI(open system interconnection)开放系统互联模型是由ISO(International Organization for Standardi ...
- 打Patch实践
一.找到相应PATCH 确认系统已安装模块版本. SELECTapp.application_short_name, app.application_name, pi.patch_level FR ...
- C#attribute-----------初级
前言: attribute是 .net FrameWork 提出的技术,可以为自己的代码添加注解,从而实现些特殊功能. 一. attribute功能 attribute被译作特性,既然是特性,必然功能 ...
- 为什么会存在using filesort
当使用explain分析SQL时常常会遇到extra的其中一值为using filesort,如: PRIMARY KEY (`id`), KEY `uid` (`uid`) explain se ...