Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
爱吃血肠
spring-framework
提交
470e0861
S
spring-framework
项目概览
爱吃血肠
/
spring-framework
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
S
spring-framework
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
470e0861
编写于
9月 17, 2008
作者:
A
Andy Clement
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
map access tests added
上级
769e706b
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
142 addition
and
32 deletion
+142
-32
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/PropertyOrFieldReference.java
...amework/expression/spel/ast/PropertyOrFieldReference.java
+28
-22
org.springframework.expression/src/test/java/org/springframework/expression/spel/AllTests.java
...st/java/org/springframework/expression/spel/AllTests.java
+1
-0
org.springframework.expression/src/test/java/org/springframework/expression/spel/EvaluationTests.java
.../org/springframework/expression/spel/EvaluationTests.java
+1
-1
org.springframework.expression/src/test/java/org/springframework/expression/spel/MapAccessTests.java
...a/org/springframework/expression/spel/MapAccessTests.java
+89
-0
org.springframework.expression/src/test/java/org/springframework/expression/spel/testresources/Inventor.java
...ringframework/expression/spel/testresources/Inventor.java
+23
-9
未找到文件。
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/PropertyOrFieldReference.java
浏览文件 @
470e0861
...
...
@@ -25,9 +25,9 @@ import org.springframework.expression.EvaluationContext;
import
org.springframework.expression.PropertyAccessor
;
import
org.springframework.expression.PropertyReaderExecutor
;
import
org.springframework.expression.PropertyWriterExecutor
;
import
org.springframework.expression.spel.ExpressionState
;
import
org.springframework.expression.spel.SpelException
;
import
org.springframework.expression.spel.SpelMessages
;
import
org.springframework.expression.spel.ExpressionState
;
import
org.springframework.expression.spel.internal.Utils
;
/**
...
...
@@ -68,9 +68,9 @@ public class PropertyOrFieldReference extends SpelNode {
return
name
.
toString
();
}
/**
/**
* 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
...
...
@@ -88,19 +88,20 @@ public class PropertyOrFieldReference extends SpelNode {
// let's try to get a new one and call it before giving up
}
}
Class
<?>
contextObjectClass
=
getObjectClass
(
contextObject
);
List
<
PropertyAccessor
>
accessorsToTry
=
getPropertyAccessorsToTry
(
contextObjectClass
,
state
);
// Go through the accessors that may be able to resolve it.
If they are a cacheable accessor then
// get the accessor and use it.
If they are not cacheable but report they can read the property
// Go through the accessors that may be able to resolve it. If they are a cacheable accessor then
// get the accessor and use it. If they are not cacheable but report they can read the property
// then ask them to read it
if
(
accessorsToTry
!=
null
)
{
try
{
for
(
PropertyAccessor
accessor
:
accessorsToTry
)
{
if
(
accessor
instanceof
CacheablePropertyAccessor
)
{
cachedReaderExecutor
=
((
CacheablePropertyAccessor
)
accessor
).
getReaderAccessor
(
eContext
,
contextObject
,
name
);
cachedReaderExecutor
=
((
CacheablePropertyAccessor
)
accessor
).
getReaderAccessor
(
eContext
,
contextObject
,
name
);
if
(
cachedReaderExecutor
!=
null
)
{
try
{
return
cachedReaderExecutor
.
execute
(
state
.
getEvaluationContext
(),
contextObject
);
...
...
@@ -124,14 +125,14 @@ public class PropertyOrFieldReference extends SpelNode {
throw
new
SpelException
(
ae
,
SpelMessages
.
EXCEPTION_DURING_PROPERTY_READ
,
name
,
ae
.
getMessage
());
}
}
throw
new
SpelException
(
SpelMessages
.
PROPERTY_OR_FIELD_NOT_FOUND
,
name
,
Utils
.
formatClassnameForMessage
(
contextObjectClass
));
throw
new
SpelException
(
SpelMessages
.
PROPERTY_OR_FIELD_NOT_FOUND
,
name
,
Utils
.
formatClassnameForMessage
(
contextObjectClass
));
}
private
void
writeProperty
(
ExpressionState
state
,
Object
name
,
Object
newValue
)
throws
SpelException
{
Object
contextObject
=
state
.
getActiveContextObject
();
EvaluationContext
eContext
=
state
.
getEvaluationContext
();
if
(
cachedWriterExecutor
!=
null
)
{
try
{
cachedWriterExecutor
.
execute
(
state
.
getEvaluationContext
(),
contextObject
,
newValue
);
...
...
@@ -149,7 +150,8 @@ public class PropertyOrFieldReference extends SpelNode {
try
{
for
(
PropertyAccessor
accessor
:
accessorsToTry
)
{
if
(
accessor
instanceof
CacheablePropertyAccessor
)
{
cachedWriterExecutor
=
((
CacheablePropertyAccessor
)
accessor
).
getWriterAccessor
(
eContext
,
contextObject
,
name
);
cachedWriterExecutor
=
((
CacheablePropertyAccessor
)
accessor
).
getWriterAccessor
(
eContext
,
contextObject
,
name
);
if
(
cachedWriterExecutor
!=
null
)
{
try
{
cachedWriterExecutor
.
execute
(
state
.
getEvaluationContext
(),
contextObject
,
newValue
);
...
...
@@ -171,7 +173,8 @@ public class PropertyOrFieldReference extends SpelNode {
}
}
}
catch
(
AccessException
ae
)
{
throw
new
SpelException
(
getCharPositionInLine
(),
ae
,
SpelMessages
.
EXCEPTION_DURING_PROPERTY_WRITE
,
name
,
ae
.
getMessage
());
throw
new
SpelException
(
getCharPositionInLine
(),
ae
,
SpelMessages
.
EXCEPTION_DURING_PROPERTY_WRITE
,
name
,
ae
.
getMessage
());
}
}
throw
new
SpelException
(
SpelMessages
.
PROPERTY_OR_FIELD_SETTER_NOT_FOUND
,
name
,
Utils
...
...
@@ -204,8 +207,8 @@ public class PropertyOrFieldReference extends SpelNode {
* Determines the set of property resolvers that should be used to try and access a property on the specified target
* type. The resolvers are considered to be in an ordered list, however in the returned list any that are exact
* matches for the input target type (as opposed to 'general' resolvers that could work for any type) are placed at
* the start of the list.
In addition, there are specific resolvers that exactly name the class in question and
* resolvers that name a specific class but it is a supertype of the class we have.
These are put at the end of the
* the start of the list. In addition, there are specific resolvers that exactly name the class in question and
* resolvers that name a specific class but it is a supertype of the class we have. These are put at the end of the
* specific resolvers set and will be tried after exactly matching accessors but before generic accessors.
*
* @param targetType the type upon which property access is being attempted
...
...
@@ -219,13 +222,16 @@ public class PropertyOrFieldReference extends SpelNode {
if
(
targets
==
null
)
{
// generic resolver that says it can be used for any type
generalAccessors
.
add
(
resolver
);
}
else
{
int
pos
=
0
;
for
(
int
i
=
0
;
i
<
targets
.
length
;
i
++)
{
Class
<?>
clazz
=
targets
[
i
];
if
(
clazz
==
targetType
)
{
// put exact matches on the front to be tried first?
specificAccessors
.
add
(
pos
++,
resolver
);
}
else
if
(
clazz
.
isAssignableFrom
(
targetType
))
{
// put supertype matches at the end of the specificAccessor list
generalAccessors
.
add
(
resolver
);
if
(
targetType
!=
null
)
{
int
pos
=
0
;
for
(
int
i
=
0
;
i
<
targets
.
length
;
i
++)
{
Class
<?>
clazz
=
targets
[
i
];
if
(
clazz
==
targetType
)
{
// put exact matches on the front to be tried first?
specificAccessors
.
add
(
pos
++,
resolver
);
}
else
if
(
clazz
.
isAssignableFrom
(
targetType
))
{
// put supertype matches at the end of the
// specificAccessor list
generalAccessors
.
add
(
resolver
);
}
}
}
}
...
...
org.springframework.expression/src/test/java/org/springframework/expression/spel/AllTests.java
浏览文件 @
470e0861
...
...
@@ -48,6 +48,7 @@ public class AllTests {
suite
.
addTestSuite
(
TemplateExpressionParsingTests
.
class
);
suite
.
addTestSuite
(
ExpressionLanguageScenarioTests
.
class
);
suite
.
addTestSuite
(
ScenariosForSpringSecurity
.
class
);
suite
.
addTestSuite
(
MapAccessTests
.
class
);
suite
.
addTestSuite
(
SpelUtilitiesTests
.
class
);
suite
.
addTestSuite
(
LiteralExpressionTests
.
class
);
suite
.
addTestSuite
(
CompositeStringExpressionTests
.
class
);
...
...
org.springframework.expression/src/test/java/org/springframework/expression/spel/EvaluationTests.java
浏览文件 @
470e0861
...
...
@@ -15,7 +15,6 @@
*/
package
org.springframework.expression.spel
;
/**
* Tests the evaluation of real expressions in a real context.
*
...
...
@@ -457,4 +456,5 @@ public class EvaluationTests extends ExpressionTestCase {
evaluateAndAskForReturnType
(
"3*4+5"
,
(
short
)
17
,
Short
.
class
);
evaluateAndAskForReturnType
(
"3*4+5"
,
"17"
,
String
.
class
);
}
}
org.springframework.expression/src/test/java/org/springframework/expression/spel/MapAccessTests.java
0 → 100644
浏览文件 @
470e0861
/*
* Copyright 2004-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org.springframework.expression.spel
;
import
java.util.Map
;
import
org.springframework.expression.AccessException
;
import
org.springframework.expression.EvaluationContext
;
import
org.springframework.expression.Expression
;
import
org.springframework.expression.PropertyAccessor
;
import
org.springframework.expression.spel.standard.StandardEvaluationContext
;
/**
* Testing variations on map access.
*
* @author Andy Clement
*/
public
class
MapAccessTests
extends
ExpressionTestCase
{
static
class
MapAccessor
implements
PropertyAccessor
{
public
boolean
canRead
(
EvaluationContext
context
,
Object
target
,
Object
name
)
throws
AccessException
{
return
(((
Map
)
target
).
containsKey
(
name
));
}
public
Object
read
(
EvaluationContext
context
,
Object
target
,
Object
name
)
throws
AccessException
{
return
((
Map
)
target
).
get
(
name
);
}
public
boolean
canWrite
(
EvaluationContext
context
,
Object
target
,
Object
name
)
throws
AccessException
{
return
true
;
}
public
void
write
(
EvaluationContext
context
,
Object
target
,
Object
name
,
Object
newValue
)
throws
AccessException
{
((
Map
)
target
).
put
(
name
,
newValue
);
}
public
Class
<?>[]
getSpecificTargetClasses
()
{
return
new
Class
[]
{
Map
.
class
};
}
}
public
void
testSimpleMapAccess01
()
{
evaluate
(
"testMap.get('monday')"
,
"montag"
,
String
.
class
);
}
public
void
testMapAccessThroughIndexer
()
{
evaluate
(
"testMap['monday']"
,
"montag"
,
String
.
class
);
}
public
void
testCustomMapAccessor
()
throws
Exception
{
SpelExpressionParser
parser
=
new
SpelExpressionParser
();
StandardEvaluationContext
ctx
=
TestScenarioCreator
.
getTestEvaluationContext
();
ctx
.
addPropertyAccessor
(
new
MapAccessor
());
Expression
expr
=
parser
.
parseExpression
(
"testMap.monday"
);
Object
value
=
expr
.
getValue
(
ctx
,
String
.
class
);
assertEquals
(
"montag"
,
value
);
}
public
void
testVariableMapAccess
()
throws
Exception
{
SpelExpressionParser
parser
=
new
SpelExpressionParser
();
StandardEvaluationContext
ctx
=
TestScenarioCreator
.
getTestEvaluationContext
();
ctx
.
setVariable
(
"day"
,
"saturday"
);
Expression
expr
=
parser
.
parseExpression
(
"testMap[#day]"
);
Object
value
=
expr
.
getValue
(
ctx
,
String
.
class
);
assertEquals
(
"samstag"
,
value
);
}
// public void testMapAccess04() {
// evaluate("testMap[monday]", "montag", String.class);
// }
}
org.springframework.expression/src/test/java/org/springframework/expression/spel/testresources/Inventor.java
浏览文件 @
470e0861
package
org.springframework.expression.spel.testresources
;
import
java.util.Date
;
import
java.util.HashMap
;
import
java.util.Map
;
@SuppressWarnings
(
"unused"
)
public
class
Inventor
{
...
...
@@ -11,15 +13,24 @@ public class Inventor {
private
String
nationality
;
private
String
[]
inventions
;
public
String
randomField
;
public
Map
testMap
;
public
Inventor
(
String
name
,
Date
birthdate
,
String
nationality
)
{
this
.
name
=
name
;
this
.
birthdate
=
birthdate
;
this
.
nationality
=
nationality
;
testMap
=
new
HashMap
();
testMap
.
put
(
"monday"
,
"montag"
);
testMap
.
put
(
"tuesday"
,
"dienstag"
);
testMap
.
put
(
"wednesday"
,
"mittwoch"
);
testMap
.
put
(
"thursday"
,
"donnerstag"
);
testMap
.
put
(
"friday"
,
"freitag"
);
testMap
.
put
(
"saturday"
,
"samstag"
);
testMap
.
put
(
"sunday"
,
"sonntag"
);
}
public
void
setPlaceOfBirth
(
PlaceOfBirth
placeOfBirth2
)
{
this
.
placeOfBirth
=
placeOfBirth2
;
placeOfBirth
=
placeOfBirth2
;
}
public
void
setInventions
(
String
[]
inventions
)
{
...
...
@@ -45,17 +56,20 @@ public class Inventor {
public
String
joinThreeStrings
(
String
a
,
String
b
,
String
c
)
{
return
a
+
b
+
c
;
}
public
int
aVarargsMethod
(
String
...
strings
)
{
if
(
strings
==
null
)
return
0
;
public
int
aVarargsMethod
(
String
...
strings
)
{
if
(
strings
==
null
)
return
0
;
return
strings
.
length
;
}
public
int
aVarargsMethod2
(
int
i
,
String
...
strings
)
{
if
(
strings
==
null
)
return
i
;
return
strings
.
length
+
i
;
public
int
aVarargsMethod2
(
int
i
,
String
...
strings
)
{
if
(
strings
==
null
)
return
i
;
return
strings
.
length
+
i
;
}
public
Inventor
(
String
...
strings
)
{
public
Inventor
(
String
...
strings
)
{
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录