/*
* Copyright [duowan.com]
* Web Site: http://www.duowan.com
* Since 2005 - 2012
*/
package com.fpcms.service.impl;
import static com.github.rapid.common.util.holder.BeanValidatorHolder.validateWithException;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import com.github.rapid.common.util.DateRange;
import com.github.rapid.common.util.page.Page;
import com.github.rapid.common.util.page.PageQuery;
import com.fpcms.common.random_gen_article.RandomArticle;
import com.fpcms.common.random_gen_article.RandomArticleBuilder;
import com.fpcms.common.util.Constants;
import com.fpcms.common.util.DomainUtil;
import com.fpcms.common.util.KeywordUtil;
import com.fpcms.common.util.RandomUtil;
import com.fpcms.common.util.TextLangUtil;
import com.fpcms.common.webcrawler.htmlparser.HtmlPage.Anchor;
import com.fpcms.dao.CmsContentDao;
import com.fpcms.model.CmsContent;
import com.fpcms.model.CmsDomain;
import com.fpcms.model.CmsSite;
import com.fpcms.query.CmsContentQuery;
import com.fpcms.service.CmsContentService;
import com.fpcms.service.CmsDomainService;
import com.fpcms.service.CmsPropertyService;
import com.fpcms.service.CmsSiteService;
/**
* [CmsContent] 的业务操作实现类
*
* @author badqiu email:badqiu(a)gmail.com
* @version 1.0
* @since 1.0
*/
@Service("cmsContentService")
@Transactional
public class CmsContentServiceImpl implements CmsContentService {
protected static final Logger log = LoggerFactory.getLogger(CmsContentServiceImpl.class);
private CmsPropertyService cmsPropertyService;
private CmsSiteService cmsSiteService;
private CmsDomainService cmsDomainService;
//
// 请删除无用的方法,代码生成器只是为你生成一个架子
//
private CmsContentDao cmsContentDao;
/**增加setXXXX()方法,spring就可以通过autowire自动设置对象属性,请注意大小写*/
public void setCmsContentDao(CmsContentDao dao) {
this.cmsContentDao = dao;
}
public void setCmsPropertyService(CmsPropertyService cmsPropertyService) {
this.cmsPropertyService = cmsPropertyService;
}
public void setCmsSiteService(CmsSiteService cmsSiteService) {
this.cmsSiteService = cmsSiteService;
}
public void setCmsDomainService(CmsDomainService cmsDomainService) {
this.cmsDomainService = cmsDomainService;
}
public CmsContent createWithRandomLink(CmsContent cmsContent) {
return createWithRandomLink(cmsContent,100);
}
/**
* 创建CmsContent,并且附加随机链接
**/
public CmsContent createWithRandomLink(CmsContent cmsContent,int randomLinkPercent) {
if(RandomUtil.randomTrue(randomLinkPercent)) {
String link = getRandomSiteLink();
if(StringUtils.isNotBlank(link)) {
String linkedContent = cmsContent.getContent();
linkedContent = linkedContent + "<a href='"+link+"'>"+link+"</a>";
cmsContent.setContent(linkedContent);
}
}
return create(cmsContent);
}
private String getRandomSiteLink() {
CmsDomain domain = RandomUtil.randomSelect(cmsDomainService.findAll());
if(domain != null ) {
return domain.getYesterdayOuterLinked();
}
return null;
}
/**
* 创建CmsContent
**/
public CmsContent create(CmsContent cmsContent) {
Assert.notNull(cmsContent,"'cmsContent' must be not null");
initDefaultValuesForCreate(cmsContent);
new CmsContentChecker().checkCreateCmsContent(cmsContent);
cmsContentDao.insert(cmsContent);
return cmsContent;
}
/**
* 更新CmsContent
**/
public CmsContent update(CmsContent cmsContent) {
Assert.notNull(cmsContent,"'cmsContent' must be not null");
new CmsContentChecker().checkUpdateCmsContent(cmsContent);
cmsContentDao.update(cmsContent);
return cmsContent;
}
/**
* 删除CmsContent
**/
public void removeById(long id) {
cmsContentDao.deleteById(id);
}
/**
* 根据ID得到CmsContent
**/
public CmsContent getById(long id) {
return cmsContentDao.getById(id);
}
/**
* 分页查询: CmsContent
**/
@Transactional(readOnly=true)
public Page<CmsContent> findPage(CmsContentQuery query) {
Assert.notNull(query,"'query' must be not null");
// Assert.hasText(query.getSite(),"'query.site' must be not empty");
return cmsContentDao.findPage(query);
}
/**
* 为创建时初始化相关默认值
**/
public void initDefaultValuesForCreate(CmsContent cmsContent) {
}
/**
* CmsContent的属性检查类,根据自己需要编写自定义检查
**/
public class CmsContentChecker {
/**可以在此检查只有更新才需要的特殊检查 */
public void checkUpdateCmsContent(CmsContent cmsContent) {
checkCmsContent(cmsContent);
}
/**可以在此检查只有创建才需要的特殊检查 */
public void checkCreateCmsContent(CmsContent cmsContent) {
checkCmsContent(cmsContent);
Date start = DateUtils.addDays(new Date(),-360);
int countByTitle = cmsContentDao.countByTitle(start,new Date(),cmsContent.getTitle());
if(countByTitle > 0) {
throw new IllegalStateException("already exist same title:"+cmsContent.getTitle()+" CmsContent");
}
int countBySearchKeyword = cmsContentDao.countBySearchKeyword(start,new Date(),cmsContent.getSearchKeyword());
if(countBySearchKeyword > 0) {
throw new IllegalStateException("already exist same searchKeyword:"+cmsContent.getSearchKeyword()+" CmsContent");
}
Assert.isTrue(TextLangUtil.chineseCountPercent(cmsContent.getContent()) > 60,"chineseCountPercent > 60 must be true on content:"+cmsContent.getContent());
}
/** 检查到有错误请直接抛异常,不要使用 return errorCode的方式 */
public void checkCmsContent(CmsContent cmsContent) {
// Bean Validator检查,属性检查失败将抛异常
validateWithException(cmsContent);
int contentLength = cmsContent.getContent().length();
Assert.isTrue(contentLength > 200,"cmsContent.title:" + cmsContent.getTitle() + " length > 200 false,current length:"+contentLength);
KeywordUtil.assertSensitiveKeyword(cmsContent.getTitle());
KeywordUtil.assertSensitiveKeyword(cmsContent.getContent());
//复杂的属性的检查一般需要分开写几个方法,如 checkProperty1(v),checkProperty2(v)
}
}
public synchronized void genRandomCmsContent() {
List<CmsSite> siteList = cmsSiteService.findAll();
for(CmsSite cmsSite : siteList) {
if(DomainUtil.isMainSite(cmsSite.getSiteDomain())) {
log.info("ignore genRandomCmsContent for site:"+cmsSite.getSiteDomain()+" by isMainSite,main site example:www.example.com example.com");
continue;
}
for(int i = 0; i < 5; i++) {
try {
genSiteRandomCmsContent(cmsSite.getSiteDomain());
break;
}catch(Exception e) {
log.error("error genSiteRandomCmsContent for site:"+cmsSite.getSiteDomain()+" cmsSite:"+cmsSite,e);
}
}
}
}
public void genSiteRandomCmsContent(String site) {
CmsSite cmsSite = cmsSiteService.getById(site);
Assert.notNull(cmsSite,"not found cmsSite by site:"+site);
if(StringUtils.isNotBlank(cmsSite.getRedirectSite())) {
log.info("ignore_genSiteRandomCmsContent for site:"+site+" by StringUtils.isNotBlank(cmsSite.getRedirectSite())");
return;
}
genSiteRandomCmsContent(cmsSite.getSiteDomain(),cmsSite.getCity());
}
private void genSiteRandomCmsContent(String site,String city) {
RandomArticleBuilder builder = new RandomArticleBuilder();
RandomArticle article = builder.buildRandomArticle(city);
Assert.hasText(article.getPerfectKeyword(),"article.getPerfectKeyword() must be not emtpy,final search keyword:"+article.getFinalSearchKeyword());
Assert.isTrue(article.getContent().length() > 500,"article.getContent().length > 500 must be true,final search keyword:"+article.getFinalSearchKeyword());
CmsContent cmsContent = new CmsContent();
cmsContent.setContent(article.getContent());
String title = article.getPerfectKeyword();
cmsContent.setTitle(StringUtils.trim(title)); //TODO 网站:关键字要附加进去
cmsContent.setAuthor("ramd");
cmsContent.setChannelCode(Constants.CHANNED_CODE_NEWS);
cmsContent.setSite(site);
cmsContent.setSearchKeyword(article.getKeyword());
createWithRandomLink(cmsContent,40);
log.info("generate_random_news by finalSearchKeyword:"+article.getFinalSearchKeyword()+",new title:"+title);
// CmsContent.baiduBlogPing(cmsContent);
}
// /**
// * 1. 增加文本及URL链接
// * 2. 打乱文章
// **/
// public String buildOriginalArticle(String content,List<Anchor> anchorList) {
//
// StringBuilder sb = new StringBuilder(content);
// int index = 0;
// while(index >= 0) {
// index = content.indexOf(",");
// if(anchorList.isEmpty()) {
// break;
// }
// Anchor anchor = anchorList.remove(0);
// }
// return "";
// }
//
@Override
public CmsContent getNextCmsContent(Date dateCreated,String site,long id) {
return cmsContentDao.getNextCmsContent(dateCreated,site,id);
}
@Override
public CmsContent getPreCmsContent(Date dateCreated,String site,long id) {
return cmsContentDao.getPreCmsContent(dateCreated,site,id);
}
@Override
public Page<CmsContent> findPage(PageQuery pageQuery, String site,String channelCode, DateRange createdRange) {
return cmsContentDao.findPage(pageQuery, site,channelCode,createdRange);
}
@Override
public Page findBySiteLike(PageQuery pageQuery, String site,
String channelCode, DateRange createdRange) {
return cmsContentDao.findBySiteLike(pageQuery, site,channelCode,createdRange);
}
@Override
public CmsContent getById(Date dateCreated, long id) {
return cmsContentDao.getById(dateCreated,id);
}
@Override
public CmsContent findLastBySite(String site) {
return cmsContentDao.findLastBySite(site);
}
public int countBySourceUrl(Date start, Date end, String sourceUrl) {
return cmsContentDao.countBySourceUrl(start, end, sourceUrl);
}
@Override
public CmsContent findFirstByCreatedDay(String site,Date createdDay) {
return cmsContentDao.findFirstByCreatedDay(site,createdDay);
}
public List<Map<String, Object>> statSite(DateRange range) {
return cmsContentDao.statSite(range);
}
}