From 461448b37291541cfc6ae9246d382e4dcba651e8 Mon Sep 17 00:00:00 2001 From: Henri Sara Date: Wed, 1 Dec 2010 15:14:18 +0000 Subject: [PATCH] #6074 bean property based item id resolver for BeanContainer svn changeset:16256/svn branch:6.5 --- .../data/util/AbstractBeanContainer.java | 70 +++++++++++++++++++ src/com/vaadin/data/util/BeanContainer.java | 14 +++- .../server/container/BeanContainerTest.java | 22 ++++++ 3 files changed, 104 insertions(+), 2 deletions(-) diff --git a/src/com/vaadin/data/util/AbstractBeanContainer.java b/src/com/vaadin/data/util/AbstractBeanContainer.java index 4708af2a08..499f8593fa 100644 --- a/src/com/vaadin/data/util/AbstractBeanContainer.java +++ b/src/com/vaadin/data/util/AbstractBeanContainer.java @@ -6,6 +6,8 @@ package com.vaadin.data.util; import java.beans.PropertyDescriptor; import java.io.IOException; import java.io.Serializable; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -84,6 +86,62 @@ public abstract class AbstractBeanContainer implements Indexed, public IDTYPE getIdForBean(BT bean); } + /** + * A item identifier resolver that returns the value of a bean property. + * + * The bean must have a getter for the property, and the getter must return + * an object of type IDTYPE. + */ + protected class PropertyBasedBeanIdResolver implements + BeanIdResolver { + + private final Object propertyId; + private transient Method getMethod; + + public PropertyBasedBeanIdResolver(Object propertyId) { + if (propertyId == null) { + throw new IllegalArgumentException( + "Property identifier must not be null"); + } + this.propertyId = propertyId; + if (getGetter() == null) { + throw new IllegalArgumentException( + "Missing accessor for property " + propertyId); + } + } + + private Method getGetter() { + if (getMethod == null) { + try { + String propertyName = propertyId.toString(); + if (Character.isLowerCase(propertyName.charAt(0))) { + final char[] buf = propertyName.toCharArray(); + buf[0] = Character.toUpperCase(buf[0]); + propertyName = new String(buf); + } + + getMethod = getBeanType().getMethod("get" + propertyName, + new Class[] {}); + } catch (NoSuchMethodException ignored) { + throw new IllegalArgumentException(); + } + } + return getMethod; + } + + @SuppressWarnings("unchecked") + public IDTYPE getIdForBean(BT bean) throws IllegalArgumentException { + try { + return (IDTYPE) getGetter().invoke(bean); + } catch (IllegalAccessException e) { + throw new IllegalArgumentException(e); + } catch (InvocationTargetException e) { + throw new IllegalArgumentException(e); + } + } + + } + /** * The resolver that finds the item ID for a bean, or null not to use * automatic resolving. @@ -1020,4 +1078,16 @@ public abstract class AbstractBeanContainer implements Indexed, return beanIdResolver; } + /** + * Create an item identifier resolver using a named bean property. + * + * @param propertyId + * property identifier, which must map to a getter in BT + * @return created resolver + */ + protected BeanIdResolver createBeanPropertyResolver( + Object propertyId) { + return new PropertyBasedBeanIdResolver(propertyId); + } + } diff --git a/src/com/vaadin/data/util/BeanContainer.java b/src/com/vaadin/data/util/BeanContainer.java index 911e696229..dbfc197674 100644 --- a/src/com/vaadin/data/util/BeanContainer.java +++ b/src/com/vaadin/data/util/BeanContainer.java @@ -117,9 +117,19 @@ public class BeanContainer extends // automatic item id resolution + /** + * Sets the bean id resolver to use a property of the beans as the + * identifier. + * + * @param propertyId + * the identifier of the property to use to find item identifiers + */ + public void setBeanIdProperty(Object propertyId) { + setIdResolver(createBeanPropertyResolver(propertyId)); + } + @Override - public void setIdResolver( - com.vaadin.data.util.AbstractBeanContainer.BeanIdResolver beanIdResolver) { + public void setIdResolver(BeanIdResolver beanIdResolver) { super.setIdResolver(beanIdResolver); } diff --git a/tests/src/com/vaadin/tests/server/container/BeanContainerTest.java b/tests/src/com/vaadin/tests/server/container/BeanContainerTest.java index c683e4f598..c8ca3cae2a 100644 --- a/tests/src/com/vaadin/tests/server/container/BeanContainerTest.java +++ b/tests/src/com/vaadin/tests/server/container/BeanContainerTest.java @@ -377,4 +377,26 @@ public class BeanContainerTest extends AbstractBeanContainerTest { assertEquals(0, container.size()); } + public void testAddBeanWithPropertyResolver() { + BeanContainer container = new BeanContainer( + Person.class); + container.setBeanIdProperty("name"); + + assertNotNull(container.addBean(new Person("John"))); + assertNotNull(container.addBeanAfter(null, new Person("Jane"))); + assertNotNull(container.addBeanAt(0, new Person("Jack"))); + + container.addAll(Arrays.asList(new Person[] { new Person("Jill"), + new Person("Joe") })); + + assertTrue(container.containsId("John")); + assertTrue(container.containsId("Jane")); + assertTrue(container.containsId("Jack")); + assertTrue(container.containsId("Jill")); + assertTrue(container.containsId("Joe")); + assertEquals(3, container.indexOfId("Jill")); + assertEquals(4, container.indexOfId("Joe")); + assertEquals(5, container.size()); + } + } -- 2.39.5