diff --git a/src/main/java/com/commafeed/backend/dao/FeedEntryService.java b/src/main/java/com/commafeed/backend/dao/FeedEntryService.java index 6b8e23f4..63b33a2c 100644 --- a/src/main/java/com/commafeed/backend/dao/FeedEntryService.java +++ b/src/main/java/com/commafeed/backend/dao/FeedEntryService.java @@ -9,6 +9,7 @@ import javax.inject.Inject; import javax.persistence.Query; import javax.persistence.TypedQuery; +import org.apache.commons.lang.ObjectUtils; import org.apache.commons.lang.StringUtils; import com.commafeed.backend.model.Feed; @@ -39,17 +40,30 @@ public class FeedEntryService extends GenericDAO { List existingEntries = getByGuids(guids); for (FeedEntry entry : entries) { - boolean found = false; + FeedEntry foundEntry = null; for (FeedEntry existingEntry : existingEntries) { if (StringUtils .equals(entry.getGuid(), existingEntry.getGuid())) { - found = true; + foundEntry = existingEntry; break; } } - if (!found) { - entry.setFeed(feed); + if (foundEntry == null) { + entry.getFeeds().add(feed); save(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); + update(foundEntry); + } } } diff --git a/src/main/java/com/commafeed/backend/model/Feed.java b/src/main/java/com/commafeed/backend/model/Feed.java index 378f62fc..6e57b1a6 100644 --- a/src/main/java/com/commafeed/backend/model/Feed.java +++ b/src/main/java/com/commafeed/backend/model/Feed.java @@ -5,6 +5,7 @@ import java.util.Set; import javax.persistence.Column; import javax.persistence.Entity; +import javax.persistence.ManyToMany; import javax.persistence.OneToMany; import javax.persistence.Table; import javax.persistence.Temporal; @@ -33,7 +34,7 @@ public class Feed extends AbstractModel { @Column(length = 1024) private String message; - @OneToMany(mappedBy = "feed") + @ManyToMany(mappedBy = "feeds") private Set entries = Sets.newHashSet(); @OneToMany(mappedBy = "feed") diff --git a/src/main/java/com/commafeed/backend/model/FeedEntry.java b/src/main/java/com/commafeed/backend/model/FeedEntry.java index 372f5b9c..32489886 100644 --- a/src/main/java/com/commafeed/backend/model/FeedEntry.java +++ b/src/main/java/com/commafeed/backend/model/FeedEntry.java @@ -5,9 +5,11 @@ import java.util.Set; import javax.persistence.Column; import javax.persistence.Entity; +import javax.persistence.FetchType; import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; import javax.persistence.Lob; -import javax.persistence.ManyToOne; +import javax.persistence.ManyToMany; import javax.persistence.OneToMany; import javax.persistence.Table; import javax.persistence.Temporal; @@ -15,6 +17,8 @@ import javax.persistence.TemporalType; import org.hibernate.annotations.Index; +import com.google.api.client.util.Sets; + @Entity @Table(name = "FEEDENTRIES") @SuppressWarnings("serial") @@ -23,9 +27,9 @@ public class FeedEntry extends AbstractModel { @Column(length = 2048, nullable = false) private String guid; - @ManyToOne - @JoinColumn(nullable = false) - private Feed feed; + @ManyToMany(fetch = FetchType.EAGER) + @JoinTable(name = "FEED_FEEDENTRIES", joinColumns = { @JoinColumn(name = "FEED_ID", nullable = false, updatable = false) }, inverseJoinColumns = { @JoinColumn(name = "FEEDENTRY_ID", nullable = false, updatable = false) }) + private Set feeds = Sets.newHashSet(); @Column(length = 2048) private String title; @@ -84,12 +88,12 @@ public class FeedEntry extends AbstractModel { this.updated = updated; } - public Feed getFeed() { - return feed; + public Set getFeeds() { + return feeds; } - public void setFeed(Feed feed) { - this.feed = feed; + public void setFeeds(Set feeds) { + this.feeds = feeds; } public Set getStatuses() { diff --git a/src/main/java/com/commafeed/frontend/rest/resources/EntriesREST.java b/src/main/java/com/commafeed/frontend/rest/resources/EntriesREST.java index 9d37cee8..cb5779eb 100644 --- a/src/main/java/com/commafeed/frontend/rest/resources/EntriesREST.java +++ b/src/main/java/com/commafeed/frontend/rest/resources/EntriesREST.java @@ -103,8 +103,14 @@ public class EntriesREST extends AbstractREST { List unreadEntries = feedEntryService.getEntries( getUser(), unreadOnly, offset, limit); for (FeedEntryWithStatus feedEntry : unreadEntries) { - Long id = feedEntry.getEntry().getFeed().getId(); - entries.add(populateEntry(buildEntry(feedEntry), subMapping.get(id))); + FeedSubscription sub = null; + for (Feed feed : feedEntry.getEntry().getFeeds()) { + sub = subMapping.get(feed.getId()); + if (sub != null) { + break; + } + } + entries.add(populateEntry(buildEntry(feedEntry), sub)); } return entries; @@ -131,8 +137,14 @@ public class EntriesREST extends AbstractREST { List unreadEntries = feedEntryService.getEntries( categories, getUser(), unreadOnly, offset, limit); for (FeedEntryWithStatus feedEntry : unreadEntries) { - Long id = feedEntry.getEntry().getFeed().getId(); - entries.add(populateEntry(buildEntry(feedEntry), subMapping.get(id))); + FeedSubscription sub = null; + for (Feed feed : feedEntry.getEntry().getFeeds()) { + sub = subMapping.get(feed.getId()); + if (sub != null) { + break; + } + } + entries.add(populateEntry(buildEntry(feedEntry), sub)); } return entries; @@ -253,8 +265,14 @@ public class EntriesREST extends AbstractREST { List entriesWithStatus = feedEntryService .getEntriesByKeywords(getUser(), keywords); for (FeedEntryWithStatus feedEntry : entriesWithStatus) { - Long id = feedEntry.getEntry().getFeed().getId(); - list.add(populateEntry(buildEntry(feedEntry), subMapping.get(id))); + FeedSubscription sub = null; + for (Feed feed : feedEntry.getEntry().getFeeds()) { + sub = subMapping.get(feed.getId()); + if (sub != null) { + break; + } + } + list.add(populateEntry(buildEntry(feedEntry), sub)); } entries.setName("Search for : " + keywords); diff --git a/src/main/resources/META-INF/orm.xml b/src/main/resources/META-INF/orm.xml index 1af3d39e..66308fc8 100644 --- a/src/main/resources/META-INF/orm.xml +++ b/src/main/resources/META-INF/orm.xml @@ -14,30 +14,30 @@ - select e, s from FeedEntry e LEFT JOIN e.statuses s WITH (s.user.id=:userId) where exists (select s2 from FeedSubscription s2 where s2.user=:user and s2.feed = e.feed) and not exists (select s3 from FeedEntryStatus s3 where s3.entry = e and s3.user =:user and s3.read=true) order by e.updated desc + select e, s from FeedEntry e LEFT JOIN e.statuses s WITH (s.user.id=:userId) where exists (select s2 from FeedSubscription s2 where s2.user=:user and s2.feed member of e.feeds) and not exists (select s3 from FeedEntryStatus s3 where s3.entry = e and s3.user =:user and s3.read=true) order by e.updated desc - select e, s from FeedEntry e LEFT JOIN e.statuses s WITH (s.user.id=:userId) where exists (select s2 from FeedSubscription s2 where s2.user=:user and s2.feed = e.feed) order by e.updated desc + select e, s from FeedEntry e LEFT JOIN e.statuses s WITH (s.user.id=:userId) where exists (select s2 from FeedSubscription s2 where s2.user=:user and s2.feed member of e.feeds) order by e.updated desc - select e, s from FeedEntry e LEFT JOIN e.statuses s WITH (s.user.id=:userId) where e.feed=:feed and not exists (select s2 from FeedEntryStatus s2 where s2.entry=e and s2.user.id=:userId and s2.read=true) order by e.updated desc + select e, s from FeedEntry e LEFT JOIN e.statuses s WITH (s.user.id=:userId) where :feed member of e.feeds and not exists (select s2 from FeedEntryStatus s2 where s2.entry=e and s2.user.id=:userId and s2.read=true) order by e.updated desc - select count(e) from FeedEntry e LEFT JOIN e.statuses s WITH (s.user.id=:userId) where e.feed=:feed and not exists (select s2 from FeedEntryStatus s2 where s2.entry=e and s2.user.id=:userId and s2.read=true) + select count(e) from FeedEntry e LEFT JOIN e.statuses s WITH (s.user.id=:userId) where :feed member of e.feeds and not exists (select s2 from FeedEntryStatus s2 where s2.entry=e and s2.user.id=:userId and s2.read=true) - select e, s from FeedEntry e LEFT JOIN e.statuses s WITH (s.user.id=:userId) where e.feed=:feed order by e.updated desc + select e, s from FeedEntry e LEFT JOIN e.statuses s WITH (s.user.id=:userId) where :feed member of e.feeds order by e.updated desc - select e, s from FeedEntry e LEFT JOIN e.statuses s WITH (s.user.id=:userId) where exists (select s2 from FeedSubscription s2 where s2.user=:user and s2.feed = e.feed and s2.category in (:categories) ) and not exists (select s3 from FeedEntryStatus s3 where s3.entry = e and s3.user =:user and s3.read=true) order by e.updated desc + select e, s from FeedEntry e LEFT JOIN e.statuses s WITH (s.user.id=:userId) where exists (select s2 from FeedSubscription s2 where s2.user=:user and s2.feed member of e.feeds and s2.category in (:categories) ) and not exists (select s3 from FeedEntryStatus s3 where s3.entry = e and s3.user =:user and s3.read=true) order by e.updated desc - select e, s from FeedEntry e LEFT JOIN e.statuses s WITH (s.user.id=:userId) where exists (select s2 from FeedSubscription s2 where s2.user=:user and s2.feed = e.feed and s2.category in (:categories) ) order by e.updated desc + select e, s from FeedEntry e LEFT JOIN e.statuses s WITH (s.user.id=:userId) where exists (select s2 from FeedSubscription s2 where s2.user=:user and s2.feed member of e.feeds and s2.category in (:categories) ) order by e.updated desc - select e, s from FeedEntry e LEFT JOIN e.statuses s WITH (s.user.id=:userId) where exists (select s2 from FeedSubscription s2 where s2.user=:user and s2.feed = e.feed) and (lower(e.content) like :keywords or lower(e.title) like :keywords) order by e.updated desc + select e, s from FeedEntry e LEFT JOIN e.statuses s WITH (s.user.id=:userId) where exists (select s2 from FeedSubscription s2 where s2.user=:user and s2.feed member of e.feeds) and (lower(e.content) like :keywords or lower(e.title) like :keywords) order by e.updated desc \ No newline at end of file diff --git a/src/main/webapp/js/controllers.js b/src/main/webapp/js/controllers.js index 15bf642b..e29f7e4d 100644 --- a/src/main/webapp/js/controllers.js +++ b/src/main/webapp/js/controllers.js @@ -88,7 +88,7 @@ module.controller('CategoryTreeCtrl', function($scope, $timeout, $stateParams, $timeout(function refreshTree() { SubscriptionService.init(function() { - $timeout(refreshTree, 30000); + $timeout(refreshTree, 15000); }); }, 30000); diff --git a/src/main/webapp/js/directives.js b/src/main/webapp/js/directives.js index 7737790f..cf35441f 100644 --- a/src/main/webapp/js/directives.js +++ b/src/main/webapp/js/directives.js @@ -20,21 +20,21 @@ module.directive('scrollTo', function($timeout) { return; $timeout(function() { var docTop = $(window).scrollTop(); - var docBottom = docTop + $(window).height(); - - var elemTop = $(element).offset().top; - var elemBottom = elemTop + $(element).height(); - - if ((elemTop > docTop) && (elemBottom < docBottom)) { - // element is entirely visible - return; - } else { - var offset = parseInt(attrs.scrollToOffset, 10); - var scrollTop = $(element).offset().top + offset; - $('html, body').animate({ - scrollTop : scrollTop - }, 0); - } + var docBottom = docTop + $(window).height(); + + var elemTop = $(element).offset().top; + var elemBottom = elemTop + $(element).height(); + + if ((elemTop > docTop) && (elemBottom < docBottom)) { + // element is entirely visible + return; + } else { + var offset = parseInt(attrs.scrollToOffset, 10); + var scrollTop = $(element).offset().top + offset; + $('html, body').animate({ + scrollTop : scrollTop + }, 0); + } }); }); }