Java tutorial
/** * This file is part of Pau's Asset Manager Project. * * Pau's Asset Manager Project is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pau's Asset Manager Project 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Pau's Asset Manager Project. If not, see <http://www.gnu.org/licenses/>. */ package org.pau.assetmanager.viewmodel.stocks; import java.util.Calendar; import java.util.Collections; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.pau.assetmanager.entities.Annotation; import org.pau.assetmanager.entities.StockExpensesAnnotation; import org.pau.assetmanager.entities.StockIncomeAnnotation; import org.pau.assetmanager.utils.AssetManagerRuntimeException; import org.pau.assetmanager.viewmodel.StocksYearlyReportViewModel; import org.pau.assetmanager.viewmodel.utils.BookSelection; import com.google.common.base.Function; import com.google.common.base.Optional; import com.google.common.base.Predicate; import com.google.common.collect.Collections2; import com.google.common.collect.HashBasedTable; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import com.google.common.collect.Table; public class HistoricalStockBalanceState { public static Table<Integer, Integer, Set<StockState>> getConiniousHistoricalStockBalanceStateTable( BookSelection bookSelection, Integer lastYear, Optional<String> optionalStockLabel) { Table<Integer, Integer, Set<StockState>> uncontiniousHistoricalStockBalanceStateTable = getDiscontiniousHistoricalStockBalanceStateTable( bookSelection, lastYear, optionalStockLabel); Table<Integer, Integer, Set<StockState>> continiousHistoricalStockBalanceStateTable = HashBasedTable .<Integer, Integer, Set<StockState>>create(); List<Integer> yearsWithHistoricalValues = Lists .newArrayList(uncontiniousHistoricalStockBalanceStateTable.rowMap().keySet()); Map<String, StockState> stockToStockState = new HashMap<String, StockState>(); if (yearsWithHistoricalValues.size() > 0) { Collections.sort(yearsWithHistoricalValues); for (Integer currentYear = yearsWithHistoricalValues.get(0); currentYear <= lastYear; currentYear++) { Map<Integer, Set<StockState>> yearHistoricalStockBalanceStateTable = uncontiniousHistoricalStockBalanceStateTable .rowMap().get(currentYear); for (Integer currentMonth = 0; currentMonth <= 11; currentMonth++) { Set<StockState> stockStateSet = new HashSet<StockState>(); if (yearHistoricalStockBalanceStateTable != null && yearHistoricalStockBalanceStateTable.get(currentMonth) != null) { stockStateSet = yearHistoricalStockBalanceStateTable.get(currentMonth); } Map<String, StockState> currentStockToStockState = Maps.uniqueIndex(stockStateSet, new Function<StockState, String>() { @Override public String apply(StockState input) { return input.getSymbol(); } }); stockToStockState.putAll(currentStockToStockState); continiousHistoricalStockBalanceStateTable.put(currentYear, currentMonth, Sets.newHashSet(stockToStockState.values())); } } } return continiousHistoricalStockBalanceStateTable; } private static Table<Integer, Integer, Set<StockState>> getDiscontiniousHistoricalStockBalanceStateTable( BookSelection bookSelection, Integer lastYear, Optional<String> optionalStockLabel) { // year --> month --> symbol Table<Integer, Integer, Set<StockState>> historicalStockBalanceStateTable = HashBasedTable .<Integer, Integer, Set<StockState>>create(); Calendar calendar = GregorianCalendar.getInstance(); List<Annotation> annotations = StocksYearlyReportViewModel.getStocksAnnotationsUntilYear(bookSelection, lastYear); if (optionalStockLabel.isPresent()) { final String stockLabel = optionalStockLabel.get(); annotations = Lists.newArrayList(Collections2.filter(annotations, new Predicate<Annotation>() { @Override public boolean apply(Annotation annotation) { if (annotation instanceof StockIncomeAnnotation || annotation instanceof StockExpensesAnnotation) { return annotation.getConcept().equals(stockLabel); } else { return false; } } })); } Map<String, StockState> symbolToCurrentStockState = new HashMap<String, StockState>(); for (Annotation annotation : annotations) { calendar.setTime(annotation.getDate()); Integer currentYear = calendar.get(Calendar.YEAR); Integer currentMonth = calendar.get(Calendar.MONTH); updateCurrentSymbolToCurrentStockState(symbolToCurrentStockState, annotation, currentMonth, currentYear); StockState stockState = symbolToCurrentStockState.get(annotation.getConcept()); Set<StockState> setOfStockStates = null; if (historicalStockBalanceStateTable.rowMap().get(currentYear) == null || historicalStockBalanceStateTable.rowMap().get(currentYear).get(currentMonth) == null) { setOfStockStates = new HashSet<StockState>(); } else { setOfStockStates = historicalStockBalanceStateTable.rowMap().get(currentYear).get(currentMonth); } if (setOfStockStates.contains(stockState)) { setOfStockStates.remove(stockState); } setOfStockStates.add(stockState); historicalStockBalanceStateTable.put(currentYear, currentMonth, setOfStockStates); } return historicalStockBalanceStateTable; } private static void updateCurrentSymbolToCurrentStockState(Map<String, StockState> symbolToCurrentStockState, Annotation annotation, Integer month, Integer year) { if (!symbolToCurrentStockState.keySet().contains(annotation.getConcept())) { if (annotation instanceof StockExpensesAnnotation) { StockExpensesAnnotation stockExpensesAnnotation = (StockExpensesAnnotation) annotation; StockState stockState = new StockState(stockExpensesAnnotation.getConcept(), -stockExpensesAnnotation.getAmount(), stockExpensesAnnotation.getNumberOfStocks(), month, year); symbolToCurrentStockState.put(annotation.getConcept(), stockState); } else { throw new AssetManagerRuntimeException("the first transaction should be buy stocks"); // TODO: error, the first transaction should be buy stocks } } else { StockState stockState = symbolToCurrentStockState.get(annotation.getConcept()); if (annotation instanceof StockExpensesAnnotation) { StockExpensesAnnotation stockExpensesAnnotation = (StockExpensesAnnotation) annotation; stockState = new StockState(stockState.getSymbol(), stockState.getBalance() - stockExpensesAnnotation.getAmount(), stockState.getNumberOfPurchasedStocks() + stockExpensesAnnotation.getNumberOfStocks(), month, year); } else if (annotation instanceof StockIncomeAnnotation) { StockIncomeAnnotation stockIncomeAnnotation = (StockIncomeAnnotation) annotation; stockState = new StockState(stockState.getSymbol(), stockState.getBalance() + stockIncomeAnnotation.getAmount(), stockState.getNumberOfPurchasedStocks() - stockIncomeAnnotation.getNumberOfStocks(), month, year); } symbolToCurrentStockState.put(annotation.getConcept(), stockState); } } }