/*******************************************************************************
* Copyright 2015 htd0324@gmail.com
*
* 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 com.laudandjolynn.mytv.service;
import java.util.ArrayList;
import java.util.List;
import com.laudandjolynn.mytv.crawler.Crawler;
import com.laudandjolynn.mytv.crawler.MyTvCrawlerManager;
import com.laudandjolynn.mytv.datasource.TvDao;
import com.laudandjolynn.mytv.datasource.TvDaoImpl;
import com.laudandjolynn.mytv.event.AllTvStationCrawlEndEvent;
import com.laudandjolynn.mytv.event.CrawlEvent;
import com.laudandjolynn.mytv.event.CrawlEventListener;
import com.laudandjolynn.mytv.event.CrawlEventListenerAdapter;
import com.laudandjolynn.mytv.event.ProgramTableCrawlEndEvent;
import com.laudandjolynn.mytv.event.TvStationFoundEvent;
import com.laudandjolynn.mytv.model.MyTv;
import com.laudandjolynn.mytv.model.ProgramTable;
import com.laudandjolynn.mytv.model.TvStation;
import com.laudandjolynn.mytv.utils.MemoryCache;
/**
* @author: Laud
* @email: htd0324@gmail.com
* @date: 2015年3月30日 下午3:05:47
* @copyright: www.laudandjolynn.com
*/
public class TvServiceImpl implements TvService {
private TvDao tvDao = new TvDaoImpl();
private final static int TV_STATION_PERSISTENT_THRESHOLD = 100;
/**
* 保存电视台
*
* @param stations
*/
@Override
public void save(TvStation... stations) {
int size = stations == null ? 0 : stations.length;
if (size == 0) {
return;
}
tvDao.save(stations);
}
/**
* 保存电视台节目表
*
* @param programTables
*/
@Override
public void save(ProgramTable... programTables) {
int size = programTables == null ? 0 : programTables.length;
if (size == 0) {
return;
}
List<ProgramTable> resultList = new ArrayList<ProgramTable>();
for (int i = 0; i < size; i++) {
ProgramTable pt = programTables[i];
String stationName = pt.getStationName();
String date = pt.getAirDate();
if (tvDao.isProgramTableExists(stationName, date)) {
continue;
}
resultList.add(pt);
}
programTables = new ProgramTable[resultList.size()];
tvDao.save(resultList.toArray(programTables));
}
/**
* 获取电视台分类
*
* @return
*/
@Override
public List<String> getMyTvClassify() {
return tvDao.getMyTvClassify();
}
@Override
public List<TvStation> getAllCrawlableStation() {
List<TvStation> stationList = tvDao.getAllCrawlableStation();
if (stationList != null) {
MemoryCache.getInstance().addCache(stationList);
}
return stationList;
}
@Override
public TvStation getStation(String stationName) {
TvStation tvStation = MemoryCache.getInstance().getStation(stationName);
if (tvStation == null) {
List<TvStation> stationList = tvDao.getStation(stationName);
if (stationList.size() > 0) {
tvStation = stationList.get(0);
MemoryCache.getInstance().addCache(tvStation);
}
}
return tvStation;
}
/**
* 根据显示名取得电视台对象
*
* @param displayName
* 电视台显示名
* @param classify
* 电视台分类,可以为null。为空时,将查找stationName与displayName相同的电视台
* @return
*/
@Override
public TvStation getStationByDisplayName(String displayName, String classify) {
TvStation tvStation = tvDao.getStationByDisplayName(displayName,
classify);
if (tvStation != null) {
MemoryCache.getInstance().addCache(tvStation);
}
return tvStation;
}
/**
* 获取指定电视台节目表
*
* @param stationName
* @param date
* @return
*/
@Override
public List<ProgramTable> getProgramTable(String stationName, String date) {
return tvDao.getProgramTable(stationName, date);
}
/**
* 根据电视台分类查询分类下的所有电视台
*
* @param classify
* @return
*/
@Override
public List<MyTv> getMyTvByClassify(String classify) {
return tvDao.getMyTvByClassify(classify);
}
/**
* 判断指定的电视节目表是否已存在
*
* @param stationName
* @param date
* @return
*/
@Override
public boolean isProgramTableExists(String stationName, String date) {
return tvDao.isProgramTableExists(stationName, date);
}
/**
* 根据电视台名称、日期抓取电视节目表
*
* @param tvStation
* 电视台对象
* @param date
* 日期,yyyy-MM-dd
* @param listeners
* 抓取事件监听器
* @return
*/
@Override
public List<ProgramTable> crawlProgramTable(TvStation tvStation,
String date, CrawlEventListener... listeners) {
Crawler crawler = MyTvCrawlerManager.getInstance().newCrawler();
crawler.registerCrawlEventListener(new CrawlEventListenerAdapter() {
@Override
public void crawlEnd(CrawlEvent event) {
if (event instanceof ProgramTableCrawlEndEvent) {
List<ProgramTable> resultList = ((ProgramTableCrawlEndEvent) event)
.getReturnValue();
ProgramTable[] resultArray = new ProgramTable[resultList
.size()];
save(resultList.toArray(resultArray));
}
}
});
for (int i = 0, length = listeners == null ? 0 : listeners.length; i < length; i++) {
crawler.registerCrawlEventListener(listeners[i]);
}
return crawler.crawlProgramTable(date, tvStation);
}
/**
* 抓取所有电视台
*
* @param listeners
* 抓取事件监听器
*
* @return
*/
@Override
public List<TvStation> crawlAllTvStation(CrawlEventListener... listeners) {
Crawler crawler = MyTvCrawlerManager.getInstance().newCrawler();
final List<TvStation> stationList = new ArrayList<TvStation>();
crawler.registerCrawlEventListener(new CrawlEventListenerAdapter() {
@Override
public void itemFound(CrawlEvent event) {
if (event instanceof TvStationFoundEvent) {
TvStation item = ((TvStationFoundEvent) event).getItem();
synchronized (stationList) {
int size = stationList.size();
if (size > 0
&& size % TV_STATION_PERSISTENT_THRESHOLD == 0) {
TvStation[] stations = new TvStation[size];
tvDao.save(stationList.toArray(stations));
// 保存之后再写入缓存,因为持久化前会判断电视台是否已经存在
MemoryCache.getInstance().addCache(stationList);
stationList.clear();
} else {
stationList.add(item);
}
}
}
}
@Override
public void crawlEnd(CrawlEvent event) {
if (event instanceof AllTvStationCrawlEndEvent) {
synchronized (stationList) {
if (stationList.size() > 0) {
TvStation[] stations = new TvStation[stationList
.size()];
tvDao.save(stationList.toArray(stations));
// 保存之后再写入缓存,因为持久化前会判断电视台是否已经存在
MemoryCache.getInstance().addCache(stationList);
stationList.clear();
}
}
}
}
});
for (int i = 0, length = listeners == null ? 0 : listeners.length; i < length; i++) {
crawler.registerCrawlEventListener(listeners[i]);
}
return crawler.crawlAllTvStation();
}
@Override
public List<TvStation> getDisplayedTvStation() {
return tvDao.getDisplayedTvStation();
}
@Override
public List<MyTv> getMyTv() {
return tvDao.getMyTv();
}
@Override
public boolean isInMyTv(TvStation tvStation) {
return MemoryCache.getInstance().isInMyTv(tvStation);
}
}