/* ================================================================== * Created [2009-4-27 下午11:32:55] by Jon.King * ================================================================== * TSS * ================================================================== * mailTo:jinpujun@hotmail.com * Copyright (c) Jon.King, 2009-2012 * ================================================================== */ package com.jinhe.tss.cms.service.impl; import java.io.File; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import com.jinhe.tss.cms.CMSConstants; import com.jinhe.tss.cms.dao.IArticleDao; import com.jinhe.tss.cms.dao.IChannelDao; import com.jinhe.tss.cms.entity.Article; import com.jinhe.tss.cms.entity.ArticleType; import com.jinhe.tss.cms.entity.Attachment; import com.jinhe.tss.cms.entity.Channel; import com.jinhe.tss.cms.entity.ChannelArticle; import com.jinhe.tss.cms.entity.ChannelDistribute; import com.jinhe.tss.cms.entity.ChannelDistributeId; import com.jinhe.tss.cms.entity.WordsFilter; import com.jinhe.tss.cms.helper.ArticleHelper; import com.jinhe.tss.cms.helper.translator.ChannelCanSelectTranslator; import com.jinhe.tss.cms.helper.translator.ExcludeSiteNodeTranslator; import com.jinhe.tss.cms.publish.PublishManger; import com.jinhe.tss.cms.service.IChannelService; import com.jinhe.tss.component.recycle.RecycleInterceptor; import com.jinhe.tss.core.exception.BusinessException; import com.jinhe.tss.core.util.BeanUtil; import com.jinhe.tss.core.util.EasyUtils; import com.jinhe.tss.core.web.dispaly.tree.LevelTreeParser; import com.jinhe.tss.core.web.dispaly.tree.TreeEncoder; public class ChannelService implements IChannelService { @Autowired private IChannelDao channelDao; @Autowired private IArticleDao articleDao; public List<?> getAllSiteChannelList() { return channelDao.getAllSiteChannelList(); } public List<?> getAllChannels() { String hql = "from Channel c where c.isSite = ? order by c.decode"; return channelDao.getEntities(hql, CMSConstants.FALSE); } public Channel getSiteById(Long siteId) { Channel site = channelDao.getEntity( siteId ); if (site == null) { throw new BusinessException("您选中站点不存在,可能已经被删除掉了!"); } return site; } public Channel getChannelById(Long id) { Channel channel = channelDao.getEntity(id); if (channel == null) { throw new BusinessException("选择栏目不存在!id = " + id); } Long typeId = channel.getArticleTypeId(); if ( typeId != null ) { ArticleType type = (ArticleType) channelDao.getEntity(ArticleType.class, typeId); if (type != null) { channel.setArticleTypeName(type.getName()); } } return channel; } public Channel createChannel(Channel channel) { if (CMSConstants.SITE_DEFAULT_NO_RULE.equals(channel.getHotArticleRule())) channel.setHotArticleRule(CMSConstants.SITE_DEFAULT_HOT_ARTICLE_RULE); if (CMSConstants.SITE_DEFAULT_NO_RULE.equals(channel.getNewArticleRule())) channel.setNewArticleRule(CMSConstants.SITE_DEFAULT_NEW_ARTICLE_RULE); channel.setSeqNo(channelDao.getNextSeqNo(channel.getParentId())); channel = channelDao.create(channel); return channel; } public Channel updateChannel(Channel channel) { channelDao.update(channel); return channel; } public Channel createSite(Channel site) { checkPath(site.getPath(), site.getDocPath(), site.getImagePath()); site.setSeqNo(channelDao.getNextSeqNo(CMSConstants.HEAD_NODE_ID)); site = channelDao.create(site); return site; } public Channel updateSite(Channel site) { checkPath(site.getPath(), site.getDocPath(), site.getImagePath()); channelDao.update(site); return site; } /** 检测输入路径的正确性 */ private void checkPath(String path, String docPath, String imgPath) { checkPath(path, "站点的发布路径填写错误,不能生成相应的发布文件路径!"); checkPath(docPath, "站点的附件上传根路径填写错误,不能生成相应的附件上传根路径路径!"); checkPath(imgPath, "站点的图片根路径填写错误,不能生成相应的图片根路径路径!"); } private void checkPath(String path, String errorMSg){ File file = new File(path); if (!(file.exists() == true && file.isDirectory() == true && file.canWrite() == true) && !(file.exists() == false && file.mkdirs() == true)) { throw new BusinessException(errorMSg); } } public void deleteChannel(Long channelId) { if (!checkDownPermission(channelId, CMSConstants.OPERATION_DELETE)) { throw new BusinessException("您没有删除该栏目的足够权限!"); } Channel channel = channelDao.getEntity(channelId); Channel site = channelDao.getSiteByChannel(channelId); // 先删除栏目下文章 String hql = "select a, ca from Article a, ChannelArticle ca, Channel c " + " where a.id = ca.id.articleId and ca.id.channelId = c.id and c.decode like ?"; List<?> articleList = channelDao.getEntities(hql, channel.getDecode() + "%"); for ( Object temp : articleList ) { Object[] objs = (Object[]) temp; Article article = (Article) objs[0]; ChannelArticle channelArticle = (ChannelArticle) objs[1]; // 相关文章处理(非分发文章),如果是分发文章,则说明文章来自其他栏目,这里不做删除 if ( !CMSConstants.ARTICLE_DISTRIBUTE.equals(channelArticle.getArticleOrigin()) ) { channelDao.deleteAll(channelDao.getEntities("from ArticleLation o where o.id.articleId = ?", article.getId())); // 需要绕过回收站拦截器直接物理删除文章,因为栏目已被删除,放入回收站也无意义(无法还原) RecycleInterceptor.switchTL.set(RecycleInterceptor.SWITCH_CLOSE_TAG); article.setSite(site); articleDao.deleteArticle(article); } channelDao.delete(channelArticle); } // 删除自己和子栏目 List<Channel> subChannels = channelDao.getChildrenById(channelId); for(Channel temp : subChannels) { channelDao.deleteById(temp.getId()); } } /** 对栏目向下权限的判断: 如果个数不相等,说明用户某些子节点不具有指定的权限 */ protected boolean checkDownPermission(Long resourceId, String operationId) { List<Channel> rsourceList = channelDao.getChildrenById(resourceId); List<?> permitedList = channelDao.getChildrenById(resourceId, operationId); return rsourceList.size() == permitedList.size(); } public void sortChannel(Long channelId, Long toChannelId, Integer direction) { channelDao.sort(channelId, toChannelId, direction); } public void moveChannel(Long channelId, Long targetId) { Channel channel = channelDao.getEntity(channelId); Channel target = channelDao.getEntity(targetId); channel.setSeqNo(channelDao.getNextSeqNo(targetId)); channel.setParentId(targetId); channelDao.moveChannel(channel); List<Channel> children = channelDao.getChildrenById(channelId); for ( Channel temp : children ) { temp.setSiteId(target.isSite() ? target.getId() : target.getSiteId()); temp.setDisabled(target.getDisabled()); channelDao.update(temp); } } public List<Channel> copyChannel(Long channelId, Long targetId) { Channel channel = getChannelById(channelId); Channel target = channelDao.getEntity(targetId); // 可能为空,复制整站时targetId=-1 Long siteId = null; List<Channel> returnList = new ArrayList<Channel>(); Map<Long, Long> idsMapping = new HashMap<Long, Long>(); // 维护源节点和复制节点间的映射关系 List<Channel> children = channelDao.getChildrenById(channelId, CMSConstants.OPERATION_VIEW); for( Channel child : children ){ Channel copyed = new Channel(); BeanUtil.copy(copyed, child); copyed.setId(null); if(child.getId().equals(channelId)) { copyed.setParentId(targetId); copyed.setSeqNo(channelDao.getNextSeqNo(targetId)); if ( child.getParentId().equals(targetId) ) { copyed.setName(CMSConstants.COPY_NAME_PREFIX.concat(channel.getName())); } } else { copyed.setParentId( idsMapping.get(copyed.getParentId()) ); } copyed = channelDao.create(copyed); if(target != null) { siteId = targetId; copyed.setDisabled(target.getDisabled()); } else { // target实体不存在,说明是整站复制(即在根节点下的复制),children里第一个节点即为站点 if(copyed.isSite()) { siteId = copyed.getId(); } } copyed.setSiteId(siteId); idsMapping.put(child.getId(), copyed.getId()); returnList.add(copyed); } channelDao.flush(); return returnList; } public void stopSite(Long siteOrChannelId) { if (!checkDownPermission(siteOrChannelId, CMSConstants.OPERATION_STOP)) { throw new BusinessException("栏目没有停用权限!"); } List<Channel> list = channelDao.getChildrenById(siteOrChannelId); for ( Channel child : list ) { child.setDisabled(CMSConstants.STATUS_STOP); } channelDao.flush(); } public void startSiteAll(Long siteId) { Channel channel = getSiteById(siteId); // 启用站点 channel.setDisabled(CMSConstants.STATUS_START); // 启用站点下栏目 if (channel.isSite()) { List<?> list = channelDao.getChannelsBySiteIdNoPermission(siteId); for ( Object entity : list ) { Channel temp = (Channel) entity; temp.setDisabled(CMSConstants.STATUS_START); } } channelDao.flush(); } public void startChannel(Long channelId) { // 启用所有父亲节点 List<Channel> parents = channelDao.getParentsById(channelId, CMSConstants.OPERATION_START); for ( Channel parent : parents ) { parent.setDisabled(CMSConstants.STATUS_START); } channelDao.flush(); } public Object[] selectCanAddArticleParentChannels() { return selectParentChannelsByOperationId(CMSConstants.OPERATION_ADD_ARTICLE); // 新建文章 } public Object[] selectCanAddChannelParentChannels() { return selectParentChannelsByOperationId(CMSConstants.OPERATION_ADD_CHANNEL); // 新建栏目 } private Object[] selectParentChannelsByOperationId(String operationId) { List<Long> canAddChannelIds = channelDao.getSiteChannelIDsByOperationId(operationId); channelDao.insertIds2TempTable( canAddChannelIds ); List<?> channels = channelDao.getParentChannel4CanAdd(); return new Object[]{channels, EasyUtils.list2Str(canAddChannelIds)}; } public List<Channel> getChannelTreeDown(Long channelId) { return channelDao.getChildrenById(channelId, CMSConstants.OPERATION_VIEW); } public void saveWordsFilter(String shieldWords, String forbidWords, Long siteId) { channelDao.createObject(new WordsFilter(siteId, shieldWords, forbidWords)); } public WordsFilter getWordsFilterInfo(Long siteId) { return (WordsFilter) channelDao.getEntity( WordsFilter.class, siteId); } public Object[] getChannelRelationShip(Long channelId) { List<?> channelList = channelDao.getAllSiteChannelList(); List<?> canAddArticleChannelIds = channelDao.getSiteChannelIDsByOperationId(CMSConstants.OPERATION_ADD_ARTICLE); String channelIds = EasyUtils.list2Str(canAddArticleChannelIds); TreeEncoder allTreeEncoder = new TreeEncoder(channelList, new LevelTreeParser()); allTreeEncoder.setTranslator(new ChannelCanSelectTranslator(channelIds, channelId)); allTreeEncoder.setNeedRootNode(false); List<?> sourceList = channelDao.getChannelSourceByChannelId(channelId); TreeEncoder fromEncoder = new TreeEncoder(sourceList); fromEncoder.setRootNodeName("分发自"); fromEncoder.setTranslator(new ExcludeSiteNodeTranslator()); List<?> desList = channelDao.getChannelDestinationByChannelId(channelId); TreeEncoder toEncoder = new TreeEncoder(desList); toEncoder.setRootNodeName("分发至"); toEncoder.setTranslator(new ExcludeSiteNodeTranslator()); return new Object[] {allTreeEncoder, fromEncoder, toEncoder}; } public void saveChannelRelationShip(Long channelId, String distributeFromIds, String distributeToIds) { // 保存栏目的源栏目信息 channelDao.deleteAll(channelDao.getDistributeFromByChannelId(channelId)); if ( !EasyUtils.isNullOrEmpty(distributeFromIds) ) { String[] sourceIds = distributeFromIds.split(","); for (int j = 0; j < sourceIds.length; j++) { Long sourceId = new Long(sourceIds[j]); insertChannelDistribute(channelId, sourceId); } } // 保存栏目的目的栏目信息 channelDao.deleteAll(channelDao.getDistributeToByChannelId(channelId)); if ( !EasyUtils.isNullOrEmpty(distributeToIds) ) { String[] desIds = distributeToIds.split(","); for (int i = 0; i < desIds.length; i++) { Long desId = new Long(desIds[i]); insertChannelDistribute(desId, channelId); } } } //添加分发栏目 private void insertChannelDistribute(Long channelId, Long distributeFromId) { ChannelDistributeId channelDistributeId = new ChannelDistributeId(); channelDistributeId.setDistributeToId(channelId); channelDistributeId.setDistributeFromId(distributeFromId); ChannelDistribute channelDispatch = new ChannelDistribute(); channelDispatch.setId(channelDistributeId); channelDao.createObject(channelDispatch); } /**************************************************** 以下为栏目(站点)文章发布 *************************************************/ public void publishArticle(List<?> articleIdList, Long siteId) { // 得到发布路径 Channel site = (Channel)getChannelById(siteId); // 得到敏感词汇 WordsFilter wordsFilter = (WordsFilter)channelDao.getEntity(WordsFilter.class, siteId); for (int i = 0; i < articleIdList.size(); i++) { // 取文章并设置文章属性 Object[] objs = (Object[]) articleIdList.get(i); // 发布的时候需要把动态属性的字段内容也发布出去 Article article = articleDao.getEntity((Long) objs[0]); setArticleValue(objs, article); // 取文章附件列表 Map<String, Attachment> attachments = articleDao.getArticleAttachments(article.getId()); article.getAttachments().putAll(attachments); // 发布文章,根据文章 创建日期 来设置xml文件的存放路径 String publishPath = site.getPath()+ "/" + ArticleHelper.getArticlePublishRule(article.getCreateTime()); String pubUrl = PublishManger.publishOneArticle(article, publishPath, wordsFilter); // 设置发布路径保存文章信息 article.setPubUrl(pubUrl); articleDao.renewArticle(article); } } /** * 设置文章相关属性,包括文章所属的栏目、文章类型、发布类路径等信息。 */ private void setArticleValue(Object[] obj, Article article) { article.setChannelId((Long) obj[1]); article.setChannelName((String) obj[2]); article.setTypeName((String) obj[3]); article.setPublishArticleClassName((String) obj[4]); article.setStatus(CMSConstants.XML_STATUS); if (article.getIssueDate() == null || !article.getIssueDate().after(new Date())) { article.setIssueDate(new Date()); } } public int getTotalRows4Publish(Long channelId, String category ) { return channelDao.getTotalRows4Publish(channelId, category); } public List<?> getPageArticleList(Long channelId, int pageNum, int pageSize, String category) { return channelDao.getPageArticleList4Publish(channelId, category, pageNum, pageSize); } public Integer getPublishableArticleCount(Long channelId) { return channelDao.getPublishableArticleCount(channelId); } public List<?> getPagePublishableArticleList(Long channelId, int currentPageNum, Integer pageSize) { return channelDao.getPagePublishableArticleList(channelId, currentPageNum, pageSize); } public Long getSiteIdByChannelId(Long channelId) { Channel channel = getChannelById(channelId); return channel.isSite() ? channel.getId() : channel.getSiteId(); } }