package m_ylf.cs.sicau.portal.action;
import com.opensymphony.xwork2.ActionSupport;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import m_ylf.cs.sicau.portal.domain.Article;
import m_ylf.cs.sicau.portal.domain.ArticleTopType;
import m_ylf.cs.sicau.portal.domain.Category;
import m_ylf.cs.sicau.portal.domain.Page;
import m_ylf.cs.sicau.portal.domain.User;
import m_ylf.cs.sicau.portal.globals.ActionMessageGlobals;
import m_ylf.cs.sicau.portal.globals.ActionReturnStringsGlobals;
import m_ylf.cs.sicau.portal.globals.AjaxMessageGlobals;
import m_ylf.cs.sicau.portal.globals.ProjectConfigureGlobals;
import m_ylf.cs.sicau.portal.service.IService;
import m_ylf.cs.sicau.portal.set.AjaxReturnSet;
import m_ylf.cs.sicau.portal.util.AjaxResponse;
import org.apache.struts2.ServletActionContext;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.util.StringUtils;
/**
*
* @author Fly_m
*/
public class ArticleAction extends ActionSupport {
/** 业务层组件对象,负责提供相应的数据,和相应的逻辑操作 **/
private IService service;
/** 文章对象,负责从页面传递相应的数据并向页面返回相应的数据 **/
private Article article;
/** 页面组件,负责对页面上的请求对数据进行分页,并返回页面上的分页逻辑 **/
private Page page;
/** 向页面传递多个文章时运用,并尝试从页面取得多个对象,在进行批处理对象时运用 **/
private List<Article> articleList;
/** 特殊追加字段,此字段在某些处理单个对象的时候运用,以避免对某些细节方面的访问,通用单个关键值
* 对象id 值访问.在页面中,通常处理某些问题只需要提供相应的key值,如id,则此属性提供这种途径来
* 提供相应的支持,此避免页面可能出现比如article.id这种暴露性的提示字段.同时也简化了对相应
* 数据的处理.
*/
private int id;
/** 置顶组件,此字段用于置顶一些文章或者取消置顶所用.由于设计的原因,导致置顶标记不能与文章产生
* 一对一的关系,而成为多对一的关系.故type不能直接被删除,为一个文章置顶之时,就会产生一个新的
* type对象,而取消置顶时,仅仅是把关联关系去掉.而因为type的作用范围很小,故不会对type对象进行
* 其它的操作.此对象是相对数据库来说安全的.
*/
private ArticleTopType type;
/**
* 在查询时,表示是否是级联查询,如果是true,表示是级联,否则其它的数据(空值)均表示不能级联查询.
*/
private String cascade;
public void setService(IService service) {
this.service = service;
}
public void setArticle(Article article) {
this.article = article;
}
public void setArticleList(List<Article> articleList) {
this.articleList = articleList;
}
public void setId(int id) {
this.id = id;
}
public void setPage(Page page) {
this.page = page;
}
public Article getArticle() {
return article;
}
public List<Article> getArticleList() {
return articleList;
}
public String getCascade() {
return cascade;
}
public int getId() {
return id;
}
public Page getPage() {
return page;
}
public IService getService() {
return service;
}
public ArticleTopType getType() {
return type;
}
/**
* 保存一篇文章,根据此文章的类别对文章进行分类,以及建立索引.并对此文章进行分页保存.
* 必须条件:除了文章的各项内容之外,还需要此文章的类别,且保证此类别是存在于数据库中的,此外,创
* 建此文章的作者也是需要的.
*/
public String saveArticle() throws Exception {
/** 查找此文章类别,此类别在下文中对查询标记,或者路径标记均有相关作用,故为必须的 **/
Category category = this.service.getCategory(id);
if (category == null) {
this.addActionError(this.getText(ActionMessageGlobals.ARTICLEACTION_SAVEARTICLE_NOCATEGORY_FAIL));
return ActionReturnStringsGlobals.ARTICLEACTION_SAVEARTICLE_FAIL;
}
/** 设置此文章的路径标记,标记同一篇文章 **/
String pathMark = category.getName() + new SimpleDateFormat("-yyyy/MM/dd-HH/mm/ss-SSS").format(new Date());
/** 设置此文章的类别查询标记,标记同一类别文章 **/
String categoryChain = category.getCategoryChain();
/** 设置文章作者ip **/
String ip = ServletActionContext.getRequest().getRemoteAddr();
/** 设置来源,此默认来源由于国际化的需要,而引用相关资源文件key值 **/
String source = this.article.getSource() == null ? this.getText(ProjectConfigureGlobals.ARTICLE_DEFAULT_LOCALSOURCE_KEY) : this.article.getSource();
/** 设置文章摘要,默认有文章的前50个字符 **/
String summary = this.article.getSummary() == null ? (this.article.getContent().length() < 50 ? this.article.getContent() : this.article.getContent().substring(0, 50)) : this.article.getSummary();
/** 得到文章内容数组,因为文章可能是分页的,所以用分隔符将其隔开,分成几个页面 **/
String[] contents = this.article.getContent().split(ProjectConfigureGlobals.ARTICLE_DEFAULT_SEPARAROR);
/** 开始保存文章 **/
int pageTotalCount = contents.length; //文章总页数
int pageCurrentIndex = 1; //文章当前页数
for (int i = 0; i < pageTotalCount; i++) {
Article a = new Article();
a.setTitle(this.article.getTitle());
a.setPathMark(pathMark);
a.setTitleColor(this.article.getTitleColor());
a.setSummary(summary);
a.setSource(source);
a.setIp(ip);
a.setContent(contents[pageCurrentIndex - 1]);
a.setPageCount(pageTotalCount);
a.setPageCurrentIndex(pageCurrentIndex);
a.setCreateUser(this.article.getCreateUser());
a.setCategory(category);
a.setCategoryChain(categoryChain);
a.setTags(this.article.getTags());
this.service.saveArticle(a);
pageCurrentIndex++;
}
this.addActionMessage(this.getText(ActionMessageGlobals.ARTICLEACTION_SAVEARTICLE_SUCCESS, new String[] {this.article.getTitle()}));
return ActionReturnStringsGlobals.ARTICLEACTION_SAVEARTICLE_SUCCESS;
}
/**
* 显示文章,此方法除了处理显示第一页面的文章之外,还处理显示后续页面文章的能力.这就要求,从文章
* id值,进而得到文章的pathMark值,从而得到下一篇/上一篇文章.
* 要求参数,文章的id值,第几页的页面数,默认为第一页.
*/
public String showArticle() throws Exception {
/** 处理id值,此id值为文章第几页数 **/
id = (id == 0 ? 1 : id);
/** 得到文章对象,由文章id值,得到pathMark值,进而得到应该传递的article对象 **/
this.article = this.service.getArticle(this.article.getId());
if (this.article != null) {
this.article = this.service.getArticleByPathMarkAndPageCurrentIndex(this.article.getPathMark(), id);
}
/** 如果文章对象为空,追加对文章最终标志地判断 **/
if (this.article == null || this.article.isShiftDeleted() == true) {
this.addActionError(this.getText(ActionMessageGlobals.ARTICLEACTION_SHOWARTICLE_NOARTICLE_FAIL));
return ActionReturnStr
评论3