/**********************************************************************************
Feedzeo!
A free and open source RSS/Atom/RDF feed aggregator
Copyright (C) 2005-2006 Anand Rao (anandrao@users.sourceforge.net)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
************************************************************************************/
/*
* AppMain.java
*
* Created on November 18, 2005, 9:43 PM
*/
package app;
import java.net.*;
import java.io.*;
import java.util.*;
import util.*;
import css.*;
import data.*;
import layout.*;
import de.nava.informa.parsers.OPMLParser;
import de.nava.informa.impl.basic.Feed;
/**
*
* @author Anand Rao
*/
public class AppMain extends Thread implements AppCommandIF {
private String FeedConfigFileName;
private String StyleInfoFileName;
private String LayoutFileName;
private String OutputPath;
private LayoutManager LayoutMgr;
private DataManager DataMgr;
private StyleManager StyleMgr;
private FeedInputFileParser fParser;
private final int DEFAULT_REFRESHTIME=30*60*1000; // 30 mins in millisecs
private final int MINIMUM_REFRESHTIME=10*60*1000; // 10 mins
private int refreshInterval=DEFAULT_REFRESHTIME;
private final String styleFname="style.css";
/** Creates a new instance of AppMain */
public AppMain(String FeedConfigFileName, String StyleInfoFileName,
String LayoutFileName, String OutputPath)
{
super();
this.FeedConfigFileName = FeedConfigFileName;
this.StyleInfoFileName = StyleInfoFileName;
this.LayoutFileName = LayoutFileName;
this.OutputPath = OutputPath;
try {
fParser = new FeedInputFileParser(FeedConfigFileName);
}
catch( Exception e) {
ExceptionUtil.reportException(e);
}
}
/*****
// called during system exit
public void shutdown() {
// close the FeedInputFileParser
fParser.closeParser();
}
*****/
private void sleepms(int ms) {
try {
sleep(ms);
} catch (Exception e) {
ExceptionUtil.reportException(e);
}
}
private int DATAMGR_ADDLINK(String Categoryname, String Link) {
int retval;
retval = DataMgr.addLink(Categoryname, Link);
return retval;
}
private int DATAMGR_DELLINK(String Categoryname, String Link) {
int retval;
retval = DataMgr.delLink(Categoryname, Link);
return retval;
}
private String DATAMGR_GET_HTMLFILENAME(String Category, String Link) {
String retval;
retval = DataMgr.getChannelHTMLPageLink(Category, Link);
return retval;
}
private String DATAMGR_GET_HTMLTABLEDATAFILENAME(String Category, String Link) {
String retval;
retval = DataMgr.getChannelHTMLTableDataPageLink(Category, Link);
return retval;
}
/*
private int DATAMGR_GET_NUMCATEGORIES() {
int retval;
retval = DataMgr.getNumCategories();
return retval;
}
*/
private Vector DATAMGR_GET_CATEGORYNAMES() {
Vector retval;
retval = DataMgr.getCategorynames();
return retval;
}
private Vector DATAMGR_GET_FEEDNAMES(String Category) {
Vector retval;
retval = DataMgr.getFeedNames(Category);
return retval;
}
private String DATAMGR_GET_FEEDNAME(String Category, String link) {
String retval;
retval = DataMgr.getFeedName(Category, link);
return retval;
}
private String DATAMGR_GET_FEEDTABLEDATAPAGELINK(String Category, String link) {
String retval;
retval = DataMgr.getFeedTableDataPageLink(Category, link);
return retval;
}
private Vector DATAMGR_GET_ALLFEEDNAMES() {
Vector retval;
retval = DataMgr.getAllFeedNames();
return retval;
}
private Vector DATAMGR_GET_FEEDPAGELINKS(String Category) {
Vector retval;
retval = DataMgr.getFeedPageLinks(Category);
return retval;
}
private Vector DATAMGR_GET_FEEDSOURCELINKS(String Category) {
Vector retval;
retval = DataMgr.getFeedSourceLinks(Category);
return retval;
}
private Vector DATAMGR_GET_ALLFEEDPAGELINKS() {
Vector retval;
retval = DataMgr.getAllFeedPageLinks();
return retval;
}
private Vector DATAMGR_GET_FEEDTABLEDATAPAGELINKS(String Category) {
Vector retval;
retval = DataMgr.getFeedTableDataPageLinks(Category);
return retval;
}
private Vector DATAMGR_GET_ALLFEEDTABLEDATAPAGELINKS() {
Vector retval;
retval = DataMgr.getAllFeedTableDataPageLinks();
return retval;
}
private void DATAMGR_REFRESHCHANNEL(String Category, String feedSourceLink) {
String HTMLFileName, HTMLTableDataFileName;
// copy the file names before refreshing the channel data
HTMLFileName = DataMgr.getChannelHTMLPageLink(Category, feedSourceLink);
HTMLTableDataFileName = DataMgr.getChannelHTMLTableDataPageLink(Category,
feedSourceLink);
if (DataMgr.refreshChannel(Category, feedSourceLink) < 0)
return; // no need to republish the html files
publishFeed(Category, feedSourceLink, HTMLFileName, HTMLTableDataFileName);
}
private void publishFeed(String Category, String feedSourceLink, String HTMLFileName,
String HTMLTableDataFileName)
{
PageRequest req;
/* generate the page for feed */
req = new PageRequest(Category, feedSourceLink,
OutputPath, HTMLFileName,
HTMLTableDataFileName,
LayoutMgr.getMainPageLayoutName());
LayoutMgr.outputPage(req);
}
private int generateFeed(String Categoryname, String Feedurl)
{
// get a filename for the feed
String filename = FileNameGen.generateFileName();
String HTMLFileName=filename+".html";
String HTMLTableDataFileName = filename+".txt";
/* add the link to datamgr */
if (DATAMGR_ADDLINK(Categoryname, Feedurl) < 0)
return -1;
publishFeed(Categoryname, Feedurl, HTMLFileName, HTMLTableDataFileName);
return 0;
}
private void generateFeedPages() {
int NumCats=0;
//System.out.println("Inside generateFeedPages");
FileNameGen.init(); // init the file name generator
try {
NumCats = fParser.getNumCategories();
//System.out.println("Num of Categories:"+NumCats);
for (int i = 0 ; i < NumCats; i++) {
String CatName, url; Vector Feedurls;
CatName = fParser.getCategory(i);
//System.out.println("Category#:"+CatName);
Feedurls = fParser.getCategoryFeedsCollection(CatName);
for (int j=0;j<Feedurls.size(); j++) {
url = (String) Feedurls.elementAt(j);
//System.out.println("### ADD Cat:"+CatName+" Link:"+url);
generateFeed(CatName, url);
sleepms(5); /* sleep for 5ms to give the request handling threads
better response time */
}
}
} catch (Exception e) {
ExceptionUtil.reportException(e);
}
}
private void refreshFeedData() {
String category, feedurl;
Vector categoryNames = DATAMGR_GET_CATEGORYNAMES();
if (categoryNames == null) return;
for (int i = 0; i < categoryNames.size(); i++)
{
category = (String) categoryNames.elementAt(i);
Vector feedSourceLinks = DATAMGR_GET_FEEDSOURCELINKS(category);
if (feedSourceLinks == null) return;
for (int j = 0; j < feedSourceLinks.size(); j++)
{
feedurl = (String) feedSourceLinks.elementAt(j);
DATAMGR_REFRESHCHANNEL(category, feedurl);
sleepms(5); /* sleep for 5ms to give the request handling threads
better response time */
}
}
}
public void run() {
int runInterval=getRefreshInterval();
System.out.println("THREAD refresh interval:"+runInterval);
// Initialize StyleManager; generate the css file for the HTML files;
StyleMgr = new StyleManager(StyleInfoFileName);
StyleMgr.generateCSSFile(FileUtils.getFullFileName(OutputPath, styleFname));
// Initialize the data manager
DataMgr = new DataManager();
SysObjects.setDataManager(DataMgr);
// Initialize the Layout manager
LayoutMgr = new LayoutManager();
SysObjects.setLayoutManager(LayoutMgr);
LayoutMgr.createFramework(LayoutFileName);
// Read through the feed config file and
// fetch each feed; for every feed fetched
// generate the corresponding HTML page
generateFeedPages();
while (true) {
sleepms(runInterval);
refreshFeedData();
}
}
/* routines processing commands from the config server */
private CmdResult sendCategoryDataCmd() {
CmdResult cmdRes=null;
Vector result;
result = DATAMGR_GET_CATEGORYNAMES();
if (result != null)
cmdRes = new CmdResult(CmdResult.SUCESS_CODE, result);
else
cmdRes = new CmdResult(CmdResult.FAIL_CODE, null);
return cmdRes;
}
/*
* does the function of addlink + also adds the url to the
* config file
*/
private int addLinkPermanent(String Category, String LinkUrl) {
int rval=-1;
rval = generateFeed(Category, LinkUrl);
if (rval < 0) return rval;
// add the link into the config file
rval = fParser.insertFeedLink(Category, LinkUrl);
System.out.println("Added in category:"+Category+" link:"+LinkUrl);
return rval;
}
private CmdResult addLinkCmd(String Category, String link) {
// add link & generate pages
if (addLinkPermanent(Category, link) == 0) {
return new CmdResult(CmdResult.SUCESS_CODE, null);
}
return new CmdResult(CmdResult.FAIL_CODE, null);
}
private CmdResult opmlImportCmd(String Category, String SourceURL) {
Vector retVal = new Vector();
Collection feedCollection;
// first parse the opml file using informa api;
try {
feedCollection = OPMLParser.parse(SourceURL);
if (feedCollection == null) return new CmdResult(CmdResult.FAIL_CODE, null);
} catch (Exception e) {
ExceptionUtil.reportException(e);
return new CmdResult(CmdResult.FAIL_CODE, null);
}
// we now have a collection of FeedIF objects;
Iterator i = feedCollection.iterator();
while (i.hasNext()) {
Feed f = (Feed) i.next();
// add this feed
CmdResult addResult = addLinkCmd(Category, f.getLocation().toString());
String resStr = "Feed "+f.getLocation().toString()+" import";
if (addResult.getReturnCode() == CmdResult.SUCESS_CODE) {
System.out.println(resStr+" succeeded");
resStr += " succeeded\n";
}
else {
System.out.println(resStr+" failed");
resStr += " failed\n";
}
retVal.addElement((String)resStr);
}
return new CmdResult(CmdResult.SUCESS_CODE, retVal);
}
private CmdResult delLinkCmd(String Category, String link) {
/*
* 1. note down the feed html and data files generated for this feed
* 2. delete the feed in data manager
* 3. delete the feed html and data files
* 4. delete the feed url from the feedinputfile
*/
String feedHTMLfile = DATAMGR_GET_HTMLFILENAME(Category, link),
feedDatafile = DATAMGR_GET_HTMLTABLEDATAFILENAME(Category, link);
//System.out.println("deleting category:"+Category+" link:"+link);
if (DATAMGR_DELLINK(Category, link) == 0) {
//System.out.println("deleting file:"+feedHTMLfile);
FileUtils.deleteFile( FileUtils.getFullFileName(OutputPath,feedHTMLfile) );
//System.out.println("deleting file:"+feedDatafile);
FileUtils.deleteFile( FileUtils.getFullFileName(OutputPath,feedDatafile) );
//System.out.println("deleting link from feedinputfile ...");
fParser.deleteFeedLink(Category, link);
return new CmdResult(CmdResult.SUCESS_CODE, null);
}
return new CmdResult(CmdResult.FAIL_CODE, null);
}
private CmdResult sendFeedNamesCmd(String Category) {
Vector feednames = DATAMGR_GET_FEEDNAMES(Category);
if (feednames != null)
return new CmdResult(CmdResult.SUCESS_CODE, feednames);
return new CmdResult(CmdResult.FAIL_CODE, null);
}
private CmdResult sendFeedNamesWithPageLinkCmd(String Category) {
Vector Result, feedNames, feedLinks;
Result = new Vector();
if (Category != null) {
feedNames = DATAMGR_GET_FEEDNAMES(Category);
feedLinks = DATAMGR_GET_FEEDPAGELINKS(Category);
}
else {
feedNames = DATAMGR_GET_ALLFEEDNAMES();
feedLinks = DATAMGR_GET_ALLFEEDPAGELINKS();
}
if ((feedNames == null) || (feedLinks == null))
return new CmdResult(CmdResult.FAIL_CODE, null);
for (int i=0; i < feedNames.size(); i++) {
String feedlinkStr = new String(feedNames.elementAt(i) +
"\t" + feedLinks.elementAt(i));
Result.addElement(feedlinkStr);
//System.out.println("RESULT: "+ feedlinkStr);
}
if (Result != null)
return new CmdResult(CmdResult.SUCESS_CODE, Result);
return new CmdResult(CmdResult.FAIL_CODE, null);
}
private CmdResult sendFeedNamesWithTableDataPageLinkCmd(String Category) {
Vector Result, feedNames, feedLinks;
Result = new Vector();
if (Category != null) {
feedNames = DATAMGR_GET_FEEDNAMES(Category);
feedLinks = DATAMGR_GET_FEEDTABLEDATAPAGELINKS(Category);
}
else {
feedNames = DATAMGR_GET_ALLFEEDNAMES();
feedLinks = DATAMGR_GET_ALLFEEDTABLEDATAPAGELINKS();
}
if ((feedNames == null) || (feedLinks == null))
return new CmdResult(CmdResult.FAIL_CODE, null);
for (int i=0; i < feedNames.size(); i++) {
String feedlinkStr = new String(feedNames.elementAt(i) +
"\t" + feedLinks.elementAt(i));
Result.addElement(feedlinkStr);
//System.out.println("RESULT: "+ feedlinkStr);
}
if (Result != null)
return new CmdResult(CmdResult.SUCESS_CODE, Result);
return new CmdResult(CmdResult.FAIL_CODE, null);
}
private CmdResult sendFeedNamesWithFeedSourceLinkCmd(String Category) {
Vector Result, feedNames, feedSourceLinks;
Result = new Vector();
if (Category != null) {
feedNames = DATAMGR_GET_FEEDNAMES(Category);
feedSourceLinks = DATAMGR_GET_FEEDSOURCELINKS(Category);
if ((feedNames == null) || (feedSourceLinks == null))
return new CmdResult(CmdResult.FAIL_CODE, null);
for (int i=0; i < feedNames.size(); i++) {
String feedlinkStr = new String(feedNames.elementAt(i) +
"\t" + feedSourceLinks.elementAt(i));
Result.addElement(feedlinkStr);
//System.out.println("APPMAIN RESULT: "+ feedlinkStr);
}
if (Result != null)
return new CmdResult(CmdResult.SUCESS_CODE, Result);
}
return new CmdResult(CmdResult.FAIL_CODE, null);
}
private CmdResult sendStyleInfoCmd() {
String str = StyleMgr.getStyleInfo();
if (str != null) {
Vector v = new Vector();
v.addElement(str);
return new CmdResult(CmdResult.SUCESS_CODE, v);
}
return new CmdResult(CmdResult.FAIL_CODE, null);
}
private CmdResult saveStyleInfoCmd(String filedata) {
int result = StyleMgr.saveStyleInfo(filedata);
if (result < 0)
return new CmdResult(CmdResult.FAIL_CODE, null);
StyleMgr.generateCSSFile(FileUtils.getFullFileName(OutputPath, styleFname));
return new CmdResult(CmdResult.SUCESS_CODE, null);
}
private CmdResult sendFeedNamesWithTblDataPgLinkFromSourceURLCmd(String Category,
String feedSourceURL)
{
Vector Result;
String feedName,feedLink;
Result = new Vector();
if ((Category == null) || (feedSourceURL == null))
return new CmdResult(CmdResult.FAIL_CODE, null);
feedName = DATAMGR_GET_FEEDNAME(Category, feedSourceURL);
feedLink = DATAMGR_GET_FEEDTABLEDATAPAGELINK(Category, feedSourceURL);
if ((feedName != null) && (feedLink != null)) {
String feedlinkStr = new String(feedName + "\t" + feedLink);
Result.addElement(feedlinkStr);
return new CmdResult(CmdResult.SUCESS_CODE, Result);
}
return new CmdResult(CmdResult.FAIL_CODE, null);
}
/* The main Application API handler */
public CmdResult handleCommand(Vector CmdInfo) {
CmdResult res=null;
String data1=null,data2=null;
int code = ((Integer) CmdInfo.elementAt(0)).intValue();
System.out.print("handleCommand: code="+code+" ");
/* for debug
for (int i = 1; i < CmdInfo.size(); i++)
System.out.println((String)CmdInfo.elementAt(i));
*/
// set up the arguments passed
if (CmdInfo.size() >= 2) {
data1 = (String) CmdInfo.elementAt(1);
if (CmdInfo.size() >= 3)
data2 = (String) CmdInfo.elementAt(2);
}
switch (code) {
case AppCmd.GET_CATEGORIES:
res = sendCategoryDataCmd();
break;
case AppCmd.ADD_LINK:
res = addLinkCmd(data1, data2);
break;
case AppCmd.OPML_IMPORT:
res = opmlImportCmd(data1, data2);
break;
case AppCmd.GET_FEEDNAMES:
res = sendFeedNamesCmd(data1);
break;
case AppCmd.GET_FEEDNAMES_W_PAGE_LINK:
res = sendFeedNamesWithPageLinkCmd(data1);
break;
case AppCmd.GET_ALL_FEEDNAMES_W_PAGE_LINK:
res = sendFeedNamesWithPageLinkCmd(null);
break;
case AppCmd.GET_FEEDNAMES_W_TABLEDATA_PAGE_LINK:
res = sendFeedNamesWithTableDataPageLinkCmd(data1);
break;
case AppCmd.GET_ALL_FEEDNAMES_W_TABLEDATA_PAGE_LINK:
res = sendFeedNamesWithTableDataPageLinkCmd(null);
break;
case AppCmd.GET_STYLE_INFO:
res = sendStyleInfoCmd();
break;
case AppCmd.SAVE_STYLE_INFO:
res = saveStyleInfoCmd(data1);
break;
case AppCmd.GET_FEEDNAMES_W_FEEDSOURCE_LINK:
res = sendFeedNamesWithFeedSourceLinkCmd(data1);
break;
case AppCmd.DEL_LINK:
res = delLinkCmd(data1, data2);
break;
case AppCmd.GET_FEEDNAMES_W_TABLEDATA_PAGE_LINK_FRM_SOURCEURL:
res = sendFeedNamesWithTblDataPgLinkFromSourceURLCmd(data1, data2);
break;
default:
break;
}
return res;
}
public int getRefreshInterval() {
return refreshInterval;
}
public void setRefreshInterval(int InMins) {
if (InMins < (MINIMUM_REFRESHTIME/(60*1000))) {
System.out.println("Refresh time less than min refresh time of "
+MINIMUM_REFRESHTIME+" mins");
System.out.println("Setting refresh interval to "+MINIMUM_REFRESHTIME+" mins");
InMins=MINIMUM_REFRESHTIME;
}
refreshInterval = InMins*60*1000;
}
}