package com.robonobo.wang.server.controller; import java.io.IOException; import java.util.*; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.RequestMapping; import com.robonobo.wang.beans.*; import com.robonobo.wang.client.LucreFacade; import com.robonobo.wang.proto.WangProtocol.BlindedCoinListMsg; import com.robonobo.wang.proto.WangProtocol.BlindedCoinListMsg.Status; import com.robonobo.wang.proto.WangProtocol.CoinRequestListMsg; import com.robonobo.wang.proto.WangProtocol.CoinRequestMsg; import com.robonobo.wang.server.UserAccount; import com.robonobo.wang.server.dao.DAOException; import com.robonobo.wang.server.dao.DenominationDao; @Controller public class GetCoinsController extends BaseController implements InitializingBean { @Autowired private DenominationDao denominationDao; private LucreFacade lucre; private Map<Integer, DenominationPrivate> denomPrivs; @Override public void afterPropertiesSet() throws Exception { lucre = new LucreFacade(); try { List<DenominationPrivate> denoms = denominationDao.getDenomsPrivate(); denomPrivs = new HashMap<Integer, DenominationPrivate>(); for (DenominationPrivate denom : denoms) { denomPrivs.put(denom.getDenom(), denom); } } catch (DAOException e) { throw new ServletException(e); } } @Transactional(rollbackFor=Exception.class) @RequestMapping(value="/getCoins") public void getCoins(HttpServletRequest req, HttpServletResponse resp) throws IOException { UserAccount user = getAuthUser(req, resp); if (user == null) { send401(req, resp); return; } resp.setContentType("application/data"); CoinRequestListMsg.Builder crlBldr = CoinRequestListMsg.newBuilder(); readFromInput(crlBldr, req); CoinRequestListMsg crl = crlBldr.build(); double coinValue = 0; for (CoinRequestMsg coinReq : crl.getCoinRequestList()) { coinValue += getDenomValue(coinReq.getDenom()); } BlindedCoinListMsg.Builder blBldr = BlindedCoinListMsg.newBuilder(); try { UserAccount lockUser = uaDao.getAndLockUserAccount(user.getEmail()); if (lockUser.getBalance() < coinValue) { blBldr.setStatus(Status.InsufficientWang); } else { for (CoinRequestMsg coinReq : crl.getCoinRequestList()) { DenominationPrivate denom = denomPrivs.get(coinReq.getDenom()); BlindedCoin bc = lucre.signCoinRequest(denom, new CoinRequestPublic(coinReq)); blBldr.addCoin(bc.toMsg()); } blBldr.setStatus(Status.OK); lockUser.setBalance(lockUser.getBalance() - coinValue); uaDao.putUserAccount(lockUser); } } catch (DAOException e) { throw new IOException(e); } writeToOutput(blBldr.build(), resp); resp.setStatus(HttpServletResponse.SC_OK); log.info("User "+user.getEmail()+" withdrew "+crl.getCoinRequestCount()+" coins worth "+WANG_CHAR+coinValue); } private double getDenomValue(Integer denom) { return Math.pow(2, denom); } }