/*******************************************************************************
* 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;
import java.util.Date;
import java.util.List;
import org.eclipse.jetty.util.ConcurrentHashSet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.laudandjolynn.mytv.exception.MyTvException;
import com.laudandjolynn.mytv.model.CrawlerTask;
import com.laudandjolynn.mytv.model.ProgramTable;
import com.laudandjolynn.mytv.model.TvStation;
import com.laudandjolynn.mytv.service.TvService;
import com.laudandjolynn.mytv.service.TvServiceImpl;
import com.laudandjolynn.mytv.utils.DateUtils;
/**
* @author: Laud
* @email: htd0324@gmail.com
* @date: 2015年3月27日 下午11:42:27
* @copyright: www.laudandjolynn.com
*/
public class CrawlAction {
private final static Logger logger = LoggerFactory
.getLogger(CrawlAction.class);
private final ConcurrentHashSet<CrawlerTask> CURRENT_EPG_TASK = new ConcurrentHashSet<CrawlerTask>();
private TvService tvService = new TvServiceImpl();
private CrawlAction() {
}
public static CrawlAction getIntance() {
return EpgTaskManagerSingletonHolder.CRAWL_ACTION;
}
private final static class EpgTaskManagerSingletonHolder {
private final static CrawlAction CRAWL_ACTION = new CrawlAction();
}
/**
* <pre>
* 所有请求入口
* 查询指定日期、电视台的节目表
* </pre>
*
* @param name
* 电视台名
* @param classify
* 电视台分类
* @param date
* 日期,yyyy-MM-dd
* @return
*/
public List<ProgramTable> queryProgramTable(String name, String classify,
String date) {
TvStation tvStation = tvService.getStation(name);
if (tvStation == null) {
tvStation = tvService.getStationByDisplayName(name, classify);
}
if (tvStation == null) {
logger.error(name + " isn't exists.");
return null;
}
String[] weeks = DateUtils.getWeek(new Date(), "yyyy-MM-dd");
// 只能查询一周内的节目表
if (date.compareTo(weeks[0]) < 0 || date.compareTo(weeks[6]) > 0) {
return null;
}
final String stationName = tvStation.getName();
logger.info("query program table of " + stationName + " at " + date);
if (tvService.isProgramTableExists(stationName, date)) {
return tvService.getProgramTable(stationName, date);
}
return queryProgramTable(tvStation, date);
}
/**
* 查询指定日期、电视台的电视节目表
*
* @param tvStation
* 电视台对象
* @param date
* 日期,yyyy-MM-dd
* @return
*/
protected List<ProgramTable> queryProgramTable(TvStation tvStation,
final String date) {
String stationName = tvStation.getName();
CrawlerTask crawlerTask = new CrawlerTask(stationName, date);
if (CURRENT_EPG_TASK.contains(crawlerTask)) {
synchronized (this) {
try {
logger.debug(crawlerTask
+ " is wait for the other same task's notification.");
wait();
} catch (InterruptedException e) {
throw new MyTvException(
"thread interrupted while query program table of "
+ stationName + " at " + date, e);
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// do nothing
}
logger.debug(crawlerTask
+ " has receive notification and try to get program table from db.");
return tvService.getProgramTable(stationName, date);
}
}
logger.debug(crawlerTask
+ " is trying to query program table from network.");
CURRENT_EPG_TASK.add(crawlerTask);
try {
return tvService.crawlProgramTable(tvStation, date);
} catch (Exception e) {
logger.error("crawl program table of " + stationName + " at "
+ date + " is fail.", e);
throw new MyTvException(e);
} finally {
synchronized (this) {
CURRENT_EPG_TASK.remove(crawlerTask);
logger.debug(crawlerTask
+ " have finished to get program table data and send notification.");
notifyAll();
}
}
}
/**
* 是否已经在查询指定电视台、日期的电视节目表
*
* @param tvStation
* @param date
* @return
*/
protected boolean isInQuerying(TvStation tvStation, String date) {
return CURRENT_EPG_TASK.contains(new CrawlerTask(tvStation.getName(),
date));
}
}