You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@roller.apache.org by sn...@apache.org on 2006/09/14 23:27:39 UTC
svn commit: r443477 [2/2] - in /incubator/roller/trunk/sandbox/planetroller:
./ etc/ nbproject/ nbproject/private/ src/org/apache/roller/tools/
src/org/apache/roller/tools/planet/ web/ web/META-INF/ web/WEB-INF/
web/WEB-INF/lib/
Modified: incubator/roller/trunk/sandbox/planetroller/src/org/apache/roller/tools/PlanetTool.java
URL: http://svn.apache.org/viewvc/incubator/roller/trunk/sandbox/planetroller/src/org/apache/roller/tools/PlanetTool.java?view=diff&rev=443477&r1=443476&r2=443477
==============================================================================
--- incubator/roller/trunk/sandbox/planetroller/src/org/apache/roller/tools/PlanetTool.java (original)
+++ incubator/roller/trunk/sandbox/planetroller/src/org/apache/roller/tools/PlanetTool.java Thu Sep 14 14:27:38 2006
@@ -1,5 +1,41 @@
/*
- * Copyright 2005 David M Johnson
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License. For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.roller.tools;
+
+import com.sun.syndication.feed.synd.SyndEntry;
+import com.sun.syndication.feed.synd.SyndFeed;
+import com.sun.syndication.fetcher.FeedFetcher;
+import com.sun.syndication.fetcher.impl.FeedFetcherCache;
+import com.sun.syndication.fetcher.impl.HttpURLFeedFetcher;
+import com.sun.syndication.fetcher.impl.SyndFeedInfo;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.sql.Timestamp;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Comparator;
+import java.util.Date;
+/*
+ * Copyright 2005 Roller project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,21 +49,23 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.Date;
+
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
+import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.roller.pojos.PlanetConfigData;
+import org.apache.roller.pojos.PlanetEntryData;
+import org.apache.roller.pojos.PlanetGroupData;
+import org.apache.roller.pojos.PlanetSubscriptionData;
+import org.apache.roller.util.Utilities;
+import org.apache.roller.util.rome.DiskFeedInfoCache;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.texen.Generator;
@@ -36,162 +74,132 @@
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.xpath.XPath;
-import org.apache.roller.RollerException;
-import org.apache.roller.business.PlanetManagerImpl;
-import org.apache.roller.pojos.PlanetConfigData;
-import org.apache.roller.pojos.PlanetEntryData;
-import org.apache.roller.pojos.PlanetGroupData;
-import org.apache.roller.pojos.PlanetSubscriptionData;
-import org.apache.roller.util.Utilities;
+
/**
- * Utility that aggregates multiple newsfeeds using Rome Fetcher and calls
+ * Utility that aggregates multiple newsfeeds using Rome Fetcher and calls
* Velocity Texen control template generate files (HTML, RSS, OPML, etc.).
* Does everything in memory; no database storage is used.
- * <p />
- * Written for Blogs, Wikis, and Feeds in Action and designed for use outside
- * of Roller.
*
* @author David M Johnson
*/
-public class PlanetTool extends PlanetManagerImpl
-{
- private static Log logger =
- LogFactory.getFactory().getInstance(PlanetTool.class);
-
+public class PlanetTool {
+ private static Log logger =
+ LogFactory.getFactory().getInstance(PlanetTool.class);
+
protected PlanetConfigData config = null;
protected Map subsByURL = new HashMap(); // keys are URL strings
protected Map groupsByHandle = new HashMap(); // keys are handle strings
protected Map aggregationsByGroup = new HashMap(); // keys are GroupData objects
- /**
- * Construct by reading confuration JDOM Document.
+ /**
+ * Construct by reading confuration JDOM Document.
*/
- public PlanetTool(Document doc) throws RollerException
- {
- try
- {
+ public PlanetTool(Document doc) throws Exception {
+ try {
initFromXML(doc);
- }
- catch (JDOMException e)
- {
- throw new RollerException("Extracting config from parsed XML", e);
+ } catch (JDOMException e) {
+ throw new Exception("Extracting config from parsed XML", e);
}
}
-
+
/**
* Call Texen control template specified by configuration to generate files.
*/
- public void generatePlanet() throws RollerException
- {
- try
- {
+ public void generatePlanet() throws Exception {
+ try {
VelocityEngine engine = new VelocityEngine();
engine.setProperty("resource.loader","file");
engine.setProperty("file.resource.loader.class",
- "org.apache.velocity.runtime.resource.loader.FileResourceLoader");
- engine.setProperty("file.resource.loader.path",
- getConfiguration().getTemplateDir());
+ "org.apache.velocity.runtime.resource.loader.FileResourceLoader");
+ engine.setProperty("file.resource.loader.path",
+ getConfiguration().getTemplateDir());
engine.init();
VelocityContext context = new VelocityContext();
context.put("date", new Date());
context.put("utilities", new Utilities());
context.put("planet", this);
-
+
+ File outputDir = new File(getConfiguration().getOutputDir());
+ if (!outputDir.exists()) outputDir.mkdirs();
+
Generator generator = Generator.getInstance();
generator.setVelocityEngine(engine);
generator.setOutputEncoding("utf-8");
generator.setInputEncoding("utf-8");
generator.setOutputPath(getConfiguration().getOutputDir());
generator.setTemplatePath(getConfiguration().getTemplateDir());
- generator.parse(config.getMainPage(), context);
+ generator.parse(config.getMainPage(), context);
generator.shutdown();
- }
- catch (Exception e)
- {
+ } catch (Exception e) {
e.printStackTrace();
- throw new RollerException("Writing planet files",e);
+ throw new Exception("Writing planet files",e);
}
}
- public void saveConfiguration(PlanetConfigData config) throws RollerException
- {
+ public void saveConfiguration(PlanetConfigData config) throws Exception {
this.config = config;
}
-
- public void saveGroup(PlanetGroupData sub) throws RollerException
- {
+
+ public void saveGroup(PlanetGroupData sub) throws Exception {
groupsByHandle.put(sub.getHandle(), sub);
}
-
- public void saveSubscription(PlanetSubscriptionData sub) throws RollerException
- {
- subsByURL.put(sub.getFeedUrl(), sub);
+
+ public void saveSubscription(PlanetSubscriptionData sub) throws Exception {
+ subsByURL.put(sub.getFeedURL(), sub);
}
- public void saveEntry(PlanetEntryData entry) throws RollerException
- {
+ public void saveEntry(PlanetEntryData entry) throws Exception {
// no-op
}
-
- public PlanetSubscriptionData getSubscription(String feedUrl)
- throws RollerException
- {
+
+ public PlanetSubscriptionData getSubscription(String feedUrl)
+ throws Exception {
return (PlanetSubscriptionData)subsByURL.get(feedUrl);
}
-
- public PlanetConfigData getConfiguration() throws RollerException
- {
+
+ public PlanetConfigData getConfiguration() throws Exception {
return config;
}
-
- public List getGroupHandles() throws RollerException
- {
+
+ public List getGroupHandles() throws Exception {
return new ArrayList(groupsByHandle.keySet());
}
-
- public List getGroups() throws RollerException
- {
+
+ public List getGroups() throws Exception {
return new ArrayList(groupsByHandle.values());
}
-
- public PlanetGroupData getGroup(String handle) throws RollerException
- {
+
+ public PlanetGroupData getGroup(String handle) throws Exception {
return (PlanetGroupData)groupsByHandle.get(handle);
}
public List getAggregation(
- PlanetGroupData group, int maxEntries) throws RollerException
- {
+ PlanetGroupData group, int maxEntries) throws Exception {
long startTime = System.currentTimeMillis();
List aggregation = null;
- try
- {
+ try {
// Get aggregation from cache
aggregation = (List)aggregationsByGroup.get(group);
- if (aggregation == null)
- {
+ if (aggregation == null) {
// No aggregation found in cache, let's create a new one
aggregation = new ArrayList();
// Comparator to help us create reverse chrono sorted list of entries
- Comparator entryDateComparator = new EntryDateComparator();
+ Comparator entryDateComparator = new EntryDateComparator();
// Add all of group's subscription's entries to ordered collection
Set sortedEntries = new TreeSet(entryDateComparator);
Iterator subs = group.getSubscriptions().iterator();
- while (subs.hasNext())
- {
+ while (subs.hasNext()) {
PlanetSubscriptionData sub = (PlanetSubscriptionData)subs.next();
Iterator candidates = sub.getEntries().iterator();
- while (candidates.hasNext())
- {
+ while (candidates.hasNext()) {
PlanetEntryData candidate = (PlanetEntryData) candidates.next();
- if (group.qualified(candidate))
- {
- sortedEntries.add(candidate);
+ if (group.qualified(candidate)) {
+ sortedEntries.add(candidate);
}
}
}
@@ -199,131 +207,111 @@
// Throw away all but first maxEntris of our new entry list
int count = 0;
Iterator entries = sortedEntries.iterator();
- while (entries.hasNext() && count++ < maxEntries)
- {
+ while (entries.hasNext() && count++ < maxEntries) {
aggregation.add(entries.next());
}
aggregationsByGroup.put(group, aggregation);
}
- }
- catch (Exception e)
- {
+ } catch (Exception e) {
logger.error("ERROR: building aggregation for: "+group.getHandle(), e);
- throw new RollerException(e);
+ throw new Exception(e);
}
long endTime = System.currentTimeMillis();
logger.info("Generated aggregation in "
+((endTime-startTime)/1000.0)+" seconds");
- return aggregation;
+ return aggregation;
}
- public void deleteEntry(PlanetEntryData entry) throws RollerException
- {
+ public void deleteEntry(PlanetEntryData entry) throws Exception {
// no-op
}
-
- public void deleteGroup(PlanetGroupData group) throws RollerException
- {
+
+ public void deleteGroup(PlanetGroupData group) throws Exception {
// no-op
}
-
- public void deleteSubscription(PlanetSubscriptionData group) throws RollerException
- {
+
+ public void deleteSubscription(PlanetSubscriptionData group) throws Exception {
// no-op
}
- public List getTopSubscriptions(int max) throws RollerException
- {
- throw new RuntimeException("Not implemented");
+ public void clearCachedAggregations() {
+ // no-op
}
- public List getTopSubscriptions(PlanetGroupData group, int max) throws RollerException
- {
- throw new RuntimeException("Not implemented");
+ public List getTopSubscriptions(int max) throws Exception {
+ throw new RuntimeException("NOT SUPPORTED");
}
-
- public List getTopSubscriptions(PlanetGroupData group, int max) throws RollerException
- {
- throw new RuntimeException("Not implemented");
+
+ public List getTopSubscriptions(PlanetGroupData group, int max) throws Exception {
+ throw new RuntimeException("NOT SUPPORTED");
}
-
- public PlanetSubscriptionData getSubscriptionById(String id)
- throws RollerException
- {
+
+ public PlanetSubscriptionData getSubscriptionById(String id) throws Exception {
throw new RuntimeException("NOT SUPPORTED");
}
-
- public PlanetGroupData getGroupById(String id)
- throws RollerException
- {
+
+ public PlanetGroupData getGroupById(String id)
+ throws Exception {
throw new RuntimeException("NOT SUPPORTED");
}
- public List getAggregation(int maxEntries) throws RollerException
- {
+ public List getAggregation(int maxEntries) throws Exception {
+ throw new RuntimeException("NOT SUPPORTED");
+ }
+
+ public Date getLastUpdated() {
+ throw new RuntimeException("NOT SUPPORTED");
+ }
+
+ public Date getLastUpdated(PlanetGroupData group) {
throw new RuntimeException("NOT SUPPORTED");
}
-
//--------------------------------------------------------------------- console
- public static void main(String[] args)
- {
+ public static void main(String[] args) {
String success = "Planet complete!";
String error = null;
Exception traceWorthy = null;
- String fileName = "planet-config.xml";
- if (args.length == 1)
- {
+ String fileName = "planet-config.xml";
+ if (args.length == 1) {
fileName = args[0];
}
- try
- {
+ try {
SAXBuilder builder = new SAXBuilder();
Document doc = builder.build(new FileInputStream(fileName));
- PlanetTool planet = new PlanetTool(doc);
+ PlanetTool planet = new PlanetTool(doc);
planet.refreshEntries();
planet.generatePlanet();
System.out.println(success);
System.exit(0);
- }
- catch (FileNotFoundException fnfe)
- {
+ } catch (FileNotFoundException fnfe) {
error = "Configuration file ["+fileName+"] not found";
- }
- catch (JDOMException jde)
- {
+ } catch (JDOMException jde) {
error = "Error parsing configuration file ["+fileName+"]";
traceWorthy = jde;
- }
- catch (IOException ioe)
- {
+ } catch (IOException ioe) {
error = "IO error. Using configuration file ["+fileName+"]";
traceWorthy = ioe;
- }
- catch (RollerException re)
- {
+ } catch (Exception re) {
error = re.getMessage();
- }
- if (error != null)
- {
+ }
+ if (error != null) {
System.out.println(error);
if (traceWorthy != null) traceWorthy.printStackTrace();
System.exit(-1);
}
}
- public Iterator getAllSubscriptions()
- {
+ public Iterator getAllSubscriptions() {
return subsByURL.values().iterator();
}
//-------------------------------------------------------------------- privates
-
+
/**
* Load config data from XML using XPath.
*/
- protected void initFromXML(Document doc) throws RollerException, JDOMException
- {
+ protected void initFromXML(Document doc) throws Exception, JDOMException {
Map subsByID = new HashMap();
Element elem = doc.getRootElement();
@@ -333,7 +321,7 @@
config.setGroupPage( getString(elem,"/planet-config/group-page"));
config.setAdminName( getString(elem,"/planet-config/admin-name"));
config.setAdminEmail( getString(elem,"/planet-config/admin-email"));
- config.setSiteUrl( getString(elem,"/planet-config/site-url"));
+ config.setSiteURL( getString(elem,"/planet-config/site-url"));
config.setOutputDir( getString(elem,"/planet-config/output-dir"));
config.setTemplateDir(getString(elem,"/planet-config/template-dir"));
config.setTitle( getString(elem,"/planet-config/title"));
@@ -341,24 +329,22 @@
XPath subsPath = XPath.newInstance("/planet-config/subscription");
Iterator subs = subsPath.selectNodes(doc).iterator();
- while (subs.hasNext())
- {
+ while (subs.hasNext()) {
Element subElem = (Element)subs.next();
PlanetSubscriptionData sub = new PlanetSubscriptionData();
String id = subElem.getAttributeValue("id");
sub.setTitle( getString(subElem, "title"));
sub.setAuthor( getString(subElem, "author"));
- sub.setFeedUrl( getString(subElem, "feed-url"));
- sub.setSiteUrl( getString(subElem, "site-url"));
- subsByURL.put(sub.getFeedUrl(), sub);
+ sub.setFeedURL( getString(subElem, "feed-url"));
+ sub.setSiteURL( getString(subElem, "site-url"));
+ subsByURL.put(sub.getFeedURL(), sub);
subsByID.put(id, sub);
}
logger.info("Found "+subsByID.size()+" subscriptions");
-
+
XPath groupsPath = XPath.newInstance("/planet-config/group");
Iterator groups = groupsPath.selectNodes(doc).iterator();
- while (groups.hasNext())
- {
+ while (groups.hasNext()) {
Element groupElem = (Element)groups.next();
PlanetGroupData group = new PlanetGroupData();
group.setHandle(groupElem.getAttributeValue("handle"));
@@ -367,36 +353,31 @@
group.setMaxFeedEntries( getInt( groupElem, "max-feed-entries"));
group.setMaxPageEntries( getInt( groupElem, "max-page-entries"));
group.setCategoryRestriction(
- getString(groupElem, "category-restriction"));
-
+ getString(groupElem, "category-restriction"));
+
XPath refsPath = XPath.newInstance("subscription-ref");
Iterator refs = refsPath.selectNodes(groupElem).iterator();
- while (refs.hasNext())
- {
+ while (refs.hasNext()) {
Element refElem = (Element)refs.next();
String includeAll = refElem.getAttributeValue("include-all");
- if (includeAll != null && includeAll.equals("true"))
- {
+ if (includeAll != null && includeAll.equals("true")) {
//group.getSubscriptions().addAll(subsByID.values());
group.addSubscriptions(subsByID.values());
- }
- else
- {
+ } else {
String refid = refElem.getAttributeValue("refid");
PlanetSubscriptionData sub = (PlanetSubscriptionData)subsByID.get(refid);
- if (sub == null)
- {
- throw new RollerException("No such subscription ["+refid+"]");
+ if (sub == null) {
+ throw new Exception("No such subscription ["+refid+"]");
}
//group.getSubscriptions().add(sub);
- group.addSubscription(sub);
+ group.addSubscription(sub);
}
}
groupsByHandle.put(group.getHandle(), group);
}
logger.info("Found "+groupsByHandle.size()+" groups");
}
-
+
//--------------------------------------------------------------- utilities
protected String getString(Element elem, String path) throws JDOMException {
@@ -411,36 +392,190 @@
return e!=null ? Integer.parseInt(e.getText()) : 0;
}
- public class EntryDateComparator implements Comparator
- {
- public int compare(Object o1, Object o2)
- {
+ public class EntryDateComparator implements Comparator {
+ public int compare(Object o1, Object o2) {
PlanetEntryData e1 = (PlanetEntryData)o1;
PlanetEntryData e2 = (PlanetEntryData)o2;
- if (e1.getPublished() != null && e2.getPublished() != null)
- {
- return e2.getPublished().compareTo(e1.getPublished());
+ if (e1.getPubTime() != null && e2.getPubTime() != null) {
+ return e2.getPubTime().compareTo(e1.getPubTime());
}
- if (e1.getPublished() == null)
- {
- logger.warn("Entry missing pubDate in sub: "
- + e1.getSubscription().getFeedUrl());
+ if (e1.getPubTime() == null) {
+ logger.warn("Entry missing pubDate in sub: "
+ + e1.getSubscription().getFeedURL());
+ }
+ if (e2.getPubTime() == null) {
+ logger.warn("Entry missing pubDate in sub: "
+ + e2.getSubscription().getFeedURL());
}
- if (e2.getPublished() == null)
- {
- logger.warn("Entry missing pubDate in sub: "
- + e2.getSubscription().getFeedUrl());
- }
return 0;
- }
+ }
}
-
+
/**
* Total number of subscriptions.
*/
- public int getSubscriptionCount() throws RollerException
- {
+ public int getSubscriptionCount() throws Exception {
return this.subsByURL.size();
- };
+ }
+
+ public void refreshEntries() throws Exception {
+ Date now = new Date();
+ long startTime = System.currentTimeMillis();
+ PlanetConfigData config = getConfiguration();
+ if (config == null || config.getCacheDir() == null) {
+ logger.warn("Planet cache directory not set, aborting refresh");
+ return;
+ }
+ FeedFetcherCache feedInfoCache =
+ new DiskFeedInfoCache(config.getCacheDir());
+
+ if (config.getProxyHost()!=null && config.getProxyPort() > 0) {
+ System.setProperty("proxySet", "true");
+ System.setProperty("http.proxyHost", config.getProxyHost());
+ System.setProperty("http.proxyPort",
+ Integer.toString(config.getProxyPort()));
+ }
+ /** a hack to set 15 sec timeouts for java.net.HttpURLConnection */
+ System.setProperty("sun.net.client.defaultConnectTimeout", "15000");
+ System.setProperty("sun.net.client.defaultReadTimeout", "15000");
+
+ FeedFetcher feedFetcher = new HttpURLFeedFetcher(feedInfoCache);
+ //FeedFetcher feedFetcher = new HttpClientFeedFetcher(feedInfoCache);
+ feedFetcher.setUsingDeltaEncoding(false);
+ feedFetcher.setUserAgent("RollerPlanetAggregator");
+
+ // Loop through all subscriptions in the system
+ Iterator subs = getAllSubscriptions();
+ while (subs.hasNext()) {
+ long subStartTime = System.currentTimeMillis();
+
+ // Fetch latest entries for each subscription
+ Set newEntries = null;
+ int count = 0;
+ PlanetSubscriptionData sub = (PlanetSubscriptionData)subs.next();
+ newEntries = getNewEntriesRemote(sub, feedFetcher, feedInfoCache);
+ count = newEntries.size();
+
+ logger.debug(" Entry count: " + count);
+ if (count > 0) {
+ Iterator entryIter = sub.getEntries().iterator();
+ while (entryIter.hasNext()) {
+ deleteEntry((PlanetEntryData)entryIter.next());
+ }
+ sub.purgeEntries();
+ sub.addEntries(newEntries);
+ }
+ long subEndTime = System.currentTimeMillis();
+ logger.info(" " + count + " - "
+ + ((subEndTime-subStartTime)/1000.0)
+ + " seconds to process (" + count + ") entries of "
+ + sub.getFeedURL());
+ }
+ // Clear the aggregation cache
+ clearCachedAggregations();
+
+ long endTime = System.currentTimeMillis();
+ logger.info("--- DONE --- Refreshed entries in "
+ + ((endTime-startTime)/1000.0) + " seconds");
+ }
+
+ /**
+ * Override this if you have local feeds (i.e. feeds that you don't
+ * have to fetch via HTTP and parse with ROME).
+ */
+ protected Set getNewEntriesLocal(PlanetSubscriptionData sub,
+ FeedFetcher feedFetcher, FeedFetcherCache feedInfoCache)
+ throws Exception {
+
+ // If you don't override, local feeds will be treated as remote feeds
+ return getNewEntriesRemote(sub, feedFetcher, feedInfoCache);
+ }
+
+ protected Set getNewEntriesRemote(PlanetSubscriptionData sub,
+ FeedFetcher feedFetcher, FeedFetcherCache feedInfoCache)
+ throws Exception {
+
+ Set newEntries = new TreeSet();
+ SyndFeed feed = null;
+ URL feedUrl = null;
+ Date lastUpdated = new Date();
+ try {
+ feedUrl = new URL(sub.getFeedURL());
+ logger.debug("Get feed from cache "+sub.getFeedURL());
+ feed = feedFetcher.retrieveFeed(feedUrl);
+ SyndFeedInfo feedInfo = feedInfoCache.getFeedInfo(feedUrl);
+ if (feedInfo.getLastModified() != null) {
+ long lastUpdatedLong =
+ ((Long)feedInfo.getLastModified()).longValue();
+ if (lastUpdatedLong != 0) {
+ lastUpdated = new Date(lastUpdatedLong);
+ }
+ }
+ Thread.sleep(100); // be nice
+ } catch (Exception e) {
+ logger.warn("ERROR parsing " + sub.getFeedURL()
+ + " : " + e.getClass().getName() + " : " + e.getMessage());
+ logger.debug(e);
+ return newEntries; // bail out
+ }
+ if (lastUpdated!=null && sub.getLastUpdated()!=null) {
+ Calendar feedCal = Calendar.getInstance();
+ feedCal.setTime(lastUpdated);
+
+ Calendar subCal = Calendar.getInstance();
+ subCal.setTime(sub.getLastUpdated());
+
+ if (!feedCal.after(subCal)) {
+ if (logger.isDebugEnabled()) {
+ String msg = MessageFormat.format(
+ " Skipping ({0} / {1})",
+ new Object[] {
+ lastUpdated, sub.getLastUpdated()});
+ logger.debug(msg);
+ }
+ return newEntries; // bail out
+ }
+ }
+ if (feed.getPublishedDate() != null) {
+ sub.setLastUpdated(feed.getPublishedDate());
+ saveSubscription(sub);
+ }
+
+ // Kludge for Feeds without entry dates: most recent entry is given
+ // feed's last publish date (or yesterday if none exists) and earler
+ // entries are placed at once day intervals before that.
+ Calendar cal = Calendar.getInstance();
+ if (sub.getLastUpdated() != null) {
+ cal.setTime(sub.getLastUpdated());
+ } else {
+ cal.setTime(new Date());
+ cal.add(Calendar.DATE, -1);
+ }
+
+ // Populate subscription object with new entries
+ Iterator entries = feed.getEntries().iterator();
+ while (entries.hasNext()) {
+ try {
+ SyndEntry romeEntry = (SyndEntry) entries.next();
+ PlanetEntryData entry =
+ new PlanetEntryData(feed, romeEntry, sub);
+ if (entry.getPubTime() == null) {
+ logger.debug(
+ "No published date, assigning fake date for "+feedUrl);
+ entry.setPubTime(new Timestamp(cal.getTime().getTime()));
+ }
+ if (entry.getPermalink() == null) {
+ logger.warn("No permalink, rejecting entry from "+feedUrl);
+ } else {
+ saveEntry(entry);
+ newEntries.add(entry);
+ }
+ cal.add(Calendar.DATE, -1);
+ } catch (Exception e) {
+ logger.error("ERROR processing subscription entry", e);
+ }
+ }
+ return newEntries;
+ }
}
Added: incubator/roller/trunk/sandbox/planetroller/web/META-INF/context.xml
URL: http://svn.apache.org/viewvc/incubator/roller/trunk/sandbox/planetroller/web/META-INF/context.xml?view=auto&rev=443477
==============================================================================
--- incubator/roller/trunk/sandbox/planetroller/web/META-INF/context.xml (added)
+++ incubator/roller/trunk/sandbox/planetroller/web/META-INF/context.xml Thu Sep 14 14:27:38 2006
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Context path="/planetroller"/>
Added: incubator/roller/trunk/sandbox/planetroller/web/WEB-INF/web.xml
URL: http://svn.apache.org/viewvc/incubator/roller/trunk/sandbox/planetroller/web/WEB-INF/web.xml?view=auto&rev=443477
==============================================================================
--- incubator/roller/trunk/sandbox/planetroller/web/WEB-INF/web.xml (added)
+++ incubator/roller/trunk/sandbox/planetroller/web/WEB-INF/web.xml Thu Sep 14 14:27:38 2006
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">
+ <display-name>Planet Roller</display-name>
+
+
+</web-app>
Added: incubator/roller/trunk/sandbox/planetroller/web/index.jsp
URL: http://svn.apache.org/viewvc/incubator/roller/trunk/sandbox/planetroller/web/index.jsp?view=auto&rev=443477
==============================================================================
--- incubator/roller/trunk/sandbox/planetroller/web/index.jsp (added)
+++ incubator/roller/trunk/sandbox/planetroller/web/index.jsp Thu Sep 14 14:27:38 2006
@@ -0,0 +1,38 @@
+<%@page contentType="text/html"%>
+<%@page pageEncoding="UTF-8"%>
+<%--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. The ASF licenses this file to You
+ under the Apache License, Version 2.0 (the "License"); you may not
+ use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License. For additional information regarding
+ copyright in this work, please see the NOTICE file in the top level
+ directory of this distribution.
+--%>
+<%--
+<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
+--%>
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+ <title>Coming soon...</title>
+ </head>
+ <body>
+
+ <h1>Planet Roller webapp</h1>
+
+
+ </body>
+</html>