| /** |
| * 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(); |
| } |
| } |