blob: 1805aac4589480a96e8b51e3798dd5b768ed363c [file] [log] [blame]
/*
* Copyright 2000-2014 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 org.eclipse.osbp.runtime.web.vaadin.common.data;
import java.util.Collection;
// TODO: Auto-generated Javadoc
/**
* 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>
* 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>
* 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>
* It is not possible to add additional properties to the container.
*
*
* @param <BEANTYPE>
* The type of the Bean
*
* @since 5.4
*/
@SuppressWarnings("serial")
public class DeepResolvingBeanItemContainer<BEANTYPE> extends
AbstractDeepResolvingBeanContainer<BEANTYPE, BEANTYPE> {
/**
* Bean identity resolver that returns the bean itself as its item
* identifier.
*
* This corresponds to the old behavior of
* {@link DeepResolvingBeanItemContainer}, and requires suitable
* (identity-based) equals() and hashCode() methods on the beans.
*
* @param <BT>
* the generic type
* @since 6.5
*/
private static class IdentityBeanIdResolver<BT> implements
BeanIdResolver<BT, BT> {
/* (non-Javadoc)
* @see org.eclipse.osbp.runtime.web.vaadin.common.data.AbstractDeepResolvingBeanContainer.BeanIdResolver#getIdForBean(java.lang.Object)
*/
@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 DeepResolvingBeanItemContainer(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 DeepResolvingBeanItemContainer#DeepResolvingBeanItemContainer(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 #DeepResolvingBeanItemContainer(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 As of 6.5, use
* {@link #DeepResolvingBeanItemContainer(Class, Collection)}
* instead
*/
@SuppressWarnings("unchecked")
@Deprecated
public DeepResolvingBeanItemContainer(
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>
* the generic type
* @param collection
* the collection
* @return the bean class for collection
* @throws IllegalArgumentException
* the illegal argument exception
*/
@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 DeepResolvingBeanItemContainer(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)
* @return the deep resolving bean item
* @throws IllegalArgumentException
* the illegal argument exception
* @see com.vaadin.data.Container.Ordered#addItemAfter(Object, Object)
*/
@Override
@SuppressWarnings("unchecked")
public DeepResolvingBeanItem<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 DeepResolvingBeanItem or null if the operation
* fails.
* @throws IllegalArgumentException
* the illegal argument exception
*/
@Override
@SuppressWarnings("unchecked")
public DeepResolvingBeanItem<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.
*
* @param itemId
* the item id
* @return the deep resolving bean item
* @see com.vaadin.data.Container#addItem(Object)
*/
@Override
@SuppressWarnings("unchecked")
public DeepResolvingBeanItem<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.
*
* @param bean
* the bean
* @return the deep resolving bean item
* @see com.vaadin.data.Container#addItem(Object)
*/
@Override
public DeepResolvingBeanItem<BEANTYPE> addBean(BEANTYPE bean) {
return addItem(bean);
}
/**
* Unsupported in BeanItemContainer.
*
* @param beanIdResolver
* the bean id resolver
* @throws UnsupportedOperationException
* the unsupported operation exception
*/
@Override
protected void setBeanIdResolver(
AbstractDeepResolvingBeanContainer.BeanIdResolver<BEANTYPE, BEANTYPE> beanIdResolver)
throws UnsupportedOperationException {
throw new UnsupportedOperationException(
"BeanItemContainer always uses an IdentityBeanIdResolver");
}
/* (non-Javadoc)
* @see org.eclipse.osbp.runtime.web.vaadin.common.data.ILazyRefreshFilterable#refreshFilters()
*/
@Override
public void refreshFilters() {
// not used in this scenario since container applies filter immediately
}
}