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;
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<IDTYPE, BT> {
+
+ 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.
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<IDTYPE, BT> createBeanPropertyResolver(
+ Object propertyId) {
+ return new PropertyBasedBeanIdResolver(propertyId);
+ }
+
}
// 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<IDTYPE, BT> beanIdResolver) {
+ public void setIdResolver(BeanIdResolver<IDTYPE, BT> beanIdResolver) {
super.setIdResolver(beanIdResolver);
}
assertEquals(0, container.size());
}
+ public void testAddBeanWithPropertyResolver() {
+ BeanContainer<String, Person> container = new BeanContainer<String, Person>(
+ 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());
+ }
+
}