OgnlContext 源码
// Copyright (c) 1998-2004, Drew Davidson and Luke Blanshard
package ognl; import ognl.enhance.LocalReference; import java.util.*; /**
* This class defines the execution context for an OGNL expression
*
* @author Luke Blanshard (blanshlu@netscape.net)
* @author Drew Davidson (drew@ognl.org)
*/
public class OgnlContext extends Object implements Map
{ public static final String CONTEXT_CONTEXT_KEY = "context";
public static final String ROOT_CONTEXT_KEY = "root";
public static final String THIS_CONTEXT_KEY = "this";
public static final String TRACE_EVALUATIONS_CONTEXT_KEY = "_traceEvaluations";
public static final String LAST_EVALUATION_CONTEXT_KEY = "_lastEvaluation";
public static final String KEEP_LAST_EVALUATION_CONTEXT_KEY = "_keepLastEvaluation";
public static final String CLASS_RESOLVER_CONTEXT_KEY = "_classResolver";
public static final String TYPE_CONVERTER_CONTEXT_KEY = "_typeConverter";
public static final String MEMBER_ACCESS_CONTEXT_KEY = "_memberAccess"; private static final String PROPERTY_KEY_PREFIX = "ognl";
private static boolean DEFAULT_TRACE_EVALUATIONS = false;
private static boolean DEFAULT_KEEP_LAST_EVALUATION = false; public static final ClassResolver DEFAULT_CLASS_RESOLVER = new DefaultClassResolver();
public static final TypeConverter DEFAULT_TYPE_CONVERTER = new DefaultTypeConverter();
public static final MemberAccess DEFAULT_MEMBER_ACCESS = new DefaultMemberAccess(false); private static Map RESERVED_KEYS = new HashMap(11); private Object _root;
private Object _currentObject;
private Node _currentNode;
private boolean _traceEvaluations = DEFAULT_TRACE_EVALUATIONS;
private Evaluation _rootEvaluation;
private Evaluation _currentEvaluation;
private Evaluation _lastEvaluation;
private boolean _keepLastEvaluation = DEFAULT_KEEP_LAST_EVALUATION; private Map _values = new HashMap(23); private ClassResolver _classResolver = DEFAULT_CLASS_RESOLVER;
private TypeConverter _typeConverter = DEFAULT_TYPE_CONVERTER;
private MemberAccess _memberAccess = DEFAULT_MEMBER_ACCESS; static {
String s; RESERVED_KEYS.put(CONTEXT_CONTEXT_KEY, null);
RESERVED_KEYS.put(ROOT_CONTEXT_KEY, null);
RESERVED_KEYS.put(THIS_CONTEXT_KEY, null);
RESERVED_KEYS.put(TRACE_EVALUATIONS_CONTEXT_KEY, null);
RESERVED_KEYS.put(LAST_EVALUATION_CONTEXT_KEY, null);
RESERVED_KEYS.put(KEEP_LAST_EVALUATION_CONTEXT_KEY, null);
RESERVED_KEYS.put(CLASS_RESOLVER_CONTEXT_KEY, null);
RESERVED_KEYS.put(TYPE_CONVERTER_CONTEXT_KEY, null);
RESERVED_KEYS.put(MEMBER_ACCESS_CONTEXT_KEY, null); try {
if ((s = System.getProperty(PROPERTY_KEY_PREFIX + ".traceEvaluations")) != null) {
DEFAULT_TRACE_EVALUATIONS = Boolean.valueOf(s.trim()).booleanValue();
}
if ((s = System.getProperty(PROPERTY_KEY_PREFIX + ".keepLastEvaluation")) != null) {
DEFAULT_KEEP_LAST_EVALUATION = Boolean.valueOf(s.trim()).booleanValue();
}
} catch (SecurityException ex) {
// restricted access environment, just keep defaults
}
} private List _typeStack = new ArrayList();
private List _accessorStack = new ArrayList(); private int _localReferenceCounter = 0;
private Map _localReferenceMap = null; /**
* Constructs a new OgnlContext with the default class resolver, type converter and member
* access.
*/
public OgnlContext()
{
} /**
* Constructs a new OgnlContext with the given class resolver, type converter and member access.
* If any of these parameters is null the default will be used.
*/
public OgnlContext(ClassResolver classResolver, TypeConverter typeConverter, MemberAccess memberAccess)
{
this();
if (classResolver != null) {
this._classResolver = classResolver;
}
if (typeConverter != null) {
this._typeConverter = typeConverter;
}
if (memberAccess != null) {
this._memberAccess = memberAccess;
}
} public OgnlContext(Map values)
{
super();
this._values = values;
} public OgnlContext(ClassResolver classResolver, TypeConverter typeConverter, MemberAccess memberAccess, Map values)
{
this(classResolver, typeConverter, memberAccess);
this._values = values;
} public void setValues(Map value)
{
for(Iterator it = value.keySet().iterator(); it.hasNext();) {
Object k = it.next(); _values.put(k, value.get(k));
}
} public Map getValues()
{
return _values;
} public void setClassResolver(ClassResolver value)
{
if (value == null) { throw new IllegalArgumentException("cannot set ClassResolver to null"); }
_classResolver = value;
} public ClassResolver getClassResolver()
{
return _classResolver;
} public void setTypeConverter(TypeConverter value)
{
if (value == null) { throw new IllegalArgumentException("cannot set TypeConverter to null"); }
_typeConverter = value;
} public TypeConverter getTypeConverter()
{
return _typeConverter;
} public void setMemberAccess(MemberAccess value)
{
if (value == null) { throw new IllegalArgumentException("cannot set MemberAccess to null"); }
_memberAccess = value;
} public MemberAccess getMemberAccess()
{
return _memberAccess;
} public void setRoot(Object value)
{
_root = value;
_accessorStack.clear();
_typeStack.clear();
_currentObject = value; if (_currentObject != null)
{
setCurrentType(_currentObject.getClass());
}
} public Object getRoot()
{
return _root;
} public boolean getTraceEvaluations()
{
return _traceEvaluations;
} public void setTraceEvaluations(boolean value)
{
_traceEvaluations = value;
} public Evaluation getLastEvaluation()
{
return _lastEvaluation;
} public void setLastEvaluation(Evaluation value)
{
_lastEvaluation = value;
} /**
* This method can be called when the last evaluation has been used and can be returned for
* reuse in the free pool maintained by the runtime. This is not a necessary step, but is useful
* for keeping memory usage down. This will recycle the last evaluation and then set the last
* evaluation to null.
*/
public void recycleLastEvaluation()
{
OgnlRuntime.getEvaluationPool().recycleAll(_lastEvaluation);
_lastEvaluation = null;
} /**
* Returns true if the last evaluation that was done on this context is retained and available
* through <code>getLastEvaluation()</code>. The default is true.
*/
public boolean getKeepLastEvaluation()
{
return _keepLastEvaluation;
} /**
* Sets whether the last evaluation that was done on this context is retained and available
* through <code>getLastEvaluation()</code>. The default is true.
*/
public void setKeepLastEvaluation(boolean value)
{
_keepLastEvaluation = value;
} public void setCurrentObject(Object value)
{
_currentObject = value;
} public Object getCurrentObject()
{
return _currentObject;
} public void setCurrentAccessor(Class type)
{
_accessorStack.add(type);
} public Class getCurrentAccessor()
{
if (_accessorStack.isEmpty())
return null; return (Class) _accessorStack.get(_accessorStack.size() - 1);
} public Class getPreviousAccessor()
{
if (_accessorStack.isEmpty())
return null; if (_accessorStack.size() > 1)
return (Class) _accessorStack.get(_accessorStack.size() - 2);
else
return null;
} public Class getFirstAccessor()
{
if (_accessorStack.isEmpty())
return null; return (Class)_accessorStack.get(0);
} /**
* Gets the current class type being evaluated on the stack, as set by {@link #setCurrentType(Class)}.
*
* @return The current object type, may be null.
*/
public Class getCurrentType()
{
if (_typeStack.isEmpty())
return null; return (Class) _typeStack.get(_typeStack.size() - 1);
} public void setCurrentType(Class type)
{
_typeStack.add(type);
} /**
* Represents the last known object type on the evaluation stack, will be the value of
* the last known {@link #getCurrentType()}.
*
* @return The previous type of object on the stack, may be null.
*/
public Class getPreviousType()
{
if (_typeStack.isEmpty())
return null; if (_typeStack.size() > 1)
return (Class)_typeStack.get(_typeStack.size() - 2);
else
return null;
} public void setPreviousType(Class type)
{
if (_typeStack.isEmpty() || _typeStack.size() < 2)
return; _typeStack.set(_typeStack.size() - 2, type);
} public Class getFirstType()
{
if (_typeStack.isEmpty())
return null; return (Class)_typeStack.get(0);
} public void setCurrentNode(Node value)
{
_currentNode = value;
} public Node getCurrentNode()
{
return _currentNode;
} /**
* Gets the current Evaluation from the top of the stack. This is the Evaluation that is in
* process of evaluating.
*/
public Evaluation getCurrentEvaluation()
{
return _currentEvaluation;
} public void setCurrentEvaluation(Evaluation value)
{
_currentEvaluation = value;
} /**
* Gets the root of the evaluation stack. This Evaluation contains the node representing the
* root expression and the source is the root source object.
*/
public Evaluation getRootEvaluation()
{
return _rootEvaluation;
} public void setRootEvaluation(Evaluation value)
{
_rootEvaluation = value;
} /**
* Returns the Evaluation at the relative index given. This should be zero or a negative number
* as a relative reference back up the evaluation stack. Therefore getEvaluation(0) returns the
* current Evaluation.
*/
public Evaluation getEvaluation(int relativeIndex)
{
Evaluation result = null; if (relativeIndex <= 0) {
result = _currentEvaluation;
while((++relativeIndex < 0) && (result != null)) {
result = result.getParent();
}
}
return result;
} /**
* Pushes a new Evaluation onto the stack. This is done before a node evaluates. When evaluation
* is complete it should be popped from the stack via <code>popEvaluation()</code>.
*/
public void pushEvaluation(Evaluation value)
{
if (_currentEvaluation != null) {
_currentEvaluation.addChild(value);
} else {
setRootEvaluation(value);
}
setCurrentEvaluation(value);
} /**
* Pops the current Evaluation off of the top of the stack. This is done after a node has
* completed its evaluation.
*/
public Evaluation popEvaluation()
{
Evaluation result; result = _currentEvaluation;
setCurrentEvaluation(result.getParent());
if (_currentEvaluation == null) {
setLastEvaluation(getKeepLastEvaluation() ? result : null);
setRootEvaluation(null);
setCurrentNode(null);
}
return result;
} public int incrementLocalReferenceCounter()
{
return ++_localReferenceCounter;
} public void addLocalReference(String key, LocalReference reference)
{
if (_localReferenceMap == null)
{
_localReferenceMap = new LinkedHashMap();
} _localReferenceMap.put(key, reference);
} public Map getLocalReferences()
{
return _localReferenceMap;
} /* ================= Map interface ================= */
public int size()
{
return _values.size();
} public boolean isEmpty()
{
return _values.isEmpty();
} public boolean containsKey(Object key)
{
return _values.containsKey(key);
} public boolean containsValue(Object value)
{
return _values.containsValue(value);
} public Object get(Object key)
{
Object result; if (RESERVED_KEYS.containsKey(key)) {
if (key.equals(OgnlContext.THIS_CONTEXT_KEY)) {
result = getCurrentObject();
} else {
if (key.equals(OgnlContext.ROOT_CONTEXT_KEY)) {
result = getRoot();
} else {
if (key.equals(OgnlContext.CONTEXT_CONTEXT_KEY)) {
result = this;
} else {
if (key.equals(OgnlContext.TRACE_EVALUATIONS_CONTEXT_KEY)) {
result = getTraceEvaluations() ? Boolean.TRUE : Boolean.FALSE;
} else {
if (key.equals(OgnlContext.LAST_EVALUATION_CONTEXT_KEY)) {
result = getLastEvaluation();
} else {
if (key.equals(OgnlContext.KEEP_LAST_EVALUATION_CONTEXT_KEY)) {
result = getKeepLastEvaluation() ? Boolean.TRUE : Boolean.FALSE;
} else {
if (key.equals(OgnlContext.CLASS_RESOLVER_CONTEXT_KEY)) {
result = getClassResolver();
} else {
if (key.equals(OgnlContext.TYPE_CONVERTER_CONTEXT_KEY)) {
result = getTypeConverter();
} else {
if (key.equals(OgnlContext.MEMBER_ACCESS_CONTEXT_KEY)) {
result = getMemberAccess();
} else {
throw new IllegalArgumentException("unknown reserved key '" + key + "'");
}
}
}
}
}
}
}
}
}
} else {
result = _values.get(key);
}
return result;
} public Object put(Object key, Object value)
{
Object result; if (RESERVED_KEYS.containsKey(key)) {
if (key.equals(OgnlContext.THIS_CONTEXT_KEY)) {
result = getCurrentObject();
setCurrentObject(value);
} else {
if (key.equals(OgnlContext.ROOT_CONTEXT_KEY)) {
result = getRoot();
setRoot(value);
} else {
if (key.equals(OgnlContext.CONTEXT_CONTEXT_KEY)) {
throw new IllegalArgumentException("can't change " + OgnlContext.CONTEXT_CONTEXT_KEY
+ " in context");
} else {
if (key.equals(OgnlContext.TRACE_EVALUATIONS_CONTEXT_KEY)) {
result = getTraceEvaluations() ? Boolean.TRUE : Boolean.FALSE;
setTraceEvaluations(OgnlOps.booleanValue(value));
} else {
if (key.equals(OgnlContext.LAST_EVALUATION_CONTEXT_KEY)) {
result = getLastEvaluation();
_lastEvaluation = (Evaluation) value;
} else {
if (key.equals(OgnlContext.KEEP_LAST_EVALUATION_CONTEXT_KEY)) {
result = getKeepLastEvaluation() ? Boolean.TRUE : Boolean.FALSE;
setKeepLastEvaluation(OgnlOps.booleanValue(value));
} else {
if (key.equals(OgnlContext.CLASS_RESOLVER_CONTEXT_KEY)) {
result = getClassResolver();
setClassResolver((ClassResolver) value);
} else {
if (key.equals(OgnlContext.TYPE_CONVERTER_CONTEXT_KEY)) {
result = getTypeConverter();
setTypeConverter((TypeConverter) value);
} else {
if (key.equals(OgnlContext.MEMBER_ACCESS_CONTEXT_KEY)) {
result = getMemberAccess();
setMemberAccess((MemberAccess) value);
} else {
throw new IllegalArgumentException("unknown reserved key '" + key + "'");
}
}
}
}
}
}
}
}
}
} else {
result = _values.put(key, value);
} return result;
} public Object remove(Object key)
{
Object result; if (RESERVED_KEYS.containsKey(key)) {
if (key.equals(OgnlContext.THIS_CONTEXT_KEY)) {
result = getCurrentObject();
setCurrentObject(null);
} else {
if (key.equals(OgnlContext.ROOT_CONTEXT_KEY)) {
result = getRoot();
setRoot(null);
} else {
if (key.equals(OgnlContext.CONTEXT_CONTEXT_KEY)) {
throw new IllegalArgumentException("can't remove " + OgnlContext.CONTEXT_CONTEXT_KEY
+ " from context");
} else {
if (key.equals(OgnlContext.TRACE_EVALUATIONS_CONTEXT_KEY)) {
throw new IllegalArgumentException("can't remove "
+ OgnlContext.TRACE_EVALUATIONS_CONTEXT_KEY + " from context");
} else {
if (key.equals(OgnlContext.LAST_EVALUATION_CONTEXT_KEY)) {
result = _lastEvaluation;
setLastEvaluation(null);
} else {
if (key.equals(OgnlContext.KEEP_LAST_EVALUATION_CONTEXT_KEY)) {
throw new IllegalArgumentException("can't remove "
+ OgnlContext.KEEP_LAST_EVALUATION_CONTEXT_KEY + " from context");
} else {
if (key.equals(OgnlContext.CLASS_RESOLVER_CONTEXT_KEY)) {
result = getClassResolver();
setClassResolver(null);
} else {
if (key.equals(OgnlContext.TYPE_CONVERTER_CONTEXT_KEY)) {
result = getTypeConverter();
setTypeConverter(null);
} else {
if (key.equals(OgnlContext.MEMBER_ACCESS_CONTEXT_KEY)) {
result = getMemberAccess();
setMemberAccess(null);
} else {
throw new IllegalArgumentException("unknown reserved key '" + key + "'");
}
}
}
}
}
}
}
}
}
} else {
result = _values.remove(key);
}
return result;
} public void putAll(Map t)
{
for(Iterator it = t.keySet().iterator(); it.hasNext();) {
Object k = it.next(); put(k, t.get(k));
}
} public void clear()
{
_values.clear();
_typeStack.clear();
_accessorStack.clear(); _localReferenceCounter = 0;
if (_localReferenceMap != null)
{
_localReferenceMap.clear();
} setRoot(null);
setCurrentObject(null);
setRootEvaluation(null);
setCurrentEvaluation(null);
setLastEvaluation(null);
setCurrentNode(null);
setClassResolver(DEFAULT_CLASS_RESOLVER);
setTypeConverter(DEFAULT_TYPE_CONVERTER);
setMemberAccess(DEFAULT_MEMBER_ACCESS);
} public Set keySet()
{
/* Should root, currentObject, classResolver, typeConverter & memberAccess be included here? */
return _values.keySet();
} public Collection values()
{
/* Should root, currentObject, classResolver, typeConverter & memberAccess be included here? */
return _values.values();
} public Set entrySet()
{
/* Should root, currentObject, classResolver, typeConverter & memberAccess be included here? */
return _values.entrySet();
} public boolean equals(Object o)
{
return _values.equals(o);
} public int hashCode()
{
return _values.hashCode();
}
}
OgnlContext 源码的更多相关文章
- struts2拦截器源码分析
前面博客我们介绍了开发struts2应用程序的基本流程(开发一个struts2的实例),通过前面我们知道了struts2实现请求转发和配置文件加载都是拦截器进行的操作,这也就是为什么我们要在web.x ...
- Struts2 源码分析-----拦截器源码解析 --- ParametersInterceptor
ParametersInterceptor拦截器其主要功能是把ActionContext中的请求参数设置到ValueStack中,如果栈顶是当前Action则把请求参数设置到了Action中,如果栈顶 ...
- 精尽 MyBatis 源码分析 - MyBatis 初始化(三)之 SQL 初始化(上)
该系列文档是本人在学习 Mybatis 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释(Mybatis源码分析 GitHub 地址.Mybatis-Spring 源码分析 GitHub ...
- 源码解析之 Mybatis 对 Integer 参数做了什么手脚?
title: 源码解析之 Mybatis 对 Integer 参数做了什么手脚? date: 2021-03-11 updated: 2021-03-11 categories: Mybatis 源码 ...
- 【原】Android热更新开源项目Tinker源码解析系列之三:so热更新
本系列将从以下三个方面对Tinker进行源码解析: Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Android热更新开源项目Tinker源码解析系列之二:资源文件热更新 A ...
- C# ini文件操作【源码下载】
介绍C#如何对ini文件进行读写操作,C#可以通过调用[kernel32.dll]文件中的 WritePrivateProfileString()和GetPrivateProfileString()函 ...
- 【原】FMDB源码阅读(三)
[原]FMDB源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 FMDB比较优秀的地方就在于对多线程的处理.所以这一篇主要是研究FMDB的多线程处理的实现.而 ...
- 从源码看Azkaban作业流下发过程
上一篇零散地罗列了看源码时记录的一些类的信息,这篇完整介绍一个作业流在Azkaban中的执行过程,希望可以帮助刚刚接手Azkaban相关工作的开发.测试. 一.Azkaban简介 Azkaban作为开 ...
- 【原】Android热更新开源项目Tinker源码解析系列之一:Dex热更新
[原]Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Tinker是微信的第一个开源项目,主要用于安卓应用bug的热修复和功能的迭代. Tinker github地址:http ...
随机推荐
- Python 随笔之Redis
Python学习记录 ——redis 2018-03-07 Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API.从 ...
- Aizu 0033 Ball(dfs,贪心)
日文题面...题意:是把一连串的有编号的球往左或者往右边放.问能不能两边都升序. 记录左边和右边最上面的球编号大小,没有就-1,dfs往能放的上面放. #include<bits/stdc++. ...
- Android(java)学习笔记74:ListViewProject案例(ListView + ArrayAdapter)
1. 首先是MainActivity.java文件,如下: package com.himi.lv1; import java.util.ArrayList; import java.util.Lis ...
- 【洛谷2152】[SDOI2009] SuperGCD(Python好题)
点此看题面 大致题意: 给你两个长度\(\le10000\)的正整数,让你求它们的\(gcd\). Python 高精请绕道. 这题的正解应该是Python. 对于这种高精题,肯定是Python最方 ...
- Java统计用户年/月/周/日网站访问量
一:准备工作,引入相关依赖: 二:运行效果图: 下一次访问 三:具体代码如下 (1):CountObjectInfo.java package cn.csrc.base.count; import ...
- CUDA:Supercomputing for the Masses (用于大量数据的超级计算)-第五节
原文链接 第五节:了解和使用共享内存(2) Rob Farber 是西北太平洋国家实验室(Pacific Northwest National Laboratory)的高级科研人员.他在多个国家级的实 ...
- SpringBoot学习记录(一)
一.SpringBoot入门 1.SpringBoot简介 简化Spring应用开发的一个框架:整个Spring技术栈的一个大整合:J2EE开发的一站式解决方案: SpringBoot的优点: (1) ...
- ASP.NET 与 Ajax 的实现方式
Ajax 应该不是一项技术,是一种思想而已,跟 ASP.NET 以及其它 Web 开发语言没有什么太大关系,这里只是谈谈 ASP.NET 中目前使用的 Ajax 技术以及其它一些实现 Ajax 的优秀 ...
- 从指定的view中截图 返回UIImage
-(UIImage *)getImageFromView:(UIView *)view{ UIGraphicsBeginImageContext(view.bounds.size); [view.la ...
- 更改zabbix-server的端口
1.前言zabbix-server的默认端口号是10051.如果存在端口号冲突,需要更改端口号. 以下为更改端口号的步骤. 2.更改配置文件 通常用安装包,也就是yum方式部署的话,其默认的配置文件是 ...