/*
* JBoss, Home of Professional Open Source
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jboss.seam.wiki.connectors.feed;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.AutoCreate;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.log.Log;
import org.jboss.seam.wiki.core.model.Feed;
import org.jboss.seam.wiki.core.model.FeedEntry;
import com.sun.syndication.feed.synd.SyndContent;
import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.io.FeedException;
import com.sun.syndication.io.SyndFeedInput;
import com.sun.syndication.io.XmlReader;
/**
*
* TODO: This requires a system property for timeout: sun.net.client.defaultConnectTimeout=30000
*
* @author Christian Bauer
*/
@Name("feedConnector")
@Scope(ScopeType.APPLICATION)
@AutoCreate
public class RomeFeedConnector implements FeedConnector {
@Logger
Log log;
@In("#{preferences.get('FeedConnector')}")
FeedConnectorPreferences prefs;
public List<FeedEntryDTO> getFeedEntries(String feedURL) {
try {
List<FeedEntryDTO> feedEntryDTOs = new ArrayList<FeedEntryDTO>();
log.debug("connecting to feed URL: " + feedURL);
URL feedSource = new URL(feedURL);
/** TODO: This breaks multi-threading somehow, two threads start calling this connector and one never returns...
URLConnection connection = feedSource.openConnection();
connection.setConnectTimeout(prefs.getConnectionTimeoutSeconds().intValue()*1000);
SyndFeedInput input = new SyndFeedInput();
SyndFeed syndFeed = input.build(new XmlReader(connection));
*/
// So we let Rome do it, whatever it uses internally seems to be safer...
SyndFeedInput input = new SyndFeedInput();
SyndFeed syndFeed = input.build(new XmlReader(feedSource));
log.debug("starting conversion from feed URL: " + feedURL);
Feed feed = convertSyndFeed(syndFeed);
for (Object o : syndFeed.getEntries()) {
SyndEntry syndEntry = (SyndEntry)o;
FeedEntry fe = convertSyndEntry(syndEntry);
// Append some information on the title
fe.setTitlePrefix("(" + feed.getTitle() + ") ");
//fe.setTitleSuffix(" (" + fe.getAuthor() + ")");
// Linking it in our model makes it persistable/cachable
feed.getFeedEntries().add(fe);
// Now project them so the client has a unified view without iterating collections of Feeds
FeedEntryDTO dto = new FeedEntryDTO(feed, fe);
feedEntryDTOs.add(dto);
}
log.debug("retrieved feed entries: " + feedEntryDTOs.size());
return feedEntryDTOs;
} catch (SocketTimeoutException timeoutEx) {
log.warn("timeout connecting to feed: " + feedURL + ", " + timeoutEx.getMessage());
} catch (IllegalArgumentException iaEx) {
log.warn("could not connect to feed: " + feedURL + ", " + iaEx.getMessage());
} catch (MalformedURLException urlEx) {
log.warn("URL is not valid: " + feedURL + ", " + urlEx.getMessage());
} catch (IOException ioEx) {
log.warn("could not connect to feed: " + feedURL + ", " + ioEx.getMessage());
} catch (FeedException fex) {
log.warn("could not marshall feed data: " + feedURL + ", " + fex.getMessage());
}
return Collections.EMPTY_LIST;
}
private Feed convertSyndFeed(SyndFeed syndFeed) {
log.debug("converting SyndFeed: " + syndFeed.getTitle());
Feed feed = new Feed();
feed.setLink(syndFeed.getLink());
feed.setTitle(syndFeed.getTitle());
feed.setPublishedDate(syndFeed.getPublishedDate());
feed.setDescription(syndFeed.getDescription());
feed.setAuthor(syndFeed.getAuthor());
return feed;
}
private FeedEntry convertSyndEntry(SyndEntry syndEntry) {
log.debug("converting SyndEntry: " + syndEntry.getTitle());
FeedEntry feedEntry = new FeedEntry();
feedEntry.setLink(syndEntry.getLink());
feedEntry.setTitle(syndEntry.getTitle());
feedEntry.setPublishedDate(syndEntry.getPublishedDate());
feedEntry.setUpdatedDate(syndEntry.getUpdatedDate());
feedEntry.setAuthor(syndEntry.getAuthor());
if (syndEntry.getDescription() != null) {
SyndContent description = syndEntry.getDescription();
// TODO: Hardcode 'html', otherwise the ROME stuff craps out and kills Firefox feed renderer...
feedEntry.setDescriptionType("html");
feedEntry.setDescriptionValue(description.getValue());
}
return feedEntry;
}
}