public Serializable execute(final ActionContext inActionContext) throws ExecutionException
{
Boolean brokenFeed = true;
String lastSeenGUID = "";
RefreshFeedRequest request = (RefreshFeedRequest) inActionContext.getParams();
Feed feed = feedFinder.execute(new FindByIdRequest("Feed", request.getFeedId()));
Date lastPostDate = feed.getLastPostDate();
Long updateFrequency = null;
Boolean isOutOfOrder = false;
log.info("Processor feed: " + feed.getUrl());
for (String oooFeed : outOfOrderFeeds)
{
if (feed.getUrl().contains(oooFeed))
{
log.info("Feed marked out of order: " + feed.getUrl());
isOutOfOrder = true;
break;
}
}
try
{
// fetch the feeds
// Gives the fetcher the feed and a list of the requestors; the fetcher will decide if it can make a single
// unauthenticated request or if it needs to make one request per requestor. A set is used to prevent
// giving the fetcher any duplicates.
Set<String> requestorAccounts = new HashSet<String>();
for (FeedSubscriber feedSubscriber : feed.getFeedSubscribers())
{
requestorAccounts.add(feedSubscriber.getRequestor().getAccountId());
}
Map<String, SyndFeed> syndFeeds = feedFetcherFactory.getSyndicatedFeed(feed.getUrl(), requestorAccounts);
FeedObjectActivityBuilder selectedObjectMapper = null;
for (ObjectBuilderForSpecificUrl entry : specificUrlMappers)
{
if (entry.match(feed.getUrl()))
{
selectedObjectMapper = entry.getBuilder();
break;
}
}
// iterate through all feed instances returned by the fetcher
List<Activity> insertedActivities = new LinkedList<Activity>();
for (Map.Entry<String, SyndFeed> mapEntry : syndFeeds.entrySet())
{
SyndFeed syndFeed = mapEntry.getValue();
List<FeedSubscriber> subscribers = getFeedSubscribers(mapEntry.getKey(), feed);
// check for update frequency info
if (updateFrequency == null)
{
SyModule syMod = (SyModule) syndFeed.getModule(SyModule.URI);
if (syMod != null)
{
updateFrequency = getUpdateFrequency(syMod.getUpdatePeriod(), syMod.getUpdateFrequency());
}
}
if (syndFeed.getEntries().size() > 0)
{
SyndEntryImpl entry = (SyndEntryImpl) syndFeed.getEntries().get(0);
lastSeenGUID = entry.getUri();
}
Boolean brokenOutOfOrder = false;
if (isOutOfOrder && feed.getLastSeenGUID() != null)
{
brokenOutOfOrder = true;
// iterate through each entry in the feed instance
for (Object entryObject : syndFeed.getEntries())
{
try
{
SyndEntryImpl entry = (SyndEntryImpl) entryObject;
if (feed.getLastSeenGUID().equals(entry.getUri()))
{
log.info("Found matching GUID in out of order feed: " + lastSeenGUID);
brokenOutOfOrder = false;
break;
}
}
catch (Exception ex)
{
log.warn("ATOM/RSS entry is not to spec. "
+ "Skipping entry and moving to the next one. Feed url: " + feed.getUrl(), ex);
}
}
}
if (!brokenOutOfOrder)
{
// iterate through each entry in the feed instance
for (Object entryObject : syndFeed.getEntries())
{
try
{
SyndEntryImpl entry = (SyndEntryImpl) entryObject;
if (lastPostDate == null || entry.getPublishedDate().after(lastPostDate))
{
lastPostDate = entry.getPublishedDate();
}
Activity activity = getActivityFromATOMEntry(feed, entry, selectedObjectMapper);
// We were able to parse at least one good entry to completion, so the feed isn't broken.
brokenFeed = false;
if (isOutOfOrder && feed.getLastSeenGUID().equals(entry.getUri()))
{
log.info("Match found based on GUID: " + lastSeenGUID);
break;
}
else
{
log.info("No match found based on GUID: " + entry.getUri());
}
if (!isOutOfOrder && !entry.getPublishedDate().after(feed.getLastPostDate()))
{
log.info("Match found based on Date: " + feed.getLastPostDate());
break;
}
else
{
log.info("No match found based on Date: " + entry.getPublishedDate()
+ " Last Post Date: " + feed.getLastPostDate());
}
// create activities per subscriber
for (FeedSubscriber feedSubscriber : subscribers)
{
Activity activityForIndividual = (Activity) activity.clone();
if (feedSubscriber.getEntityType().equals(EntityType.PERSON))
{
Person person = personFinder.execute(new FindByIdRequest("Person", feedSubscriber
.getEntityId()));
if (person.isAccountLocked())
{
log.info("Ignoring locked account: " + person.getAccountId());
}
else
{
activityForIndividual.setActorId(person.getAccountId());
activityForIndividual.setRecipientStreamScope(person.getStreamScope());
activityForIndividual.setIsDestinationStreamPublic(true);
activityForIndividual.setActorType(feedSubscriber.getEntityType());
insertedActivities.add(activityForIndividual);
}
}
else if (feedSubscriber.getEntityType().equals(EntityType.GROUP))
{
DomainGroup group = groupFinder.execute(new FindByIdRequest("DomainGroup",
feedSubscriber.getEntityId()));
activityForIndividual.setActorId(group.getShortName());
activityForIndividual.setRecipientStreamScope(group.getStreamScope());
activityForIndividual.setIsDestinationStreamPublic(group.isPublicGroup());