diff options
Diffstat (limited to 'server/src/com/vaadin/data/util/BeanItemContainer.java')
-rw-r--r-- | server/src/com/vaadin/data/util/BeanItemContainer.java | 253 |
1 files changed, 253 insertions, 0 deletions
diff --git a/server/src/com/vaadin/data/util/BeanItemContainer.java b/server/src/com/vaadin/data/util/BeanItemContainer.java new file mode 100644 index 0000000000..3f3bf1de9d --- /dev/null +++ b/server/src/com/vaadin/data/util/BeanItemContainer.java @@ -0,0 +1,253 @@ +/* + * Copyright 2011 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.data.util; + +import java.util.Collection; + +/** + * An in-memory container for JavaBeans. + * + * <p> + * The properties of the container are determined automatically by introspecting + * the used JavaBean class. Only beans of the same type can be added to the + * container. + * </p> + * + * <p> + * BeanItemContainer uses the beans themselves as identifiers. The + * {@link Object#hashCode()} of a bean is used when storing and looking up beans + * so it must not change during the lifetime of the bean (it should not depend + * on any part of the bean that can be modified). Typically this restricts the + * implementation of {@link Object#equals(Object)} as well in order for it to + * fulfill the contract between {@code equals()} and {@code hashCode()}. + * </p> + * + * <p> + * To add items to the container, use the methods {@link #addBean(Object)}, + * {@link #addBeanAfter(Object, Object)} and {@link #addBeanAt(int, Object)}. + * Also {@link #addItem(Object)}, {@link #addItemAfter(Object, Object)} and + * {@link #addItemAt(int, Object)} can be used as synonyms for them. + * </p> + * + * <p> + * It is not possible to add additional properties to the container and nested + * bean properties are not supported. + * </p> + * + * @param <BEANTYPE> + * The type of the Bean + * + * @since 5.4 + */ +@SuppressWarnings("serial") +public class BeanItemContainer<BEANTYPE> extends + AbstractBeanContainer<BEANTYPE, BEANTYPE> { + + /** + * Bean identity resolver that returns the bean itself as its item + * identifier. + * + * This corresponds to the old behavior of {@link BeanItemContainer}, and + * requires suitable (identity-based) equals() and hashCode() methods on the + * beans. + * + * @param <BT> + * + * @since 6.5 + */ + private static class IdentityBeanIdResolver<BT> implements + BeanIdResolver<BT, BT> { + + @Override + public BT getIdForBean(BT bean) { + return bean; + } + + } + + /** + * Constructs a {@code BeanItemContainer} for beans of the given type. + * + * @param type + * the type of the beans that will be added to the container. + * @throws IllegalArgumentException + * If {@code type} is null + */ + public BeanItemContainer(Class<? super BEANTYPE> type) + throws IllegalArgumentException { + super(type); + super.setBeanIdResolver(new IdentityBeanIdResolver<BEANTYPE>()); + } + + /** + * Constructs a {@code BeanItemContainer} and adds the given beans to it. + * The collection must not be empty. + * {@link BeanItemContainer#BeanItemContainer(Class)} can be used for + * creating an initially empty {@code BeanItemContainer}. + * + * Note that when using this constructor, the actual class of the first item + * in the collection is used to determine the bean properties supported by + * the container instance, and only beans of that class or its subclasses + * can be added to the collection. If this is problematic or empty + * collections need to be supported, use {@link #BeanItemContainer(Class)} + * and {@link #addAll(Collection)} instead. + * + * @param collection + * a non empty {@link Collection} of beans. + * @throws IllegalArgumentException + * If the collection is null or empty. + * + * @deprecated use {@link #BeanItemContainer(Class, Collection)} instead + */ + @SuppressWarnings("unchecked") + @Deprecated + public BeanItemContainer(Collection<? extends BEANTYPE> collection) + throws IllegalArgumentException { + // must assume the class is BT + // the class information is erased by the compiler + this((Class<BEANTYPE>) getBeanClassForCollection(collection), + collection); + } + + /** + * Internal helper method to support the deprecated {@link Collection} + * container. + * + * @param <BT> + * @param collection + * @return + * @throws IllegalArgumentException + */ + @SuppressWarnings("unchecked") + @Deprecated + private static <BT> Class<? extends BT> getBeanClassForCollection( + Collection<? extends BT> collection) + throws IllegalArgumentException { + if (collection == null || collection.isEmpty()) { + throw new IllegalArgumentException( + "The collection passed to BeanItemContainer constructor must not be null or empty. Use the other BeanItemContainer constructor."); + } + return (Class<? extends BT>) collection.iterator().next().getClass(); + } + + /** + * Constructs a {@code BeanItemContainer} and adds the given beans to it. + * + * @param type + * the type of the beans that will be added to the container. + * @param collection + * a {@link Collection} of beans (can be empty or null). + * @throws IllegalArgumentException + * If {@code type} is null + */ + public BeanItemContainer(Class<? super BEANTYPE> type, + Collection<? extends BEANTYPE> collection) + throws IllegalArgumentException { + super(type); + super.setBeanIdResolver(new IdentityBeanIdResolver<BEANTYPE>()); + + if (collection != null) { + addAll(collection); + } + } + + /** + * Adds all the beans from a {@link Collection} in one go. More efficient + * than adding them one by one. + * + * @param collection + * The collection of beans to add. Must not be null. + */ + @Override + public void addAll(Collection<? extends BEANTYPE> collection) { + super.addAll(collection); + } + + /** + * Adds the bean after the given bean. + * + * The bean is used both as the item contents and as the item identifier. + * + * @param previousItemId + * the bean (of type BT) after which to add newItemId + * @param newItemId + * the bean (of type BT) to add (not null) + * + * @see com.vaadin.data.Container.Ordered#addItemAfter(Object, Object) + */ + @Override + @SuppressWarnings("unchecked") + public BeanItem<BEANTYPE> addItemAfter(Object previousItemId, + Object newItemId) throws IllegalArgumentException { + return super.addBeanAfter((BEANTYPE) previousItemId, + (BEANTYPE) newItemId); + } + + /** + * Adds a new bean at the given index. + * + * The bean is used both as the item contents and as the item identifier. + * + * @param index + * Index at which the bean should be added. + * @param newItemId + * The bean to add to the container. + * @return Returns the new BeanItem or null if the operation fails. + */ + @Override + @SuppressWarnings("unchecked") + public BeanItem<BEANTYPE> addItemAt(int index, Object newItemId) + throws IllegalArgumentException { + return super.addBeanAt(index, (BEANTYPE) newItemId); + } + + /** + * Adds the bean to the Container. + * + * The bean is used both as the item contents and as the item identifier. + * + * @see com.vaadin.data.Container#addItem(Object) + */ + @Override + @SuppressWarnings("unchecked") + public BeanItem<BEANTYPE> addItem(Object itemId) { + return super.addBean((BEANTYPE) itemId); + } + + /** + * Adds the bean to the Container. + * + * The bean is used both as the item contents and as the item identifier. + * + * @see com.vaadin.data.Container#addItem(Object) + */ + @Override + public BeanItem<BEANTYPE> addBean(BEANTYPE bean) { + return addItem(bean); + } + + /** + * Unsupported in BeanItemContainer. + */ + @Override + protected void setBeanIdResolver( + AbstractBeanContainer.BeanIdResolver<BEANTYPE, BEANTYPE> beanIdResolver) + throws UnsupportedOperationException { + throw new UnsupportedOperationException( + "BeanItemContainer always uses an IdentityBeanIdResolver"); + } + +} |