summaryrefslogtreecommitdiffstats
path: root/documentation/datamodel/datamodel-container.asciidoc
diff options
context:
space:
mode:
Diffstat (limited to 'documentation/datamodel/datamodel-container.asciidoc')
-rw-r--r--documentation/datamodel/datamodel-container.asciidoc834
1 files changed, 0 insertions, 834 deletions
diff --git a/documentation/datamodel/datamodel-container.asciidoc b/documentation/datamodel/datamodel-container.asciidoc
deleted file mode 100644
index 8f88e7c8bf..0000000000
--- a/documentation/datamodel/datamodel-container.asciidoc
+++ /dev/null
@@ -1,834 +0,0 @@
----
-title: Collecting Items in Containers
-order: 5
-layout: page
----
-
-[[datamodel.container]]
-= Collecting Items in Containers
-
-((("[classname]#Container#", id="term.datamodel.container", range="startofrange")))
-
-
-The [classname]#Container# interface is the highest containment level of the
-Vaadin data model, for containing items (rows) which in turn contain properties
-(columns). Containers can therefore represent tabular data, which can be viewed
-in a [classname]#Table# or some other selection component, as well as
-hierarchical data.
-
-The items contained in a container are identified by an __item identifier__ or
-__IID__, and the properties by a __property identifier__ or __PID__.
-
-[[datamodel.container.intro]]
-== Basic Use of Containers
-
-The basic use of containers involves creating one, adding items to it, and
-binding it as a container data source of a component.
-
-[[datamodel.container.intro.default]]
-=== Default Containers and Delegation
-
-Before saying anything about creation of containers, it should be noted that all
-components that can be bound to a container data source are by default bound to
-a default container. For example, [classname]#Table# is bound to a
-[classname]#IndexedContainer#, [classname]#Tree# to a
-[classname]#HierarchicalContainer#, and so forth.
-
-All of the user interface components using containers also implement the
-relevant container interfaces themselves, so that the access to the underlying
-data source is delegated through the component.
-
-
-----
-// Create a table with one column
-Table table = new Table("My Table");
-table.addContainerProperty("col1", String.class, null);
-
-// Access items and properties through the component
-table.addItem("row1"); // Create item by explicit ID
-Item item1 = table.getItem("row1");
-Property property1 = item1.getItemProperty("col1");
-property1.setValue("some given value");
-
-// Equivalent access through the container
-Container container = table.getContainerDataSource();
-container.addItem("row2");
-Item item2 = container.getItem("row2");
-Property property2 = item2.getItemProperty("col1");
-property2.setValue("another given value");
-----
-
-
-[[datamodel.container.intro.creating]]
-=== Creating and Binding a Container
-
-A container is created and bound to a component as follows:
-
-
-----
-// Create a container of some type
-Container container = new IndexedContainer();
-
-// Initialize the container as required by the container type
-container.addContainerProperty("name", String.class, "none");
-container.addContainerProperty("volume", Double.class, 0.0);
-
-... add items ...
-
-// Bind it to a component
-Table table = new Table("My Table");
-table.setContainerDataSource(container);
-----
-
-Most components that can be bound to a container allow passing it also in the
-constructor, in addition to using [methodname]#setContainerDataSource()#.
-Creation of the container depends on its type. For some containers, such as the
-[classname]#IndexedContainer#, you need to define the contained properties
-(columns) as was done above, while some others determine them otherwise. The
-definition of a property with [methodname]#addContainerProperty()# requires a
-unique property ID, type, and a default value. You can also give
-[parameter]#null#.
-
-Vaadin has a several built-in in-memory container implementations, such as
-[classname]#IndexedContainer# and [classname]#BeanItemContainer#, which are easy
-to use for setting up nonpersistent data storages. For persistent data, either
-the built-in [classname]#SQLContainer# or the [classname]#JPAContainer# add-on
-container can be used.
-
-
-[[datamodel.container.intro.adding]]
-=== Adding Items and Accessing Properties
-
-Items can be added to a container with the [methodname]#addItem()# method. The
-parameterless version of the method automatically generates the item ID.
-
-
-----
-// Create an item
-Object itemId = container.addItem();
-----
-
-Properties can be requested from container by first requesting an item with
-[methodname]#getItem()# and then getting the properties from the item with
-[methodname]#getItemProperty()#.
-
-
-----
-// Get the item object
-Item item = container.getItem(itemId);
-
-// Access a property in the item
-Property<String> nameProperty =
- item.getItemProperty("name");
-
-// Do something with the property
-nameProperty.setValue("box");
-----
-
-You can also get a property directly by the item and property ids with
-[methodname]#getContainerProperty()#.
-
-
-----
-container.getContainerProperty(itemId, "volume").setValue(5.0);
-----
-
-
-[[datamodel.container.intro.givenid]]
-=== Adding Items by Given ID
-
-Some containers, such as [classname]#IndexedContainer# and
-[classname]#HierarchicalContainer#, allow adding items by a given ID, which can
-be any [classname]#Object#.
-
-
-----
-Item item = container.addItem("agivenid");
-item.getItemProperty("name").setValue("barrel");
-Item.getItemProperty("volume").setValue(119.2);
-----
-
-Notice that the actual item __is not__ given as a parameter to the method, only
-its ID, as the interface assumes that the container itself creates all the items
-it contains. Some container implementations can provide methods to add
-externally created items, and they can even assume that the item ID object is
-also the item itself. Lazy containers might not create the item immediately, but
-lazily when it is accessed by its ID.
-
-
-
-[[datamodel.container.inner]]
-== Container Subinterfaces
-
-The [classname]#Container# interface contains inner interfaces that container
-implementations can implement to fulfill different features required by
-components that present container data.
-
-[interfacename]#Container.Filterable#:: Filterable containers allow filtering the contained items by filters, as
-described in <<datamodel.container.filtered>>.
-
-[interfacename]#Container.Hierarchical#:: Hierarchical containers allow representing hierarchical relationships between
-items and are required by the [classname]#Tree# and [classname]#TreeTable#
-components. The [classname]#HierarchicalContainer# is a built-in in-memory
-container for hierarchical data, and is used as the default container for the
-tree components. The [classname]#FilesystemContainer# provides access to
-browsing the content of a file system. Also [classname]#JPAContainer# is
-hierarchical, as described in
-<<dummy/../../../framework/jpacontainer/jpacontainer-usage#jpacontainer.usage.hierarchical,"Hierarchical
-Container">>.
-
-[interfacename]#Container.Indexed#:: An indexed container allows accessing items by an index number, not just their
-item ID. This feature is required by some components, especially
-[classname]#Table#, which needs to provide lazy access to large containers. The
-[classname]#IndexedContainer# is a basic in-memory implementation, as described
-in <<datamodel.container.indexedcontainer>>.
-
-[interfacename]#Container.Ordered#:: An ordered container allows traversing the items in successive order in either
-direction. Most built-in containers are ordered.
-
-[interfacename]#Container.SimpleFilterable#:: This interface enables filtering a container by string matching with
-[methodname]#addContainerFilter()#. The filtering is done by either searching
-the given string anywhere in a property value, or as its prefix.
-
-[interfacename]#Container.Sortable#:: A sortable container is required by some components that allow sorting the
-content, such as [classname]#Table#, where the user can click a column header to
-sort the table by the column. Some other components, such as
-[classname]#Calendar#, may require that the content is sorted to be able to
-display it properly. Depending on the implementation, sorting can be done only
-when the [methodname]#sort()# method is called, or the container is
-automatically kept in order according to the last call of the method.
-
-
-
-See the API documentation for a detailed description of the interfaces.
-
-
-[[datamodel.container.indexedcontainer]]
-== [classname]#IndexedContainer#
-
-The [classname]#IndexedContainer# is an in-memory container that implements the
-[interfacename]#Indexed# interface to allow referencing the items by an index.
-[classname]#IndexedContainer# is used as the default container in most selection
-components in Vaadin.
-
-The properties need to be defined with [methodname]#addContainerProperty()#,
-which takes the property ID, type, and a default value. This must be done before
-any items are added to the container.
-
-
-----
-// Create the container
-IndexedContainer container = new IndexedContainer();
-
-// Define the properties (columns)
-container.addContainerProperty("name", String.class, "noname");
-container.addContainerProperty("volume", Double.class, -1.0d);
-
-// Add some items
-Object content[][] = { {"jar", 2.0}, {"bottle", 0.75},
- {"can", 1.5}};
-for (Object[] row: content) {
- Item newItem = container.getItem(container.addItem());
- newItem.getItemProperty("name").setValue(row[0]);
- newItem.getItemProperty("volume").setValue(row[1]);
-}
-----
-
-New items are added with [methodname]#addItem()#, which returns the item ID of
-the new item, or by giving the item ID as a parameter as was described earlier.
-Note that the [classname]#Table# component, which has
-[classname]#IndexedContainer# as its default container, has a conveniency
-[methodname]#addItem()# method that allows adding items as object vectors
-containing the property values.
-
-The container implements the [interfacename]#Container.Indexed# feature to allow
-accessing the item IDs by their index number, with [methodname]#getIdByIndex()#,
-etc. The feature is required mainly for internal purposes of some components,
-such as [classname]#Table#, which uses it to enable lazy transmission of table
-data to the client-side.
-
-
-[[datamodel.container.beancontainer]]
-== [classname]#BeanContainer#
-
-The [classname]#BeanContainer# is an in-memory container for JavaBean objects.
-Each contained bean is wrapped inside a [classname]#BeanItem# wrapper. The item
-properties are determined automatically by inspecting the getter and setter
-methods of the class. This requires that the bean class has public visibility,
-local classes for example are not allowed. Only beans of the same type can be
-added to the container.
-
-The generic has two parameters: a bean type and an item identifier type. The
-item identifiers can be obtained by defining a custom resolver, using a specific
-item property for the IDs, or by giving item IDs explicitly. As such, it is more
-general than the [classname]#BeanItemContainer#, which uses the bean object
-itself as the item identifier, making the use usually simpler. Managing the item
-IDs makes [classname]#BeanContainer# more complex to use, but it is necessary in
-some cases where the [methodname]#equals()# or [methodname]#hashCode()# methods
-have been reimplemented in the bean.
-
-
-----
-// Here is a JavaBean
-public class Bean implements Serializable {
- String name;
- double energy; // Energy content in kJ/100g
-
- public Bean(String name, double energy) {
- this.name = name;
- this.energy = energy;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public double getEnergy() {
- return energy;
- }
-
- public void setEnergy(double energy) {
- this.energy = energy;
- }
-}
-
-void basic(VerticalLayout layout) {
- // Create a container for such beans with
- // strings as item IDs.
- BeanContainer<String, Bean> beans =
- new BeanContainer<String, Bean>(Bean.class);
-
- // Use the name property as the item ID of the bean
- beans.setBeanIdProperty("name");
-
- // Add some beans to it
- beans.addBean(new Bean("Mung bean", 1452.0));
- beans.addBean(new Bean("Chickpea", 686.0));
- beans.addBean(new Bean("Lentil", 1477.0));
- beans.addBean(new Bean("Common bean", 129.0));
- beans.addBean(new Bean("Soybean", 1866.0));
-
- // Bind a table to it
- Table table = new Table("Beans of All Sorts", beans);
- layout.addComponent(table);
-}
-----
-See the http://demo.vaadin.com/book-examples-vaadin7/book#datamodel.container.beancontainer.basic[on-line example, window="_blank"].
-
-To use explicit item IDs, use the methods [methodname]#addItem(Object, Object)#,
-[methodname]#addItemAfter(Object, Object, Object)#, and
-[methodname]#addItemAt(int, Object, Object)#.
-
-It is not possible to add additional properties to the container, except
-properties in a nested bean.
-
-[[datamodel.container.beancontainer.nestedproperties]]
-=== Nested Properties
-
-((("nested bean properties", id="term.datamodel.container.beancontainer.nestedproperties", range="startofrange")))
-
-
-If you have a nested bean with an 1:1 relationship inside a bean type contained
-in a [classname]#BeanContainer# or [classname]#BeanItemContainer#, you can add
-its properties to the container by specifying them with
-[methodname]#addNestedContainerProperty()#. The feature is defined at the level
-of [classname]#AbstractBeanContainer#.
-((("[methodname]#addNestedContainerProperty()#")))
-
-As with the bean in a bean container, also a nested bean must have public
-visibility or otherwise an access exception is thrown. An intermediate reference
-from a bean in the bean container to a nested bean may have a null value.
-
-For example, let us assume that we have the following two beans with the first
-one nested inside the second one.
-
-
-----
-/** Bean to be nested */
-public class EqCoord implements Serializable {
- double rightAscension; /* In angle hours */
- double declination; /* In degrees */
-
- ... setters and getters for the properties ...
-}
-
-/** Bean referencing a nested bean */
-public class Star implements Serializable {
- String name;
- EqCoord equatorial; /* Nested bean */
-
- ... setters and getters for the properties ...
-}
-----
-See the http://demo.vaadin.com/book-examples-vaadin7/book#datamodel.container.beanitemcontainer.nestedbean[on-line example, window="_blank"].
-
-After creating the container, you can declare the nested properties by
-specifying their property identifiers with the
-[methodname]#addNestedContainerProperty()# in dot notation.
-
-
-----
-// Create a container for beans
-BeanItemContainer<Star> stars =
- new BeanItemContainer<Star>(Star.class);
-
-// Declare the nested properties to be used in the container
-stars.addNestedContainerProperty("equatorial.rightAscension");
-stars.addNestedContainerProperty("equatorial.declination");
-
-// Add some items
-stars.addBean(new Star("Sirius", new EqCoord(6.75, 16.71611)));
-stars.addBean(new Star("Polaris", new EqCoord(2.52, 89.26417)));
-
-// Here the nested bean reference is null
-stars.addBean(new Star("Vega", null));
-----
-See the http://demo.vaadin.com/book-examples-vaadin7/book#datamodel.container.beanitemcontainer.nestedbean[on-line example, window="_blank"].
-
-If you bind such a container to a [classname]#Table#, you probably also need to
-set the column headers. Notice that the entire nested bean itself is still a
-property in the container and would be displayed in its own column. The
-[methodname]#toString()# method is used for obtaining the displayed value, which
-is by default an object reference. You normally do not want this, so you can
-hide the column with [methodname]#setVisibleColumns()#.
-((("[methodname]#setVisibleColumns()#")))
-
-
-----
-// Put them in a table
-Table table = new Table("Stars", stars);
-table.setColumnHeader("equatorial.rightAscension", "RA");
-table.setColumnHeader("equatorial.declination", "Decl");
-table.setPageLength(table.size());
-
-// Have to set explicitly to hide the "equatorial" property
-table.setVisibleColumns("name",
- "equatorial.rightAscension", "equatorial.declination");
-----
-See the http://demo.vaadin.com/book-examples-vaadin7/book#datamodel.container.beanitemcontainer.nestedbean[on-line example, window="_blank"].
-
-The resulting table is shown in
-<<figure.datamodel.container.beancontainer.nestedproperties>>.
-
-[[figure.datamodel.container.beancontainer.nestedproperties]]
-.[classname]#Table# Bound to a [classname]#BeanContainer# with Nested Properties
-image::img/beanitemcontainer-nested-beans.png[]
-
-The bean binding in [classname]#AbstractBeanContainer# normally uses the
-[classname]#MethodProperty# implementation of the [classname]#Property#
-interface to access the bean properties using the setter and getter methods. For
-nested properties, the [classname]#NestedMethodProperty# implementation is used.
-((("[classname]#MethodProperty#")))
-((("[classname]#NestedMethodProperty#")))
-
-(((range="endofrange", startref="term.datamodel.container.beancontainer.nestedproperties")))
-
-ifdef::web[]
-[[datamodel.container.beancontainer.idresolver]]
-=== Defining a Bean ID Resolver
-
-If a bean ID resolver is set using [methodname]#setBeanIdResolver()# or
-[methodname]#setBeanIdProperty()#, the methods [methodname]#addBean()#,
-[methodname]#addBeanAfter()#, [methodname]#addBeanAt()# and
-[methodname]#addAll()# can be used to add items to the container. If one of
-these methods is called, the resolver is used to generate an identifier for the
-item (must not return [parameter]#null#).
-
-Note that explicit item identifiers can also be used when a resolver has been
-set by calling the [methodname]#addItem*()# methods - the resolver is only used
-when adding beans using the [methodname]#addBean*()# or
-[methodname]#addAll(Collection)# methods.
-
-endif::web[]
-
-
-[[datamodel.container.beanitemcontainer]]
-== [classname]#BeanItemContainer#
-
-[classname]#BeanItemContainer# is a container for JavaBean objects where each
-bean is wrapped inside a [classname]#BeanItem# wrapper. The item properties are
-determined automatically by inspecting the getter and setter methods of the
-class. This requires that the bean class has public visibility, local classes
-for example are not allowed. Only beans of the same type can be added to the
-container.
-
-[classname]#BeanItemContainer# is a specialized version of the
-[classname]#BeanContainer# described in <<datamodel.container.beancontainer>>.
-It uses the bean itself as the item identifier, which makes it a bit easier to
-use than [classname]#BeanContainer# in many cases. The latter is, however,
-needed if the bean has reimplemented the [methodname]#equals()# or
-[methodname]#hashCode()# methods.
-
-Let us revisit the example given in <<datamodel.container.beancontainer>> using
-the [classname]#BeanItemContainer#.
-
-
-----
-// Create a container for the beans
-BeanItemContainer<Bean> beans =
- new BeanItemContainer<Bean>(Bean.class);
-
-// Add some beans to it
-beans.addBean(new Bean("Mung bean", 1452.0));
-beans.addBean(new Bean("Chickpea", 686.0));
-beans.addBean(new Bean("Lentil", 1477.0));
-beans.addBean(new Bean("Common bean", 129.0));
-beans.addBean(new Bean("Soybean", 1866.0));
-
-// Bind a table to it
-Table table = new Table("Beans of All Sorts", beans);
-----
-See the http://demo.vaadin.com/book-examples-vaadin7/book#datamodel.container.beanitemcontainer.basic[on-line example, window="_blank"].
-
-It is not possible to add additional properties to a
-[classname]#BeanItemContainer#, except properties in a nested bean, as described
-in <<datamodel.container.beancontainer>>. ((("nested bean
-properties")))
-
-
-ifdef::web[]
-[[datamodel.container.iterating]]
-== Iterating Over a Container
-
-As the items in a [classname]#Container# are not necessarily indexed, iterating
-over the items has to be done using an [classname]#Iterator#. The
-[methodname]#getItemIds()# method of [classname]#Container# returns a
-[classname]#Collection# of item identifiers over which you can iterate. The
-following example demonstrates a typical case where you iterate over the values
-of check boxes in a column of a [classname]#Table# component. The context of the
-example is the example used in
-<<dummy/../../../framework/components/components-table#components.table,"Table">>.
-
-
-----
-// Collect the results of the iteration into this string.
-String items = "";
-
-// Iterate over the item identifiers of the table.
-for (Iterator i = table.getItemIds().iterator(); i.hasNext();) {
- // Get the current item identifier, which is an integer.
- int iid = (Integer) i.next();
-
- // Now get the actual item from the table.
- Item item = table.getItem(iid);
-
- // And now we can get to the actual checkbox object.
- Button button = (Button)
- (item.getItemProperty("ismember").getValue());
-
- // If the checkbox is selected.
- if ((Boolean)button.getValue() == true) {
- // Do something with the selected item; collect the
- // first names in a string.
- items += item.getItemProperty("First Name")
- .getValue() + " ";
- }
-}
-
-// Do something with the results; display the selected items.
-layout.addComponent (new Label("Selected items: " + items));
-----
-
-Notice that the [methodname]#getItemIds()# returns an __unmodifiable
-collection__, so the [classname]#Container# may not be modified during
-iteration. You can not, for example, remove items from the
-[classname]#Container# during iteration. The modification includes modification
-in another thread. If the [classname]#Container# is modified during iteration, a
-[classname]#ConcurrentModificationException# is thrown and the iterator may be
-left in an undefined state.
-
-endif::web[]
-
-[[datamodel.container.gpc]]
-== [classname]#GeneratedPropertyContainer#
-
-[classname]#GeneratedPropertyContainer# is a container wrapper that allows
-defining generated values for properties (columns). The generated properties can
-shadow properties with the same IDs in the wrapped container. Removing a
-property from the wrapper hides it.
-
-The container is especially useful with [classname]#Grid#, which does not
-support generated columns or hiding columns like [classname]#Table# does.
-
-[[datamodel.container.gpc.wrapping]]
-=== Wrapping a Container
-
-A container to be wrapped must be a [interfacename]#Container.Indexed#. It can
-optionally also implement [interfacename]#Container.Sortable# or
-[interfacename]#Container.Filterable# to enable sorting and filtering the
-container, respectively.
-
-For example, let us consider the following container with some regular columns:
-
-
-----
-IndexedContainer container = new IndexedContainer();
-container.addContainerProperty("firstname", String.class, null);
-container.addContainerProperty("lastname", String.class, null);
-container.addContainerProperty("born", Integer.class, null);
-container.addContainerProperty("died", Integer.class, null);
-
-// Wrap it
-GeneratedPropertyContainer gpcontainer =
- new GeneratedPropertyContainer(container);
-----
-
-
-[[datamodel.container.gpc.properties]]
-=== Generated Properties
-
-Now, you can add generated properties in the container with
-[methodname]#addGeneratedProperty()# by specifying a property ID and a
-[interfacename]#PropertyValueGenerator#. The method takes the ID of the
-generated property as first parameter; you can use a same ID as in the wrapped
-container to shadow its properties.
-
-You need to implement [methodname]#getType()#, which must return the class
-object of the value type of the property, and [methodname]#getValue()#, which
-returns the property value for the given item. The item ID and the property ID
-of the generated property are also given in case they are needed. You can access
-other properties of the item to compute the property value.
-
-
-----
-gpcontainer.addGeneratedProperty("lived",
- new PropertyValueGenerator<Integer>() {
- @Override
- public Integer getValue(Item item, Object itemId,
- Object propertyId) {
- int born = (Integer)
- item.getItemProperty("born").getValue();
- int died = (Integer)
- item.getItemProperty("died").getValue();
- return Integer.valueOf(died - born);
- }
-
- @Override
- public Class<Integer> getType() {
- return Integer.class;
- }
-});
-----
-
-You can access other items in the container, also their generated properties,
-although you should beware of accidental recursion.
-
-
-[[datamodel.container.gpc.using]]
-=== Using [classname]#GeneratedPropertyContainer#
-
-Finally, you need to bind the [classname]#GeneratedPropertyContainer# to the
-component instead of the wrapped container.
-
-
-----
-Grid grid = new Grid(gpcontainer);
-----
-
-When using [classname]#GeneratedPropertyContainer# in [classname]#Grid#, notice
-that generated columns are read-only, so you can not add grid rows with
-[methodname]#addRow()#. In editable mode, editor fields are not generated for
-generated columns.
-
-
-[[datamodel.container.gpc.sorting]]
-=== Sorting
-
-Even though the [classname]#GeneratedPropertyContainer# implements
-[interfacename]#Container.Sortable#, the wrapped container must also support it
-or otherwise sorting is disabled. Also, the generated properties are not
-normally sortable, but require special handling to enable sorting.
-
-
-
-[[datamodel.container.filtered]]
-== [classname]#Filterable# Containers
-
-((("Container", "Filterable", id="term.datamodel.container.filtered.filterable", range="startofrange")))
-
-
-((("[classname]#Filter# (in [classname]#Container#)", id="term.datamodel.container.filtered.filters", range="startofrange")))
-
-
-Containers that implement the [classname]#Container.Filterable# interface can be
-filtered. For example, the built-in [classname]#IndexedContainer# and the bean
-item containers implement it. Filtering is typically used for filtering the
-content of a [classname]#Table#.
-((("[classname]#IndexedContainer#")))
-((("[classname]#Table#")))
-
-Filters implement the [classname]#Filter# interface and you add them to a
-filterable container with the [methodname]#addContainerFilter()# method.
-Container items that pass the filter condition are kept and shown in the
-filterable component.
-((("[methodname]#addContainerFilter()#")))
-
-
-----
-Filter filter = new SimpleStringFilter("name",
- "Douglas", true, false);
-table.addContainerFilter(filter);
-----
-See the http://demo.vaadin.com/book-examples-vaadin7/book#datamodel.container.filter.basic[on-line example, window="_blank"].
-
-If multiple filters are added to a container, they are evaluated using the
-logical AND operator so that only items that are passed by all the filters are
-kept.
-
-[[datamodel.container.filtered.composite]]
-=== Atomic and Composite Filters
-
-Filters can be classified as __atomic__ and __composite__. Atomic filters, such
-as [classname]#SimpleStringFilter#, define a single condition, usually for a
-specific container property. Composite filters make filtering decisions based on
-the result of one or more other filters. The built-in composite filters
-implement the logical operators AND, OR, or NOT.
-
-For example, the following composite filter would filter out items where the
-[literal]#++name++# property contains the name "Douglas" somewhere __or__ where
-the [literal]#++age++# property has value less than 42. The properties must have
-[classname]#String# and [classname]#Integer# types, respectively.
-
-
-----
-
-filter = new Or(new SimpleStringFilter("name",
- "Douglas", true, false),
- new Compare.Less("age", 42));
-----
-
-
-[[datamodel.container.filtered.builtin]]
-=== Built-In Filter Types
-
-The built-in filter types are the following:
-
-[classname]#SimpleStringFilter#:: ((("[classname]#SimpleStringFilter#")))
-+
-Passes items where the specified property, that must be of [classname]#String#
-type, contains the given [parameter]#filterString# as a substring. If
-[parameter]#ignoreCase# is [parameter]#true#, the search is case insensitive. If
-the [parameter]#onlyMatchPrefix# is [parameter]#true#, the substring may only be
-in the beginning of the string, otherwise it may be elsewhere as well.
-
-[classname]#IsNull#:: ((("[classname]#IsNull# (filter)")))
-+
-Passes items where the specified property has null value. For in-memory
-filtering, a simple [literal]#++==++# check is performed. For other containers,
-the comparison implementation is container dependent, but should correspond to
-the in-memory null check.
-
-[classname]#Equal#,[classname]#Greater#,
- [classname]#Less#,
- [classname]#GreaterOrEqual#, and[classname]#LessOrEqual#:: ((("[classname]#Equal# (filter)")))
-((("[classname]#Greater# (filter)")))
-((("[classname]#Less# (filter)")))
-((("[classname]#GreaterOrEqual# (filter)")))
-((("[classname]#LessOrEqual# (filter)")))
-+
-The comparison filter implementations compare the specified property value to
-the given constant and pass items for which the comparison result is true. The
-comparison operators are included in the abstract [classname]#Compare# class.
-
-+
-For the [classname]#Equal# filter, the [methodname]#equals()# method for the
-property is used in built-in in-memory containers. In other types of containers,
-the comparison is container dependent and may use, for example, database
-comparison operations.
-
-+
-For the other filters, the property value type must implement the
-[classname]#Comparable# interface to work with the built-in in-memory
-containers. Again for the other types of containers, the comparison is container
-dependent.
-
-[classname]#And#and[classname]#Or#:: ((("[classname]#And# (filter)")))
-((("[classname]#Or# (filter)")))
-+
-These logical operator filters are composite filters that combine multiple other
-filters.
-
-[classname]#Not#:: ((("[classname]#Not# (filter)")))
-+
-The logical unary operator filter negates which items are passed by the filter
-given as the parameter.
-
-
-
-
-[[datamodel.container.filtered.custom]]
-=== Implementing Custom Filters
-
-A custom filter needs to implement the [classname]#Container.Filter# interface.
-
-A filter can use a single or multiple properties for the filtering logic. The
-properties used by the filter must be returned with the
-[methodname]#appliesToProperty()# method. If the filter applies to a
-user-defined property or properties, it is customary to give the properties as
-the first argument for the constructor of the filter.
-
-
-----
-class MyCustomFilter implements Container.Filter {
- protected String propertyId;
- protected String regex;
-
- public MyCustomFilter(String propertyId, String regex) {
- this.propertyId = propertyId;
- this.regex = regex;
- }
-
- /** Tells if this filter works on the given property. */
- @Override
- public boolean appliesToProperty(Object propertyId) {
- return propertyId != null &&
- propertyId.equals(this.propertyId);
- }
-----
-See the http://demo.vaadin.com/book-examples-vaadin7/book#datamodel.container.filter.custom[on-line example, window="_blank"].
-
-The actual filtering logic is done in the [methodname]#passesFilter()# method,
-which simply returns [literal]#++true++# if the item should pass the filter and
-[literal]#++false++# if it should be filtered out.
-
-
-----
- /** Apply the filter on an item to check if it passes. */
- @Override
- public boolean passesFilter(Object itemId, Item item)
- throws UnsupportedOperationException {
- // Acquire the relevant property from the item object
- Property p = item.getItemProperty(propertyId);
-
- // Should always check validity
- if (p == null || !p.getType().equals(String.class))
- return false;
- String value = (String) p.getValue();
-
- // The actual filter logic
- return value.matches(regex);
- }
-}
-----
-See the http://demo.vaadin.com/book-examples-vaadin7/book#datamodel.container.filter.custom[on-line example, window="_blank"].
-
-You can use such a custom filter just like any other:
-
-
-----
-c.addContainerFilter(
- new MyCustomFilter("Name", (String) tf.getValue()));
-----
-See the http://demo.vaadin.com/book-examples-vaadin7/book#datamodel.container.filter.custom[on-line example, window="_blank"].
-
-
-(((range="endofrange", startref="term.datamodel.container.filtered.filters")))
-(((range="endofrange", startref="term.datamodel.container.filtered.filterable")))
-
-(((range="endofrange", startref="term.datamodel.container")))
-
-