Class AbstractQueryContainer<T>
- java.lang.Object
-
- com.vaadin.data.util.AbstractContainer
-
- org.dellroad.stuff.vaadin7.AbstractQueryContainer<T>
-
- Type Parameters:
T- the type of the Java objects that back eachItemin the container
- All Implemented Interfaces:
Container,Container.Indexed,Container.ItemSetChangeNotifier,Container.Ordered,Container.PropertySetChangeNotifier,Serializable,Connectable,PropertyExtractor<T>
- Direct Known Subclasses:
AbstractUnsizedContainer
public abstract class AbstractQueryContainer<T> extends AbstractContainer implements PropertyExtractor<T>, Container.Ordered, Container.Indexed, Container.PropertySetChangeNotifier, Container.ItemSetChangeNotifier, Connectable
Support superclass for read-onlyContainerimplementations where eachItemin the container is backed by a Java object, and the Java objects are generated via a query that returns aQueryListcontaining only some portion of the total list of backing objects at any one time.This
Container'sPropertys are defined viaPropertyDefs, and aPropertyExtractoris used to actually extract the property values from each underlying object (alternately, subclasses can overridegetPropertyValue()). However, the easist way to configure the containerPropertys is to pass a@ProvidesProperty-annotated Java class to theAbstractQueryContainer(Class)constructor.This
Container's item ID's are simply the indexes of the corresponding objects in the overall list. TheQueryListinterface is designed for scalability; at minimum, it is required to provide only the size of the total list (which may only be an estimate) and one backing object at a specified index.This class will invoke
query(long)as needed to (re)generate theQueryList; theQueryListis then cached. However, if any invocation ofQueryList.get(long)throws anInvalidQueryListException, then the cached list is discarded andquery(long)is invoked again to regenerate it. In this way, theQueryListis allowed to decide, on demand, when it is invalid or incapable of providing a specific list member. For example, when using JPA, a list may be considered invalid if the current EntityManager session has changed.Note that the
QueryListbeing invalid is an orthogonal concept from the contents of the list having changed. Invalid means "this list can no longer be used" while changed means "this list contains out-of-date information". Normally, the latter implies the former (but not vice-versa). The list becoming invalid does not in itself not cause any notifications to be sent, so no new query will be performed until e.g. the user interface explicitly requests more information.Therefore, if the list size or content changes, first invoke
invalidate()to discard the cachedQueryList, and thenAbstractContainer.fireItemSetChange()to notify listeners; for convenience,reload()will perform these two steps for you. The new size and content will be provided by theQueryListreturned by the next invocation ofquery(long).The subclass may forcibly invalidate the current
QueryListviainvalidate(); this merely discards it and will force a new invocation ofquery(long)on the next container access. In many situations, however, the use ofinvalidate()is never required.For scalability reasons the
QueryListmay actually only contain a portion of the list, throwingInvalidQueryListExceptions when other list members are accessed. An "index hint" parameter provided toquery(long)indicates which member of the container is of current interest. The returnedQueryListis required to provide exception-free access only to the indicated member, so in the extreme case only a single list member could be kept. In practice, normally range of members near to the index hint would be kept; see for exampleWindowQueryList.
-
-
Nested Class Summary
-
Nested classes/interfaces inherited from class com.vaadin.data.util.AbstractContainer
AbstractContainer.BaseItemSetChangeEvent, AbstractContainer.BasePropertySetChangeEvent
-
Nested classes/interfaces inherited from interface com.vaadin.data.Container
Container.Editor, Container.Filter, Container.Filterable, Container.Hierarchical, Container.Indexed, Container.ItemSetChangeEvent, Container.ItemSetChangeListener, Container.ItemSetChangeNotifier, Container.Ordered, Container.PropertySetChangeEvent, Container.PropertySetChangeListener, Container.PropertySetChangeNotifier, Container.SimpleFilterable, Container.Sortable, Container.Viewer
-
Nested classes/interfaces inherited from interface com.vaadin.data.Container.Indexed
Container.Indexed.ItemAddEvent, Container.Indexed.ItemRemoveEvent
-
-
Constructor Summary
Constructors Modifier Constructor Description protectedAbstractQueryContainer()Constructor.protectedAbstractQueryContainer(Class<? super T> type)Constructor.protectedAbstractQueryContainer(Collection<? extends PropertyDef<?>> propertyDefs)Constructor.protectedAbstractQueryContainer(PropertyExtractor<? super T> propertyExtractor)Constructor.protectedAbstractQueryContainer(PropertyExtractor<? super T> propertyExtractor, Collection<? extends PropertyDef<?>> propertyDefs)Constructor.
-
Method Summary
All Methods Instance Methods Abstract Methods Concrete Methods Modifier and Type Method Description booleanaddContainerProperty(Object propertyId, Class<?> type, Object defaultValue)ItemaddItem()ItemaddItem(Object itemId)ItemaddItemAfter(Object previousItemId)ItemaddItemAfter(Object previousItemId, Object newItemId)ObjectaddItemAt(int index)ItemaddItemAt(int index, Object newItemId)voidaddItemSetChangeListener(Container.ItemSetChangeListener listener)voidaddListener(Container.ItemSetChangeListener listener)voidaddListener(Container.PropertySetChangeListener listener)voidaddPropertySetChangeListener(Container.PropertySetChangeListener listener)voidconnect()Connect this instance to non-Vaadin resources.booleancontainsId(Object itemId)protected BackedItem<T>createBackedItem(T object, Collection<PropertyDef<?>> propertyDefs, PropertyExtractor<? super T> propertyExtractor)Create aBackedItemfor the given backing Java object.voiddisconnect()Disconnect this instance from non-Vaadin resources.protected longensureList(int hint)Ensure we have a cached query list.IntegerfirstItemId()PropertygetContainerProperty(Object itemId, Object propertyId)Set<String>getContainerPropertyIds()IntegergetIdByIndex(int index)BackedItem<T>getItem(Object itemId)Collection<Integer>getItemIds()List<Integer>getItemIds(int startIndex, int numberOfItems)protected TgetJavaObject(int index)Get the Java backing object at the given index in the list.PropertyExtractor<? super T>getPropertyExtractor()Get the configuredPropertyExtractorfor this container.<V> VgetPropertyValue(T obj, PropertyDef<V> propertyDef)Read the value of the property defined bypropertyDeffrom the given object.Class<?>getType(Object propertyId)protected voidhandleSizeChange()intindexOfId(Object itemId)protected voidinvalidate()Discard the current cachedQueryList, if any.booleanisFirstId(Object itemId)booleanisLastId(Object itemId)IntegerlastItemId()IntegernextItemId(Object itemId)IntegerprevItemId(Object itemId)protected abstract QueryList<? extends T>query(long hint)Perform a query to (re)generate the list of Java objects backing this container.voidreload()Reload this container.booleanremoveAllItems()booleanremoveContainerProperty(Object propertyId)booleanremoveItem(Object itemId)voidremoveItemSetChangeListener(Container.ItemSetChangeListener listener)voidremoveListener(Container.ItemSetChangeListener listener)voidremoveListener(Container.PropertySetChangeListener listener)voidremovePropertySetChangeListener(Container.PropertySetChangeListener listener)voidsetProperties(Collection<? extends PropertyDef<?>> propertyDefs)Change the configured properties of this container.voidsetPropertyExtractor(PropertyExtractor<? super T> propertyExtractor)Change the configuredPropertyExtractorfor this container.intsize()-
Methods inherited from class com.vaadin.data.util.AbstractContainer
fireContainerPropertySetChange, fireContainerPropertySetChange, fireItemSetChange, fireItemSetChange, getItemSetChangeListeners, getListeners, getPropertySetChangeListeners, setItemSetChangeListeners, setPropertySetChangeListeners
-
-
-
-
Constructor Detail
-
AbstractQueryContainer
protected AbstractQueryContainer()
Constructor.After using this constructor, subsequent invocations of
setPropertyExtractor()andsetProperties()are required to define the properties of this container and how to extract them.
-
AbstractQueryContainer
protected AbstractQueryContainer(PropertyExtractor<? super T> propertyExtractor)
Constructor.After using this constructor, a subsequent invocation of
setProperties()is required to define the properties of this container.- Parameters:
propertyExtractor- used to extract properties from the underlying Java objects; may be null but then container is not usable until one is configured viasetPropertyExtractor()
-
AbstractQueryContainer
protected AbstractQueryContainer(Collection<? extends PropertyDef<?>> propertyDefs)
Constructor.After using this constructor, a subsequent invocation of
setPropertyExtractor()is required to define how to extract the properties of this container; alternately, subclasses can overridegetPropertyValue().- Parameters:
propertyDefs- container property definitions; null is treated like the empty set
-
AbstractQueryContainer
protected AbstractQueryContainer(PropertyExtractor<? super T> propertyExtractor, Collection<? extends PropertyDef<?>> propertyDefs)
Constructor.- Parameters:
propertyExtractor- used to extract properties from the underlying Java objects; may be null but then container is not usable until one is configured viasetPropertyExtractor()propertyDefs- container property definitions; null is treated like the empty set
-
AbstractQueryContainer
protected AbstractQueryContainer(Class<? super T> type)
Constructor.Properties will be determined by the
@ProvidesPropertyand@ProvidesPropertySortannotated methods in the given class.- Parameters:
type- class to introspect for annotated methods- Throws:
IllegalArgumentException- iftypeis nullIllegalArgumentException- iftypehas two@ProvidesPropertyor@ProvidesPropertySortannotated methods for the same propertyIllegalArgumentException- if a@ProvidesProperty-annotated method with no property name specified has a name which cannot be interpreted as a bean property "getter" method- See Also:
ProvidesProperty,ProvidesPropertySort,ProvidesPropertyScanner
-
-
Method Detail
-
getPropertyExtractor
public PropertyExtractor<? super T> getPropertyExtractor()
Get the configuredPropertyExtractorfor this container.- Returns:
- the configured
PropertyExtractor
-
setPropertyExtractor
public void setPropertyExtractor(PropertyExtractor<? super T> propertyExtractor)
Change the configuredPropertyExtractorfor this container. Invoking this method does not result in any container notifications.- Parameters:
propertyExtractor- used to extract properties from the underlying Java objects; may be null but the container is not usable without one
-
getPropertyValue
public <V> V getPropertyValue(T obj, PropertyDef<V> propertyDef)
Read the value of the property defined bypropertyDeffrom the given object.The implementation in
AbstractQueryContainerjust delegates to the configuredPropertyExtractor; subclasses may override to customize property extraction.- Specified by:
getPropertyValuein interfacePropertyExtractor<T>- Type Parameters:
V- value type- Parameters:
obj- Java objectpropertyDef- definition of which property to read- Returns:
- property value
- Throws:
NullPointerException- if either parameter is nullIllegalStateException- if noPropertyExtractoris configured for this container
-
setProperties
public void setProperties(Collection<? extends PropertyDef<?>> propertyDefs)
Change the configured properties of this container.- Parameters:
propertyDefs- container property definitions; null is treated like the empty set- Throws:
IllegalArgumentException- ifpropertyDefscontains a property with a duplicate name
-
reload
public void reload()
Reload this container.This discards the current cached
QueryList(if any) and fires an item set change event.
-
connect
public void connect()
Connect this instance to non-Vaadin resources.The implementation in
AbstractQueryContainerdoes nothing.- Specified by:
connectin interfaceConnectable- Throws:
IllegalStateException- if there is noVaadinSessionassociated with the current thread
-
disconnect
public void disconnect()
Disconnect this instance from non-Vaadin resources.The implementation in
AbstractQueryContainerdoes nothing.- Specified by:
disconnectin interfaceConnectable- Throws:
IllegalStateException- if there is noVaadinSessionassociated with the current thread
-
query
protected abstract QueryList<? extends T> query(long hint)
Perform a query to (re)generate the list of Java objects backing this container.The particular position in the list we are interested in is given as a hint by the
hintparameter. That is, an invocation ofQueryList.get(long)(hint)is likely immediately after this method returns and if so it must complete without throwing an exception, unlesshintis out of range.The
hintcan be used to implement a highly scalable query list containing external objects (such as from a database) where only a small "window" of objects is actually kept in memory at any one time. Of course, implementations are also free to ignorehint. However, the returnedQueryListmust at least tolerate one invocation ofget(hint)without throwing an exception whenhintis less that thesize()of the returnedQueryList.- Parameters:
hint- index of the list element we are interested in- Returns:
- list of Java objects backing this container
-
invalidate
protected void invalidate()
Discard the current cachedQueryList, if any.
-
getJavaObject
protected T getJavaObject(int index)
Get the Java backing object at the given index in the list.- Parameters:
index- list index- Returns:
- backing object, or null if
indexis out of range
-
ensureList
protected long ensureList(int hint)
Ensure we have a cached query list.- Parameters:
hint- index of the list element we are interested in, passed toquery(long)if no query list is cached- Returns:
- the size of the cached query list
-
handleSizeChange
protected void handleSizeChange()
Invoked when a newQueryListhas returned a changedsize()for the underlying list.Normally, this implies an item set change notification will be generated elsewhere and so no additional action needs to be taken by this method. However, some implementations may lack such a mechanism, for example, when the container's size is only ever calculated when
query(long)is invoked. In such cases, this method may trigger a notification.Note: to avoid re-entrancy problems, this method should not send out any notifications itself; instead, it may schedule notifications to be delivered later, e.g., via
VaadinUtil.invokeLater(com.vaadin.server.VaadinSession, java.lang.Runnable).The implementation in
AbstractQueryContainerdoes nothing, assuming the notification is handled elsewhere. Subclasses may override if needed.
-
createBackedItem
protected BackedItem<T> createBackedItem(T object, Collection<PropertyDef<?>> propertyDefs, PropertyExtractor<? super T> propertyExtractor)
Create aBackedItemfor the given backing Java object.The implementation in
AbstractQueryContainerreturnsnew SimpleItem<T>(object, propertyDefs, propertyExtractor).- Parameters:
object- underlying Java objectpropertyDefs- property definitionspropertyExtractor- extracts the property value fromobject- Returns:
- new
BackedItem - Throws:
IllegalArgumentException- if any parameter is null
-
getItem
public BackedItem<T> getItem(Object itemId)
-
getItemIds
public Collection<Integer> getItemIds()
- Specified by:
getItemIdsin interfaceContainer
-
getContainerPropertyIds
public Set<String> getContainerPropertyIds()
- Specified by:
getContainerPropertyIdsin interfaceContainer
-
getContainerProperty
public Property getContainerProperty(Object itemId, Object propertyId)
- Specified by:
getContainerPropertyin interfaceContainer
-
containsId
public boolean containsId(Object itemId)
- Specified by:
containsIdin interfaceContainer
-
addItem
public Item addItem(Object itemId)
- Specified by:
addItemin interfaceContainer- Throws:
UnsupportedOperationException- always
-
addItem
public Item addItem()
- Specified by:
addItemin interfaceContainer- Throws:
UnsupportedOperationException- always
-
removeItem
public boolean removeItem(Object itemId)
- Specified by:
removeItemin interfaceContainer- Throws:
UnsupportedOperationException- always
-
addContainerProperty
public boolean addContainerProperty(Object propertyId, Class<?> type, Object defaultValue)
- Specified by:
addContainerPropertyin interfaceContainer- Throws:
UnsupportedOperationException- always
-
removeContainerProperty
public boolean removeContainerProperty(Object propertyId)
- Specified by:
removeContainerPropertyin interfaceContainer- Throws:
UnsupportedOperationException- always
-
removeAllItems
public boolean removeAllItems()
- Specified by:
removeAllItemsin interfaceContainer- Throws:
UnsupportedOperationException- always
-
addItemAt
public Object addItemAt(int index)
- Specified by:
addItemAtin interfaceContainer.Indexed- Throws:
UnsupportedOperationException- always
-
addItemAt
public Item addItemAt(int index, Object newItemId)
- Specified by:
addItemAtin interfaceContainer.Indexed- Throws:
UnsupportedOperationException- always
-
getIdByIndex
public Integer getIdByIndex(int index)
- Specified by:
getIdByIndexin interfaceContainer.Indexed
-
getItemIds
public List<Integer> getItemIds(int startIndex, int numberOfItems)
- Specified by:
getItemIdsin interfaceContainer.Indexed
-
indexOfId
public int indexOfId(Object itemId)
- Specified by:
indexOfIdin interfaceContainer.Indexed
-
nextItemId
public Integer nextItemId(Object itemId)
- Specified by:
nextItemIdin interfaceContainer.Ordered
-
prevItemId
public Integer prevItemId(Object itemId)
- Specified by:
prevItemIdin interfaceContainer.Ordered
-
firstItemId
public Integer firstItemId()
- Specified by:
firstItemIdin interfaceContainer.Ordered
-
lastItemId
public Integer lastItemId()
- Specified by:
lastItemIdin interfaceContainer.Ordered
-
isFirstId
public boolean isFirstId(Object itemId)
- Specified by:
isFirstIdin interfaceContainer.Ordered
-
isLastId
public boolean isLastId(Object itemId)
- Specified by:
isLastIdin interfaceContainer.Ordered
-
addItemAfter
public Item addItemAfter(Object previousItemId)
- Specified by:
addItemAfterin interfaceContainer.Ordered- Throws:
UnsupportedOperationException- always
-
addItemAfter
public Item addItemAfter(Object previousItemId, Object newItemId)
- Specified by:
addItemAfterin interfaceContainer.Ordered- Throws:
UnsupportedOperationException- always
-
addListener
public void addListener(Container.PropertySetChangeListener listener)
- Specified by:
addListenerin interfaceContainer.PropertySetChangeNotifier- Overrides:
addListenerin classAbstractContainer
-
addPropertySetChangeListener
public void addPropertySetChangeListener(Container.PropertySetChangeListener listener)
- Specified by:
addPropertySetChangeListenerin interfaceContainer.PropertySetChangeNotifier- Overrides:
addPropertySetChangeListenerin classAbstractContainer
-
removeListener
public void removeListener(Container.PropertySetChangeListener listener)
- Specified by:
removeListenerin interfaceContainer.PropertySetChangeNotifier- Overrides:
removeListenerin classAbstractContainer
-
removePropertySetChangeListener
public void removePropertySetChangeListener(Container.PropertySetChangeListener listener)
- Specified by:
removePropertySetChangeListenerin interfaceContainer.PropertySetChangeNotifier- Overrides:
removePropertySetChangeListenerin classAbstractContainer
-
addListener
public void addListener(Container.ItemSetChangeListener listener)
- Specified by:
addListenerin interfaceContainer.ItemSetChangeNotifier- Overrides:
addListenerin classAbstractContainer
-
addItemSetChangeListener
public void addItemSetChangeListener(Container.ItemSetChangeListener listener)
- Specified by:
addItemSetChangeListenerin interfaceContainer.ItemSetChangeNotifier- Overrides:
addItemSetChangeListenerin classAbstractContainer
-
removeListener
public void removeListener(Container.ItemSetChangeListener listener)
- Specified by:
removeListenerin interfaceContainer.ItemSetChangeNotifier- Overrides:
removeListenerin classAbstractContainer
-
removeItemSetChangeListener
public void removeItemSetChangeListener(Container.ItemSetChangeListener listener)
- Specified by:
removeItemSetChangeListenerin interfaceContainer.ItemSetChangeNotifier- Overrides:
removeItemSetChangeListenerin classAbstractContainer
-
-