package com.commafeed.backend.services; import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; import java.util.List; import java.util.concurrent.TimeUnit; import javax.ejb.AccessTimeout; import javax.ejb.Lock; import javax.ejb.LockType; import javax.ejb.Singleton; import javax.inject.Inject; import org.apache.commons.lang.ObjectUtils; import org.apache.commons.lang.StringUtils; import com.commafeed.backend.MetricsBean; import com.commafeed.backend.dao.FeedEntryDAO; import com.commafeed.backend.dao.FeedEntryStatusDAO; import com.commafeed.backend.dao.FeedSubscriptionDAO; import com.commafeed.backend.model.Feed; import com.commafeed.backend.model.FeedEntry; import com.commafeed.backend.model.FeedEntryStatus; import com.commafeed.backend.model.FeedSubscription; import com.google.common.collect.Lists; @Singleton public class FeedUpdateService { @Inject FeedSubscriptionDAO feedSubscriptionDAO; @Inject FeedEntryDAO feedEntryDAO; @Inject FeedEntryStatusDAO feedEntryStatusDAO; @Inject MetricsBean metricsBean; @Lock(LockType.WRITE) @AccessTimeout(value = 5, unit = TimeUnit.MINUTES) public void updateEntries(Feed feed, Collection entries) { List existingEntries = getExistingEntries(entries); List subscriptions = feedSubscriptionDAO .findByFeed(feed); List entryUpdateList = Lists.newArrayList(); List statusUpdateList = Lists.newArrayList(); for (FeedEntry entry : entries) { FeedEntry foundEntry = findEntry(existingEntries, entry); if (foundEntry == null) { entry.setInserted(Calendar.getInstance().getTime()); entry.getFeeds().add(feed); entryUpdateList.add(entry); } else { boolean foundFeed = false; for (Feed existingFeed : foundEntry.getFeeds()) { if (ObjectUtils.equals(existingFeed.getId(), feed.getId())) { foundFeed = true; break; } } if (!foundFeed) { foundEntry.getFeeds().add(feed); entryUpdateList.add(foundEntry); } } } for (FeedEntry entry : entryUpdateList) { for (FeedSubscription sub : subscriptions) { FeedEntryStatus status = new FeedEntryStatus(); status.setEntry(entry); status.setSubscription(sub); statusUpdateList.add(status); } } feedEntryDAO.saveOrUpdate(entryUpdateList); feedEntryStatusDAO.saveOrUpdate(statusUpdateList); metricsBean .feedUpdated(entryUpdateList.size(), statusUpdateList.size()); } private FeedEntry findEntry(List existingEntries, FeedEntry entry) { FeedEntry foundEntry = null; for (FeedEntry existingEntry : existingEntries) { if (StringUtils.equals(entry.getGuid(), existingEntry.getGuid()) && StringUtils.equals(entry.getUrl(), existingEntry.getUrl())) { foundEntry = existingEntry; break; } } return foundEntry; } private List getExistingEntries(Collection entries) { List guids = Lists.newArrayList(); for (FeedEntry entry : entries) { guids.add(entry.getGuid()); } List existingEntries = guids.isEmpty() ? new ArrayList() : feedEntryDAO.findByGuids(guids); return existingEntries; } }