程序类基本完成,页面还没有做。使用rome可以较好的实现所有rss版本和atom的feed。个人认为还是应用得比较成功的。今天早上已经把全部代码和argoUML0.18.1的粗略设计提交到了cvs库。
主要类的实现概略:(希望得到你的意见或建议,也供想使用rome的朋友参考。)
1、
//$ Id: RSSAction.java,v 1.0 2006/02/26 20:49:06 dashing_meng Exp $
//Copyright (c) 2004-2005 Http://www.learndiary.com. All Rights Reserved.
//Permission to use, copy, modify, and distribute this software and its
//documentation without fee, and without a written agreement is hereby
//granted, provided that the above copyright notice and this paragraph
//appear in all copies. This software program and documentation are
//copyrighted by http://www.learndiary.com. The software program and
//documentation are supplied "AS IS", without any accompanying services
//from The LearnDiary. The LearnDiary does not warrant that the operation
//of the program will be uninterrupted or error-free. The end-user
//understands that the program was developed for research purposes and is
//advised not to rely exclusively on the program for any reason.
//IN NO EVENT SHALL HTTP://WWW.LEARNDIARY.COM BE LIABLE TO ANY PARTY FOR
//DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,
//INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
//DOCUMENTATION, EVEN IF HTTP://WWW.LEARNDIARY.COM HAS BEEN ADVISED OF THE
//POSSIBILITY OF SUCH DAMAGE. HTTP://WWW.LEARNDIARY.COM SPECIFICALLY
//DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
//WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
//SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND
//HTTP://WWW.LEARNDIARY.COM HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE,
//SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
package com.learndiary.website.action.rss;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts.action.ActionForward;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts.action.ActionMapping;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import com.learndiary.website.util.rss.*;
import com.sun.syndication.io.FeedException;
/**
* action for generating rss feed.
* @author http://www.learndiary.com,LearnDiary Develop Group
*/
public class RSSAction extends Action {
/* {src_lang=Java}*/
private Log __log = LogFactory.getFactory().getInstance(this.getClass());
;
/* {transient=false, volatile=false}*/
/**
* pseudo code:
* {
* //the rss feed type,includes:
* //latestDiariesOfMyProcessGoal, latestAdvicesOfMyDiaries,
* //latestGoals, mostJoinedGoals, latestDiaries, latestAdvices,
* //latestDiariesOfGoal, latestAdvicesOfGoal,etc..
* String type=request.getParameter("type");
*
* //feed type,includes:
* //RSS 0.90, RSS 0.91 Netscape, RSS 0.91 Userland,
* //RSS 0.92, RSS 0.93, RSS 0.94, RSS 1.0,
* // RSS 2.0, Atom 0.3, Atom 1.0
* String rssVersion = request.getParameter("feedType");
*
* //entries number:
* //user can specify how many entries he would like to see,
* //the default entries number is 39.
* int entriesNum=Integer.parseInt(request.getParemeter("entriesNum"));
*
* //user's name:
* //for getting specified user's entries.
* String userName=request.getParameter("userName");
*
* //channel article's ID:
* //it is only for subscribing a goal's sub-entries,goalID.
* int channelID=Integer.parseInt(request.getParemeter("channelID"));
*
* if (type.equal("latestDiaries")){
* RSSGenerator generator = new LatestDiariesRSS(feedType, entriesNum);
* generator.outputFeed();
* }else if(type.equal("latestAdvices")){
* RSSGenerator generator = new LatestAdvicesRSS(feedType, entriesNum);
* generator.outputFeed();
* }else if(type.equal("latestDiariesOfMyProcessGoal")){
* RSSGenerator generator = new LatestDiariesOfMyProcessGoalRSS(feedType, entriesNum, userName);
* generator.outputFeed();
* }else if(type.equal("latestMyDiariesOfMyProcessGoal")){
* RSSGenerator generator = new LatestMyDiariesOfMyProcessGoalRSS(feedType, entriesNum, userName);
* generator.outputFeed();
* }else if(type.equal("latestAdvicesOfMyDiaries")){
* RSSGenerator generator = new LatestAdvicesOfMyDiariesRSS(feedType, entriesNum, userName);
* generator.outputFeed();
* }else if(type.equal("latestDiariesOfGoal")){
* RSSGenerator generator = new LatestDiariesOfGoalRSS(feedType, entriesNum, channelID);
* generator.outputFeed();
* }else if(type.equal("latestAdvicesOfGoal")){
* RSSGenerator generator = new LatestAdvicesOfGoalRSS(feedType, entriesNum, channelID);
* generator.outputFeed();
* }else if(type.equal("latestGoals")){
* RSSGenerator generator = new LatestGoalsRSS(feedType, entriesNum);
* generator.outputFeed();
* }else if(type.equal("mostJoinedGoals")){
* RSSGenerator generator = new MostJoinedGoalsRSS(feedType, entriesNum);
* generator.outputFeed();
* }else {
* show "error type" message;
* }
* }//end of excute() method
*
*/
public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) {
//the rss feed type,includes:
//latestDiariesOfMyProcessGoal, latestAdvicesOfMyDiaries,
//latestGoals, mostJoinedGoals, latestDiaries, latestAdvices,
//latestDiariesOfGoal, latestAdvicesOfGoal,etc..
String type = request.getParameter("type");
//feed type,includes:
//RSS 0.90, RSS 0.91 Netscape, RSS 0.91 Userland,
//RSS 0.92, RSS 0.93, RSS 0.94, RSS 1.0,
// RSS 2.0, Atom 0.3, Atom 1.0
String feedType = request.getParameter("feedType");
//entries number:
//user can specify how many entries he would like to see,
//the default entries number is 39.
int entriesNum = Integer.parseInt(request.getParameter("entriesNum"));
//user's name:
//for getting specified user's entries.
String userName = request.getParameter("userName");
//channel article's ID:
//it is only for subscribing a goal's sub-entries,goalID.
int channelID = 0;
String channelIDStr = request.getParameter("channelID");
if (channelIDStr != null && !channelIDStr.equals(""))
channelID = Integer.parseInt(channelIDStr);
try {
if (type.equals("latestDiaries")) {
RSSGenerator generator = new LatestDiariesRSS(feedType, entriesNum);
generator.outputFeed(response);
__log.info(
"get feed of latestDiaries:feedType="
+ feedType
+ " entriesNum="
+ entriesNum);
} else if (type.equals("latestAdvices")) {
RSSGenerator generator = new LatestAdvicesRSS(feedType, entriesNum);
generator.outputFeed(response);
__log.info(
"get feed of latestAdvices:feedType="
+ feedType
+ " entriesNum="
+ entriesNum);
} else if (type.equals("latestDiariesOfMyProcessGoal")) {
RSSGenerator generator =
new LatestDiariesOfMyProcessGoalRSS(feedType, entriesNum, userName);
generator.outputFeed(response);
__log.info(
"get feed of latestDiariesOfMyProcessGoal:feedType="
+ feedType
+ " entriesNum="
+ entriesNum
+ " userName="
+ userName);
} else if (type.equals("latestMyDiariesOfMyProcessGoal")) {
RSSGenerator generator =
new LatestMyDiariesOfMyProcessGoalRSS(feedType, entriesNum, userName);
generator.outputFeed(response);
__log.info(
"get feed of latestMyDiariesOfMyProcessGoal:feedType="
+ feedType
+ " entriesNum="
+ entriesNum
+ " userName="
+ userName);
} else if (type.equals("latestAdvicesOfMyDiaries")) {
RSSGenerator generator =
new LatestAdvicesOfMyDiariesRSS(feedType, entriesNum, userName);
generator.outputFeed(response);
__log.info(
"get feed of latestAdvicesOfMyDiaries:feedType="
+ feedType
+ " entriesNum="
+ entriesNum
+ " userName="
+ userName);
} else if (type.equals("latestDiariesOfGoal")) {
RSSGenerator generator =
new LatestDiariesOfGoalRSS(feedType, entriesNum, channelID);
generator.outputFeed(response);
__log.info(
"get feed of latestDiariesOfGoal:feedType="
+ feedType
+ " entriesNum="
+ entriesNum
+ " channelID="
+ channelID);
} else if (type.equals("latestAdvicesOfGoal")) {
RSSGenerator generator =
new LatestAdvicesOfGoalRSS(feedType, entriesNum, channelID);
generator.outputFeed(response);
__log.info(
"get feed of latestAdvicesOfGoal:feedType="
+ feedType
+ " entriesNum="
+ entriesNum
+ " channelID="
+ channelID);
} else if (type.equals("latestGoals")) {
RSSGenerator generator = new LatestGoalsRSS(feedType, entriesNum);
generator.outputFeed(response);
__log.info(
"get feed of LatestGoalsRSS:feedType="
+ feedType
+ " entriesNum="
+ entriesNum);
} else if (type.equals("mostJoinedGoals")) {
RSSGenerator generator = new MostJoinedGoalsRSS(feedType, entriesNum);
generator.outputFeed(response);
__log.info(
"get feed of mostJoinedGoals:feedType="
+ feedType
+ " entriesNum="
+ entriesNum);
} else {
return mapping.findForward("commonFailure");
}
} catch (IOException e1) {
e1.printStackTrace();
} catch (FeedException e2) {
e2.printStackTrace();
} catch (Exception e3) {
e3.printStackTrace();
}
return null;
}
}
2、
//$ Id: RSSGenerator.java,v1.4 2006/02/26 20:49:06 dashing_meng Exp $
//Copyright (c) 2004-2005 Http://www.learndiary.com. All Rights Reserved.
//Permission to use, copy, modify, and distribute this software and its
//documentation without fee, and without a written agreement is hereby
//granted, provided that the above copyright notice and this paragraph
//appear in all copies. This software program and documentation are
//copyrighted by http://www.learndiary.com. The software program and
//documentation are supplied "AS IS", without any accompanying services
//from The LearnDiary. The LearnDiary does not warrant that the operation
//of the program will be uninterrupted or error-free. The end-user
//understands that the program was developed for research purposes and is
//advised not to rely exclusively on the program for any reason.
//IN NO EVENT SHALL HTTP://WWW.LEARNDIARY.COM BE LIABLE TO ANY PARTY FOR
//DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,
//INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
//DOCUMENTATION, EVEN IF HTTP://WWW.LEARNDIARY.COM HAS BEEN ADVISED OF THE
//POSSIBILITY OF SUCH DAMAGE. HTTP://WWW.LEARNDIARY.COM SPECIFICALLY
//DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
//WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
//SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND
//HTTP://WWW.LEARNDIARY.COM HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE,
//SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
package com.learndiary.website.util.rss;
import com.sun.syndication.feed.synd.SyndCategory;
import com.sun.syndication.feed.synd.SyndCategoryImpl;
import com.sun.syndication.feed.synd.SyndContent;
import com.sun.syndication.feed.synd.SyndContentImpl;
import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndEntryImpl;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.io.FeedException;
import com.sun.syndication.io.SyndFeedOutput;
import com.learndiary.website.Constants;
import com.learndiary.website.Consts;
import com.learndiary.website.model.ArticleInfo;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import org.apache.commons.logging.Log;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import com.learndiary.website.db.ArticleDB;
import com.learndiary.website.dao.TransContext;
import javax.servlet.http.HttpServletResponse;
/**
* the base abstract class for generating rss feed.
* @author http://www.learndiary.com,LearnDiary Develop Group
*/
public abstract class RSSGenerator {
protected static final DateFormat DATE_PARSER =
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
/* {transient=false, volatile=false}*/
protected Log __log = null; //should it be added "static" modifier?
/* {transient=false, volatile=false}*/
protected static TransContext trans = null;
/* {transient=false, volatile=false}*/
protected static ArticleDB myDB = null;
/* {transient=false, volatile=false}*/
protected String feedType = "rss_2.0";
/* {transient=false, volatile=false}*/
protected int entriesNum = 39;
/* {transient=false, volatile=false}*/
protected final List entries = new ArrayList();
/* {transient=false, volatile=false}*/
protected SyndFeed feed = null;
/* {transient=false, volatile=false}*/
protected String catName = null;
/* {transient=false, volatile=false}*/
/**
* output the rss feed xml page
* pseudo code:
* {
* res.setContentType("application/xml; charset=UTF-8");
* SyndFeedOutput output = new SyndFeedOutput();
* output.output(feed,res.getWriter());
* }
* @param res the HttpServletResponse come from the excute() method of struts Action
*/
public void outputFeed(HttpServletResponse res)
throws IOException, FeedException, Exception {
try {
this.setFeed();
} catch (Exception e1) {
e1.printStackTrace();
}
res.setContentType("application/xml; charset=UTF-8");
SyndFeedOutput output = new SyndFeedOutput();
PrintWriter out = res.getWriter();
try {
output.output(feed, out);
} catch (IOException e) {
e.printStackTrace();
} catch (FeedException e) {
e.printStackTrace();
}
}
/**
* set rss feed
*/
abstract protected void setFeed() throws Exception;
/**
* set articles into the entries list of the rss feed
* {
* List artList=(ArrayList)myDB.getCPageList(0, entriesNum, "article", condition, Consts.ART_WRITE, Consts.DIR_DESC, Consts.HTML_FLAG);
* Iterator it=artList.listIterator();
* while (it.hasNext()) {
* ArticleInfo anArt = (ArticleInfo)it.next();
* entries.addEntry(anArt);
* }
* }
* @param condition "WHERE" clause in the sql statement,for example:"WHERE parentID=1 AND typeID=2"
*/
protected void setEntries(String condition,int orderType,int direction,int htmlFlag) throws Exception {
List artList = new ArrayList();
__log.debug("setEntries() in RSSGenerator:entriesNum="+entriesNum+" condition is:"+condition);
try {
artList =
(ArrayList) myDB.getCPageList(
0,
entriesNum,
"article",
condition,
orderType,
direction,
htmlFlag);
} catch (Exception e) {
e.printStackTrace();
}
__log.debug("artList is:"+artList);
if (artList == null)
return;
Iterator it = artList.listIterator();
while (it.hasNext()) {
ArticleInfo anArt = (ArticleInfo) it.next();
this.addEntry(anArt);
}
}
/**
* add an articleInfo into rss entries list
* pseudo code:
* {
* SyndEntry entry = new SyndEntryImpl();
* entry.setAuthor(anArt.getUserName());
* entry.setTitle(title);
* entry.setLink(link);
* entry.setPublishedDate(DATE_PARSER.parse(date));
* SyndContent description = new SyndContentImpl();
* description.setType("text/plain");
* description.setValue(blogContent);
* entry.setDescription(description);
* List categories = new ArrayList();
* SyndCategory category = new SyndCategoryImpl();
* category.setName(catName);
* categories.add(category);
* entry.setCategories(categories);
* entries.add(entry);
* }
* @param anArt an article's information
*/
private void addEntry(ArticleInfo anArt) throws Exception, ParseException {
int artType = anArt.getTypeID();
int artID = anArt.getArticleID();
int parentID = anArt.getParentID();
String parentName = anArt.getParentArticleName();
String parentParentName = null;
int parentType = 0;
try {
parentType = myDB.getArtTypeByID(parentID);
if (parentType == Consts.DIARY_TYPE)
parentParentName = myDB.getArtNameByID(myDB.getParentIDByID(parentID));
} catch (Exception e1) {
e1.printStackTrace();
}
String artName = anArt.getArticleName();
String artAuthor = anArt.getUserName();
String artContent = anArt.getArticleText();
String artResource = anArt.getArticleResource();
String writeDate = anArt.getWriteDate();
SyndEntry entry = new SyndEntryImpl();
entry.setAuthor(artAuthor);
__log.debug("set entry's author is:" + artAuthor);
entry.setTitle(artName);
__log.debug("set entry's title is:" + artName);
//get article's link and rss description head information;
String link = null, headInfo = null;
if (artType == Consts.GOAL_TYPE) {
link =
Constants.APPLICATION_PATH.concat(
"/disGoalContentAction.do?goalID=" + artID);
headInfo =
"\""
+ artAuthor
+ "\" 在:"
+ writeDate
+ " 首先创建了目标:\""
+ artName
+ "\"<p>";
} else if (artType == Consts.DIARY_TYPE) {
link =
Constants.APPLICATION_PATH.concat(
"/disDiaryContentAction.do?goalID" + artID);
headInfo =
"\""
+ artAuthor
+ "\" 于:"
+ writeDate
+ " 在目标:\""
+ parentName
+ "\"下添加了日记:\""
+ artName
+ "\"<p>";
} else if (
artType == Consts.ADVICE_TYPE && parentType == Consts.GOAL_TYPE) {
link =
Constants.APPLICATION_PATH.concat(
"/disGoalContentAction.do?goalID" + parentID);
headInfo =
"\""
+ artAuthor
+ "\" 于:"
+ writeDate
+ " 在目标:\""
+ parentName
+ "\"下添加了评论:\""
+ artName
+ "\"<p>";
} else {
link =
Constants.APPLICATION_PATH.concat(
"/disDiaryContentAction.do?goalID" + parentID);
headInfo =
"\""
+ artAuthor
+ "\" 于:"
+ writeDate
+ " 在目标:\""
+ parentParentName
+ "\"的日记:\""
+ parentName
+ "\"下添加了评论:\""
+ artName
+ "\"<p>";
}
entry.setLink(link);
__log.debug("set entry's link is:" + link);
try {
entry.setPublishedDate(DATE_PARSER.parse(writeDate));
__log.debug("set entry's publishedDate is:" + writeDate);
} catch (ParseException e) {
e.printStackTrace();
}
SyndContent description = new SyndContentImpl();
description.setType("text/plain");
String value =
headInfo.concat("文章内容:<br>").concat(artContent).concat(
"<p>相关资源:<br>" + artResource);
description.setValue(value);
__log.debug("set description's value is:" + value);
entry.setDescription(description);
List categories = new ArrayList();
SyndCategory category = new SyndCategoryImpl();
category.setName(catName);
__log.debug("set category's name is:" + catName);
categories.add(category);
entry.setCategories(categories);
entries.add(entry);
__log.debug(
"add an entry into entriesList.\n*********************************");
}
}
3、
//$ Id: LatestGoalsRSS.java,v 1.0 2006/02/26 20:49:06 dashing_meng Exp $
//Copyright (c) 2004-2005 Http://www.learndiary.com. All Rights Reserved.
//Permission to use, copy, modify, and distribute this software and its
//documentation without fee, and without a written agreement is hereby
//granted, provided that the above copyright notice and this paragraph
//appear in all copies. This software program and documentation are
//copyrighted by http://www.learndiary.com. The software program and
//documentation are supplied "AS IS", without any accompanying services
//from The LearnDiary. The LearnDiary does not warrant that the operation
//of the program will be uninterrupted or error-free. The end-user
//understands that the program was developed for research purposes and is
//advised not to rely exclusively on the program for any reason.
//IN NO EVENT SHALL HTTP://WWW.LEARNDIARY.COM BE LIABLE TO ANY PARTY FOR
//DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,
//INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
//DOCUMENTATION, EVEN IF HTTP://WWW.LEARNDIARY.COM HAS BEEN ADVISED OF THE
//POSSIBILITY OF SUCH DAMAGE. HTTP://WWW.LEARNDIARY.COM SPECIFICALLY
//DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
//WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
//SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND
//HTTP://WWW.LEARNDIARY.COM HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE,
//SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
package com.learndiary.website.util.rss;
import org.apache.commons.logging.LogFactory;
import com.learndiary.website.Constants;
import com.learndiary.website.Consts;
import com.learndiary.website.dao.TransContext;
import com.learndiary.website.db.ArticleDB;
import com.sun.syndication.feed.synd.SyndFeedImpl;
/**
* for generating latest goals' rss feed.
* @author http://www.learndiary.com,LearnDiary Develop Group
*/
public class LatestGoalsRSS extends RSSGenerator {
public LatestGoalsRSS(String feedType, int entriesNum) {
this.__log = LogFactory.getFactory().getInstance(this.getClass());
try {
RSSGenerator.trans = new TransContext();
RSSGenerator.myDB = new ArticleDB(trans);
} catch (Exception e) {
e.printStackTrace();
}
this.feedType = feedType;
this.entriesNum = entriesNum;
this.catName = "最新创建的" + entriesNum + "个目标";
}
protected void setFeed() throws Exception {
try {
this.setEntries("WHERE typeID=1",Consts.ART_WRITE,Consts.DIR_DESC,Consts.HTML_FLAG);
} catch (Exception e) {
e.printStackTrace();
}
feed = new SyndFeedImpl();
feed.setFeedType(feedType);
feed.setTitle("最新创建的" + entriesNum + "个目标");
feed.setLink(Constants.APPLICATION_PATH.concat("/indexAction.do"));
feed.setDescription("学习日记里按时间排序的最新创建的" + entriesNum + "个目标。");
feed.setCopyright(
"除原作者特别声明外,本站所有帖子以<a rel=\"license\" href=\"http://creativecommons.org/licenses/by/2.0/\" target=\"creativecommons\">Creative Commons License</a>方式授权.");
feed.setEntries(entries);
}
}