package cn.com.uangel.adsys.server;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Vector;
import cn.com.uangel.adsys.entity.AD;
import cn.com.uangel.adsys.entity.ADArs;
import cn.com.uangel.adsys.entity.ADPhoneType;
import cn.com.uangel.adsys.entity.ADShowType;
import cn.com.uangel.adsys.entity.ADZone;
import cn.com.uangel.adsys.entity.App;
import cn.com.uangel.adsys.entity.Member;
import cn.com.uangel.adsys.server.entity.HourRequestTimes;
import cn.com.uangel.adsys.service.SocketServerService;
import cn.com.uangel.adsys.service.impl.SocketServerServiceImpl;
import cn.com.uangel.adsys.util.DoubleUtil;
import cn.com.uangel.adsys.util.Log;
public class DataManager {
private Vector<AD> allRunningADs;
public Vector<Member> allMembers;
public Vector<Member> allMembersBak;// 当日所以用户信息的备份,用于计算当日用户的花费和收入
private Vector<App> allApps;
private Vector<ADShowType> allADShowTypes;
private Vector<ADZone> allADZones;
private Vector<ADArs> allADArs;
private Vector<ADPhoneType> allADPhoneTypes;
private Vector<String> requestInfoList; // 用于缓存请求信息字符串
private Vector<String> showInfoList; // 用于缓存显示信息字符串
private Vector<String> clickInfoList; // 用于缓存点击信息字符串
private SimpleDateFormat daySDF;
private SimpleDateFormat hourSDF;
private SimpleDateFormat secondSDF;
private SaveToDB saveToDBTask;
// TODO 可以定期清理一下内部次数为0的数据
/** 应用记录每小时每个Imei请求次数 */
private Map<String, HourRequestTimes> imeiReqeustTimes;
private Map<String, HourRequestTimes> imeiClickTimes;
private Thread saveRequestStringThread;// 用于将缓存队列中的信息存到文件中的线程,请求
private Thread saveShowStringThread;// 用于将缓存队列中的信息存到文件中的线程,显示
private Thread saveClickStringThread;// 用于将缓存队列中的信息存到文件中的线程,点击
private boolean isSaveRequestStringThreadRunning = false;
private boolean isSaveShowStringThreadRunning = false;
private boolean isSaveClickStringThreadRunning = false;
/** CPM与CPC的权值比,用于竞价排名 */
public static final int CPMVSCPC = 15;
/** 广告主付费一次,开发者得到的比例 */
public static final double DEVELOPER_GET_RATE = 0.8;
/** 存储请求信息数据的文件路径 */
public static final String REQUEST_INFO_PATH = "D:\\adData\\request\\";
public static final String SHOW_INFO_PATH = "D:\\adData\\show\\";
public static final String CLICK_INFO_PATH = "D:\\adData\\click\\";
// public static final String REQUEST_INFO_PATH =
// "/root/adsysServer/adData/request/";
// public static final String SHOW_INFO_PATH =
// "/root/adsysServer/adData/show/";
// public static final String CLICK_INFO_PATH =
// "/root/adsysServer/adData/click/";
private String currentRequestInfoPath;
private String currentShowInfoPath;
private String currentClickInfoPath;
private SocketServerService sss;
public void init() {
initProperties();
loadingNewestData();
Log.info("今日数据库最新数据初始化完毕!");
// 开启任务:每天凌晨2点保存前一天的请求数据
Timer timer = new Timer();
saveToDBTask = this.new SaveToDB();
timer.schedule(saveToDBTask, 60 * 60 * 1000, 12 * 60 * 60 * 1000);
Log.info("存储每日请求数据到数据库的任务开启完毕!");
}
// 初始化类属性
private void initProperties() {
requestInfoList = new Vector<String>();
showInfoList = new Vector<String>();
clickInfoList = new Vector<String>();
imeiReqeustTimes = new HashMap<String, HourRequestTimes>();
imeiClickTimes = new HashMap<String, HourRequestTimes>();
daySDF = new SimpleDateFormat("yyyy_MM_dd");
hourSDF = new SimpleDateFormat("yyyy_MM_dd_HH");
secondSDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
}
// 初始化广告数据
private void loadingNewestData() {
if (sss == null) {
sss = new SocketServerServiceImpl();
}
allRunningADs = sss.getAllRunningADs();
allMembers = sss.getAllMembers();
allMembersBak = sss.getAllMembers();
allADShowTypes = sss.getAllADShowTypes();
allADZones = sss.getAllADZones();
allADArs = sss.getAllADArs();
allADPhoneTypes = sss.getAllPhoneTypes();
allApps = sss.getAllApps();
// sss.loadingNewestData(allRunningADs, allMembers, allMembersBak,
// allADShowTypes, allADZones, allADArs,
// allADPhoneTypes, allApps);
//
// public void loadingNewestData(Vector<AD> allRunningADs,
// Vector<Member> allMembers, Vector<Member> allMembersBak,
// Vector<ADShowType> allADShowTypes, Vector<ADZone> allADZones,
// Vector<ADArs> allADArs,
// Vector<ADPhoneType> allADPhoneTypes, Vector<App> allApps);
}
public void startSaveRequestStringThread() {
saveRequestStringThread = new Thread() {
@Override
public void run() {
synchronized (DataManager.this) {
isSaveRequestStringThreadRunning = true;
FileWriter fw = null;
try {
Date d = new Date();
String folderName = daySDF.format(d);
String fileName = hourSDF.format(d);
String folderPath = REQUEST_INFO_PATH + folderName;
File folder = new File(folderPath);
if (!folder.exists()) {
folder.mkdir();
}
// urd: UangelRequestData.
currentRequestInfoPath = folderPath + File.separator + fileName + ".urd";
File f = new File(currentRequestInfoPath);
fw = new FileWriter(f, true);
// 如果缓存队列中有数据,则将其存入文件中
while (requestInfoList.size() > 0) {
fw.write(requestInfoList.get(0));
requestInfoList.remove(0);
}
} catch (Exception e) {
Log.error(e);
} finally {
try {
fw.close();
} catch (IOException e) {
}
isSaveRequestStringThreadRunning = false;
}
}
}
};
saveRequestStringThread.start();
}
public void startSaveShowStringThread() {
saveShowStringThread = new Thread() {
@Override
public void run() {
synchronized (DataManager.this) {
isSaveShowStringThreadRunning = true;
FileWriter fw = null;
try {
Date d = new Date();
String folderName = daySDF.format(d);
String fileName = hourSDF.format(d);
String folderPath = SHOW_INFO_PATH + folderName;
File folder = new File(folderPath);
if (!folder.exists()) {
folder.mkdir();
}
// usd: UangelShowData.
currentShowInfoPath = folderPath + File.separator + fileName + ".usd";
File f = new File(currentShowInfoPath);
fw = new FileWriter(f, true);
// 如果缓存队列中有数据,则将其存入文件中
while (showInfoList.size() > 0) {
fw.write(showInfoList.get(0));
showInfoList.remove(0);
}
} catch (Exception e) {
Log.error(e);
} finally {
try {
fw.close();
} catch (IOException e) {
}
isSaveShowStringThreadRunning = false;
}
}
}
};
saveShowStringThread.start();
}
public void startSaveClickStringThread() {
saveClickStringThread = new Thread() {
@Override
public void run() {
synchronized (DataManager.this) {
isSaveClickStringThreadRunning = true;
FileWriter fw = null;
try {
Date d = new Date();
String folderName = daySDF.format(d);
String fileName = hourSDF.format(d);
String folderPath = CLICK_INFO_PATH + folderName;
File folder = new File(folderPath);
if (!folder.exists()) {
folder.mkdir();
}
// ucd: UangelClickData.
currentClickInfoPath = folderPath + File.separator + fileName + ".ucd";
File f = new File(currentClickInfoPath);
fw = new FileWriter(f, true);
// 如果缓存队列中有数据,则将其存入文件中
while (clickInfoList.size() > 0) {
fw.write(clickInfoList.get(0));
clickInfoList.remove(0);
}
} catch (Exception e) {
Log.error(e);
} finally {
try {
fw.close();
} catch (IOException e) {
}
isSaveClickStringThreadRunning = false;
}
}
}
};
saveClickStringThread.start();
}
public String testImeiAndPackage(String appId, String imei, String packageName) {
// 测试每个imei单位时间内请求次数
String hour = hourSDF.format(new Date());
if (imeiReqeustTimes.containsKey(imei)) {
HourRequestTimes hrt = imeiReqeustTimes.get(imei);
Log.debug("IMEI: " + imei + " RequestTimes: " + hrt.getTimes());
if (hour.equals(hrt.getHour())) {
int times = hrt.getTimes();
if (times > 240) {
return "4"; // 请求次数过多,暂定每小时240次
}
hrt.setTimes(times + 1);
} else {
hrt.setHour(hour);
hrt.setTimes(0);
}
} else {
imeiReqeustTimes.put(imei, new HourRequestTimes(hour, 1));
}
App app = getAppByAppID(appId);
if (!"通过".equals(app.getApp_state())) {
return "1"; // 此应用暂时还问通过
}
if (app.getPakage_name() == null) {
return "2"; // 包名为空
}
if (!app.getPakage_name().equals(packageName)) {
return "3"; // 此appID已经绑定其他应用
}
return "0"; // No problem 没问题!
}
public boolean testImeiClickTimes(String appID, String imei) {
String hour = hourSDF.format(new Date());
if (imeiClickTimes.containsKey(imei)) {
HourRequestTimes hrt = imeiClickTimes.get(imei);
Log.debug("IMEI: " + imei + " ClickTimes: " + hrt.getTimes());
if (hour.equals(hrt.getHour())) {
int times = hrt.getTimes();
if (times > 60) {
return true; // 请求次数过多,暂定每小时60次
}
hrt.setTimes(times + 1);
} else {
hrt.setHour(hour);
hrt.setTimes(0);
}
} else {
imeiClickTimes.put(imei, new HourRequestTimes(hour, 1));
}
return false;
}
/** 选出满足请求条件的广告 */
public Vector<ADShowType> getOKADs(String typeCode, String zoneCode, double lon, double lat, String phoneType,
String arsName, String appID, String netType, int wannerCount) {
Vector<ADShowType> okShowTypes = allADShowTypes;
okShowTypes = filtratePause(okShowTypes);
if (typeCode != null) {
okShowTypes = filtrateShowType(okShowTypes, typeCode);
}
if (zoneCode != null) {
okShowTypes = filtrateZone(okShowTypes, zoneCode, lon, lat);
}
if (phoneType != null) {
okShowTypes = filtratePhoneType(okShowTypes, phoneType);
}
if (arsName != null) {
okShowTypes = filtrateArs(okShowTypes, arsName);
}
if (appID != null) {
okShowTypes = filtrateCrowdAndGender(okShowTypes, appID);
}
okShowTypes = filtrateTime(okShowTypes);
if (netType != null) {
okShowTypes = filtrateNet(okShowTypes, netType);
}
Log.debug("满足请求条件的广告: ");
for (ADShowType ast : okShowTypes) {
Log.debug(ast);
}
// 根据竞价排名,随机选出wannerCount条合适的广告
List<Integer> okADsPriceWeight = new ArrayList<Integer>();
List<Integer> copy = new ArrayList<Integer>();
Random ran = new Random();
for (int i = 0; i < okShowTypes.size(); i++) {
int weight = 0;
ADShowType ast = okShowTypes.get(i);
if ("按印象付费".equals(ast.getPay_mode())) {
weight = ran.nextInt((int) (ast.getPrice() * 10000));
okADsPriceWeight.add(weight);
copy.add(weight);
} else {
weight = ran.nextInt((int) (ast.getPrice() * CPMVSCPC * 10000));
okADsPriceWeight.add(weight);
copy.add(weight);
}
}
Collections.sort(copy);
Vector<ADShowType> ret = new Vector<ADShowType>();
if (copy.size() >= wannerCount) {
for (int i = 1; i <= wannerCount; i++) {
ret.add(okShowTypes.get(okADsPriceWeight.indexOf(copy.get(copy.size() - i))));
}
} else {
for (int i = 1; i <= copy.size(); i++) {
ret.add(okShowTypes.get(okADsPriceWeight.indexOf(copy.get(copy.size() - i))));
}
}
return ret;
}
/** 解析请求字符串 */
public synchronized String parseRequestMessage(String msg) throws Exception {
String[] msgs = msg.split("‖");
String appID = msgs[0];
String imei = msgs[1];
String arsName = msgs[2];
String phoneType = msgs[3];// 手机型号
String netType = msgs[4];
String typeCode = msgs[5];// 1:条幅型,2:插屏型,3:悬浮型
String packageName = msgs[6];
String zoneCode = msgs[7];
double longitude = Double.parseDouble(msgs[8]);
double latitude = Double.parseDouble(msgs[9]);
String testIP = testImeiAndPackage(appID, imei, packageName);
if ("1".equals(testIP)) {
return "This appication is not passed temporarily";
} else if ("2".equals(testIP)) {
return "The package name is null";
} else if ("3".equals(testIP)) {
return "This appID has used in other application";
} else if ("4".equals(testIP)) {
// TODO 最后讨论一下,此时的请求记录是否有必要存到数据库中
return "Request too many times for a moment";
}
phoneType = parsePhoneType(phoneType);
int adCount = 0;// 请求广告的数量
if ("3".equals(typeCode)) {
adCount = 3;
} else {
adCount = 1;
}
Vector<ADShowType> okADs = getOKADs(typeCode, zoneCode, longitude, latitude, phoneType, arsName, appID,
netType, adCount);
Log.debug("typeCode : " + typeCode + " okADs num: " + okADs.size());
String retMsg = "";
if (okADs != null) {
// 封装RequestInfo字符串
for (ADShowType okAD : okADs) {
String saveRequestMsg = appID + "︴" + okAD.getAd_id() + "︴" + secondSDF.format(new Date()) + "︴" + imei
+ "︴" + zoneCode + "︴" + okAD.getId() + "\n";
// 将封装好的字符串加入缓存队里中
requestInfoList.add(saveRequestMsg);
if (!isSaveRequestStringThreadRunning) {
startSaveRequestStringThread();
}
Double cpmPrice = 0.0;
AD ad = getADByAdID(okAD.getAd_id());
Member ador = getMemByAdID(ad.getMem_id());// 广告主
Log.debug("paymode: " + okAD.getPay_mode() + " 余额: " + ador.getAd_balance());
if ("按印象付费".equals(okAD.getPay_mode())) {
cpmPrice = okAD.getPrice() / 1000;
// 扣除广告出本次请求的CPM费用,这里只起判定如果广告余额<0.5,让此广告主的广告置为暂停状态,并不允许再显示
ador.setAd_balance(DoubleUtil.subtract(ador.getAd_balance(), cpmPrice));
if (ador.getAd_balance() < 0.5) {
for (AD a : allRunningADs) {
if (a.getMem_id().equals(ador.getId())) {
a.setState("暂停");
}
}
}
// 给开发者相应的分红,此功能放在凌晨更新时实现
// Member developer = getMemByAppID(appID);
// developer.setIncome_balance(cpmPrice * DEVELOPER_GET_RATE
// + developer.getIncome_balance());
}
// 封装ShowInfo字符串
String saveShowMsg = appID + "︴" + okAD.getAd_id() + "︴" + secondSDF.format(new Date()) + "︴"
+ cpmPrice + "︴" + imei + "︴" + zoneCode + "︴" + okAD.getId() + "\n";
showInfoList.add(saveShowMsg);
if (!isSaveShowStringThreadRunning) {
startSaveShowStringThread();
}
retMsg += okAD.toString() + "︴";
}
}
return okADs == null || retMsg.length() == 0 ? "No ADs" : retMsg.substring(0, retMsg.length() - 1);
}
public synchronized String parseClickMessage(String msg) throws Exception {
Log.debug("click: " + msg);
String[] msgs = msg.split("‖");
String appID = msgs[0];
String adID = msgs[1];
String imei = msgs[2];
String zoneCode = msgs[3];
// String showTypeID = msgs[4];
if (testImeiClickTimes(appID, imei)) {
return "Click too many times for a moment";
}
ADShowType okAD = getADShowTypeByADID(Integer.parseInt(adID));
if (okAD != null) {
Double cpcPrice = 0.0;
AD ad = getADByAdID(okAD.getAd_id());
Member mem = getMemByAdID(ad.getMem_id());
Log.debug("paymode: " + okAD.getPay_mode() + " 余额: " + mem.getAd_balance());
if ("按单次点击付费".equals(okAD.getPay_mode())) {
cpcPrice = okAD.getPrice();
// 扣除广告出本次请求的CPC费用
mem.setAd_balance(DoubleUtil.subtract(mem.getAd_balance(), cpcPrice));
if (mem.getAd_balance() < 0.5) {
for (AD a : allRunningADs) {
if (a.getMem_id().equals(mem.getId())) {
a.setState("暂停");
}
}
}
// 给开发者相应的分红
Member developer = getMemByAppID(appID);
developer.setIncome_balance(cpcPrice * DEVELOPER_GET_RATE + developer.getIncome_balance());
}
// 封装ClickInfo字符串
String saveClickMsg = appID + "︴" + okAD.getAd_id() + "︴" + secondSDF.format(new Date()) + "︴" + cpcPrice
+ "︴" + imei + "︴" + zoneCode + "︴" + okAD.getId() + "\n";
clickInfoList.add(saveClickMsg);
if (!isSaveClickStringThreadRunning) {
startSaveClickStringThread();
}
}
return "click: " + okAD.getTitle();
}
// 讲手机生产厂商的英文转成中文
private String parsePhoneType(String phoneType) {
if ("samsung".equalsIgnoreCase(phoneType)) {
phoneType = "三星";
} else if ("zte".equalsIgnoreCase(phoneType)) {
phoneType = "中兴";
} else if ("motorola".equalsIgnoreCase(phoneType)) {
phoneType = "摩托罗拉";
} else if ("htc".equalsIgnoreCase(phoneType)) {
phoneType = "HTC";
} else if ("sony ericsson".equalsIgnoreCase(phoneType)) {
phoneType = "索尼爱立信";// 未测试
} else if ("LG".equalsIgnoreCase(phoneType)) {
phoneType = "LG";// 未测试
} else if ("lenovo".equalsIgnoreCase(phoneType)) {
phoneType = "联想";// 未测试
} else if ("gionee".equalsIgnoreCase(phoneType)) {
phoneType = "金立";// 未测试
} else if ("huawei".equalsIgnoreCase(phoneType)) {
phoneType = "华为";// 未测试
} else {
phoneType = "其它";
}
return phoneType;
}
private ADShowType getADShowTypeByADID(int AdId) {
for (ADShowType ast : allADShowTypes) {
if (ast.getAd_id().equals(AdId)) {
return ast;
}
}
return null;
}
private App getAppByAppID(String appId) {
for (App app : allApps) {
if (app.getPid().equals(appId)) {
return app;
}
}
return null;
}
private AD getADByAdID(int adId) {
for (AD ad : allRunningADs) {
if (ad.getId().equals(adId)) {
return ad;
}
}
return null;
}
private Member getMemByAdID(int memId) {
for (Member mem : allMembers) {
if (mem.getId().equals(memId)) {
return mem;
}
}
return null;
}
private Member getMemByAppID(String appId) {
for (App app : allApps) {
if (appId.equals(app.getPid())) {
return getMemByAdID(app.getMem_id());
}
}
return null;
}
// 过滤掉运行过程中由于余额不足暂停的广告
private Vector<ADShowType> filtratePause(Vector<ADShowType> original) {
Vector<ADShowType> okADShowTypes = new Vector<ADShowType>();
for (ADShowType ast : original) {
for (AD ad : allRunningADs) {
if (ad.getId().equals(ast.getAd_id()) && !"暂停".equals(ad.getState())) {
okADShowTypes.add(ast);
}
}
}
return okADShowTypes;
}
// 找出满足展现方式的ADShowTypes(条幅型,插屏型,悬浮型)
private Vector<ADShowType> filtrateShowType(Vector<ADShowType> original, String typeCode) {
Vector<ADShowType> okADShowTypes = new Vector<ADShowType>();
String type = "";
if ("1".equals(typeCode)) {
type = "条幅型";
} else if ("2".equals(typeCode)) {
type = "插屏型";
} else if ("3".equals(typeCode)) {
type = "悬浮型";
}
for (ADShowType ast : original) {
String showType = ast.getShow_type_name().split(":")[0];
if (showType.equals(type)) {
okADShowTypes.add(ast);
}
}
return okADShowTypes;
}
// 找出满足地理条件的ADShowTypes
private Vector<ADShowType> filtrateZone(Vector<ADShowType> original, String zoneCode, double lon, double lat) {
Vector<ADShowType> okADShowTypes = new Vector<ADShowType>();
for (ADShowType ast : original) {
for (ADZone adZone : allADZones) {
if (adZone.getAd_id().equals(ast.getAd_id())) {
if (adZone.getZone_code().equals(zoneCode)) {
okADShowTypes.add(ast);
} else if (Integer.parseInt(adZone.getZone_code()) == -1) {
String[] zoneInfo = adZone.getZone_name().split(":");
double adLon = Double.parseDouble(zoneInfo[0]); // 设定的中心经度
double adLat = Double.parseDouble(zoneInfo[1]); // 设定的中心纬度
double adRadius = Double.parseDouble(zoneInfo[2]); // 设定的半径
double pathLength = Math.sqrt(Math.pow((lon - adLon) * 85390, 2)
+ Math.pow((lat - adLat) * 111000, 2));
Log.debug("实际经纬度: " + lon + ", " + lat);
Log.debug("广告经纬度: " + adLon + ", " + adLat);
Log.debug("adRadius: " + adRadius);
Log.debug("pathLength: " + pathLength);// TODO Wifi 测试 误差1400米左右
if (pathLength < adRadius) {
okADShowTypes.add(ast);
}
}
}
}
}
return okADShowTypes;
}
// 找出满足手机类型的ADShowTypes
private Vector<ADShowType> filtratePhoneType(Vector<ADShowType> original, String phoneType) {
Vector<ADShowType> okADShowTypes = new Vector<ADShowType>();
for (ADShowType ast : original) {
for (ADPhoneType apt : allADPhoneTypes) {
if (apt.getPhone_name().equals(phoneType) && apt.getAd_id().equals(ast.getAd_id())) {
okADShowTypes.add(ast);
}
}
}
return okADShowTypes;
}
// 找出满足运营商的ADShowTypes
private Vector<ADShowType> filtrateArs(Vector<ADShowType> original, String arsName) {
Vector<ADShowType> okADShowTypes = new Vector<ADShowType>();
for (ADShowType ast : original) {
for (ADArs ars : allADArs) {
if (ars.getArs_name().equals(arsName) && ars.getAd_id().equals(ast.getAd_id())) {
okADShowTypes.add(ast);
}
}
}
return okADShowTypes;
}
// 找出满足 用户群 和 性别 条件的ADShowTypes
private Vector<ADShowType> filtrateCrowdAndGender(Vector<ADShowType> original, String appID) {
Vector<ADShowType> okADShowTypes = new Vector<ADShowType>();
App app = getAppByAppID(appID);
for (ADShowType ast : original) {
AD ad = getADByAdID(ast.getAd_id());
// 满足性别条件
if (ad.getPut_gender().equals("0") || app.getApp_gender().equals("0")
|| app.getApp_gender().equals(ad.getPut_gender())) {
// String appCrowd = app.getApp_crowd();
// 满足用户群条件
if (ad.getPut_crowd().equals("15")) {
okADShowTypes.add(ast);
} else {
int adCrowdInt = Integer.parseInt(ad.getPut_crowd());
int appCrowdInt = Integer.parseInt(app.getApp_crowd());
for (int i = 0; i < 4; i++) {
if ((adCrowdInt >> i) % 2 == 1 && (appCrowdInt >> i) % 2 == 1) {
okADShowTypes.add(ast);
break;
}
}
}
}
}
return okADShowTypes;
}
// 找出满足时间段条件的ADShowTypes(上午,下午等)
private Vector<ADShowType> filtrateTime(Vector<ADShowType> original) {
SimpleDateFormat sdf = new SimpleDateFormat("HH");
int hour = Integer.parseInt(sdf.format(new Date()));
if (hour >= 6 && hour < 12) {
hour = 8;
} else if (hour >= 12 && hour < 18) {
hour = 4;
} else if (hour >= 18 && hour < 24) {
hour = 2;
} else if (hour >= 0 && hour < 6) {
hour = 1;
}
Vector<ADShowType> okADShowTypes = new Vector<ADShowType>();
for (ADShowType ast : original) {
AD ad = getADByAdID(ast.getAd_id());
int adTimes = Integer.parseInt(ad.getPut_time());
if (adTimes == 15) {
okADShowTypes.add(ast);
} else {
for (int i = 0; i < 4; i++) {
if ((adTimes >> i) % 2 == 1 && (hour >> i) % 2 == 1) {
okADShowTypes.add(ast);
break;
}
}
}
}
return okADShowTypes;
}
// 找出满足网络条件的ADShowTypes(Wifi,普通2G,3G) netType 0:非Wifi;1:Wifi
public Vector<ADShowType> filtrateNet(Vector<ADShowType> original, String netType) {
if ("1".equals(netType)) {
return original;
}
Vector<ADShowType> okADShowTypes = new Vector<ADShowType>();
for (ADShowType ast : original) {
String[] showTypeName = ast.getShow_type_name().split(":");
if ("插屏型".equals(showTypeName[0])) {
okADShowTypes.add(ast);
} else {
String clickEffect = ast.getClick_effect();
if ("播放音乐".equals(clickEffect) || "全屏图片".equals(clickEffect) || "视频动画".equals(clickEffect)) {
okADShowTypes.add(ast);
}
}
}
return okADShowTypes;
}
public String loadRequestInfo() throws Exception {
if (currentRequestInfoPath == null) {
String date = hourSDF.format(new Date());
// urd: UangelRequestData.
currentRequestInfoPath = REQUEST_INFO_PATH + date + ".urd";
}
File f = new File(currentRequestInfoPath);
if (!f.exists()) {
return "";
}
FileReader fr = new FileReader(f);
BufferedReader br = new BufferedReader(fr);
StringBuilder result = new StringBuilder();
String s;
while ((s = br.readLine()) != null) {
result.append(s);
}
br.close();
fr.close();
return result.toString();
}
// 当出现未知异常时,保存当前内存中的数据到数据库
public void saveDataWhenException() {
String yesterday = daySDF.format(System.currentTimeMillis() - 24 * 60 * 60 * 1000);
sss.synDatabase(allRunningADs, allMembers, allMembersBak, yesterday, REQUEST_INFO_PATH, SHOW_INFO_PATH,
CLICK_INFO_PATH, DEVELOPER_GET_RATE);
String today = daySDF.format(System.currentTimeMillis());
sss.synDatabase(allRunningADs, allMembers, allMembersBak, today, REQUEST_INFO_PATH, SHOW_INFO_PATH,
CLICK_INFO_PATH, DEVELOPER_GET_RATE);
// 前一天和今日的数据已存入数据库,把前一天和今日的数据备份之后从当日文件夹删除即可。
}
class SaveToDB extends TimerTask { // 凌晨2点将昨日数据存入数据库,并更新当前内存中的数据
@Override
public void run() {
synchronized (DataManager.this) {
long start = System.currentTimeMillis();
// 昨天字符串
// String yesterday = daySDF.format(System.currentTimeMillis() -
// 24 * 60 * 60 * 1000);
String yesterday = daySDF.format(System.currentTimeMillis()); // 测试用
Log.info(yesterday + "'s Task Start at " + start);
// 同步前一天的信息到数据库。
sss.synDatabase(allRunningADs, allMembers, allMembersBak, yesterday, REQUEST_INFO_PATH, SHOW_INFO_PATH,
CLICK_INFO_PATH, DEVELOPER_GET_RATE);
Log.info("同步前一天的信息到数据库成功");
// 昨天是最后一天的广告的状态置为结束
sss.updateEndADs(yesterday);
Log.info("昨天是最后一天的广告的状态置为结束成功");
// 重新初始化
Log.info("读取最新数据");
loadingNewestData();
Log.info(yesterday + "'s Task End. Use " + (System.currentTimeMillis() - start) + " ms.");
}
}
}
}