forked from Archives/Athou_commafeed
optimize opml export (fix #687)
This commit is contained in:
@@ -13,6 +13,9 @@ import com.commafeed.backend.dao.FeedSubscriptionDAO;
|
|||||||
import com.commafeed.backend.model.FeedCategory;
|
import com.commafeed.backend.model.FeedCategory;
|
||||||
import com.commafeed.backend.model.FeedSubscription;
|
import com.commafeed.backend.model.FeedSubscription;
|
||||||
import com.commafeed.backend.model.User;
|
import com.commafeed.backend.model.User;
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
|
import com.google.common.collect.Multimaps;
|
||||||
import com.rometools.opml.feed.opml.Attribute;
|
import com.rometools.opml.feed.opml.Attribute;
|
||||||
import com.rometools.opml.feed.opml.Opml;
|
import com.rometools.opml.feed.opml.Opml;
|
||||||
import com.rometools.opml.feed.opml.Outline;
|
import com.rometools.opml.feed.opml.Outline;
|
||||||
@@ -21,6 +24,14 @@ import com.rometools.opml.feed.opml.Outline;
|
|||||||
@Singleton
|
@Singleton
|
||||||
public class OPMLExporter {
|
public class OPMLExporter {
|
||||||
|
|
||||||
|
private static Long ROOT_CATEGORY_ID = new Long(-1);
|
||||||
|
private static final Function<FeedSubscription, Long> SUBSCRIPTION_TO_CATEGORYID = new Function<FeedSubscription, Long>() {
|
||||||
|
@Override
|
||||||
|
public Long apply(FeedSubscription sub) {
|
||||||
|
return sub.getCategory() == null ? ROOT_CATEGORY_ID : sub.getCategory().getId();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private final FeedCategoryDAO feedCategoryDAO;
|
private final FeedCategoryDAO feedCategoryDAO;
|
||||||
private final FeedSubscriptionDAO feedSubscriptionDAO;
|
private final FeedSubscriptionDAO feedSubscriptionDAO;
|
||||||
|
|
||||||
@@ -31,7 +42,7 @@ public class OPMLExporter {
|
|||||||
opml.setCreated(new Date());
|
opml.setCreated(new Date());
|
||||||
|
|
||||||
List<FeedCategory> categories = feedCategoryDAO.findAll(user);
|
List<FeedCategory> categories = feedCategoryDAO.findAll(user);
|
||||||
List<FeedSubscription> subscriptions = feedSubscriptionDAO.findAll(user);
|
Multimap<Long, FeedSubscription> subscriptions = Multimaps.index(feedSubscriptionDAO.findAll(user), SUBSCRIPTION_TO_CATEGORYID);
|
||||||
|
|
||||||
// export root categories
|
// export root categories
|
||||||
for (FeedCategory cat : categories) {
|
for (FeedCategory cat : categories) {
|
||||||
@@ -41,17 +52,15 @@ public class OPMLExporter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// export root subscriptions
|
// export root subscriptions
|
||||||
for (FeedSubscription sub : subscriptions) {
|
for (FeedSubscription sub : subscriptions.get(ROOT_CATEGORY_ID)) {
|
||||||
if (sub.getCategory() == null) {
|
opml.getOutlines().add(buildSubscriptionOutline(sub));
|
||||||
opml.getOutlines().add(buildSubscriptionOutline(sub));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return opml;
|
return opml;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Outline buildCategoryOutline(FeedCategory cat, List<FeedSubscription> subscriptions) {
|
private Outline buildCategoryOutline(FeedCategory cat, Multimap<Long, FeedSubscription> subscriptions) {
|
||||||
Outline outline = new Outline();
|
Outline outline = new Outline();
|
||||||
outline.setText(cat.getName());
|
outline.setText(cat.getName());
|
||||||
outline.setTitle(cat.getName());
|
outline.setTitle(cat.getName());
|
||||||
@@ -60,10 +69,8 @@ public class OPMLExporter {
|
|||||||
outline.getChildren().add(buildCategoryOutline(child, subscriptions));
|
outline.getChildren().add(buildCategoryOutline(child, subscriptions));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (FeedSubscription sub : subscriptions) {
|
for (FeedSubscription sub : subscriptions.get(cat.getId())) {
|
||||||
if (sub.getCategory() != null && sub.getCategory().getId().equals(cat.getId())) {
|
outline.getChildren().add(buildSubscriptionOutline(sub));
|
||||||
outline.getChildren().add(buildSubscriptionOutline(sub));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return outline;
|
return outline;
|
||||||
}
|
}
|
||||||
|
|||||||
141
src/test/java/com/commafeed/backend/opml/OPMLExporterTest.java
Normal file
141
src/test/java/com/commafeed/backend/opml/OPMLExporterTest.java
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
package com.commafeed.backend.opml;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
|
import com.commafeed.backend.dao.FeedCategoryDAO;
|
||||||
|
import com.commafeed.backend.dao.FeedSubscriptionDAO;
|
||||||
|
import com.commafeed.backend.model.Feed;
|
||||||
|
import com.commafeed.backend.model.FeedCategory;
|
||||||
|
import com.commafeed.backend.model.FeedSubscription;
|
||||||
|
import com.commafeed.backend.model.User;
|
||||||
|
import com.rometools.opml.feed.opml.Opml;
|
||||||
|
import com.rometools.opml.feed.opml.Outline;
|
||||||
|
|
||||||
|
public class OPMLExporterTest {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private FeedCategoryDAO feedCategoryDAO;
|
||||||
|
@Mock
|
||||||
|
private FeedSubscriptionDAO feedSubscriptionDAO;
|
||||||
|
|
||||||
|
private User user = new User();
|
||||||
|
|
||||||
|
private FeedCategory cat1 = new FeedCategory();
|
||||||
|
private FeedCategory cat2 = new FeedCategory();
|
||||||
|
|
||||||
|
private FeedSubscription rootFeed = newFeedSubscription("rootFeed", "rootFeed.com");
|
||||||
|
private FeedSubscription cat1Feed = newFeedSubscription("cat1Feed", "cat1Feed.com");
|
||||||
|
private FeedSubscription cat2Feed = newFeedSubscription("cat2Feed", "cat2Feed.com");
|
||||||
|
|
||||||
|
private List<FeedCategory> categories = new ArrayList<>();
|
||||||
|
private List<FeedSubscription> subscriptions = new ArrayList<>();
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void before_each_test() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
|
||||||
|
user.setName("John Doe");
|
||||||
|
|
||||||
|
cat1.setId(1l);
|
||||||
|
cat1.setName("cat1");
|
||||||
|
cat1.setParent(null);
|
||||||
|
cat1.setChildren(new HashSet<FeedCategory>());
|
||||||
|
cat1.setSubscriptions(new HashSet<FeedSubscription>());
|
||||||
|
|
||||||
|
cat2.setId(2l);
|
||||||
|
cat2.setName("cat2");
|
||||||
|
cat2.setParent(cat1);
|
||||||
|
cat2.setChildren(new HashSet<FeedCategory>());
|
||||||
|
cat2.setSubscriptions(new HashSet<FeedSubscription>());
|
||||||
|
|
||||||
|
cat1.getChildren().add(cat2);
|
||||||
|
|
||||||
|
rootFeed.setCategory(null);
|
||||||
|
cat1Feed.setCategory(cat1);
|
||||||
|
cat2Feed.setCategory(cat2);
|
||||||
|
|
||||||
|
cat1.getSubscriptions().add(cat1Feed);
|
||||||
|
cat2.getSubscriptions().add(cat2Feed);
|
||||||
|
|
||||||
|
categories.add(cat1);
|
||||||
|
categories.add(cat2);
|
||||||
|
|
||||||
|
subscriptions.add(rootFeed);
|
||||||
|
subscriptions.add(cat1Feed);
|
||||||
|
subscriptions.add(cat2Feed);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Feed newFeed(String url) {
|
||||||
|
Feed feed = new Feed();
|
||||||
|
feed.setUrl(url);
|
||||||
|
return feed;
|
||||||
|
}
|
||||||
|
|
||||||
|
private FeedSubscription newFeedSubscription(String title, String url) {
|
||||||
|
FeedSubscription feedSubscription = new FeedSubscription();
|
||||||
|
feedSubscription.setTitle(title);
|
||||||
|
feedSubscription.setFeed(newFeed(url));
|
||||||
|
return feedSubscription;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void generates_OPML_correctly() {
|
||||||
|
when(feedCategoryDAO.findAll(user)).thenReturn(categories);
|
||||||
|
when(feedSubscriptionDAO.findAll(user)).thenReturn(subscriptions);
|
||||||
|
|
||||||
|
Opml opml = new OPMLExporter(feedCategoryDAO, feedSubscriptionDAO).export(user);
|
||||||
|
|
||||||
|
List<Outline> rootOutlines = opml.getOutlines();
|
||||||
|
assertEquals(2, rootOutlines.size());
|
||||||
|
assertTrue(containsCategory(rootOutlines, "cat1"));
|
||||||
|
assertTrue(containsFeed(rootOutlines, "rootFeed", "rootFeed.com"));
|
||||||
|
|
||||||
|
Outline cat1Outline = getCategoryOutline(rootOutlines, "cat1");
|
||||||
|
List<Outline> cat1Children = cat1Outline.getChildren();
|
||||||
|
assertEquals(2, cat1Children.size());
|
||||||
|
assertTrue(containsCategory(cat1Children, "cat2"));
|
||||||
|
assertTrue(containsFeed(cat1Children, "cat1Feed", "cat1Feed.com"));
|
||||||
|
|
||||||
|
Outline cat2Outline = getCategoryOutline(cat1Children, "cat2");
|
||||||
|
List<Outline> cat2Children = cat2Outline.getChildren();
|
||||||
|
assertEquals(1, cat2Children.size());
|
||||||
|
assertTrue(containsFeed(cat2Children, "cat2Feed", "cat2Feed.com"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean containsCategory(List<Outline> outlines, String category) {
|
||||||
|
for (Outline o : outlines)
|
||||||
|
if (!"rss".equals(o.getType()))
|
||||||
|
if (category.equals(o.getTitle()))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean containsFeed(List<Outline> outlines, String title, String url) {
|
||||||
|
for (Outline o : outlines)
|
||||||
|
if ("rss".equals(o.getType()))
|
||||||
|
if (title.equals(o.getTitle()) && o.getAttributeValue("xmlUrl").equals(url))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Outline getCategoryOutline(List<Outline> outlines, String title) {
|
||||||
|
for (Outline o : outlines)
|
||||||
|
if (o.getTitle().equals(title))
|
||||||
|
return o;
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user