Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
爱吃血肠
spring-framework
提交
0783a1c6
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 搜索 >>
提交
0783a1c6
编写于
7月 15, 2015
作者:
J
Juergen Hoeller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
SpEL selection/projection works with Iterable as well
Issue: SPR-13231
上级
ea2a1d33
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
108 addition
and
35 deletion
+108
-35
spring-expression/src/main/java/org/springframework/expression/spel/ast/Projection.java
...a/org/springframework/expression/spel/ast/Projection.java
+8
-5
spring-expression/src/main/java/org/springframework/expression/spel/ast/Selection.java
...va/org/springframework/expression/spel/ast/Selection.java
+14
-12
spring-expression/src/test/java/org/springframework/expression/spel/SelectionAndProjectionTests.java
...ramework/expression/spel/SelectionAndProjectionTests.java
+86
-18
未找到文件。
spring-expression/src/main/java/org/springframework/expression/spel/ast/Projection.java
浏览文件 @
0783a1c6
...
...
@@ -19,7 +19,6 @@ package org.springframework.expression.spel.ast;
import
java.lang.reflect.Array
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Collection
;
import
java.util.List
;
import
java.util.Map
;
...
...
@@ -38,6 +37,7 @@ import org.springframework.util.ObjectUtils;
*
* @author Andy Clement
* @author Mark Fisher
* @author Juergen Hoeller
* @since 3.0
*/
public
class
Projection
extends
SpelNodeImpl
{
...
...
@@ -86,9 +86,10 @@ public class Projection extends SpelNodeImpl {
return
new
ValueRef
.
TypedValueHolderValueRef
(
new
TypedValue
(
result
),
this
);
// TODO unable to build correct type descriptor
}
if
(
operand
instanceof
Collection
||
operandIsArray
)
{
Collection
<?>
data
=
(
operand
instanceof
Collection
?
(
Collection
<?>)
operand
:
Arrays
.
asList
(
ObjectUtils
.
toObjectArray
(
operand
)));
if
(
operand
instanceof
Iterable
||
operandIsArray
)
{
Iterable
<?>
data
=
(
operand
instanceof
Iterable
?
(
Iterable
<?>)
operand
:
Arrays
.
asList
(
ObjectUtils
.
toObjectArray
(
operand
)));
List
<
Object
>
result
=
new
ArrayList
<
Object
>();
int
idx
=
0
;
Class
<?>
arrayElementType
=
null
;
...
...
@@ -108,6 +109,7 @@ public class Projection extends SpelNodeImpl {
}
idx
++;
}
if
(
operandIsArray
)
{
if
(
arrayElementType
==
null
)
{
arrayElementType
=
Object
.
class
;
...
...
@@ -116,10 +118,11 @@ public class Projection extends SpelNodeImpl {
System
.
arraycopy
(
result
.
toArray
(),
0
,
resultArray
,
0
,
result
.
size
());
return
new
ValueRef
.
TypedValueHolderValueRef
(
new
TypedValue
(
resultArray
),
this
);
}
return
new
ValueRef
.
TypedValueHolderValueRef
(
new
TypedValue
(
result
),
this
);
}
if
(
operand
==
null
)
{
if
(
operand
==
null
)
{
if
(
this
.
nullSafe
)
{
return
ValueRef
.
NullValueRef
.
INSTANCE
;
}
...
...
spring-expression/src/main/java/org/springframework/expression/spel/ast/Selection.java
浏览文件 @
0783a1c6
...
...
@@ -19,7 +19,6 @@ package org.springframework.expression.spel.ast;
import
java.lang.reflect.Array
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Collection
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
...
...
@@ -43,6 +42,7 @@ import org.springframework.util.ObjectUtils;
* @author Andy Clement
* @author Mark Fisher
* @author Sam Brannen
* @author Juergen Hoeller
* @since 3.0
*/
public
class
Selection
extends
SpelNodeImpl
{
...
...
@@ -75,13 +75,14 @@ public class Selection extends SpelNodeImpl {
protected
ValueRef
getValueRef
(
ExpressionState
state
)
throws
EvaluationException
{
TypedValue
op
=
state
.
getActiveContextObject
();
Object
operand
=
op
.
getValue
();
SpelNodeImpl
selectionCriteria
=
this
.
children
[
0
];
if
(
operand
instanceof
Map
)
{
Map
<?,
?>
mapdata
=
(
Map
<?,
?>)
operand
;
// TODO don't lose generic info for the new map
Map
<
Object
,
Object
>
result
=
new
HashMap
<
Object
,
Object
>();
Object
lastKey
=
null
;
for
(
Map
.
Entry
<?,
?>
entry
:
mapdata
.
entrySet
())
{
try
{
TypedValue
kvPair
=
new
TypedValue
(
entry
);
...
...
@@ -108,6 +109,7 @@ public class Selection extends SpelNodeImpl {
state
.
exitScope
();
}
}
if
((
this
.
variant
==
FIRST
||
this
.
variant
==
LAST
)
&&
result
.
isEmpty
())
{
return
new
ValueRef
.
TypedValueHolderValueRef
(
new
TypedValue
(
null
),
this
);
}
...
...
@@ -122,11 +124,10 @@ public class Selection extends SpelNodeImpl {
return
new
ValueRef
.
TypedValueHolderValueRef
(
new
TypedValue
(
result
),
this
);
}
if
((
operand
instanceof
Collection
)
||
ObjectUtils
.
isArray
(
operand
))
{
List
<
Object
>
data
=
new
ArrayList
<
Object
>();
Collection
<?>
coll
=
(
operand
instanceof
Collection
?
(
Collection
<?>)
operand
:
Arrays
.
asList
(
ObjectUtils
.
toObjectArray
(
operand
)));
data
.
addAll
(
coll
);
if
(
operand
instanceof
Iterable
||
ObjectUtils
.
isArray
(
operand
))
{
Iterable
<?>
data
=
(
operand
instanceof
Iterable
?
(
Iterable
<?>)
operand
:
Arrays
.
asList
(
ObjectUtils
.
toObjectArray
(
operand
)));
List
<
Object
>
result
=
new
ArrayList
<
Object
>();
int
index
=
0
;
for
(
Object
element
:
data
)
{
...
...
@@ -154,22 +155,23 @@ public class Selection extends SpelNodeImpl {
}
}
if
((
this
.
variant
==
FIRST
||
this
.
variant
==
LAST
)
&&
result
.
size
()
==
0
)
{
if
((
this
.
variant
==
FIRST
||
this
.
variant
==
LAST
)
&&
result
.
isEmpty
()
)
{
return
ValueRef
.
NullValueRef
.
INSTANCE
;
}
if
(
this
.
variant
==
LAST
)
{
return
new
ValueRef
.
TypedValueHolderValueRef
(
new
TypedValue
(
result
.
get
(
result
.
size
()
-
1
)),
this
);
return
new
ValueRef
.
TypedValueHolderValueRef
(
new
TypedValue
(
result
.
get
(
result
.
size
()
-
1
)),
this
);
}
if
(
operand
instanceof
Collection
)
{
return
new
ValueRef
.
TypedValueHolderValueRef
(
new
TypedValue
(
result
),
this
);
if
(
operand
instanceof
Iterable
)
{
return
new
ValueRef
.
TypedValueHolderValueRef
(
new
TypedValue
(
result
),
this
);
}
Class
<?>
elementType
=
ClassUtils
.
resolvePrimitiveIfNecessary
(
op
.
getTypeDescriptor
().
getElementTypeDescriptor
().
getType
());
Object
resultArray
=
Array
.
newInstance
(
elementType
,
result
.
size
());
System
.
arraycopy
(
result
.
toArray
(),
0
,
resultArray
,
0
,
result
.
size
());
return
new
ValueRef
.
TypedValueHolderValueRef
(
new
TypedValue
(
resultArray
),
this
);
return
new
ValueRef
.
TypedValueHolderValueRef
(
new
TypedValue
(
resultArray
),
this
);
}
if
(
operand
==
null
)
{
if
(
this
.
nullSafe
)
{
...
...
spring-expression/src/test/java/org/springframework/expression/spel/SelectionAndProjectionTests.java
浏览文件 @
0783a1c6
/*
* Copyright 2002-201
4
the original author or authors.
* Copyright 2002-201
5
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.
...
...
@@ -17,6 +17,7 @@
package
org.springframework.expression.spel
;
import
java.util.ArrayList
;
import
java.util.Iterator
;
import
java.util.LinkedHashSet
;
import
java.util.List
;
import
java.util.Map
;
...
...
@@ -37,6 +38,7 @@ import static org.junit.Assert.*;
/**
* @author Mark Fisher
* @author Sam Brannen
* @author Juergen Hoeller
*/
public
class
SelectionAndProjectionTests
{
...
...
@@ -106,6 +108,21 @@ public class SelectionAndProjectionTests {
assertEquals
(
4
,
value
);
}
@Test
public
void
selectionWithIterable
()
throws
Exception
{
Expression
expression
=
new
SpelExpressionParser
().
parseRaw
(
"integers.?[#this<5]"
);
EvaluationContext
context
=
new
StandardEvaluationContext
(
new
IterableTestBean
());
Object
value
=
expression
.
getValue
(
context
);
assertTrue
(
value
instanceof
List
);
List
<?>
list
=
(
List
<?>)
value
;
assertEquals
(
5
,
list
.
size
());
assertEquals
(
0
,
list
.
get
(
0
));
assertEquals
(
1
,
list
.
get
(
1
));
assertEquals
(
2
,
list
.
get
(
2
));
assertEquals
(
3
,
list
.
get
(
3
));
assertEquals
(
4
,
list
.
get
(
4
));
}
@Test
public
void
selectionWithArray
()
throws
Exception
{
Expression
expression
=
new
SpelExpressionParser
().
parseRaw
(
"integers.?[#this<5]"
);
...
...
@@ -242,6 +259,20 @@ public class SelectionAndProjectionTests {
assertEquals
(
7
,
list
.
get
(
2
));
}
@Test
public
void
projectionWithIterable
()
throws
Exception
{
Expression
expression
=
new
SpelExpressionParser
().
parseRaw
(
"#testList.![wrapper.value]"
);
EvaluationContext
context
=
new
StandardEvaluationContext
();
context
.
setVariable
(
"testList"
,
IntegerTestBean
.
createIterable
());
Object
value
=
expression
.
getValue
(
context
);
assertTrue
(
value
instanceof
List
);
List
<?>
list
=
(
List
<?>)
value
;
assertEquals
(
3
,
list
.
size
());
assertEquals
(
5
,
list
.
get
(
0
));
assertEquals
(
6
,
list
.
get
(
1
));
assertEquals
(
7
,
list
.
get
(
2
));
}
@Test
public
void
projectionWithArray
()
throws
Exception
{
Expression
expression
=
new
SpelExpressionParser
().
parseRaw
(
"#testArray.![wrapper.value]"
);
...
...
@@ -258,23 +289,6 @@ public class SelectionAndProjectionTests {
assertEquals
(
new
Integer
(
7
),
array
[
2
]);
}
static
class
MapTestBean
{
private
final
Map
<
String
,
String
>
colors
=
new
TreeMap
<
String
,
String
>();
MapTestBean
()
{
// colors.put("black", "schwarz");
colors
.
put
(
"red"
,
"rot"
);
colors
.
put
(
"brown"
,
"braun"
);
colors
.
put
(
"blue"
,
"blau"
);
colors
.
put
(
"yellow"
,
"gelb"
);
colors
.
put
(
"beige"
,
"beige"
);
}
public
Map
<
String
,
String
>
getColors
()
{
return
colors
;
}
}
static
class
ListTestBean
{
...
...
@@ -291,6 +305,7 @@ public class SelectionAndProjectionTests {
}
}
static
class
SetTestBean
{
private
final
Set
<
Integer
>
integers
=
new
LinkedHashSet
<
Integer
>();
...
...
@@ -306,6 +321,28 @@ public class SelectionAndProjectionTests {
}
}
static
class
IterableTestBean
{
private
final
Set
<
Integer
>
integers
=
new
LinkedHashSet
<
Integer
>();
IterableTestBean
()
{
for
(
int
i
=
0
;
i
<
10
;
i
++)
{
integers
.
add
(
i
);
}
}
public
Iterable
<
Integer
>
getIntegers
()
{
return
new
Iterable
<
Integer
>()
{
@Override
public
Iterator
<
Integer
>
iterator
()
{
return
integers
.
iterator
();
}
};
}
}
static
class
ArrayTestBean
{
private
final
int
[]
ints
=
new
int
[
10
];
...
...
@@ -328,6 +365,26 @@ public class SelectionAndProjectionTests {
}
}
static
class
MapTestBean
{
private
final
Map
<
String
,
String
>
colors
=
new
TreeMap
<
String
,
String
>();
MapTestBean
()
{
// colors.put("black", "schwarz");
colors
.
put
(
"red"
,
"rot"
);
colors
.
put
(
"brown"
,
"braun"
);
colors
.
put
(
"blue"
,
"blau"
);
colors
.
put
(
"yellow"
,
"gelb"
);
colors
.
put
(
"beige"
,
"beige"
);
}
public
Map
<
String
,
String
>
getColors
()
{
return
colors
;
}
}
static
class
IntegerTestBean
{
private
final
IntegerWrapper
wrapper
;
...
...
@@ -356,6 +413,16 @@ public class SelectionAndProjectionTests {
return
set
;
}
static
Iterable
<
IntegerTestBean
>
createIterable
()
{
final
Set
<
IntegerTestBean
>
set
=
createSet
();
return
new
Iterable
<
IntegerTestBean
>()
{
@Override
public
Iterator
<
IntegerTestBean
>
iterator
()
{
return
set
.
iterator
();
}
};
}
static
IntegerTestBean
[]
createArray
()
{
IntegerTestBean
[]
array
=
new
IntegerTestBean
[
3
];
for
(
int
i
=
0
;
i
<
3
;
i
++)
{
...
...
@@ -369,6 +436,7 @@ public class SelectionAndProjectionTests {
}
}
static
class
IntegerWrapper
{
private
final
Number
value
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录