/** TwitStreet - Twitter Stock Market Game Copyright (C) 2012 Engin Guller (bisanthe@gmail.com), Cagdas Ozek (cagdasozek@gmail.com) This program 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. This program 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 this program. If not, see <http://www.gnu.org/licenses/>. **/ package com.twitstreet.season; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import org.apache.log4j.Logger; import com.google.inject.Inject; import com.google.inject.Singleton; import com.twitstreet.config.ConfigMgr; import com.twitstreet.db.base.DBConstants; import com.twitstreet.db.base.DBMgr; import com.twitstreet.db.data.RankingData; import com.twitstreet.db.data.User; import com.twitstreet.localization.LocalizationUtil; import com.twitstreet.session.UserMgr; import com.twitstreet.twitter.AnnouncerMgr; @Singleton public class SeasonMgrImpl implements SeasonMgr { private static Logger logger = Logger.getLogger(SeasonMgrImpl.class); private static String INSERT_UPDATE_SEASON_INFO = "insert into season_info (id, startTime, endTime, active, updateInProgress) values (?,?,?,?,?) on duplicate key update startTime=?, endTime=?, active=?, updateInProgress=? "; private static String SELECT_FROM_SEASON_INFO = " select id, startTime, endTime, active, updateInProgress from season_info "; private static String GET_SEASON_RESULT = " select rh.* from ranking_history rh inner join season_result sr on " + " rh.id = sr.ranking_history_id where rh.season_id = ? " + " order by rh.rank asc "; private HashMap<Integer, SeasonResult> seasonResults = new HashMap<Integer, SeasonResult>(); @Inject DBMgr dbMgr; @Inject UserMgr userMgr; @Inject AnnouncerMgr announcerMgr; private ArrayList<SeasonInfo> allSeasons = new ArrayList<SeasonInfo>(); @Inject ConfigMgr configMgr; private SeasonInfo currentSeason; LocalizationUtil lutil = LocalizationUtil.getInstance(); @Override public SeasonInfo getSeasonInfo(int id) { Connection connection = null; PreparedStatement ps = null; ResultSet rs = null; SeasonInfo siDO = null; try { connection = dbMgr.getConnection(); ps = connection.prepareStatement(SELECT_FROM_SEASON_INFO + " where id = ?"); ps.setInt(1, id); rs = ps.executeQuery(); if (rs.next()) { siDO = new SeasonInfo(); siDO.getDataFromResultSet(rs); } logger.debug(DBConstants.QUERY_EXECUTION_SUCC + ps.toString()); } catch (SQLException ex) { logger.error(DBConstants.QUERY_EXECUTION_FAIL + ps.toString(), ex); } finally { dbMgr.closeResources(connection, ps, rs); } return siDO; } @Override public ArrayList<SeasonInfo> getAllSeasons() { if (allSeasons.size() < 1) { loadAllSeasons(); } return allSeasons; } private ArrayList<SeasonInfo> loadAllSeasons() { Connection connection = null; PreparedStatement ps = null; ResultSet rs = null; SeasonInfo siDO = null; ArrayList<SeasonInfo> siList = new ArrayList<SeasonInfo>(); try { connection = dbMgr.getConnection(); ps = connection.prepareStatement(SELECT_FROM_SEASON_INFO + " order by id desc"); rs = ps.executeQuery(); while (rs.next()) { siDO = new SeasonInfo(); siDO.getDataFromResultSet(rs); siList.add(siDO); } logger.debug(DBConstants.QUERY_EXECUTION_SUCC + ps.toString()); } catch (SQLException ex) { logger.error(DBConstants.QUERY_EXECUTION_FAIL + ps.toString(), ex); } finally { dbMgr.closeResources(connection, ps, rs); } return allSeasons = siList; } public void loadSeasonInfo() { try { loadAllSeasons(); loadCurrentSeason(); getSeasonResult(getCurrentSeason().getId()); } catch (Exception ex) { logger.error("Error in getting season info", ex); } } @Override public SeasonInfo getCurrentSeason() { if (currentSeason.getId() < 1) { loadCurrentSeason(); } return currentSeason; } public void setCurrentSeason(SeasonInfo currentSeason) { this.currentSeason = currentSeason; } private SeasonInfo loadCurrentSeason() { Connection connection = null; PreparedStatement ps = null; ResultSet rs = null; SeasonInfo siDO = null; try { connection = dbMgr.getConnection(); ps = connection.prepareStatement(SELECT_FROM_SEASON_INFO + " where active = true"); rs = ps.executeQuery(); if (rs.next()) { siDO = new SeasonInfo(); siDO.getDataFromResultSet(rs); } logger.debug(DBConstants.QUERY_EXECUTION_SUCC + ps.toString()); } catch (SQLException ex) { logger.error(DBConstants.QUERY_EXECUTION_FAIL + ps.toString(), ex); } finally { dbMgr.closeResources(connection, ps, rs); } return currentSeason = siDO; } @Override public SeasonInfo setSeasonInfo(SeasonInfo si) { Connection connection = null; PreparedStatement ps = null; ResultSet rs = null; SeasonInfo siDO = null; try { connection = dbMgr.getConnection(); ps = connection.prepareStatement(INSERT_UPDATE_SEASON_INFO); ps.setInt(1, si.getId()); ps.setTimestamp(2, si.getStartTime()); ps.setTimestamp(3, si.getEndTime()); ps.setBoolean(4, si.isActive()); ps.setBoolean(5, si.isUpdateInProgress()); ps.setTimestamp(6, si.getStartTime()); ps.setTimestamp(7, si.getEndTime()); ps.setBoolean(8, si.isActive()); ps.setBoolean(9, si.isUpdateInProgress()); ps.executeUpdate(); logger.debug(DBConstants.QUERY_EXECUTION_SUCC + ps.toString()); } catch (SQLException ex) { logger.error(DBConstants.QUERY_EXECUTION_FAIL + ps.toString(), ex); } finally { dbMgr.closeResources(connection, ps, rs); } return siDO; } @Override public void newSeason() { Connection connection = null; CallableStatement cs = null; loadSeasonInfo(); if (getCurrentSeason().isUpdateInProgress()) { return; } SeasonInfo current = getCurrentSeason(); current.setUpdateInProgress(true); setSeasonInfo(current); Date nowDate = new Date(); List<User> userList = userMgr.getTopNUsers(3); if(userList.size() == 3){ DecimalFormat df = new DecimalFormat("###,###.##"); announcerMgr.announceFromTwitStreetGame(lutil.get("season.result", LocalizationUtil.DEFAULT_LANGUAGE, new Object[]{ current.getId(), "@"+userList.get(0).getUserName(), df.format(userList.get(0).getTotal()), "@"+userList.get(1).getUserName(), df.format(userList.get(1).getTotal()), "@"+userList.get(2).getUserName(), df.format(userList.get(2).getTotal()) } )); } try { connection = dbMgr.getConnection(); cs = connection.prepareCall("{call new_season(?)}"); cs.setDouble(1, configMgr.getInitialMoney()); cs.execute(); logger.debug(DBConstants.QUERY_EXECUTION_SUCC + cs.toString()); } catch (SQLException ex) { logger.error(DBConstants.QUERY_EXECUTION_FAIL + cs.toString(), ex); } finally { dbMgr.closeResources(connection, cs, null); } current.setActive(false); current.setUpdateInProgress(false); setSeasonInfo(current); loadSeasonInfo(); } @Override public SeasonResult getSeasonResult(int seasonId) { return getSeasonResult(seasonId, 0, 3); } @Override public SeasonResult getSeasonResult(int seasonId, int offset, int count) { SeasonResult seasonResult = new SeasonResult(); try { if (getSeasonResults().containsKey(seasonId)) { seasonResult = getSeasonResults().get(seasonId); seasonResult.setRankingHistory(new ArrayList<RankingData>(seasonResult.getRankingHistory().subList(offset, offset + count))); }else{ loadSeasonResults(); if (getSeasonResults().containsKey(seasonId)) { seasonResult = getSeasonResults().get(seasonId); seasonResult.setRankingHistory(new ArrayList<RankingData>(seasonResult.getRankingHistory().subList(offset, offset + count))); } } } catch (Exception ex) { } return seasonResult; } private void loadSeasonResults() { ArrayList<SeasonInfo> allSeasons = getAllSeasons(); Connection connection = null; PreparedStatement ps = null; ResultSet rs = null; try { connection = dbMgr.getConnection(); for (SeasonInfo si : allSeasons) { if (si.isActive()) { continue; } ps = connection.prepareStatement(GET_SEASON_RESULT); ps.setInt(1, si.getId()); rs = ps.executeQuery(); SeasonResult seasonResult = new SeasonResult(); seasonResult.getDataFromResultSet(rs); if (seasonResult.getSeasonId() > 0) { seasonResults.put(seasonResult.getSeasonId(), seasonResult); } } logger.debug(DBConstants.QUERY_EXECUTION_SUCC + ps.toString()); } catch (SQLException ex) { logger.error(DBConstants.QUERY_EXECUTION_FAIL + ps.toString(), ex); } finally { dbMgr.closeResources(connection, ps, rs); } } public HashMap<Integer, SeasonResult> getSeasonResults() { if(seasonResults.size()<1){ loadSeasonResults(); } return seasonResults; } }