#708806 : added field access option to QBean

This commit is contained in:
Timo Westkämper 2011-01-27 18:43:55 +00:00
parent d644aff0c0
commit 8aeff005ed
2 changed files with 113 additions and 14 deletions

View File

@ -62,28 +62,76 @@ public class QBean<T> extends ExpressionBase<T> implements FactoryExpression<T>{
private final Map<String, ? extends Expression<?>> bindings;
private final Map<String, Field> fields = new HashMap<String, Field>();
private final List<Expression<?>> args;
private final boolean fieldAccess;
@SuppressWarnings("unchecked")
public QBean(Path<T> type, Expression<?>... args) {
this((Class)type.getType(), args);
this((Class)type.getType(), false, args);
}
@SuppressWarnings("unchecked")
public QBean(Path<T> type, Map<String, ? extends Expression<?>> bindings) {
this((Class)type.getType(), bindings);
this((Class)type.getType(), false, bindings);
}
@SuppressWarnings("unchecked")
public QBean(Path<T> type, boolean fieldAccess, Expression<?>... args) {
this((Class)type.getType(), fieldAccess, args);
}
@SuppressWarnings("unchecked")
public QBean(Path<T> type, boolean fieldAccess, Map<String, ? extends Expression<?>> bindings) {
this((Class)type.getType(), fieldAccess, bindings);
}
public QBean(Class<T> type, Map<String, ? extends Expression<?>> bindings) {
super(type);
this.args = new ArrayList<Expression<?>>(bindings.values());
this.bindings = bindings;
this(type, false, bindings);
}
public QBean(Class<T> type, Expression<?>... args) {
this(type, false, args);
}
public QBean(Class<T> type, boolean fieldAccess, Map<String, ? extends Expression<?>> bindings) {
super(type);
this.args = new ArrayList<Expression<?>>(bindings.values());
this.bindings = bindings;
this.fieldAccess = fieldAccess;
if (fieldAccess){
initFields();
}
}
public QBean(Class<T> type, boolean fieldAccess, Expression<?>... args) {
super(type);
this.args = Arrays.asList(args);
bindings = createBindings(args);
this.bindings = createBindings(args);
this.fieldAccess = fieldAccess;
if (fieldAccess){
initFields();
}
}
private void initFields() {
for (String property : bindings.keySet()){
Class<?> beanType = type;
while (!beanType.equals(Object.class)){
try {
Field field = type.getDeclaredField(property);
field.setAccessible(true);
fields.put(property, field);
beanType = Object.class;
} catch (SecurityException e) {
// do nothing
} catch (NoSuchFieldException e) {
beanType = beanType.getSuperclass();
}
}
}
}
private Map<String,Expression<?>> createBindings(Expression<?>... args) {
@ -120,13 +168,22 @@ public class QBean<T> extends ExpressionBase<T> implements FactoryExpression<T>{
public T newInstance(Object... args){
try {
T rv = getType().newInstance();
BeanMap beanMap = new BeanMap(rv);
for (Map.Entry<String, ? extends Expression<?>> entry : bindings.entrySet()){
Object value = args[this.args.indexOf(entry.getValue())];
if (value != null){
beanMap.put(entry.getKey(), value);
}
}
if (fieldAccess){
for (Map.Entry<String, ? extends Expression<?>> entry : bindings.entrySet()){
Object value = args[this.args.indexOf(entry.getValue())];
if (value != null){
fields.get(entry.getKey()).set(rv, value);
}
}
}else{
BeanMap beanMap = new BeanMap(rv);
for (Map.Entry<String, ? extends Expression<?>> entry : bindings.entrySet()){
Object value = args[this.args.indexOf(entry.getValue())];
if (value != null){
beanMap.put(entry.getKey(), value);
}
}
}
return rv;
} catch (InstantiationException e) {
throw new ExpressionException(e.getMessage(),e);

View File

@ -93,6 +93,15 @@ public class QBeanTest {
assertEquals(30, bean.getAge());
assertEquals(true, bean.isMarried());
}
@Test
public void with_Class_and_Exprs_using_fields(){
QBean<Entity> beanProjection = new QBean<Entity>(Entity.class, true, name, age, married);
Entity bean = beanProjection.newInstance("Fritz", 30, true);
assertEquals("Fritz", bean.getName());
assertEquals(30, bean.getAge());
assertEquals(true, bean.isMarried());
}
@Test
public void with_Path_and_Exprs(){
@ -103,6 +112,15 @@ public class QBeanTest {
assertEquals(true, bean.isMarried());
}
@Test
public void with_Path_and_Exprs_using_fields(){
QBean<Entity> beanProjection = new QBean<Entity>(entity, true, name, age, married);
Entity bean = beanProjection.newInstance("Fritz", 30, true);
assertEquals("Fritz", bean.getName());
assertEquals(30, bean.getAge());
assertEquals(true, bean.isMarried());
}
@Test
public void with_Class_and_Map(){
Map<String,Expression<?>> bindings = new LinkedHashMap<String,Expression<?>>();
@ -116,6 +134,19 @@ public class QBeanTest {
assertEquals(true, bean.isMarried());
}
@Test
public void with_Class_and_Map_using_fields(){
Map<String,Expression<?>> bindings = new LinkedHashMap<String,Expression<?>>();
bindings.put("name", name);
bindings.put("age", age);
bindings.put("married", married);
QBean<Entity> beanProjection = new QBean<Entity>(Entity.class, true, bindings);
Entity bean = beanProjection.newInstance("Fritz", 30, true);
assertEquals("Fritz", bean.getName());
assertEquals(30, bean.getAge());
assertEquals(true, bean.isMarried());
}
@Test
public void with_Class_and_Alias(){
StringPath name2 = new StringPath("name2");
@ -126,4 +157,15 @@ public class QBeanTest {
assertEquals(30, bean.getAge());
assertEquals(true, bean.isMarried());
}
@Test
public void with_Class_and_Alias_using_fields(){
StringPath name2 = new StringPath("name2");
QBean<Entity> beanProjection = new QBean<Entity>(Entity.class, true, name.as(name2), age, married);
Entity bean = beanProjection.newInstance("Fritz", 30, true);
assertNull(bean.getName());
assertEquals("Fritz", bean.getName2());
assertEquals(30, bean.getAge());
assertEquals(true, bean.isMarried());
}
}