package com.hongqiang.shop.modules.content.service; import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.OutputStreamWriter; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.servlet.ServletContext; import org.apache.commons.io.IOUtils; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.Assert; import org.springframework.web.context.ServletContextAware; import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer; import com.hongqiang.shop.common.base.persistence.Page; import com.hongqiang.shop.common.service.BaseService; import com.hongqiang.shop.common.utils.CacheUtils; import com.hongqiang.shop.common.utils.Filter; import com.hongqiang.shop.common.utils.Order; import com.hongqiang.shop.common.utils.Pageable; import com.hongqiang.shop.modules.content.dao.ArticleDao; import com.hongqiang.shop.modules.entity.Article; import com.hongqiang.shop.modules.entity.ArticleCategory; import com.hongqiang.shop.modules.entity.Tag; import com.hongqiang.shop.modules.util.service.TemplateService; @Service public class ArticleServiceImpl extends BaseService implements ArticleService, DisposableBean, ServletContextAware { private long systemTime = System.currentTimeMillis(); public static final String HITS_CACHE_NAME = "articleHits"; public static final int HITS_CACHE_INTERVAL = 600000; private ServletContext servletContext; @Autowired private FreeMarkerConfigurer freeMarkerConfigurer; @Autowired private TemplateService templateService; @Autowired private ArticleDao articleDao; public void setServletContext(ServletContext servletContext) { this.servletContext = servletContext; } @Transactional(readOnly = true) public List<Article> findList(ArticleCategory articleCategory, List<Tag> tags, Integer count, List<Filter> filters, List<Order> orders) { return this.articleDao.findList(articleCategory, tags, count, filters, orders); } @Transactional(readOnly = true) @Cacheable({ "article" }) public List<Article> findList(ArticleCategory articleCategory, List<Tag> tags, Integer count, List<Filter> filters, List<Order> orders, String cacheRegion) { return this.articleDao.findList(articleCategory, tags, count, filters, orders); } @Transactional(readOnly = true) public List<Article> findList(ArticleCategory articleCategory, Date beginDate, Date endDate, Integer first, Integer count) { return this.articleDao.findList(articleCategory, beginDate, endDate, first, count); } @Transactional(readOnly = true) public Page<Article> findPage(ArticleCategory articleCategory, List<Tag> tags, Pageable pageable) { return this.articleDao.findPage(articleCategory, tags, pageable); } @Transactional(readOnly = true) public Page<Article> findPage(Pageable pageable) { return this.articleDao.findPage(pageable); } @Transactional(readOnly = true) public Article find(Long id) { return this.articleDao.find(id); } public long viewHits(Long id){ System.out.println("id="+id); System.out.println("idString="+id.toString()); Long hits = (Long)CacheUtils.get(HITS_CACHE_NAME, id.toString()); if (hits == null) { Article localArticle = (Article) this.articleDao.find(id); if (localArticle == null) return 0L; hits = localArticle.getHits(); } Long returnHits = Long.valueOf(hits.longValue() + 1L); CacheUtils.put(HITS_CACHE_NAME, id.toString(), returnHits); long l = System.currentTimeMillis(); if (l > this.systemTime + HITS_CACHE_INTERVAL) { this.systemTime = l; destroyCache(); CacheUtils.removeAll(HITS_CACHE_NAME); } return returnHits.longValue(); } public void destroy() { destroyCache(); } private void destroyCache(){ @SuppressWarnings("unchecked") List<Long> localList = (List<Long>) CacheUtils.getKeys(HITS_CACHE_NAME); Iterator<Long> localIterator = localList.iterator(); while (localIterator.hasNext()) { Long id = (Long) localIterator.next(); Article localArticle = (Article) this.articleDao.find(id); if (localArticle == null) continue; Long hits = (Long)CacheUtils.get(HITS_CACHE_NAME, id.toString()); localArticle.setHits(hits); this.articleDao.merge(localArticle); } } @Transactional @CacheEvict(value = { "article", "articleCategory" }, allEntries = true) public void save(Article article) { Assert.notNull(article); this.articleDao.persist(article); this.articleDao.flush(); build(article); } @Transactional @CacheEvict(value = { "article", "articleCategory" }, allEntries = true) public Article update(Article article) { Assert.notNull(article); Article localArticle = (Article) this.articleDao.merge(article); this.articleDao.flush(); build(localArticle); return localArticle; } @Transactional @CacheEvict(value = { "article", "articleCategory" }, allEntries = true) public Article update(Article article, String[] ignoreProperties) { return (Article) this.articleDao.update(article, ignoreProperties); } @Transactional @CacheEvict(value = { "article", "articleCategory" }, allEntries = true) public void delete(Long id) { this.articleDao.delete(id); } @Transactional @CacheEvict(value = { "article", "articleCategory" }, allEntries = true) public void delete(Long[] ids) { if (ids != null) for (Long localSerializable : ids) this.articleDao.delete(localSerializable); } @Transactional @CacheEvict(value = { "article", "articleCategory" }, allEntries = true) public void delete(Article article) { if (article != null) deleteStaticArticle(article); this.articleDao.delete(article); } @Transactional(readOnly=true) public int build(Article article) { Assert.notNull(article); deleteStaticArticle(article); com.hongqiang.shop.modules.utils.Template localTemplate = this.templateService .get("articleContent"); int i = 0; if (article.getIsPublication().booleanValue()) { HashMap<String, Object> localHashMap = new HashMap<String, Object>(); localHashMap.put("article", article); for (int j = 1; j <= article.getTotalPages(); j++) { article.setPageNumber(Integer.valueOf(j)); i += build(localTemplate.getTemplatePath(), article.getPath(), localHashMap); } article.setPageNumber(null); } return i; } @Transactional(readOnly=true) private int build(String templatePath, String staticPath, Map<String, Object> model) { Assert.hasText(templatePath); Assert.hasText(staticPath); FileOutputStream localFileOutputStream = null; OutputStreamWriter localOutputStreamWriter = null; BufferedWriter localBufferedWriter = null; try { freemarker.template.Template localTemplate = this.freeMarkerConfigurer .getConfiguration().getTemplate(templatePath); File localFile1 = new File( this.servletContext.getRealPath(staticPath)); File localFile2 = localFile1.getParentFile(); if (!localFile2.exists()) localFile2.mkdirs(); localFileOutputStream = new FileOutputStream(localFile1); localOutputStreamWriter = new OutputStreamWriter( localFileOutputStream, "UTF-8"); localBufferedWriter = new BufferedWriter(localOutputStreamWriter); localTemplate.process(model, localBufferedWriter); localBufferedWriter.flush(); return 1; } catch (Exception localException1) { localException1.printStackTrace(); } finally { IOUtils.closeQuietly(localBufferedWriter); IOUtils.closeQuietly(localOutputStreamWriter); IOUtils.closeQuietly(localFileOutputStream); } return 0; } @Transactional(readOnly=true) public int deleteStaticArticle(Article article) { Assert.notNull(article); int i = 0; for (int j = 1; j <= article.getTotalPages() + 1000; j++) { article.setPageNumber(Integer.valueOf(j)); int k = delete(article.getPath()); if (k < 1) break; i += k; } article.setPageNumber(null); return i; } @Transactional(readOnly=true) private int delete(String staticPath) { Assert.hasText(staticPath); File localFile = new File(this.servletContext.getRealPath(staticPath)); if (localFile.exists()) { localFile.delete(); return 1; } return 0; } }