summaryrefslogtreecommitdiffstats
path: root/server/src/com/vaadin/data/util
diff options
context:
space:
mode:
authorLeif Åstrand <leif@vaadin.com>2014-09-20 10:01:44 +0300
committerLeif Åstrand <leif@vaadin.com>2014-09-20 10:15:37 +0300
commit9542a79187efc287e0ac5d1c7ca3911587e6f059 (patch)
tree175e18bd43f3d4c73d7d2eb6a277f81be8dd8488 /server/src/com/vaadin/data/util
parent526b23cd86ccc7603e280da45d48f3f4bfcc4ecd (diff)
parent48e208c78e1ca2227d422985e4084a8b1ed7304f (diff)
downloadvaadin-framework-9542a79187efc287e0ac5d1c7ca3911587e6f059.tar.gz
vaadin-framework-9542a79187efc287e0ac5d1c7ca3911587e6f059.zip
Merge remote-tracking branch 'origin/master' into grid
Change-Id: I8a35a090619778b1cfbff55e112ab2f30e6881a2
Diffstat (limited to 'server/src/com/vaadin/data/util')
-rw-r--r--server/src/com/vaadin/data/util/AbstractBeanContainer.java20
-rw-r--r--server/src/com/vaadin/data/util/AbstractInMemoryContainer.java151
-rw-r--r--server/src/com/vaadin/data/util/GeneratedPropertyContainer.java592
-rw-r--r--server/src/com/vaadin/data/util/IndexedContainer.java7
-rw-r--r--server/src/com/vaadin/data/util/PropertyValueGenerator.java100
5 files changed, 852 insertions, 18 deletions
diff --git a/server/src/com/vaadin/data/util/AbstractBeanContainer.java b/server/src/com/vaadin/data/util/AbstractBeanContainer.java
index adf6313770..0559585e14 100644
--- a/server/src/com/vaadin/data/util/AbstractBeanContainer.java
+++ b/server/src/com/vaadin/data/util/AbstractBeanContainer.java
@@ -222,6 +222,7 @@ public abstract class AbstractBeanContainer<IDTYPE, BEANTYPE> extends
@Override
public boolean removeAllItems() {
int origSize = size();
+ IDTYPE firstItem = getFirstVisibleItem();
internalRemoveAllItems();
@@ -234,7 +235,7 @@ public abstract class AbstractBeanContainer<IDTYPE, BEANTYPE> extends
// fire event only if the visible view changed, regardless of whether
// filtered out items were removed or not
if (origSize != 0) {
- fireItemSetChange();
+ fireItemsRemoved(0, firstItem, origSize);
}
return true;
@@ -679,6 +680,8 @@ public abstract class AbstractBeanContainer<IDTYPE, BEANTYPE> extends
protected void addAll(Collection<? extends BEANTYPE> collection)
throws IllegalStateException, IllegalArgumentException {
boolean modified = false;
+ int origSize = size();
+
for (BEANTYPE bean : collection) {
// TODO skipping invalid beans - should not allow them in javadoc?
if (bean == null
@@ -699,13 +702,22 @@ public abstract class AbstractBeanContainer<IDTYPE, BEANTYPE> extends
if (modified) {
// Filter the contents when all items have been added
if (isFiltered()) {
- filterAll();
- } else {
- fireItemSetChange();
+ doFilterContainer(!getFilters().isEmpty());
+ }
+ if (visibleNewItemsWasAdded(origSize)) {
+ // fire event about added items
+ int firstPosition = origSize;
+ IDTYPE firstItemId = getVisibleItemIds().get(firstPosition);
+ int affectedItems = size() - origSize;
+ fireItemsAdded(firstPosition, firstItemId, affectedItems);
}
}
}
+ private boolean visibleNewItemsWasAdded(int origSize) {
+ return size() > origSize;
+ }
+
/**
* Use the bean resolver to get the identifier for a bean.
*
diff --git a/server/src/com/vaadin/data/util/AbstractInMemoryContainer.java b/server/src/com/vaadin/data/util/AbstractInMemoryContainer.java
index b19cddb021..5ddc11ec6f 100644
--- a/server/src/com/vaadin/data/util/AbstractInMemoryContainer.java
+++ b/server/src/com/vaadin/data/util/AbstractInMemoryContainer.java
@@ -15,8 +15,10 @@
*/
package com.vaadin.data.util;
+import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
+import java.util.EventObject;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
@@ -146,6 +148,85 @@ public abstract class AbstractInMemoryContainer<ITEMIDTYPE, PROPERTYIDCLASS, ITE
}
}
+ private static abstract class BaseItemAddOrRemoveEvent extends
+ EventObject implements Serializable {
+ protected Object itemId;
+ protected int index;
+ protected int count;
+
+ public BaseItemAddOrRemoveEvent(Container source, Object itemId,
+ int index, int count) {
+ super(source);
+ this.itemId = itemId;
+ this.index = index;
+ this.count = count;
+ }
+
+ public Container getContainer() {
+ return (Container) getSource();
+ }
+
+ public Object getFirstItemId() {
+ return itemId;
+ }
+
+ public int getFirstIndex() {
+ return index;
+ }
+
+ public int getAffectedItemsCount() {
+ return count;
+ }
+ }
+
+ /**
+ * An <code>Event</code> object specifying information about the added
+ * items.
+ *
+ * <p>
+ * This class provides information about the first added item and the number
+ * of added items.
+ * </p>
+ */
+ protected static class BaseItemAddEvent extends
+ BaseItemAddOrRemoveEvent implements
+ Container.Indexed.ItemAddEvent {
+
+ public BaseItemAddEvent(Container source, Object itemId, int index,
+ int count) {
+ super(source, itemId, index, count);
+ }
+
+ @Override
+ public int getAddedItemsCount() {
+ return getAffectedItemsCount();
+ }
+ }
+
+ /**
+ * An <code>Event</code> object specifying information about the removed
+ * items.
+ *
+ * <p>
+ * This class provides information about the first removed item and the
+ * number of removed items.
+ * </p>
+ */
+ protected static class BaseItemRemoveEvent extends
+ BaseItemAddOrRemoveEvent implements
+ Container.Indexed.ItemRemoveEvent {
+
+ public BaseItemRemoveEvent(Container source, Object itemId,
+ int index, int count) {
+ super(source, itemId, index, count);
+ }
+
+ @Override
+ public int getRemovedItemsCount() {
+ return getAffectedItemsCount();
+ }
+ }
+
/**
* Get an item even if filtered out.
*
@@ -898,36 +979,69 @@ public abstract class AbstractInMemoryContainer<ITEMIDTYPE, PROPERTYIDCLASS, ITE
* Notify item set change listeners that an item has been added to the
* container.
*
- * Unless subclasses specify otherwise, the default notification indicates a
- * full refresh.
- *
* @param postion
- * position of the added item in the view (if visible)
+ * position of the added item in the view
* @param itemId
* id of the added item
* @param item
* the added item
*/
protected void fireItemAdded(int position, ITEMIDTYPE itemId, ITEMCLASS item) {
- fireItemSetChange();
+ fireItemsAdded(position, itemId, 1);
+ }
+
+ /**
+ * Notify item set change listeners that items has been added to the
+ * container.
+ *
+ * @param firstPosition
+ * position of the first visible added item in the view
+ * @param firstItemId
+ * id of the first visible added item
+ * @param numberOfItems
+ * the number of visible added items
+ */
+ protected void fireItemsAdded(int firstPosition, ITEMIDTYPE firstItemId,
+ int numberOfItems) {
+ BaseItemAddEvent addEvent = new BaseItemAddEvent(this,
+ firstItemId, firstPosition, numberOfItems);
+ fireItemSetChange(addEvent);
}
/**
* Notify item set change listeners that an item has been removed from the
* container.
*
- * Unless subclasses specify otherwise, the default notification indicates a
- * full refresh.
+ * @param position
+ * position of the removed item in the view prior to removal
*
- * @param postion
- * position of the removed item in the view prior to removal (if
- * was visible)
* @param itemId
* id of the removed item, of type {@link Object} to satisfy
* {@link Container#removeItem(Object)} API
*/
protected void fireItemRemoved(int position, Object itemId) {
- fireItemSetChange();
+ fireItemsRemoved(position, itemId, 1);
+ }
+
+ /**
+ * Notify item set change listeners that items has been removed from the
+ * container.
+ *
+ * @param firstPosition
+ * position of the first visible removed item in the view prior
+ * to removal
+ * @param firstItemId
+ * id of the first visible removed item, of type {@link Object}
+ * to satisfy {@link Container#removeItem(Object)} API
+ * @param numberOfItems
+ * the number of removed visible items
+ *
+ */
+ protected void fireItemsRemoved(int firstPosition, Object firstItemId,
+ int numberOfItems) {
+ BaseItemRemoveEvent removeEvent = new BaseItemRemoveEvent(this,
+ firstItemId, firstPosition, numberOfItems);
+ fireItemSetChange(removeEvent);
}
// visible and filtered item identifier lists
@@ -946,6 +1060,21 @@ public abstract class AbstractInMemoryContainer<ITEMIDTYPE, PROPERTYIDCLASS, ITE
}
/**
+ * Returns the item id of the first visible item after filtering. 'Null' is
+ * returned if there is no visible items.
+ *
+ * For internal use only.
+ *
+ * @return item id of the first visible item
+ */
+ protected ITEMIDTYPE getFirstVisibleItem() {
+ if (!getVisibleItemIds().isEmpty()) {
+ return getVisibleItemIds().get(0);
+ }
+ return null;
+ }
+
+ /**
* Returns true is the container has active filters.
*
* @return true if the container is currently filtered
diff --git a/server/src/com/vaadin/data/util/GeneratedPropertyContainer.java b/server/src/com/vaadin/data/util/GeneratedPropertyContainer.java
new file mode 100644
index 0000000000..4dd190908e
--- /dev/null
+++ b/server/src/com/vaadin/data/util/GeneratedPropertyContainer.java
@@ -0,0 +1,592 @@
+/*
+ * 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 com.vaadin.data.util;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import com.google.gwt.thirdparty.guava.common.collect.Sets;
+import com.vaadin.data.Container;
+import com.vaadin.data.Item;
+import com.vaadin.data.Property;
+import com.vaadin.data.util.filter.UnsupportedFilterException;
+import com.vaadin.shared.ui.grid.SortDirection;
+import com.vaadin.ui.components.grid.sort.SortOrder;
+
+/**
+ * Container supporting generated properties.
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class GeneratedPropertyContainer extends AbstractContainer implements
+ Container.Indexed, Container.Sortable, Container.Filterable,
+ Container.PropertySetChangeNotifier, Container.ItemSetChangeNotifier {
+
+ private final Container.Indexed wrappedContainer;
+ private final Map<Object, PropertyValueGenerator<?>> propertyGenerators;
+ private final Map<Filter, List<Filter>> activeFilters;
+ private Sortable sortableContainer = null;
+ private Filterable filterableContainer = null;
+
+ /**
+ * Property implementation for generated properties
+ */
+ protected static class GeneratedProperty<T> implements Property<T> {
+
+ private Item item;
+ private Object itemId;
+ private Object propertyId;
+ private PropertyValueGenerator<T> generator;
+
+ public GeneratedProperty(Item item, Object propertyId, Object itemId,
+ PropertyValueGenerator<T> generator) {
+ this.item = item;
+ this.itemId = itemId;
+ this.propertyId = propertyId;
+ this.generator = generator;
+ }
+
+ @Override
+ public T getValue() {
+ return generator.getValue(item, itemId, propertyId);
+ }
+
+ @Override
+ public void setValue(T newValue) throws ReadOnlyException {
+ throw new ReadOnlyException("Generated properties are read only");
+ }
+
+ @Override
+ public Class<? extends T> getType() {
+ return generator.getType();
+ }
+
+ @Override
+ public boolean isReadOnly() {
+ return true;
+ }
+
+ @Override
+ public void setReadOnly(boolean newStatus) {
+ if (newStatus) {
+ // No-op
+ return;
+ }
+ throw new UnsupportedOperationException(
+ "Generated properties are read only");
+ }
+ }
+
+ /**
+ * Item implementation for generated properties.
+ */
+ protected static class GeneratedPropertyItem implements Item {
+
+ private Map<Object, Property<?>> generatedProperties = new HashMap<Object, Property<?>>();
+ Item wrappedItem;
+ Object itemId;
+
+ protected GeneratedPropertyItem(Object itemId, Item item) {
+ this.itemId = itemId;
+ wrappedItem = item;
+ }
+
+ @Override
+ public Property getItemProperty(Object id) {
+ if (generatedProperties.containsKey(id)) {
+ return generatedProperties.get(id);
+ }
+ return wrappedItem.getItemProperty(id);
+ }
+
+ @Override
+ public Collection<?> getItemPropertyIds() {
+ return Sets.union(asSet(wrappedItem.getItemPropertyIds()),
+ asSet(generatedProperties.keySet()));
+ }
+
+ @Override
+ public boolean addItemProperty(Object id, Property property)
+ throws UnsupportedOperationException {
+ generatedProperties.put(id, property);
+ return true;
+ }
+
+ @Override
+ public boolean removeItemProperty(Object id)
+ throws UnsupportedOperationException {
+ return generatedProperties.remove(id) != null;
+ }
+ };
+
+ /**
+ * Constructor for GeneratedPropertyContainer.
+ *
+ * @param container
+ * underlying indexed container
+ */
+ public GeneratedPropertyContainer(Container.Indexed container) {
+ wrappedContainer = container;
+ propertyGenerators = new HashMap<Object, PropertyValueGenerator<?>>();
+
+ if (wrappedContainer instanceof Sortable) {
+ sortableContainer = (Sortable) wrappedContainer;
+ }
+
+ if (wrappedContainer instanceof Filterable) {
+ activeFilters = new HashMap<Filter, List<Filter>>();
+ filterableContainer = (Filterable) wrappedContainer;
+ } else {
+ activeFilters = null;
+ }
+
+ // ItemSetChangeEvents
+ if (wrappedContainer instanceof ItemSetChangeNotifier) {
+ ((ItemSetChangeNotifier) wrappedContainer)
+ .addItemSetChangeListener(new ItemSetChangeListener() {
+
+ @Override
+ public void containerItemSetChange(
+ ItemSetChangeEvent event) {
+ fireItemSetChange();
+ }
+ });
+ }
+
+ // PropertySetChangeEvents
+ if (wrappedContainer instanceof PropertySetChangeNotifier) {
+ ((PropertySetChangeNotifier) wrappedContainer)
+ .addPropertySetChangeListener(new PropertySetChangeListener() {
+
+ @Override
+ public void containerPropertySetChange(
+ PropertySetChangeEvent event) {
+ fireContainerPropertySetChange();
+ }
+ });
+ }
+ }
+
+ /* Functions related to generated properties */
+
+ /**
+ * Add a new PropertyValueGenerator with given property id. This will
+ * override any existing properties with the same property id. Fires a
+ * PropertySetChangeEvent.
+ *
+ * @param propertyId
+ * property id
+ * @param generator
+ * a property value generator
+ */
+ public void addGeneratedProperty(Object propertyId,
+ PropertyValueGenerator<?> generator) {
+ propertyGenerators.put(propertyId, generator);
+ fireContainerPropertySetChange();
+ }
+
+ /**
+ * Removes any possible PropertyValueGenerator with given property id. Fires
+ * a PropertySetChangeEvent.
+ *
+ * @param propertyId
+ * property id
+ */
+ public void removeGeneratedProperty(Object propertyId) {
+ if (propertyGenerators.containsKey(propertyId)) {
+ propertyGenerators.remove(propertyId);
+ fireContainerPropertySetChange();
+ }
+ }
+
+ private Item createGeneratedPropertyItem(final Object itemId,
+ final Item item) {
+ Item generatedItem = new GeneratedPropertyItem(itemId, item);
+
+ for (Object propertyId : propertyGenerators.keySet()) {
+ generatedItem.addItemProperty(
+ propertyId,
+ createProperty(item, propertyId, itemId,
+ propertyGenerators.get(propertyId)));
+ }
+ return generatedItem;
+ }
+
+ private <T> Property<T> createProperty(final Item item,
+ final Object propertyId, final Object itemId,
+ final PropertyValueGenerator<T> generator) {
+ return new GeneratedProperty<T>(item, propertyId, itemId, generator);
+ }
+
+ private static <T> Set<T> asSet(Collection<T> collection) {
+ if (collection instanceof Set) {
+ return (Set<T>) collection;
+ } else {
+ return new HashSet<T>(collection);
+ }
+ }
+
+ /* Listener functionality */
+
+ @Override
+ public void addItemSetChangeListener(ItemSetChangeListener listener) {
+ super.addItemSetChangeListener(listener);
+ }
+
+ @Override
+ public void addListener(ItemSetChangeListener listener) {
+ super.addListener(listener);
+ }
+
+ @Override
+ public void removeItemSetChangeListener(ItemSetChangeListener listener) {
+ super.removeItemSetChangeListener(listener);
+ }
+
+ @Override
+ public void removeListener(ItemSetChangeListener listener) {
+ super.removeListener(listener);
+ }
+
+ @Override
+ public void addPropertySetChangeListener(PropertySetChangeListener listener) {
+ super.addPropertySetChangeListener(listener);
+ }
+
+ @Override
+ public void addListener(PropertySetChangeListener listener) {
+ super.addListener(listener);
+ }
+
+ @Override
+ public void removePropertySetChangeListener(
+ PropertySetChangeListener listener) {
+ super.removePropertySetChangeListener(listener);
+ }
+
+ @Override
+ public void removeListener(PropertySetChangeListener listener) {
+ super.removeListener(listener);
+ }
+
+ /* Filtering functionality */
+
+ @Override
+ public void addContainerFilter(Filter filter)
+ throws UnsupportedFilterException {
+ if (filterableContainer == null) {
+ throw new UnsupportedOperationException(
+ "Wrapped container is not filterable");
+ }
+
+ List<Filter> addedFilters = new ArrayList<Filter>();
+ for (Entry<?, PropertyValueGenerator<?>> entry : propertyGenerators
+ .entrySet()) {
+ Object property = entry.getKey();
+ if (filter.appliesToProperty(property)) {
+ // Have generated property modify filter to fit the original
+ // data in the container.
+ Filter modifiedFilter = entry.getValue().modifyFilter(filter);
+ filterableContainer.addContainerFilter(modifiedFilter);
+ // Keep track of added filters
+ addedFilters.add(modifiedFilter);
+ }
+ }
+
+ if (addedFilters.isEmpty()) {
+ // No generated property modified this filter, use it as is
+ addedFilters.add(filter);
+ filterableContainer.addContainerFilter(filter);
+ }
+ // Map filter to actually added filters
+ activeFilters.put(filter, addedFilters);
+ }
+
+ @Override
+ public void removeContainerFilter(Filter filter) {
+ if (filterableContainer == null) {
+ throw new UnsupportedOperationException(
+ "Wrapped container is not filterable");
+ }
+
+ if (activeFilters.containsKey(filter)) {
+ for (Filter f : activeFilters.get(filter)) {
+ filterableContainer.removeContainerFilter(f);
+ }
+ activeFilters.remove(filter);
+ }
+ }
+
+ @Override
+ public void removeAllContainerFilters() {
+ if (filterableContainer == null) {
+ throw new UnsupportedOperationException(
+ "Wrapped container is not filterable");
+ }
+ filterableContainer.removeAllContainerFilters();
+ activeFilters.clear();
+ }
+
+ @Override
+ public Collection<Filter> getContainerFilters() {
+ if (filterableContainer == null) {
+ throw new UnsupportedOperationException(
+ "Wrapped container is not filterable");
+ }
+ return Collections.unmodifiableSet(activeFilters.keySet());
+ }
+
+ /* Sorting functionality */
+
+ @Override
+ public void sort(Object[] propertyId, boolean[] ascending) {
+ if (sortableContainer == null) {
+ new UnsupportedOperationException(
+ "Wrapped container is not Sortable");
+ }
+
+ if (propertyId.length == 0) {
+ sortableContainer.sort(propertyId, ascending);
+ return;
+ }
+
+ List<Object> actualSortProperties = new ArrayList<Object>();
+ List<Boolean> actualSortDirections = new ArrayList<Boolean>();
+
+ for (int i = 0; i < propertyId.length; ++i) {
+ Object property = propertyId[i];
+ SortDirection direction;
+ boolean isAscending = i < ascending.length ? ascending[i] : true;
+ if (isAscending) {
+ direction = SortDirection.ASCENDING;
+ } else {
+ direction = SortDirection.DESCENDING;
+ }
+
+ if (propertyGenerators.containsKey(property)) {
+ // Sorting by a generated property. Generated property should
+ // modify sort orders to work with original properties in the
+ // container.
+ for (SortOrder s : propertyGenerators.get(property)
+ .getSortProperties(new SortOrder(property, direction))) {
+ actualSortProperties.add(s.getPropertyId());
+ actualSortDirections
+ .add(s.getDirection() == SortDirection.ASCENDING);
+ }
+ } else {
+ actualSortProperties.add(property);
+ actualSortDirections.add(isAscending);
+ }
+ }
+
+ boolean[] actualAscending = new boolean[actualSortDirections.size()];
+ for (int i = 0; i < actualAscending.length; ++i) {
+ actualAscending[i] = actualSortDirections.get(i);
+ }
+
+ sortableContainer.sort(actualSortProperties.toArray(), actualAscending);
+ }
+
+ @Override
+ public Collection<?> getSortableContainerPropertyIds() {
+ if (sortableContainer == null) {
+ new UnsupportedOperationException(
+ "Wrapped container is not Sortable");
+ }
+
+ Set<Object> sortablePropertySet = new HashSet<Object>(
+ sortableContainer.getSortableContainerPropertyIds());
+ for (Entry<?, PropertyValueGenerator<?>> entry : propertyGenerators
+ .entrySet()) {
+ Object property = entry.getKey();
+ SortOrder order = new SortOrder(property, SortDirection.ASCENDING);
+ if (entry.getValue().getSortProperties(order).length > 0) {
+ sortablePropertySet.add(property);
+ } else {
+ sortablePropertySet.remove(property);
+ }
+ }
+
+ return sortablePropertySet;
+ }
+
+ /* Item related overrides */
+
+ @Override
+ public Item addItemAfter(Object previousItemId, Object newItemId)
+ throws UnsupportedOperationException {
+ Item item = wrappedContainer.addItemAfter(previousItemId, newItemId);
+ return createGeneratedPropertyItem(newItemId, item);
+ }
+
+ @Override
+ public Item addItem(Object itemId) throws UnsupportedOperationException {
+ Item item = wrappedContainer.addItem(itemId);
+ return createGeneratedPropertyItem(itemId, item);
+ }
+
+ @Override
+ public Item addItemAt(int index, Object newItemId)
+ throws UnsupportedOperationException {
+ Item item = wrappedContainer.addItemAt(index, newItemId);
+ return createGeneratedPropertyItem(newItemId, item);
+ }
+
+ @Override
+ public Item getItem(Object itemId) {
+ Item item = wrappedContainer.getItem(itemId);
+ return createGeneratedPropertyItem(itemId, item);
+ }
+
+ /* Property related overrides */
+
+ @SuppressWarnings("rawtypes")
+ @Override
+ public Property getContainerProperty(Object itemId, Object propertyId) {
+ if (propertyGenerators.keySet().contains(propertyId)) {
+ return getItem(itemId).getItemProperty(propertyId);
+ } else {
+ return wrappedContainer.getContainerProperty(itemId, propertyId);
+ }
+ }
+
+ @Override
+ public Collection<?> getContainerPropertyIds() {
+ return Sets.union(asSet(wrappedContainer.getContainerPropertyIds()),
+ asSet(propertyGenerators.keySet()));
+ }
+
+ /* Type related overrides */
+
+ @Override
+ public Class<?> getType(Object propertyId) {
+ if (propertyGenerators.containsKey(propertyId)) {
+ return propertyGenerators.get(propertyId).getType();
+ } else {
+ return wrappedContainer.getType(propertyId);
+ }
+ }
+
+ /* Unmodified functions */
+
+ @Override
+ public Object nextItemId(Object itemId) {
+ return wrappedContainer.nextItemId(itemId);
+ }
+
+ @Override
+ public Object prevItemId(Object itemId) {
+ return wrappedContainer.prevItemId(itemId);
+ }
+
+ @Override
+ public Object firstItemId() {
+ return wrappedContainer.firstItemId();
+ }
+
+ @Override
+ public Object lastItemId() {
+ return wrappedContainer.lastItemId();
+ }
+
+ @Override
+ public boolean isFirstId(Object itemId) {
+ return wrappedContainer.isFirstId(itemId);
+ }
+
+ @Override
+ public boolean isLastId(Object itemId) {
+ return wrappedContainer.isLastId(itemId);
+ }
+
+ @Override
+ public Object addItemAfter(Object previousItemId)
+ throws UnsupportedOperationException {
+ return wrappedContainer.addItemAfter(previousItemId);
+ }
+
+ @Override
+ public Collection<?> getItemIds() {
+ return wrappedContainer.getItemIds();
+ }
+
+ @Override
+ public int size() {
+ return wrappedContainer.size();
+ }
+
+ @Override
+ public boolean containsId(Object itemId) {
+ return wrappedContainer.containsId(itemId);
+ }
+
+ @Override
+ public Object addItem() throws UnsupportedOperationException {
+ return wrappedContainer.addItem();
+ }
+
+ @Override
+ public boolean removeItem(Object itemId)
+ throws UnsupportedOperationException {
+ return wrappedContainer.removeItem(itemId);
+ }
+
+ @Override
+ public boolean addContainerProperty(Object propertyId, Class<?> type,
+ Object defaultValue) throws UnsupportedOperationException {
+ return wrappedContainer.addContainerProperty(propertyId, type,
+ defaultValue);
+ }
+
+ @Override
+ public boolean removeContainerProperty(Object propertyId)
+ throws UnsupportedOperationException {
+ return wrappedContainer.removeContainerProperty(propertyId);
+ }
+
+ @Override
+ public boolean removeAllItems() throws UnsupportedOperationException {
+ return wrappedContainer.removeAllItems();
+ }
+
+ @Override
+ public int indexOfId(Object itemId) {
+ return wrappedContainer.indexOfId(itemId);
+ }
+
+ @Override
+ public Object getIdByIndex(int index) {
+ return wrappedContainer.getIdByIndex(index);
+ }
+
+ @Override
+ public List<?> getItemIds(int startIndex, int numberOfItems) {
+ return wrappedContainer.getItemIds(startIndex, numberOfItems);
+ }
+
+ @Override
+ public Object addItemAt(int index) throws UnsupportedOperationException {
+ return wrappedContainer.addItemAt(index);
+ }
+}
diff --git a/server/src/com/vaadin/data/util/IndexedContainer.java b/server/src/com/vaadin/data/util/IndexedContainer.java
index 68960335d7..f9cc4c482a 100644
--- a/server/src/com/vaadin/data/util/IndexedContainer.java
+++ b/server/src/com/vaadin/data/util/IndexedContainer.java
@@ -226,6 +226,7 @@ public class IndexedContainer extends
@Override
public boolean removeAllItems() {
int origSize = size();
+ Object firstItem = getFirstVisibleItem();
internalRemoveAllItems();
@@ -235,7 +236,7 @@ public class IndexedContainer extends
// filtered out items were removed or not
if (origSize != 0) {
// Sends a change event
- fireItemSetChange();
+ fireItemsRemoved(0, firstItem, origSize);
}
return true;
@@ -620,8 +621,7 @@ public class IndexedContainer extends
@Override
protected void fireItemAdded(int position, Object itemId, Item item) {
if (position >= 0) {
- fireItemSetChange(new IndexedContainer.ItemSetChangeEvent(this,
- position));
+ super.fireItemAdded(position, itemId, item);
}
}
@@ -1211,4 +1211,5 @@ public class IndexedContainer extends
public Collection<Filter> getContainerFilters() {
return super.getContainerFilters();
}
+
}
diff --git a/server/src/com/vaadin/data/util/PropertyValueGenerator.java b/server/src/com/vaadin/data/util/PropertyValueGenerator.java
new file mode 100644
index 0000000000..88169b785b
--- /dev/null
+++ b/server/src/com/vaadin/data/util/PropertyValueGenerator.java
@@ -0,0 +1,100 @@
+/*
+ * 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 com.vaadin.data.util;
+
+import java.io.Serializable;
+
+import com.vaadin.data.Container.Filter;
+import com.vaadin.data.Item;
+import com.vaadin.data.Property;
+import com.vaadin.data.util.filter.UnsupportedFilterException;
+import com.vaadin.ui.components.grid.sort.SortOrder;
+
+/**
+ * PropertyValueGenerator for GeneratedPropertyContainer.
+ *
+ * @param <T>
+ * Property data type
+ * @since
+ * @author Vaadin Ltd
+ */
+public abstract class PropertyValueGenerator<T> implements Serializable {
+
+ /**
+ * Returns value for given Item. Used by GeneratedPropertyContainer when
+ * generating new properties.
+ *
+ * @param item
+ * currently handled item
+ * @param itemId
+ * item id for currently handled item
+ * @param propertyId
+ * id for this property
+ * @return generated value
+ */
+ public abstract T getValue(Item item, Object itemId, Object propertyId);
+
+ /**
+ * Return Property type for this generator. This function is called when
+ * {@link Property#getType()} is called for generated property.
+ *
+ * @return type of generated property
+ */
+ public abstract Class<T> getType();
+
+ /**
+ * Translates sorting of the generated property in a specific direction to a
+ * set of property ids and directions in the underlying container.
+ *
+ * SortOrder is similar to (or the same as) the SortOrder already defined
+ * for Grid.
+ *
+ * The default implementation of this method returns an empty array, which
+ * means that the property will not be included in
+ * getSortableContainerPropertyIds(). Attempting to sort by that column
+ * throws UnsupportedOperationException.
+ *
+ * Returning null is not allowed.
+ *
+ * @param order
+ * a sort order for this property
+ * @return an array of sort orders describing how this property is sorted
+ */
+ public SortOrder[] getSortProperties(SortOrder order) {
+ return new SortOrder[] {};
+ }
+
+ /**
+ * Return an updated filter that should be compatible with the underlying
+ * container.
+ *
+ * This function is called when setting a filter for this generated
+ * property. Returning null from this function causes
+ * GeneratedPropertyContainer to discard the filter and not use it.
+ *
+ * By default this function throws UnsupportedFilterException.
+ *
+ * @param filter
+ * original filter for this property
+ * @return modified filter that is compatible with the underlying container
+ * @throws UnsupportedFilterException
+ */
+ public Filter modifyFilter(Filter filter) throws UnsupportedFilterException {
+ throw new UnsupportedFilterException("Filter" + filter
+ + " is not supported");
+ }
+
+}