/*
* 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;
}
}