You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

BeanItemContainer.java 7.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. /*
  2. @VaadinApache2LicenseForJavaFiles@
  3. */
  4. package com.vaadin.data.util;
  5. import java.util.Collection;
  6. /**
  7. * An in-memory container for JavaBeans.
  8. *
  9. * <p>
  10. * The properties of the container are determined automatically by introspecting
  11. * the used JavaBean class. Only beans of the same type can be added to the
  12. * container.
  13. * </p>
  14. *
  15. * <p>
  16. * BeanItemContainer uses the beans themselves as identifiers. The
  17. * {@link Object#hashCode()} of a bean is used when storing and looking up beans
  18. * so it must not change during the lifetime of the bean (it should not depend
  19. * on any part of the bean that can be modified). Typically this restricts the
  20. * implementation of {@link Object#equals(Object)} as well in order for it to
  21. * fulfill the contract between {@code equals()} and {@code hashCode()}.
  22. * </p>
  23. *
  24. * <p>
  25. * To add items to the container, use the methods {@link #addBean(Object)},
  26. * {@link #addBeanAfter(Object, Object)} and {@link #addBeanAt(int, Object)}.
  27. * Also {@link #addItem(Object)}, {@link #addItemAfter(Object, Object)} and
  28. * {@link #addItemAt(int, Object)} can be used as synonyms for them.
  29. * </p>
  30. *
  31. * <p>
  32. * It is not possible to add additional properties to the container and nested
  33. * bean properties are not supported.
  34. * </p>
  35. *
  36. * @param <BEANTYPE>
  37. * The type of the Bean
  38. *
  39. * @since 5.4
  40. */
  41. @SuppressWarnings("serial")
  42. public class BeanItemContainer<BEANTYPE> extends
  43. AbstractBeanContainer<BEANTYPE, BEANTYPE> {
  44. /**
  45. * Bean identity resolver that returns the bean itself as its item
  46. * identifier.
  47. *
  48. * This corresponds to the old behavior of {@link BeanItemContainer}, and
  49. * requires suitable (identity-based) equals() and hashCode() methods on the
  50. * beans.
  51. *
  52. * @param <BT>
  53. *
  54. * @since 6.5
  55. */
  56. private static class IdentityBeanIdResolver<BT> implements
  57. BeanIdResolver<BT, BT> {
  58. public BT getIdForBean(BT bean) {
  59. return bean;
  60. }
  61. }
  62. /**
  63. * Constructs a {@code BeanItemContainer} for beans of the given type.
  64. *
  65. * @param type
  66. * the type of the beans that will be added to the container.
  67. * @throws IllegalArgumentException
  68. * If {@code type} is null
  69. */
  70. public BeanItemContainer(Class<? super BEANTYPE> type)
  71. throws IllegalArgumentException {
  72. super(type);
  73. super.setBeanIdResolver(new IdentityBeanIdResolver<BEANTYPE>());
  74. }
  75. /**
  76. * Constructs a {@code BeanItemContainer} and adds the given beans to it.
  77. * The collection must not be empty.
  78. * {@link BeanItemContainer#BeanItemContainer(Class)} can be used for
  79. * creating an initially empty {@code BeanItemContainer}.
  80. *
  81. * Note that when using this constructor, the actual class of the first item
  82. * in the collection is used to determine the bean properties supported by
  83. * the container instance, and only beans of that class or its subclasses
  84. * can be added to the collection. If this is problematic or empty
  85. * collections need to be supported, use {@link #BeanItemContainer(Class)}
  86. * and {@link #addAll(Collection)} instead.
  87. *
  88. * @param collection
  89. * a non empty {@link Collection} of beans.
  90. * @throws IllegalArgumentException
  91. * If the collection is null or empty.
  92. *
  93. * @deprecated use {@link #BeanItemContainer(Class, Collection)} instead
  94. */
  95. @SuppressWarnings("unchecked")
  96. @Deprecated
  97. public BeanItemContainer(Collection<? extends BEANTYPE> collection)
  98. throws IllegalArgumentException {
  99. // must assume the class is BT
  100. // the class information is erased by the compiler
  101. this((Class<BEANTYPE>) getBeanClassForCollection(collection),
  102. collection);
  103. }
  104. /**
  105. * Internal helper method to support the deprecated {@link Collection}
  106. * container.
  107. *
  108. * @param <BT>
  109. * @param collection
  110. * @return
  111. * @throws IllegalArgumentException
  112. */
  113. @SuppressWarnings("unchecked")
  114. @Deprecated
  115. private static <BT> Class<? extends BT> getBeanClassForCollection(
  116. Collection<? extends BT> collection)
  117. throws IllegalArgumentException {
  118. if (collection == null || collection.isEmpty()) {
  119. throw new IllegalArgumentException(
  120. "The collection passed to BeanItemContainer constructor must not be null or empty. Use the other BeanItemContainer constructor.");
  121. }
  122. return (Class<? extends BT>) collection.iterator().next().getClass();
  123. }
  124. /**
  125. * Constructs a {@code BeanItemContainer} and adds the given beans to it.
  126. *
  127. * @param type
  128. * the type of the beans that will be added to the container.
  129. * @param collection
  130. * a {@link Collection} of beans (can be empty or null).
  131. * @throws IllegalArgumentException
  132. * If {@code type} is null
  133. */
  134. public BeanItemContainer(Class<? super BEANTYPE> type,
  135. Collection<? extends BEANTYPE> collection)
  136. throws IllegalArgumentException {
  137. super(type);
  138. super.setBeanIdResolver(new IdentityBeanIdResolver<BEANTYPE>());
  139. if (collection != null) {
  140. addAll(collection);
  141. }
  142. }
  143. /**
  144. * Adds all the beans from a {@link Collection} in one go. More efficient
  145. * than adding them one by one.
  146. *
  147. * @param collection
  148. * The collection of beans to add. Must not be null.
  149. */
  150. @Override
  151. public void addAll(Collection<? extends BEANTYPE> collection) {
  152. super.addAll(collection);
  153. }
  154. /**
  155. * Adds the bean after the given bean.
  156. *
  157. * The bean is used both as the item contents and as the item identifier.
  158. *
  159. * @param previousItemId
  160. * the bean (of type BT) after which to add newItemId
  161. * @param newItemId
  162. * the bean (of type BT) to add (not null)
  163. *
  164. * @see com.vaadin.data.Container.Ordered#addItemAfter(Object, Object)
  165. */
  166. @Override
  167. @SuppressWarnings("unchecked")
  168. public BeanItem<BEANTYPE> addItemAfter(Object previousItemId,
  169. Object newItemId) throws IllegalArgumentException {
  170. return super.addBeanAfter((BEANTYPE) previousItemId,
  171. (BEANTYPE) newItemId);
  172. }
  173. /**
  174. * Adds a new bean at the given index.
  175. *
  176. * The bean is used both as the item contents and as the item identifier.
  177. *
  178. * @param index
  179. * Index at which the bean should be added.
  180. * @param newItemId
  181. * The bean to add to the container.
  182. * @return Returns the new BeanItem or null if the operation fails.
  183. */
  184. @Override
  185. @SuppressWarnings("unchecked")
  186. public BeanItem<BEANTYPE> addItemAt(int index, Object newItemId)
  187. throws IllegalArgumentException {
  188. return super.addBeanAt(index, (BEANTYPE) newItemId);
  189. }
  190. /**
  191. * Adds the bean to the Container.
  192. *
  193. * The bean is used both as the item contents and as the item identifier.
  194. *
  195. * @see com.vaadin.data.Container#addItem(Object)
  196. */
  197. @Override
  198. @SuppressWarnings("unchecked")
  199. public BeanItem<BEANTYPE> addItem(Object itemId) {
  200. return super.addBean((BEANTYPE) itemId);
  201. }
  202. /**
  203. * Adds the bean to the Container.
  204. *
  205. * The bean is used both as the item contents and as the item identifier.
  206. *
  207. * @see com.vaadin.data.Container#addItem(Object)
  208. */
  209. @Override
  210. public BeanItem<BEANTYPE> addBean(BEANTYPE bean) {
  211. return addItem(bean);
  212. }
  213. /**
  214. * Unsupported in BeanItemContainer.
  215. */
  216. @Override
  217. protected void setBeanIdResolver(
  218. AbstractBeanContainer.BeanIdResolver<BEANTYPE, BEANTYPE> beanIdResolver)
  219. throws UnsupportedOperationException {
  220. throw new UnsupportedOperationException(
  221. "BeanItemContainer always uses an IdentityBeanIdResolver");
  222. }
  223. }