outfox.dict.contest.service.CrontabService.java Source code

Java tutorial

Introduction

Here is the source code for outfox.dict.contest.service.CrontabService.java

Source

/**
 * @(#)CrontabService.java, 2016-3-4. 
 * 
 * Copyright 2016 Yodao, Inc. All rights reserved.
 * YODAO PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */
package outfox.dict.contest.service;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import javax.annotation.PostConstruct;

import lombok.Getter;

import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;

import outfox.dict.contest.dao.ContestDAO;
import outfox.dict.contest.data.AreaEntity;
import outfox.dict.contest.data.BaseEntity;
import outfox.dict.contest.data.SingerEntity;
import outfox.dict.contest.front.data.ContestConsts;
import outfox.dict.contest.util.HttpToolKit;

/**
 * 
 * @author wangning
 *
 */
@Service
public class CrontabService {

    private static final Logger LOG = Logger.getLogger(CrontabService.class);

    @Autowired
    private ContestDAO contestDAO;

    private volatile Map<String, String> singerInfoMap = new HashMap<String, String>();

    private volatile Map<String, List<BaseEntity>> singersRankMap = new HashMap<String, List<BaseEntity>>();

    private volatile Multimap<String, Integer> singersRandomMap = ArrayListMultimap.create();

    @Getter
    private Map<String, Boolean> preparedBarrageMap = new HashMap<String, Boolean>();

    public Map<String, String> getSingerInfoMap() {
        return singerInfoMap;
    }

    public Map<String, List<BaseEntity>> getSingersRankMap() {
        return singersRankMap;
    }

    public Multimap<String, Integer> getSingersRandomMap() {
        return singersRandomMap;
    }

    @PostConstruct
    public void init() {
        ScheduledExecutorService executor = Executors.newScheduledThreadPool(ContestConsts.CORE_POOL_SIZE);
        executor.scheduleAtFixedRate(new SingerInfoUpdate(), 0, ContestConsts.CRONTAB_TIME, TimeUnit.DAYS);
        // ???Zzzz
        // loadingPreparedBarrage();
    }

    private class SingerInfoUpdate extends Thread {
        @Override
        public void run() {
            updateInfoInCache();
        }

    }

    /*
     * ?
     */
    public void updateInfoInCache() {
        LOG.info("updateInfo in cache Start...");

        HttpResponse response = null;
        try {
            response = HttpToolKit.getInstance().doGet(ContestConsts.LIST_VOTE_INTERFACE);
            if (response != null) {
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    JSONObject jsonObj = JSON.parseObject(EntityUtils.toString(entity));
                    // ?json?
                    if (jsonObj != null) {
                        JSONArray dataArray = jsonObj.getJSONArray("data");
                        if (dataArray != null) {
                            JSONObject dataObj = dataArray.getJSONObject(0);
                            if (dataObj != null) {
                                // ??
                                JSONObject voteinfo = dataObj.getJSONObject("voteinfo");

                                // ??
                                long startTime = 0, endTime = 0;
                                if (voteinfo != null) {
                                    startTime = voteinfo.getLong("startTime");
                                    endTime = voteinfo.getLong("endTime");
                                }

                                // ???
                                JSONArray optionArray = dataObj.getJSONArray("options");

                                // options???
                                if (optionArray != null) {
                                    Object[] objArray = optionArray.toArray();
                                    List<Map<String, String>> optionList = new ArrayList<Map<String, String>>();
                                    Multimap<String, BaseEntity> rankMap = ArrayListMultimap.create();

                                    for (Object obj : objArray) {
                                        JSONObject option = JSON.parseObject(obj.toString());
                                        SingerEntity singer = new SingerEntity();
                                        int optionId = option.getIntValue("id");
                                        int voteNum = option.getIntValue("voteNum");
                                        singer.setOptionId(optionId);
                                        singer.setPhotoUrl(option.getString("picture"));
                                        singer.setVoteNum(voteNum);
                                        singer.setStartTime(startTime);
                                        singer.setEndTime(endTime);
                                        String content = option.getString("content");
                                        String areaName = null;
                                        int state = 0;
                                        if (StringUtils.isNotBlank(content)) {
                                            JSONObject contentObj = JSON.parseObject(content);
                                            singer.setId(contentObj.getIntValue("id"));
                                            singer.setName(contentObj.getString("name"));
                                            singer.setSchool(contentObj.getString("school"));
                                            areaName = contentObj.getString("areaName");
                                            singer.setAreaName(areaName);
                                            singer.setAudioUrl(contentObj.getString("audioUrl"));
                                            singer.setMusicName(contentObj.getString("musicName"));
                                            state = contentObj.getIntValue("state");
                                            singer.setState(state);
                                        }

                                        /** 1: ?mapkey?+optionid+statevalue? **/
                                        singerInfoMap.put(ContestConsts.SINGER_INFO_PREFIX_KEY + optionId,
                                                JSON.toJSONString(singer));

                                        /** 2: ???mapid??? **/
                                        // 2.1: ??
                                        rankMap.put(ContestConsts.RANK_PREFIX_KEY + areaName + ":" + state,
                                                new BaseEntity(optionId, voteNum));

                                        // 2.2: ??
                                        rankMap.put(ContestConsts.RANK_PREFIX_KEY + state,
                                                new BaseEntity(optionId, voteNum));

                                        /** 3: ?mapid??? **/
                                        // 3.1: ?idmap
                                        Map<String, String> map = new HashMap<String, String>();
                                        map.put("areaName", areaName);
                                        map.put("optionId", String.valueOf(optionId));
                                        map.put("state", String.valueOf(state));
                                        optionList.add(map);
                                    }

                                    // 3.2: ??
                                    Collections.shuffle(optionList);

                                    // 3.3: ??map
                                    Multimap<String, Integer> randomMap = ArrayListMultimap.create();
                                    for (Map<String, String> map : optionList) {
                                        int optionId = Integer.parseInt(map.get("optionId"));
                                        int state = Integer.parseInt(map.get("state"));
                                        String areaName = map.get("areaName");
                                        // 3.3.1 ?
                                        randomMap.put(ContestConsts.RANDOM_SHOWN_PREFIX_KEY + state, optionId);

                                        // 3.3.2 ??
                                        randomMap.put(
                                                ContestConsts.RANDOM_SHOWN_PREFIX_KEY + areaName + ":" + state,
                                                optionId);
                                    }
                                    singersRandomMap = randomMap;

                                    /** 4???????? **/
                                    // 4.1: ????
                                    for (int state = 0; state <= 1; state++) {
                                        String key = ContestConsts.RANK_PREFIX_KEY + state;
                                        List<BaseEntity> globalRankList = (List<BaseEntity>) rankMap.get(key);
                                        Collections.sort(globalRankList, voteNumComparator);
                                        singersRankMap.put(key, globalRankList);
                                    }

                                    // 4.2: ??????100?????
                                    List<AreaEntity> areaList = contestDAO.listContestAreas(ContestConsts.PERIOD);
                                    if (areaList != null) {
                                        for (AreaEntity area : areaList) {
                                            // 4.2.1: ????
                                            String key = ContestConsts.RANK_PREFIX_KEY + area.getName() + ":0";
                                            List<BaseEntity> areaRankList = (List<BaseEntity>) rankMap.get(key);
                                            Collections.sort(areaRankList, voteNumComparator);
                                            singersRankMap.put(key, areaRankList);

                                            // 4.2.2: ?12???????12??1413??
                                            if (areaRankList != null) {
                                                int rank = 0, lastVoteNum = -1, index = 1;
                                                for (BaseEntity ele : areaRankList) {
                                                    String singerStr = singerInfoMap.get(
                                                            ContestConsts.SINGER_INFO_PREFIX_KEY + ele.getId());
                                                    if (singerStr != null) {
                                                        SingerEntity singer = JSON.parseObject(singerStr,
                                                                SingerEntity.class);
                                                        if (lastVoteNum != singer.getVoteNum()) {
                                                            rank++;
                                                        }
                                                        singer.setRanking(rank);
                                                        singer.setStartTime(area.getVoteStartTime());
                                                        singer.setEndTime(area.getVoteEndTime());
                                                        singerInfoMap.put(
                                                                ContestConsts.SINGER_INFO_PREFIX_KEY + ele.getId(),
                                                                JSON.toJSONString(singer));
                                                        index++;
                                                        lastVoteNum = singer.getVoteNum();
                                                        // ?12????
                                                        if (index > ContestConsts.RANK_NUM) {
                                                            break;
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            LOG.error("CrontabService.singerInfoUpdate error...", e);
        } finally {
            HttpToolKit.closeQuiet(response);
        }
        LOG.info("updateInfo in cache End...");
    }

    /**
     * ???
     */
    private static Comparator<BaseEntity> voteNumComparator = new Comparator<BaseEntity>() {

        @Override
        public int compare(BaseEntity o1, BaseEntity o2) {
            return o2.getVoteNum() - o1.getVoteNum();
        }
    };

    /**
     * Map
     */
    public void loadingPreparedBarrage() {
        try {
            BufferedReader br = new BufferedReader(new FileReader(System.getProperty("barrageListPath")));
            String line = null;
            while ((line = br.readLine()) != null) {
                if (StringUtils.isBlank(line) || line.startsWith("#")) {
                    continue;
                }
                preparedBarrageMap.put(line, true);
            }
        } catch (FileNotFoundException e) {
            LOG.error("loadingPraparedBarrage file not found", e);
        } catch (Exception e) {
            LOG.error("loadingPraparedBarrage exception", e);
        }
    }

}