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.从 ...
- Codeforces Round #327 (Div. 2) B Rebranding(映射)
O(1)变换映射,最后一次性替换. #include<bits/stdc++.h> using namespace std; typedef long long ll; ; char s[ ...
- POJ-1149 PIGS---最大流+建图
题目链接: https://vjudge.net/problem/POJ-1149 题目大意: M个猪圈,N个顾客,每个顾客有一些的猪圈的钥匙,只能购买这些有钥匙的猪圈里的猪,而且要买一定数量的猪,每 ...
- Go - 环境安装
目录 你好,Go语言 环境安装 目录结构 命令 开发工具 学习网址 小结 你好,Go语言 Go 是一个开源的编程语言,它能让构造简单.可靠且高效的软件变得容易. 因工作需要,准备入坑,先从环境安装开始 ...
- 在PHP中读取二进制文件
很多时候,数据并不是用文本的方式保存的,这就需要将二进制数据读取出来,还原成我们需要的格式.PHP在二进制处理方面也提供了强大的支持. 任务 下面以读取并分析一个PNG图像的文件头为例,讲解如何使用P ...
- Bootstrap 历练实例-轮播(carousel)插件方法
方法 下面是一些轮播(Carousel)插件中有用的方法: 方法 描述 实例 .carousel(options) 初始化轮播为可选的 options 对象,并开始循环项目. $('#identifi ...
- 【SQL】连接 —— 内连接、外连接、左连接、右连接、交叉连接
连接 · 内连接 · 外连接 · 左连接 · 右连接 · 全连接 · 交叉连接 · 匹配符号(+) 连接 根据表之间的关系,呈现跨表查询的结果. 外连接 内连接 左连接 右连接 全 ...
- 【前端_js】解决ajax跨域请求数据
1.ajax发送请求必须遵循同源策略,即请求方和相应方的协议头.域名.端口全部一样.只要三者有一个不一样都视为跨域,浏览器出于安全考虑不允许跨域访问. 解决ajax跨域访问的常用方法: a.使用jso ...
- 【前端_js】ajax的应用
1.设置请求头部 function makeRequest() { alert("inside makeRequest()"); var settings = { type: &q ...
- python变量声明及简单数据类型
一.python声明变量 变量的命名和使用 # 在Python中使用变量时,需要遵守一些规则和指南. # 违反这些规则将引发错误,而指南旨在让你编写的代码更容易阅读和理解.请务必牢记下述有关变量的规则 ...