package name.abuchen.portfolio.ui.views.dashboard; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; import javax.inject.Inject; import org.eclipse.jface.preference.IPreferenceStore; import name.abuchen.portfolio.model.Client; import name.abuchen.portfolio.model.Dashboard; import name.abuchen.portfolio.money.CurrencyConverter; import name.abuchen.portfolio.money.CurrencyConverterImpl; import name.abuchen.portfolio.money.ExchangeRateProviderFactory; import name.abuchen.portfolio.snapshot.ClientPerformanceSnapshot; import name.abuchen.portfolio.snapshot.PerformanceIndex; import name.abuchen.portfolio.snapshot.ReportingPeriod; import name.abuchen.portfolio.ui.views.dataseries.DataSeries; import name.abuchen.portfolio.ui.views.dataseries.DataSeriesCache; import name.abuchen.portfolio.ui.views.dataseries.DataSeriesSet; public class DashboardData { private static final class CacheKey { private Class<?> type; private ReportingPeriod period; public CacheKey(Class<?> type, ReportingPeriod period) { this.type = Objects.requireNonNull(type); this.period = Objects.requireNonNull(period); } @Override public int hashCode() { return Objects.hash(type, period); } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; CacheKey other = (CacheKey) obj; if (!type.equals(other.type)) return false; if (!period.equals(other.period)) return false; return true; } } private final Client client; private final IPreferenceStore preferences; private final ExchangeRateProviderFactory factory; private final CurrencyConverter converter; private final Map<CacheKey, Object> cache = new HashMap<>(); private List<ReportingPeriod> defaultReportingPeriods = new ArrayList<>(); private ReportingPeriod defaultReportingPeriod; private DataSeriesSet dataSeriesSet; private DataSeriesCache dataSeriesCache; private Dashboard dashboard; @Inject public DashboardData(Client client, IPreferenceStore preferences, ExchangeRateProviderFactory factory) { this.client = client; this.preferences = preferences; this.factory = factory; this.converter = new CurrencyConverterImpl(factory, client.getBaseCurrency()); this.dataSeriesSet = new DataSeriesSet(client, preferences, DataSeries.UseCase.RETURN_VOLATILITY); this.dataSeriesCache = new DataSeriesCache(client, factory); } public Client getClient() { return client; } public IPreferenceStore getPreferences() { return preferences; } public Dashboard getDashboard() { return dashboard; } public void setDashboard(Dashboard dashboard) { this.dashboard = dashboard; } public void setDefaultReportingPeriods(List<ReportingPeriod> defaultReportingPeriods) { this.defaultReportingPeriods = defaultReportingPeriods; } public List<ReportingPeriod> getDefaultReportingPeriods() { return defaultReportingPeriods; } public void setDefaultReportingPeriod(ReportingPeriod reportingPeriod) { this.defaultReportingPeriod = reportingPeriod; } public ReportingPeriod getDefaultReportingPeriod() { return defaultReportingPeriod; } public ExchangeRateProviderFactory getExchangeRateProviderFactory() { return factory; } public DataSeriesSet getDataSeriesSet() { return dataSeriesSet; } public void clearCache() { cache.clear(); dataSeriesCache.clear(); } public <T> T calculate(Class<T> type, ReportingPeriod period) { CacheKey key = new CacheKey(type, period); return type.cast(cache.computeIfAbsent(key, k -> doCalculate(type, period))); } private Object doCalculate(Class<?> type, ReportingPeriod period) { if (type.equals(ClientPerformanceSnapshot.class)) { return new ClientPerformanceSnapshot(client, converter, period); } else if (type.equals(PerformanceIndex.class)) { return PerformanceIndex.forClient(client, converter, period, new ArrayList<Exception>()); } else { return null; } } public DataSeriesCache getDataSeriesCache() { return dataSeriesCache; } public PerformanceIndex calculate(DataSeries dataSeries, ReportingPeriod reportingPeriod) { return dataSeriesCache.lookup(dataSeries, reportingPeriod); } }