net.java.javamoney.examples.tradingapp.web.PortfolioController.java Source code

Java tutorial

Introduction

Here is the source code for net.java.javamoney.examples.tradingapp.web.PortfolioController.java

Source

/*
 * JSR 354 Stock-Trading Example
 * Copyright 2005-2013, Werner Keil and individual contributors by the @author tag. 
 * See the copyright.txt in the distribution for a full listing of individual contributors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,  
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.java.javamoney.examples.tradingapp.web;

import static net.java.javamoney.examples.tradingapp.Constants.MARKET;
import static net.java.javamoney.examples.tradingapp.Constants.MODEL;
import static net.java.javamoney.examples.tradingapp.Constants.PORTFOLIO;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.StringTokenizer;

import javax.measure.unit.UnitFormat;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.java.javamoney.examples.tradingapp.business.Market;
import net.java.javamoney.examples.tradingapp.business.Portfolio;
import net.java.javamoney.examples.tradingapp.quotes.QuoteManager;
import net.neurotech.quotes.Quote;
import net.neurotech.quotes.QuoteException;
import net.neurotech.quotes.QuoteFactory;

import org.apache.log4j.Logger;
import org.jscience.economics.money.Currency;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

public class PortfolioController implements Controller {
    /**
     * Logger for this class
     */
    private static final Logger logger = Logger.getLogger(PortfolioController.class);

    private Market market;
    private net.java.javamoney.examples.tradingapp.business.Portfolio portfolio;
    private static QuoteFactory quoteFactory;
    private Properties props;

    public PortfolioController(Portfolio portfolio, Market market) {
        this.props = new Properties(); // TODO i18n, use ResourceBundle or Messages where possible
        this.market = market;
        this.portfolio = portfolio;
        quoteFactory = QuoteManager.getQuoteFactory();

        try {
            InputStream in = PortfolioController.class.getResourceAsStream("/currency.properties");
            props.load(in);

            if (Currency.getReferenceCurrency() != null) {
                labelCurrency(Currency.getReferenceCurrency());
            }
        } catch (IOException ie) {
            logger.warn("Error loading properties", ie);
        }
    }

    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) {
        Map<String, Object> model = new HashMap<String, Object>();

        String m = null;
        Object o;
        Enumeration e = request.getParameterNames();
        while (e.hasMoreElements()) {
            o = e.nextElement();
            //logger.info("Param: " + o);
            if (String.valueOf(o).equals(MODEL)) {
                o = request.getParameter(MODEL);
                if (o instanceof Map) {
                    //logger.info("It's a Map");
                    model = (Map) o;
                }
            } else if (String.valueOf(o).equals(MARKET)) {
                m = request.getParameter(MARKET);
            }
        }

        if (m != null && m.length() > 0) {
            String mDetails = this.market.getKnownMarkets().get(m);
            logger.info("Market: " + m + "=" + mDetails);
            market.setSymbol(m);
            //model.put(MARKET, m);

            String cSymbol = null;
            String mName = null;
            StringTokenizer st = new StringTokenizer(mDetails, ";");
            while (st.hasMoreElements()) {
                if (mName == null) {
                    mName = st.nextToken();
                } else {
                    if (cSymbol == null) {
                        cSymbol = st.nextToken();
                    }
                }
            }
            if (mName != null) {
                market.setName(mName);
            }
            if (cSymbol != null) {
                Currency curr = new Currency(cSymbol);

                // TODO retrieve this from Yahoo Service similar to quotes, or 354 style ExchangeRateProvider
                Object oRate = market.getCurrencyExchangeRates().get(cSymbol);
                if (oRate != null) {
                    Number exchangeRate;
                    if (oRate instanceof Number) {
                        exchangeRate = (Number) oRate;
                    } else {
                        try {
                            exchangeRate = Double.parseDouble(String.valueOf(oRate));
                        } catch (NumberFormatException nfe) {
                            logger.warn("Error during currency conversion", nfe);
                            exchangeRate = 0;
                        }
                    }
                    logger.info(exchangeRate);
                    curr.setExchangeRate(exchangeRate.doubleValue());
                } else {
                    logger.warn("Could not find exchange rate for " + curr);
                    curr.setExchangeRate(0); // TODO kind of dodgy, should throw exception or something?
                }
                //curr.setExchangeRate(1.4);

                labelCurrency(cSymbol, curr);
                //Currency.setReferenceCurrency(curr);
                portfolio.setCurrency(curr);

                // TODO portfolio should directly store market!
                market.setCurrency(curr);
            }
        }
        List<PortfolioItemBean> portfolioItems = getPortfolioItems();
        model.put(MARKET, market);
        model.put("currency", portfolio.getCurrency());
        model.put("cash", portfolio.getCash() + "");
        model.put("amount", portfolio.getAmount());
        model.put("amountLocal", portfolio.getAmount().to(portfolio.getCurrency()));
        model.put("portfolioItems", portfolioItems);

        return new ModelAndView(PORTFOLIO, MODEL, model);
    }

    private void labelCurrency(String symbol, Currency curr) {
        //String label = market.getCurrencyLabels().get(cSymbol);
        String label = props.getProperty(symbol, "");
        if (label != null && label.length() > 0) {
            UnitFormat.getInstance().label(curr, label);
        }
    }

    private void labelCurrency(Currency curr) {
        labelCurrency(curr.getCode(), curr);
    }

    private List<PortfolioItemBean> getPortfolioItems() {
        List<PortfolioItemBean> portfolioItems = new ArrayList<PortfolioItemBean>();

        Iterator symbolIter = portfolio.getSymbolIterator();
        //QuoteFactory quoteFactory = new QuoteFactory();

        while (symbolIter.hasNext()) {
            String symbol = (String) symbolIter.next();

            int shares = portfolio.getNumberOfShares(symbol);

            Quote quote = null;

            try {
                quote = quoteFactory.getQuote(symbol);
            } catch (QuoteException e) {
                logger.warn("Error during quote", e);
                quote = new Quote(this.getClass().getName()) {
                };
            }

            PortfolioItemBean portfolioItem = new PortfolioItemBean(portfolio);
            portfolioItem.setSymbol(symbol);
            portfolioItem.setShares(shares);
            portfolioItem.setQuote(quote);
            portfolioItem.setCurrentValue(shares * quote.getValue());
            portfolioItem.setGainLoss(shares * quote.getPctChange());
            portfolioItems.add(portfolioItem);
        }
        return portfolioItems;
    }
}