blob: 51f54a959ee9c204aafda020b672b71bda63676b [file] [log] [blame]
/**
* Copyright (c) 2011, 2015 - Lunifera GmbH (Gross Enzersdorf, Austria), Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Florian Pirchner - Initial implementation
*/
package org.eclipse.osbp.runtime.web.vaadin.common.data;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.osbp.dsl.dto.lib.services.SortBy;
import org.eclipse.osbp.dsl.dto.lib.services.SortOrder;
import org.eclipse.osbp.runtime.common.annotations.DtoUtils;
import org.eclipse.osbp.runtime.common.state.ISharedStateContext;
import org.eclipse.osbp.runtime.common.state.SharedStateUnitOfWork;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.vaadin.data.Container;
import com.vaadin.data.Container.Filterable;
import com.vaadin.data.Container.Indexed;
import com.vaadin.data.Container.SimpleFilterable;
import com.vaadin.data.Container.Sortable;
import com.vaadin.data.Item;
import com.vaadin.data.Property;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.Property.ValueChangeListener;
import com.vaadin.data.util.AbstractContainer;
import com.vaadin.data.util.NestedPropertyDescriptor;
import com.vaadin.data.util.VaadinPropertyDescriptor;
import com.vaadin.data.util.filter.SimpleStringFilter;
import com.vaadin.data.util.filter.UnsupportedFilterException;
// TODO: Auto-generated Javadoc
/**
* The Class BeanServiceLazyLoadingContainer.
*
* @param <BEANTYPE>
* the generic type
*/
@SuppressWarnings("serial")
public class BeanServiceLazyLoadingContainer<BEANTYPE> extends
AbstractContainer implements Filterable, Indexed, SimpleFilterable,
ILazyRefreshFilterable, Sortable, ValueChangeListener,
Container.ItemSetChangeNotifier, Container.PropertySetChangeNotifier,
IClearable, INestedPropertyAble<BEANTYPE> {
/** The Constant LOGGER. */
private static final Logger LOGGER = LoggerFactory
.getLogger(BeanServiceLazyLoadingContainer.class);
/** The service. */
private IBeanSearchService<BEANTYPE> service;
/** The sort order. */
private SortOrder sortOrder = new SortOrder();
/** The filters. */
private List<Filter> filters = new ArrayList<Filter>();
/** The type. */
private Class<BEANTYPE> type;
/** The sortable properties. */
private Set<String> sortableProperties = new HashSet<String>();
/** The model. */
private LinkedHashMap<String, VaadinPropertyDescriptor<BEANTYPE>> model;
/** The cache. */
private Map<Object, DeepResolvingBeanItem<BEANTYPE>> cache = new HashMap<Object, DeepResolvingBeanItem<BEANTYPE>>();
/** The external cache. */
// new records that have been added from outside -> new records
private Map<Object, DeepResolvingBeanItem<BEANTYPE>> externalCache = new HashMap<Object, DeepResolvingBeanItem<BEANTYPE>>();
/** The shared state. */
private final ISharedStateContext sharedState;
/**
* Instantiates a new bean service lazy loading container.
*
* @param service
* the service
* @param type
* the type
* @param sharedState
* the shared state
*/
public BeanServiceLazyLoadingContainer(
IBeanSearchService<BEANTYPE> service, Class<BEANTYPE> type,
ISharedStateContext sharedState) {
this.service = service != null ? service
: new StatefulInMemoryBeanSearchService<BEANTYPE>(type);
this.type = type;
model = DeepResolvingBeanItem
.getPropertyDescriptors((Class<BEANTYPE>) type);
// create all sortable columns
for (String column : model.keySet()) {
if (DtoUtils.isDirtyField(type, column)) {
continue;
}
sortableProperties.add(column);
}
this.sharedState = sharedState;
}
/* (non-Javadoc)
* @see com.vaadin.data.util.AbstractContainer#addListener(com.vaadin.data.Container.PropertySetChangeListener)
*/
@Override
public void addListener(PropertySetChangeListener listener) {
super.addPropertySetChangeListener(listener);
}
/* (non-Javadoc)
* @see com.vaadin.data.util.AbstractContainer#removeListener(com.vaadin.data.Container.PropertySetChangeListener)
*/
@Override
public void removeListener(PropertySetChangeListener listener) {
super.removePropertySetChangeListener(listener);
}
/* (non-Javadoc)
* @see com.vaadin.data.util.AbstractContainer#addListener(com.vaadin.data.Container.ItemSetChangeListener)
*/
@Override
public void addListener(ItemSetChangeListener listener) {
super.addItemSetChangeListener(listener);
}
/* (non-Javadoc)
* @see com.vaadin.data.util.AbstractContainer#removeListener(com.vaadin.data.Container.ItemSetChangeListener)
*/
@Override
public void removeListener(ItemSetChangeListener listener) {
super.removeItemSetChangeListener(listener);
}
/* (non-Javadoc)
* @see com.vaadin.data.util.AbstractContainer#addPropertySetChangeListener(com.vaadin.data.Container.PropertySetChangeListener)
*/
@Override
public void addPropertySetChangeListener(PropertySetChangeListener listener) {
super.addPropertySetChangeListener(listener);
}
/* (non-Javadoc)
* @see com.vaadin.data.util.AbstractContainer#removePropertySetChangeListener(com.vaadin.data.Container.PropertySetChangeListener)
*/
@Override
public void removePropertySetChangeListener(
PropertySetChangeListener listener) {
super.removePropertySetChangeListener(listener);
}
/* (non-Javadoc)
* @see com.vaadin.data.util.AbstractContainer#addItemSetChangeListener(com.vaadin.data.Container.ItemSetChangeListener)
*/
@Override
public void addItemSetChangeListener(ItemSetChangeListener listener) {
super.addItemSetChangeListener(listener);
}
/* (non-Javadoc)
* @see com.vaadin.data.util.AbstractContainer#removeItemSetChangeListener(com.vaadin.data.Container.ItemSetChangeListener)
*/
@Override
public void removeItemSetChangeListener(ItemSetChangeListener listener) {
super.removeItemSetChangeListener(listener);
}
/**
* Adds the item.
*
* @param itemId
* the item id
* @param bean
* the bean
* @return the deep resolving bean item
*/
protected DeepResolvingBeanItem<BEANTYPE> addItem(Object itemId,
BEANTYPE bean) {
return addBean(bean);
}
/**
* Internal add item at end.
*
* @param newItemId
* the new item id
* @param item
* the item
* @return the deep resolving bean item
*/
protected DeepResolvingBeanItem<BEANTYPE> internalAddItemAtEnd(
Object newItemId, DeepResolvingBeanItem<BEANTYPE> item) {
if (externalCache.containsKey(newItemId)) {
cache.put(newItemId, externalCache.get(newItemId));
} else {
cache.put(newItemId, item);
}
return item;
}
/**
* Creates the bean item.
*
* @param bean
* the bean
* @return the deep resolving bean item
*/
protected DeepResolvingBeanItem<BEANTYPE> createBeanItem(BEANTYPE bean) {
return bean == null ? null : new DeepResolvingBeanItem<BEANTYPE>(bean,
model);
}
/* (non-Javadoc)
* @see com.vaadin.data.Container.Ordered#nextItemId(java.lang.Object)
*/
@SuppressWarnings("unchecked")
@Override
public Object nextItemId(final Object itemId) {
if (sharedState != null) {
return new SharedStateUnitOfWork<Object>() {
@Override
protected Object doExecute() {
return service.getNextBean((BEANTYPE) itemId, filters,
sortOrder);
}
}.execute(sharedState);
} else {
return mapToCachedId(service.getNextBean((BEANTYPE) itemId,
filters, sortOrder));
}
}
/* (non-Javadoc)
* @see com.vaadin.data.Container.Ordered#prevItemId(java.lang.Object)
*/
@SuppressWarnings("unchecked")
@Override
public Object prevItemId(final Object itemId) {
if (sharedState != null) {
return new SharedStateUnitOfWork<Object>() {
@Override
protected Object doExecute() {
return service.getPreviousBean((BEANTYPE) itemId, filters,
sortOrder);
}
}.execute(sharedState);
} else {
return mapToCachedId(service.getPreviousBean((BEANTYPE) itemId,
filters, sortOrder));
}
}
/* (non-Javadoc)
* @see com.vaadin.data.Container.Ordered#firstItemId()
*/
@Override
public Object firstItemId() {
if (sharedState != null) {
return new SharedStateUnitOfWork<Object>() {
@Override
protected Object doExecute() {
return service.getFirstBean(filters, sortOrder);
}
}.execute(sharedState);
} else {
return mapToCachedId(service.getFirstBean(filters, sortOrder));
}
}
/* (non-Javadoc)
* @see com.vaadin.data.Container.Ordered#lastItemId()
*/
@Override
public Object lastItemId() {
if (sharedState != null) {
return new SharedStateUnitOfWork<Object>() {
@Override
protected Object doExecute() {
return service.getLastBean(filters, sortOrder);
}
}.execute(sharedState);
} else {
return mapToCachedId(service.getLastBean(filters, sortOrder));
}
}
/* (non-Javadoc)
* @see com.vaadin.data.Container.Ordered#isFirstId(java.lang.Object)
*/
@SuppressWarnings("unchecked")
@Override
public boolean isFirstId(final Object itemId) {
if (sharedState != null) {
return new SharedStateUnitOfWork<Boolean>() {
@Override
protected Boolean doExecute() {
return service.isFirstBean((BEANTYPE) itemId, filters,
sortOrder);
}
}.execute(sharedState);
} else {
return service.isFirstBean((BEANTYPE) itemId, filters, sortOrder);
}
}
/* (non-Javadoc)
* @see com.vaadin.data.Container.Ordered#isLastId(java.lang.Object)
*/
@SuppressWarnings("unchecked")
@Override
public boolean isLastId(final Object itemId) {
if (sharedState != null) {
return new SharedStateUnitOfWork<Boolean>() {
@Override
protected Boolean doExecute() {
return service.isLastBean((BEANTYPE) itemId, filters,
sortOrder);
}
}.execute(sharedState);
} else {
return service.isLastBean((BEANTYPE) itemId, filters, sortOrder);
}
}
/* (non-Javadoc)
* @see com.vaadin.data.Container.Ordered#addItemAfter(java.lang.Object)
*/
@Override
public Object addItemAfter(Object previousItemId)
throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
/* (non-Javadoc)
* @see com.vaadin.data.Container.Ordered#addItemAfter(java.lang.Object, java.lang.Object)
*/
@Override
public Item addItemAfter(Object previousItemId, Object newItemId)
throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
/* (non-Javadoc)
* @see com.vaadin.data.Container#getItem(java.lang.Object)
*/
@SuppressWarnings("unchecked")
@Override
public Item getItem(Object itemId) {
if (cache.containsKey(itemId)) {
return cache.get(itemId);
} else if (externalCache.containsKey(itemId)) {
return externalCache.get(itemId);
}
return addBean((BEANTYPE) itemId);
}
/* (non-Javadoc)
* @see com.vaadin.data.Container#getContainerPropertyIds()
*/
@Override
public Collection<?> getContainerPropertyIds() {
return model.keySet();
}
/* (non-Javadoc)
* @see com.vaadin.data.Container#getItemIds()
*/
@Override
public Collection<?> getItemIds() {
// Due to directly call of this method by com.vaadin.ui.ListSelect
// without a previous calculation of pagesize a fix pagesize of 100
// elements will be set in this method.
@SuppressWarnings("unchecked")
// List<Object> itemIds = new ArrayList<Object>();
List<Object> itemIds = (List<Object>) getItemIds(0, 100);
if (itemIds.size() == 0) {
itemIds.addAll(cache.keySet());
itemIds.addAll(externalCache.keySet());
}
return itemIds;
}
/* (non-Javadoc)
* @see com.vaadin.data.Container#getContainerProperty(java.lang.Object, java.lang.Object)
*/
@Override
public Property<?> getContainerProperty(Object itemId, Object propertyId) {
Item item = getItem(itemId);
if (item == null) {
return null;
}
return item.getItemProperty(propertyId);
}
/* (non-Javadoc)
* @see com.vaadin.data.Container#getType(java.lang.Object)
*/
@Override
public Class<?> getType(Object propertyId) {
return model.get(propertyId).getPropertyType();
}
/* (non-Javadoc)
* @see com.vaadin.data.Container#size()
*/
@Override
public int size() {
if (sharedState != null) {
return new SharedStateUnitOfWork<Integer>() {
@Override
protected Integer doExecute() {
return service.size(filters) + externalCache.size();
}
}.execute(sharedState);
} else {
return service.size(filters) + externalCache.size();
}
}
/* (non-Javadoc)
* @see com.vaadin.data.Container#containsId(java.lang.Object)
*/
@SuppressWarnings("unchecked")
@Override
public boolean containsId(final Object itemId) {
if (cache.containsKey(itemId) || externalCache.containsKey(itemId)) {
return true;
}
if (sharedState != null) {
return new SharedStateUnitOfWork<Boolean>() {
@Override
protected Boolean doExecute() {
return service.contains((BEANTYPE) itemId, filters);
}
}.execute(sharedState);
} else {
return service.contains((BEANTYPE) itemId, filters);
}
}
/* (non-Javadoc)
* @see com.vaadin.data.Container#addItem(java.lang.Object)
*/
@SuppressWarnings("unchecked")
@Override
public Item addItem(Object itemId) throws UnsupportedOperationException {
// external data -> new record
return addBean((BEANTYPE) itemId, true);
}
/* (non-Javadoc)
* @see com.vaadin.data.Container#addItem()
*/
@Override
public Object addItem() throws UnsupportedOperationException {
throw new UnsupportedOperationException("Bean required for new item!");
}
/* (non-Javadoc)
* @see com.vaadin.data.Container#removeItem(java.lang.Object)
*/
@Override
public boolean removeItem(Object itemId)
throws UnsupportedOperationException {
throw new UnsupportedOperationException(
"Does not support deleting item!");
}
/* (non-Javadoc)
* @see com.vaadin.data.Container#addContainerProperty(java.lang.Object, java.lang.Class, java.lang.Object)
*/
@Override
public boolean addContainerProperty(Object propertyId, Class<?> type,
Object defaultValue) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
/* (non-Javadoc)
* @see com.vaadin.data.Container#removeContainerProperty(java.lang.Object)
*/
@Override
public boolean removeContainerProperty(Object propertyId)
throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.osbp.runtime.web.vaadin.common.data.INestedPropertyAble#
* addNestedContainerProperty(java.lang.String)
*/
@Override
@SuppressWarnings({ "rawtypes", "unchecked" })
public boolean addNestedContainerProperty(String propertyId) {
return addContainerProperty(propertyId, new NestedPropertyDescriptor(
propertyId, type));
}
/**
* Adds a property for the container and all its items.
*
* Primarily for internal use, may change in future versions.
*
* @param propertyId
* the property id
* @param propertyDescriptor
* the property descriptor
* @return true if the property was added
*/
protected final boolean addContainerProperty(String propertyId,
VaadinPropertyDescriptor<BEANTYPE> propertyDescriptor) {
if (null == propertyId || null == propertyDescriptor) {
return false;
}
// Fails if the Property is already present
if (model.containsKey(propertyId)) {
return false;
}
model.put(propertyId, propertyDescriptor);
// add to sortable properties
sortableProperties.add(propertyId);
// Sends a change event
fireContainerPropertySetChange();
return true;
}
/* (non-Javadoc)
* @see com.vaadin.data.Container#removeAllItems()
*/
@Override
public boolean removeAllItems() throws UnsupportedOperationException {
throw new UnsupportedOperationException(
"Does not support deleting all items!");
}
/* (non-Javadoc)
* @see com.vaadin.data.Property.ValueChangeListener#valueChange(com.vaadin.data.Property.ValueChangeEvent)
*/
@Override
public void valueChange(ValueChangeEvent event) {
}
/* (non-Javadoc)
* @see com.vaadin.data.Container.Sortable#sort(java.lang.Object[], boolean[])
*/
@Override
public void sort(Object[] propertyIds, boolean[] ascending) {
sortOrder.clear();
for (int i = 0; i < propertyIds.length; i++) {
sortOrder.add(new SortBy((String) propertyIds[i], ascending[i]));
}
clearCache();
fireItemSetChange();
}
/* (non-Javadoc)
* @see com.vaadin.data.Container.Sortable#getSortableContainerPropertyIds()
*/
@Override
public Collection<?> getSortableContainerPropertyIds() {
return sortableProperties;
}
/* (non-Javadoc)
* @see com.vaadin.data.Container.SimpleFilterable#addContainerFilter(java.lang.Object, java.lang.String, boolean, boolean)
*/
@Override
public void addContainerFilter(Object propertyId, String filterString,
boolean ignoreCase, boolean onlyMatchPrefix) {
addContainerFilter(new SimpleStringFilter(propertyId, filterString,
ignoreCase, onlyMatchPrefix));
}
/* (non-Javadoc)
* @see com.vaadin.data.Container.SimpleFilterable#removeContainerFilters(java.lang.Object)
*/
@Override
public void removeContainerFilters(Object propertyId) {
if (getFilters().isEmpty() || propertyId == null) {
return;
}
boolean result = false;
for (Iterator<Filter> iterator = getFilters().iterator(); iterator
.hasNext();) {
Filter f = iterator.next();
if (f.appliesToProperty(propertyId)) {
iterator.remove();
result = true;
}
}
if (result) {
clearCache();
}
}
/**
* Gets the filters.
*
* @return the filters
*/
protected List<Filter> getFilters() {
return filters;
}
/* (non-Javadoc)
* @see com.vaadin.data.Container.Filterable#addContainerFilter(com.vaadin.data.Container.Filter)
*/
@Override
public void addContainerFilter(Filter filter)
throws UnsupportedFilterException {
if (!filters.contains(filter)) {
filters.add(filter);
clearCache();
}
fireItemSetChange();
}
/**
* Clear cache.
*/
protected void clearCache() {
cache.clear();
}
/* (non-Javadoc)
* @see com.vaadin.data.Container.Filterable#removeContainerFilter(com.vaadin.data.Container.Filter)
*/
@Override
public void removeContainerFilter(Filter filter) {
if (filters.remove(filter)) {
clearCache();
}
}
/* (non-Javadoc)
* @see com.vaadin.data.Container.Filterable#removeAllContainerFilters()
*/
@Override
public void removeAllContainerFilters() {
filters.clear();
clearCache();
}
/* (non-Javadoc)
* @see com.vaadin.data.Container.Filterable#getContainerFilters()
*/
@Override
public Collection<Filter> getContainerFilters() {
return Collections.unmodifiableList(filters);
}
/* (non-Javadoc)
* @see org.eclipse.osbp.runtime.web.vaadin.common.data.ILazyRefreshFilterable#refreshFilters()
*/
@Override
public void refreshFilters() {
fireItemSetChange();
}
/* (non-Javadoc)
* @see com.vaadin.data.Container.Indexed#indexOfId(java.lang.Object)
*/
@SuppressWarnings("unchecked")
@Override
public int indexOfId(final Object itemId) {
if (sharedState != null) {
return new SharedStateUnitOfWork<Integer>() {
@Override
protected Integer doExecute() {
return service.indexOf((BEANTYPE) itemId, filters,
sortOrder);
}
}.execute(sharedState);
} else {
return service.indexOf((BEANTYPE) itemId, filters, sortOrder);
}
}
/* (non-Javadoc)
* @see com.vaadin.data.Container.Indexed#getIdByIndex(int)
*/
@Override
public Object getIdByIndex(final int index) {
if (sharedState != null) {
return new SharedStateUnitOfWork<BEANTYPE>() {
@Override
protected BEANTYPE doExecute() {
BEANTYPE result = null;
result = (BEANTYPE) service.getBeanByIndex(index, filters,
sortOrder);
addBean(result);
return result;
}
}.execute(sharedState);
} else {
BEANTYPE result = null;
result = (BEANTYPE) service.getBeanByIndex(index, filters,
sortOrder);
if (isCached(result)) {
result = mapToCachedId(result);
} else {
addBean(result);
}
return result;
}
}
/**
* Tries to find the itemId in the cache. If it does so, the cached instance
* is returned.<br>
* This method will NOT add the itemId to the cache.
*
* @param itemId
* the item id
* @return the beantype
*/
private BEANTYPE mapToCachedId(BEANTYPE itemId) {
if (!isCached(itemId)) {
return itemId;
}
if (cache.containsKey(itemId)) {
return cache.get(itemId).getBean();
} else if (externalCache.containsKey(itemId)) {
return externalCache.get(itemId).getBean();
}
return null;
}
/**
* Checks if is cached.
*
* @param bean
* the bean
* @return true, if is cached
*/
protected boolean isCached(Object bean) {
return cache.containsKey(bean) || externalCache.containsKey(bean);
}
/**
* Adds the bean.
*
* @param result
* the result
* @return the deep resolving bean item
*/
protected DeepResolvingBeanItem<BEANTYPE> addBean(BEANTYPE result) {
return addBean(result, false);
}
/**
* Adds the bean.
*
* @param result
* the result
* @param toExternalCache
* the to external cache
* @return the deep resolving bean item
*/
protected DeepResolvingBeanItem<BEANTYPE> addBean(BEANTYPE result,
boolean toExternalCache) {
return addBean(result, result, toExternalCache);
}
/**
* Adds the bean.
*
* @param itemId
* the item id
* @param result
* the result
* @param toExternalCache
* the to external cache
* @return the deep resolving bean item
*/
protected DeepResolvingBeanItem<BEANTYPE> addBean(Object itemId,
BEANTYPE result, boolean toExternalCache) {
if (cache.containsKey(itemId)) {
return cache.get(itemId);
}
if (externalCache.containsKey(itemId)) {
return externalCache.get(itemId);
}
DeepResolvingBeanItem<BEANTYPE> item = createBeanItem(result);
if (toExternalCache) {
externalCache.put(itemId, item);
}
return internalAddItemAtEnd(itemId, item);
}
/* (non-Javadoc)
* @see com.vaadin.data.Container.Indexed#getItemIds(int, int)
*/
@SuppressWarnings("unchecked")
@Override
public List<BEANTYPE> getItemIds(final int startIndex,
final int numberOfItems) {
LOGGER.debug(String.format(
"Fetching item ids: StartIndex:%d NumberOfItems:%d",
startIndex, numberOfItems));
if (sharedState != null) {
return new SharedStateUnitOfWork<List<BEANTYPE>>() {
@Override
protected List<BEANTYPE> doExecute() {
List<BEANTYPE> beans = new ArrayList<BEANTYPE>();
// beans.addAll((Collection<? extends BEANTYPE>)
// externalCache
// .keySet());
beans.addAll((List<BEANTYPE>) service.getBeansByIndex(
startIndex, numberOfItems, filters, sortOrder));
for (BEANTYPE bean : beans) {
addBean(bean);
LOGGER.debug(String.format("Fetched bean: %s",
bean.toString()));
}
return beans;
}
}.execute(sharedState);
} else {
List<BEANTYPE> beans = new ArrayList<BEANTYPE>();
beans.addAll((Collection<? extends BEANTYPE>) externalCache
.keySet());
// map the results to cached instances
for (BEANTYPE bean : service.getBeansByIndex(startIndex,
numberOfItems, filters, sortOrder)) {
if (isCached(bean)) {
beans.add(mapToCachedId(bean));
} else {
addBean(bean);
beans.add(bean);
}
}
return beans;
}
}
/* (non-Javadoc)
* @see com.vaadin.data.Container.Indexed#addItemAt(int)
*/
@Override
public Object addItemAt(int index) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
/* (non-Javadoc)
* @see com.vaadin.data.Container.Indexed#addItemAt(int, java.lang.Object)
*/
@SuppressWarnings("unchecked")
@Override
public Item addItemAt(int index, Object newItemId)
throws UnsupportedOperationException {
// external data -> new record
return addBean((BEANTYPE) newItemId, true);
}
/* (non-Javadoc)
* @see org.eclipse.osbp.runtime.web.vaadin.common.data.IClearable#clear()
*/
@Override
public void clear() {
cache.clear();
externalCache.clear();
}
}