From 8aeff005ed7154d5913ddbea255d401a5c2bb29d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Westk=C3=A4mper?= Date: Thu, 27 Jan 2011 18:43:55 +0000 Subject: [PATCH] #708806 : added field access option to QBean --- .../java/com/mysema/query/types/QBean.java | 85 ++++++++++++++++--- .../com/mysema/query/types/QBeanTest.java | 42 +++++++++ 2 files changed, 113 insertions(+), 14 deletions(-) diff --git a/querydsl-core/src/main/java/com/mysema/query/types/QBean.java b/querydsl-core/src/main/java/com/mysema/query/types/QBean.java index 9dd5de6bb..d64fab6f6 100644 --- a/querydsl-core/src/main/java/com/mysema/query/types/QBean.java +++ b/querydsl-core/src/main/java/com/mysema/query/types/QBean.java @@ -62,28 +62,76 @@ public class QBean extends ExpressionBase implements FactoryExpression{ private final Map> bindings; + private final Map fields = new HashMap(); + private final List> args; + private final boolean fieldAccess; + @SuppressWarnings("unchecked") public QBean(Path type, Expression... args) { - this((Class)type.getType(), args); + this((Class)type.getType(), false, args); } @SuppressWarnings("unchecked") public QBean(Path type, Map> bindings) { - this((Class)type.getType(), bindings); + this((Class)type.getType(), false, bindings); } - + + @SuppressWarnings("unchecked") + public QBean(Path type, boolean fieldAccess, Expression... args) { + this((Class)type.getType(), fieldAccess, args); + } + + @SuppressWarnings("unchecked") + public QBean(Path type, boolean fieldAccess, Map> bindings) { + this((Class)type.getType(), fieldAccess, bindings); + } + public QBean(Class type, Map> bindings) { - super(type); - this.args = new ArrayList>(bindings.values()); - this.bindings = bindings; + this(type, false, bindings); } public QBean(Class type, Expression... args) { + this(type, false, args); + } + + public QBean(Class type, boolean fieldAccess, Map> bindings) { + super(type); + this.args = new ArrayList>(bindings.values()); + this.bindings = bindings; + this.fieldAccess = fieldAccess; + if (fieldAccess){ + initFields(); + } + } + + public QBean(Class 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> createBindings(Expression... args) { @@ -120,13 +168,22 @@ public class QBean extends ExpressionBase implements FactoryExpression{ public T newInstance(Object... args){ try { T rv = getType().newInstance(); - BeanMap beanMap = new BeanMap(rv); - for (Map.Entry> entry : bindings.entrySet()){ - Object value = args[this.args.indexOf(entry.getValue())]; - if (value != null){ - beanMap.put(entry.getKey(), value); - } - } + if (fieldAccess){ + for (Map.Entry> 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> 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); diff --git a/querydsl-core/src/test/java/com/mysema/query/types/QBeanTest.java b/querydsl-core/src/test/java/com/mysema/query/types/QBeanTest.java index f6f8228ac..05afd712b 100644 --- a/querydsl-core/src/test/java/com/mysema/query/types/QBeanTest.java +++ b/querydsl-core/src/test/java/com/mysema/query/types/QBeanTest.java @@ -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 beanProjection = new QBean(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 beanProjection = new QBean(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> bindings = new LinkedHashMap>(); @@ -116,6 +134,19 @@ public class QBeanTest { assertEquals(true, bean.isMarried()); } + @Test + public void with_Class_and_Map_using_fields(){ + Map> bindings = new LinkedHashMap>(); + bindings.put("name", name); + bindings.put("age", age); + bindings.put("married", married); + QBean beanProjection = new QBean(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 beanProjection = new QBean(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()); + } }