/* * Copyright 2010, Andrew M Gibson * * www.andygibson.net * * This file is part of DataValve. * * DataValve is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * DataValve is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * * You should have received a copy of the GNU Lesser General Public License * along with DataValve. If not, see <http://www.gnu.org/licenses/>. * */ package org.fluttercode.datavalve.provider; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import org.fluttercode.datavalve.DataProvider; import org.fluttercode.datavalve.DefaultPaginator; import org.fluttercode.datavalve.Paginator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Implementation of a {@link DataProvider} that acts as an adapter onto another * data provider and makes it an in memory data provider. It does this by * pre-fetching the data from the underlying data provider and holding it * locally in memory. There are a couple of reasons to use this : * <ul> * <li>Caching data from a slow data store in memory for reuse</li> * <li>Allowing multiple independent data sources to work from a single in * memory store by keeping separate lists of the data in the adapter. Note that * while the lists are independent, the actual objects in the list are shared.</li> * </ul> * To use, just create an instance of this data provider and pass it the * {@link DataProvider} to source the data from. This provider can also use the * in memory sorting facilities using comparators. * * @author Andy Gibson * * @param <T> * The type of object this provider will return. */ public class InMemoryAdapterProvider<T> extends InMemoryDataProvider<T> implements Serializable{ private static final long serialVersionUID = 1L; private static Logger log = LoggerFactory .getLogger(InMemoryAdapterProvider.class); private DataProvider<T> provider; private List<T> backingData; public InMemoryAdapterProvider() { super(); } public InMemoryAdapterProvider(DataProvider<T> provider) { setProvider(provider); } @Override protected List<T> fetchBackingData() { if (backingData == null) { generateBackingData(); } invalidateData(); return backingData; } private void generateBackingData() { if (provider == null) { throw new NullPointerException("Provider is null"); } log.debug("Fetching backing data from provider"); log.debug("provider = " + provider); Paginator p = new DefaultPaginator(); p.setFirstResult(0); p.setMaxRows(null); List<T> results = provider.fetchResults(p); List<T> temp = new ArrayList<T>(results.size()); for (T item : results) { temp.add(item); } backingData = temp; } public void setProvider(DataProvider<T> provider) { if (this.provider != provider) { this.provider = provider; //to be helpful, if we are sourcing from an {@link InMemoryDataProvider} //then try and automatically assign the order key information if (provider instanceof InMemoryDataProvider<?>) { InMemoryDataProvider<T> imProvider = (InMemoryDataProvider<T>) provider; getOrderKeyMap().clear(); getOrderKeyMap().putAll(imProvider.getOrderKeyMap()); } invalidateData(); } } }