Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
wang2java
Spring Framework
提交
4aab3153
S
Spring Framework
项目概览
wang2java
/
Spring Framework
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
S
Spring Framework
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
4aab3153
编写于
10月 26, 2013
作者:
J
Juergen Hoeller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
ExpressionState.getConfiguration() should never return null
Issue: SPR-11031
上级
08517667
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
69 addition
and
72 deletion
+69
-72
spring-expression/src/main/java/org/springframework/expression/spel/ExpressionState.java
.../org/springframework/expression/spel/ExpressionState.java
+27
-30
spring-expression/src/main/java/org/springframework/expression/spel/SpelParserConfiguration.java
...ingframework/expression/spel/SpelParserConfiguration.java
+1
-2
spring-expression/src/main/java/org/springframework/expression/spel/ast/PropertyOrFieldReference.java
...amework/expression/spel/ast/PropertyOrFieldReference.java
+41
-40
未找到文件。
spring-expression/src/main/java/org/springframework/expression/spel/ExpressionState.java
浏览文件 @
4aab3153
...
...
@@ -30,6 +30,7 @@ import org.springframework.expression.PropertyAccessor;
import
org.springframework.expression.TypeComparator
;
import
org.springframework.expression.TypeConverter
;
import
org.springframework.expression.TypedValue
;
import
org.springframework.util.Assert
;
/**
* An ExpressionState is for maintaining per-expression-evaluation state, any changes to
...
...
@@ -49,35 +50,33 @@ public class ExpressionState {
private
final
EvaluationContext
relatedContext
;
private
Stack
<
VariableScope
>
variableScopes
;
private
final
TypedValue
rootObject
;
private
Stack
<
TypedValue
>
contextObjects
;
private
final
SpelParserConfiguration
configuration
;
private
final
TypedValue
rootObject
;
private
Stack
<
VariableScope
>
variableScopes
;
private
S
pelParserConfiguration
configuration
;
private
S
tack
<
TypedValue
>
contextObjects
;
public
ExpressionState
(
EvaluationContext
context
)
{
this
.
relatedContext
=
context
;
this
.
rootObject
=
context
.
getRootObject
();
this
(
context
,
context
.
getRootObject
(),
new
SpelParserConfiguration
(
false
,
false
));
}
public
ExpressionState
(
EvaluationContext
context
,
SpelParserConfiguration
configuration
)
{
this
.
relatedContext
=
context
;
this
.
configuration
=
configuration
;
this
.
rootObject
=
context
.
getRootObject
();
this
(
context
,
context
.
getRootObject
(),
configuration
);
}
public
ExpressionState
(
EvaluationContext
context
,
TypedValue
rootObject
)
{
this
.
relatedContext
=
context
;
this
.
rootObject
=
rootObject
;
this
(
context
,
rootObject
,
new
SpelParserConfiguration
(
false
,
false
));
}
public
ExpressionState
(
EvaluationContext
context
,
TypedValue
rootObject
,
SpelParserConfiguration
configuration
)
{
Assert
.
notNull
(
context
,
"EvaluationContext must not be null"
);
Assert
.
notNull
(
configuration
,
"SpelParserConfiguration must not be null"
);
this
.
relatedContext
=
context
;
this
.
configuration
=
configuration
;
this
.
rootObject
=
rootObject
;
this
.
configuration
=
configuration
;
}
...
...
@@ -93,23 +92,22 @@ public class ExpressionState {
* The active context object is what unqualified references to properties/etc are resolved against.
*/
public
TypedValue
getActiveContextObject
()
{
if
(
this
.
contextObjects
==
null
||
this
.
contextObjects
.
isEmpty
())
{
if
(
this
.
contextObjects
==
null
||
this
.
contextObjects
.
isEmpty
())
{
return
this
.
rootObject
;
}
return
this
.
contextObjects
.
peek
();
}
public
void
pushActiveContextObject
(
TypedValue
obj
)
{
if
(
this
.
contextObjects
==
null
)
{
this
.
contextObjects
=
new
Stack
<
TypedValue
>();
if
(
this
.
contextObjects
==
null
)
{
this
.
contextObjects
=
new
Stack
<
TypedValue
>();
}
this
.
contextObjects
.
push
(
obj
);
}
public
void
popActiveContextObject
()
{
if
(
this
.
contextObjects
==
null
)
{
this
.
contextObjects
=
new
Stack
<
TypedValue
>();
if
(
this
.
contextObjects
==
null
)
{
this
.
contextObjects
=
new
Stack
<
TypedValue
>();
}
this
.
contextObjects
.
pop
();
}
...
...
@@ -151,14 +149,12 @@ public class ExpressionState {
public
Object
convertValue
(
TypedValue
value
,
TypeDescriptor
targetTypeDescriptor
)
throws
EvaluationException
{
Object
val
=
value
.
getValue
();
return
this
.
relatedContext
.
getTypeConverter
().
convertValue
(
val
,
TypeDescriptor
.
forObject
(
val
),
targetTypeDescriptor
);
return
this
.
relatedContext
.
getTypeConverter
().
convertValue
(
val
,
TypeDescriptor
.
forObject
(
val
),
targetTypeDescriptor
);
}
/*
* A new scope is entered when a function is invoked
* A new scope is entered when a function is invoked
.
*/
public
void
enterScope
(
Map
<
String
,
Object
>
argMap
)
{
ensureVariableScopesInitialized
();
this
.
variableScopes
.
push
(
new
VariableScope
(
argMap
));
...
...
@@ -197,8 +193,8 @@ public class ExpressionState {
return
new
TypedValue
(
returnValue
);
}
else
{
String
leftType
=
(
left
==
null
?
"null"
:
left
.
getClass
().
getName
());
String
rightType
=
(
right
==
null
?
"null"
:
right
.
getClass
().
getName
());
String
leftType
=
(
left
==
null
?
"null"
:
left
.
getClass
().
getName
());
String
rightType
=
(
right
==
null
?
"null"
:
right
.
getClass
().
getName
());
throw
new
SpelEvaluationException
(
SpelMessage
.
OPERATOR_NOT_SUPPORTED_BETWEEN_TYPES
,
op
,
leftType
,
rightType
);
}
}
...
...
@@ -217,16 +213,18 @@ public class ExpressionState {
/**
* A new scope is entered when a function is called and it is used to hold the parameters to the function call. If the names
* of the parameters clash with those in a higher level scope, those in the higher level scope will not be accessible whilst
* the function is executing. When the function returns the scope is exited.
* A new scope is entered when a function is called and it is used to hold the
* parameters to the function call. If the names of the parameters clash with
* those in a higher level scope, those in the higher level scope will not be
* accessible whilst the function is executing. When the function returns,
* the scope is exited.
*/
private
static
class
VariableScope
{
private
final
Map
<
String
,
Object
>
vars
=
new
HashMap
<
String
,
Object
>();
public
VariableScope
()
{
}
public
VariableScope
()
{
}
public
VariableScope
(
Map
<
String
,
Object
>
arguments
)
{
if
(
arguments
!=
null
)
{
...
...
@@ -238,7 +236,6 @@ public class ExpressionState {
this
.
vars
.
put
(
name
,
value
);
}
public
Object
lookupVariable
(
String
name
)
{
return
this
.
vars
.
get
(
name
);
}
...
...
spring-expression/src/main/java/org/springframework/expression/spel/SpelParserConfiguration.java
浏览文件 @
4aab3153
...
...
@@ -49,8 +49,7 @@ public class SpelParserConfiguration {
* @param autoGrowCollections if collections should automatically grow
* @param maximumAutoGrowSize the maximum size that the collection can auto grow
*/
public
SpelParserConfiguration
(
boolean
autoGrowNullReferences
,
boolean
autoGrowCollections
,
int
maximumAutoGrowSize
)
{
public
SpelParserConfiguration
(
boolean
autoGrowNullReferences
,
boolean
autoGrowCollections
,
int
maximumAutoGrowSize
)
{
this
.
autoGrowNullReferences
=
autoGrowNullReferences
;
this
.
autoGrowCollections
=
autoGrowCollections
;
this
.
maximumAutoGrowSize
=
maximumAutoGrowSize
;
...
...
spring-expression/src/main/java/org/springframework/expression/spel/ast/PropertyOrFieldReference.java
浏览文件 @
4aab3153
...
...
@@ -67,50 +67,20 @@ public class PropertyOrFieldReference extends SpelNodeImpl {
}
static
class
AccessorLValue
implements
ValueRef
{
private
final
PropertyOrFieldReference
ref
;
private
final
TypedValue
contextObject
;
private
final
EvaluationContext
eContext
;
private
final
boolean
isAutoGrowNullReferences
;
public
AccessorLValue
(
PropertyOrFieldReference
propertyOrFieldReference
,
TypedValue
activeContextObject
,
EvaluationContext
evaluationContext
,
boolean
isAutoGrowNullReferences
)
{
this
.
ref
=
propertyOrFieldReference
;
this
.
contextObject
=
activeContextObject
;
this
.
eContext
=
evaluationContext
;
this
.
isAutoGrowNullReferences
=
isAutoGrowNullReferences
;
}
@Override
public
TypedValue
getValue
()
{
return
this
.
ref
.
getValueInternal
(
this
.
contextObject
,
this
.
eContext
,
this
.
isAutoGrowNullReferences
);
}
@Override
public
void
setValue
(
Object
newValue
)
{
this
.
ref
.
writeProperty
(
this
.
contextObject
,
this
.
eContext
,
this
.
ref
.
name
,
newValue
);
}
@Override
public
boolean
isWritable
()
{
return
true
;
}
}
@Override
public
ValueRef
getValueRef
(
ExpressionState
state
)
throws
EvaluationException
{
return
new
AccessorLValue
(
this
,
state
.
getActiveContextObject
(),
state
.
getEvaluationContext
(),
state
.
getConfiguration
().
isAutoGrowNullReferences
());
return
new
AccessorLValue
(
this
,
state
.
getActiveContextObject
(),
state
.
getEvaluationContext
(),
state
.
getConfiguration
().
isAutoGrowNullReferences
());
}
@Override
public
TypedValue
getValueInternal
(
ExpressionState
state
)
throws
EvaluationException
{
return
getValueInternal
(
state
.
getActiveContextObject
(),
state
.
getEvaluationContext
(),
state
.
getConfiguration
().
isAutoGrowNullReferences
());
return
getValueInternal
(
state
.
getActiveContextObject
(),
state
.
getEvaluationContext
(),
state
.
getConfiguration
().
isAutoGrowNullReferences
());
}
private
TypedValue
getValueInternal
(
TypedValue
contextObject
,
EvaluationContext
eContext
,
boolean
isAutoGrowNullReferences
)
throws
EvaluationException
{
private
TypedValue
getValueInternal
(
TypedValue
contextObject
,
EvaluationContext
eContext
,
boolean
isAutoGrowNullReferences
)
throws
EvaluationException
{
TypedValue
result
=
readProperty
(
contextObject
,
eContext
,
this
.
name
);
...
...
@@ -195,14 +165,11 @@ public class PropertyOrFieldReference extends SpelNodeImpl {
/**
* Attempt to read the named property from the current context object.
* @param state the evaluation state
* @param name the name of the property
* @return the value of the property
* @throws SpelEvaluationException if any problem accessing the property or it cannot be found
*/
private
TypedValue
readProperty
(
TypedValue
contextObject
,
EvaluationContext
eContext
,
String
name
)
throws
EvaluationException
{
Object
targetObject
=
contextObject
.
getValue
();
if
(
targetObject
==
null
&&
this
.
nullSafe
)
{
return
TypedValue
.
NULL
;
}
...
...
@@ -252,7 +219,6 @@ public class PropertyOrFieldReference extends SpelNodeImpl {
}
private
void
writeProperty
(
TypedValue
contextObject
,
EvaluationContext
eContext
,
String
name
,
Object
newValue
)
throws
SpelEvaluationException
{
if
(
contextObject
.
getValue
()
==
null
&&
this
.
nullSafe
)
{
return
;
}
...
...
@@ -356,4 +322,39 @@ public class PropertyOrFieldReference extends SpelNodeImpl {
return
resolvers
;
}
private
static
class
AccessorLValue
implements
ValueRef
{
private
final
PropertyOrFieldReference
ref
;
private
final
TypedValue
contextObject
;
private
final
EvaluationContext
eContext
;
private
final
boolean
autoGrowNullReferences
;
public
AccessorLValue
(
PropertyOrFieldReference
propertyOrFieldReference
,
TypedValue
activeContextObject
,
EvaluationContext
evaluationContext
,
boolean
autoGrowNullReferences
)
{
this
.
ref
=
propertyOrFieldReference
;
this
.
contextObject
=
activeContextObject
;
this
.
eContext
=
evaluationContext
;
this
.
autoGrowNullReferences
=
autoGrowNullReferences
;
}
@Override
public
TypedValue
getValue
()
{
return
this
.
ref
.
getValueInternal
(
this
.
contextObject
,
this
.
eContext
,
this
.
autoGrowNullReferences
);
}
@Override
public
void
setValue
(
Object
newValue
)
{
this
.
ref
.
writeProperty
(
this
.
contextObject
,
this
.
eContext
,
this
.
ref
.
name
,
newValue
);
}
@Override
public
boolean
isWritable
()
{
return
true
;
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录