/*******************************************************************************
* Copyright (c) 2013 Luigi Sgro. 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:
* Luigi Sgro - initial API and implementation
******************************************************************************/
package com.quantcomponents.ui.marketdata;
import java.net.ConnectException;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import com.quantcomponents.core.exceptions.RequestFailedException;
import com.quantcomponents.core.model.BarSize;
import com.quantcomponents.core.model.DataType;
import com.quantcomponents.core.model.IContract;
import com.quantcomponents.core.model.IPrettyNamed;
import com.quantcomponents.core.model.ISeries;
import com.quantcomponents.core.model.ISeriesPoint;
import com.quantcomponents.core.model.ITaskMonitor;
import com.quantcomponents.marketdata.IMarketDataManager;
import com.quantcomponents.marketdata.IStockDatabase;
import com.quantcomponents.ui.core.IMonitorableContainer;
import com.quantcomponents.ui.core.IMonitorableContainerListener;
import com.quantcomponents.ui.core.IMutableMonitorableContainer;
public class MarketDataManagerPresentationWrapper implements IMarketDataManager, IPrettyNamed, IMonitorableContainer<StockDatabasePresentationWrapper> {
private final IMarketDataManager marketDataManager;
private final IMutableMonitorableContainer<IMarketDataManager, MarketDataManagerPresentationWrapper> parent;
private final Map<String, StockDatabasePresentationWrapper> wrappersByID = new ConcurrentHashMap<String, StockDatabasePresentationWrapper>();
private final Set<IMonitorableContainerListener<StockDatabasePresentationWrapper>> listeners = new CopyOnWriteArraySet<IMonitorableContainerListener<StockDatabasePresentationWrapper>>();
public MarketDataManagerPresentationWrapper(IMarketDataManager manager, IMutableMonitorableContainer<IMarketDataManager, MarketDataManagerPresentationWrapper> parent) {
this.marketDataManager = manager;
this.parent = parent;
}
public IMarketDataManager getMarketDataManager() {
return marketDataManager;
}
public IMutableMonitorableContainer<IMarketDataManager, MarketDataManagerPresentationWrapper> getParent() {
return parent;
}
@Override
public String getPrettyName() {
return getMarketDataManager().getPrettyName();
}
public void synchronizeStockDatabases() {
Collection<IStockDatabase> stockDatabases = getMarketDataManager().allStockDatabases();
Set<String> stockDbNames = new HashSet<String>();
for (IStockDatabase stockDb : stockDatabases) {
String stockDbID = stockDb.getPersistentID();
stockDbNames.add(stockDbID);
if (!wrappersByID.containsKey(stockDbID)) {
StockDatabasePresentationWrapper wrapper = getOrCreateWrapper(stockDb);
for (IMonitorableContainerListener<StockDatabasePresentationWrapper> listener : listeners) {
listener.onElementAdded(wrapper);
}
}
}
Iterator<Map.Entry<String, StockDatabasePresentationWrapper>> iterator = wrappersByID.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, StockDatabasePresentationWrapper> entry = iterator.next();
if (!stockDbNames.contains(entry.getKey())) {
iterator.remove();
for (IMonitorableContainerListener<StockDatabasePresentationWrapper> listener : listeners) {
listener.onElementRemoved(entry.getValue());
}
}
}
}
@Override
public DataType[] availableDataTypes() {
return getMarketDataManager().availableDataTypes();
}
@Override
public BarSize[] availableBarSizes() {
return getMarketDataManager().availableBarSizes();
}
@Override
public List<IContract> searchContracts(IContract criteria, ITaskMonitor taskMonitor) throws ConnectException, RequestFailedException {
return getMarketDataManager().searchContracts(criteria, taskMonitor);
}
@SuppressWarnings("unchecked")
@Override
public Collection<IStockDatabase> allStockDatabases() {
return (Collection<IStockDatabase>) (Collection<?>) getElements();
}
@Override
public StockDatabasePresentationWrapper findStockDatabase(IContract contract, DataType dataType, BarSize barSize, Boolean includeAfterHours) {
IStockDatabase stockDatabase = getMarketDataManager().findStockDatabase(contract, dataType, barSize, includeAfterHours);
if (stockDatabase != null) {
return getOrCreateWrapper(stockDatabase);
} else {
return null;
}
}
@Override
public StockDatabasePresentationWrapper createStockDatabase(IContract contract, DataType dataType, BarSize barSize, boolean includeAfterHours, TimeZone timeZone) {
IStockDatabase stockDatabase = getMarketDataManager().createStockDatabase(contract, dataType, barSize, includeAfterHours, timeZone);
StockDatabasePresentationWrapper wrapper = getOrCreateWrapper(stockDatabase);
for (IMonitorableContainerListener<StockDatabasePresentationWrapper> listener : listeners) {
listener.onElementAdded(wrapper);
}
return wrapper;
}
@Override
public void removeStockDatabase(IStockDatabase stockDb) throws ConnectException, RequestFailedException {
if (stockDb instanceof StockDatabasePresentationWrapper) {
StockDatabasePresentationWrapper wrapper = (StockDatabasePresentationWrapper) stockDb;
stockDb = wrapper.getInner();
wrappersByID.remove(wrapper.getPersistentID());
for (IMonitorableContainerListener<StockDatabasePresentationWrapper> listener : listeners) {
listener.onElementRemoved(wrapper);
}
}
getMarketDataManager().removeStockDatabase(stockDb);
}
@Override
public void fillHistoricalData(IStockDatabase stockDb, Date startDate, Date endDate, ITaskMonitor taskMonitor) throws ConnectException,
RequestFailedException {
if (stockDb instanceof StockDatabasePresentationWrapper) {
stockDb = ((StockDatabasePresentationWrapper) stockDb).getInner();
}
getMarketDataManager().fillHistoricalData(stockDb, startDate, endDate, taskMonitor);
}
@Override
public int numberOfStockDatabases() {
return wrappersByID.size();
}
@Override
public Collection<StockDatabasePresentationWrapper> getElements() {
Collection<StockDatabasePresentationWrapper> result = new LinkedList<StockDatabasePresentationWrapper>();
result.addAll(wrappersByID.values());
return result;
}
@Override
public void addListener(IMonitorableContainerListener<StockDatabasePresentationWrapper> listener) {
listeners.add(listener);
}
@Override
public void removeListener(IMonitorableContainerListener<StockDatabasePresentationWrapper> listener) {
listeners.remove(listener);
}
@Override
public StockDatabasePresentationWrapper getStockDatabase(String ID) {
return getOrCreateWrapper(getMarketDataManager().getStockDatabase(ID));
}
@Override
public ISeries<Date, Double, ? extends ISeriesPoint<Date, Double>> getSeries(String ID) {
return getStockDatabase(ID).getVirtualTimeSeries();
}
private synchronized StockDatabasePresentationWrapper getOrCreateWrapper(IStockDatabase stockDatabase) {
StockDatabasePresentationWrapper wrapper = wrappersByID.get(stockDatabase.getPersistentID());
if (wrapper == null) {
wrapper = new StockDatabasePresentationWrapper(stockDatabase, this);
wrappersByID.put(wrapper.getPersistentID(), wrapper);
}
return wrapper;
}
@Override
public void dispose() {
wrappersByID.clear();
listeners.clear();
}
}