forked from Archives/Athou_commafeed
major improvement in the way data is stored
This commit is contained in:
@@ -19,7 +19,11 @@ import com.uaihebert.model.EasyCriteria;
|
|||||||
public class FeedCategoryService extends GenericDAO<FeedCategory> {
|
public class FeedCategoryService extends GenericDAO<FeedCategory> {
|
||||||
|
|
||||||
public List<FeedCategory> findAll(User user) {
|
public List<FeedCategory> findAll(User user) {
|
||||||
return findByField(MF.i(MF.p(FeedCategory.class).getUser()), user);
|
EasyCriteria<FeedCategory> criteria = createCriteria();
|
||||||
|
criteria.andEquals(MF.i(proxy().getUser()), user);
|
||||||
|
|
||||||
|
criteria.innerJoinFetch(MF.i(proxy().getUser()));
|
||||||
|
return criteria.getResultList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public FeedCategory findById(User user, Long id) {
|
public FeedCategory findById(User user, Long id) {
|
||||||
|
|||||||
@@ -3,27 +3,19 @@ package com.commafeed.backend.dao;
|
|||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import javax.ejb.Stateless;
|
import javax.ejb.Stateless;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.persistence.Query;
|
|
||||||
import javax.persistence.TypedQuery;
|
import javax.persistence.TypedQuery;
|
||||||
|
|
||||||
import org.apache.commons.lang.ObjectUtils;
|
import org.apache.commons.lang.ObjectUtils;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
|
||||||
import com.commafeed.backend.model.Feed;
|
import com.commafeed.backend.model.Feed;
|
||||||
import com.commafeed.backend.model.FeedCategory;
|
|
||||||
import com.commafeed.backend.model.FeedEntry;
|
import com.commafeed.backend.model.FeedEntry;
|
||||||
import com.commafeed.backend.model.FeedEntryStatus;
|
import com.commafeed.backend.model.FeedEntryStatus;
|
||||||
import com.commafeed.backend.model.FeedSubscription;
|
import com.commafeed.backend.model.FeedSubscription;
|
||||||
import com.commafeed.backend.model.User;
|
|
||||||
import com.commafeed.backend.model.extended.FeedEntryWithStatus;
|
|
||||||
import com.commafeed.frontend.utils.ModelFactory.MF;
|
|
||||||
import com.google.common.collect.Iterables;
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Sets;
|
|
||||||
|
|
||||||
@Stateless
|
@Stateless
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
@@ -36,9 +28,7 @@ public class FeedEntryService extends GenericDAO<FeedEntry> {
|
|||||||
FeedSubscriptionService feedSubscriptionService;
|
FeedSubscriptionService feedSubscriptionService;
|
||||||
|
|
||||||
public void updateEntries(String url, Collection<FeedEntry> entries) {
|
public void updateEntries(String url, Collection<FeedEntry> entries) {
|
||||||
Feed feed = Iterables.getFirst(
|
Feed feed = feedService.findByUrl(url);
|
||||||
feedService.findByField(MF.i(MF.p(Feed.class).getUrl()), url),
|
|
||||||
null);
|
|
||||||
List<String> guids = Lists.newArrayList();
|
List<String> guids = Lists.newArrayList();
|
||||||
for (FeedEntry entry : entries) {
|
for (FeedEntry entry : entries) {
|
||||||
guids.add(entry.getGuid());
|
guids.add(entry.getGuid());
|
||||||
@@ -56,7 +46,6 @@ public class FeedEntryService extends GenericDAO<FeedEntry> {
|
|||||||
}
|
}
|
||||||
if (foundEntry == null) {
|
if (foundEntry == null) {
|
||||||
addFeedToEntry(entry, feed);
|
addFeedToEntry(entry, feed);
|
||||||
save(entry);
|
|
||||||
} else {
|
} else {
|
||||||
boolean foundFeed = false;
|
boolean foundFeed = false;
|
||||||
for (Feed existingFeed : foundEntry.getFeeds()) {
|
for (Feed existingFeed : foundEntry.getFeeds()) {
|
||||||
@@ -68,7 +57,6 @@ public class FeedEntryService extends GenericDAO<FeedEntry> {
|
|||||||
|
|
||||||
if (!foundFeed) {
|
if (!foundFeed) {
|
||||||
addFeedToEntry(foundEntry, feed);
|
addFeedToEntry(foundEntry, feed);
|
||||||
update(foundEntry);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -80,12 +68,13 @@ public class FeedEntryService extends GenericDAO<FeedEntry> {
|
|||||||
|
|
||||||
private void addFeedToEntry(FeedEntry entry, Feed feed) {
|
private void addFeedToEntry(FeedEntry entry, Feed feed) {
|
||||||
entry.getFeeds().add(feed);
|
entry.getFeeds().add(feed);
|
||||||
|
saveOrUpdate(entry);
|
||||||
List<FeedSubscription> subscriptions = feedSubscriptionService
|
List<FeedSubscription> subscriptions = feedSubscriptionService
|
||||||
.findByFeed(feed);
|
.findByFeed(feed);
|
||||||
for (FeedSubscription sub : subscriptions) {
|
for (FeedSubscription sub : subscriptions) {
|
||||||
FeedEntryStatus status = new FeedEntryStatus();
|
FeedEntryStatus status = new FeedEntryStatus();
|
||||||
status.setEntry(entry);
|
status.setEntry(entry);
|
||||||
status.setUser(sub.getUser());
|
status.setSubscription(sub);
|
||||||
em.persist(status);
|
em.persist(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,123 +87,4 @@ public class FeedEntryService extends GenericDAO<FeedEntry> {
|
|||||||
return query.getResultList();
|
return query.getResultList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<FeedEntryWithStatus> getEntriesByKeywords(User user,
|
|
||||||
String keywords) {
|
|
||||||
return getEntriesByKeywords(user, keywords, -1, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<FeedEntryWithStatus> getEntriesByKeywords(User user,
|
|
||||||
String keywords, int offset, int limit) {
|
|
||||||
Query query = em.createNamedQuery("Entry.allByKeywords");
|
|
||||||
query.setParameter("userId", user.getId());
|
|
||||||
query.setParameter("user", user);
|
|
||||||
|
|
||||||
String joinedKeywords = StringUtils.join(
|
|
||||||
keywords.toLowerCase().split(" "), "%");
|
|
||||||
query.setParameter("keywords", "%" + joinedKeywords + "%");
|
|
||||||
if (offset > -1) {
|
|
||||||
query.setFirstResult(offset);
|
|
||||||
}
|
|
||||||
if (limit > -1) {
|
|
||||||
query.setMaxResults(limit);
|
|
||||||
}
|
|
||||||
return buildList(query.getResultList());
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<FeedEntryWithStatus> getEntries(User user, boolean unreadOnly) {
|
|
||||||
return getEntries(user, unreadOnly, -1, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<FeedEntryWithStatus> getEntries(User user, boolean unreadOnly,
|
|
||||||
int offset, int limit) {
|
|
||||||
String queryName = null;
|
|
||||||
if (unreadOnly) {
|
|
||||||
queryName = "Entry.unread";
|
|
||||||
} else {
|
|
||||||
queryName = "Entry.all";
|
|
||||||
}
|
|
||||||
Query query = em.createNamedQuery(queryName);
|
|
||||||
query.setParameter("userId", user.getId());
|
|
||||||
query.setParameter("user", user);
|
|
||||||
if (offset > -1) {
|
|
||||||
query.setFirstResult(offset);
|
|
||||||
}
|
|
||||||
if (limit > -1) {
|
|
||||||
query.setMaxResults(limit);
|
|
||||||
}
|
|
||||||
return buildList(query.getResultList());
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getUnreadCount(Feed feed, User user) {
|
|
||||||
TypedQuery<Long> query = em.createNamedQuery("Entry.unreadByFeedCount",
|
|
||||||
Long.class);
|
|
||||||
query.setParameter("feed", feed);
|
|
||||||
query.setParameter("userId", user.getId());
|
|
||||||
return query.getSingleResult();
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<FeedEntryWithStatus> getEntries(Feed feed, User user,
|
|
||||||
boolean unreadOnly) {
|
|
||||||
return getEntries(feed, user, unreadOnly, -1, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<FeedEntryWithStatus> getEntries(Feed feed, User user,
|
|
||||||
boolean unreadOnly, int offset, int limit) {
|
|
||||||
String queryName = null;
|
|
||||||
if (unreadOnly) {
|
|
||||||
queryName = "Entry.unreadByFeed";
|
|
||||||
} else {
|
|
||||||
queryName = "Entry.allByFeed";
|
|
||||||
}
|
|
||||||
Query query = em.createNamedQuery(queryName);
|
|
||||||
query.setParameter("feed", feed);
|
|
||||||
query.setParameter("userId", user.getId());
|
|
||||||
if (offset > -1) {
|
|
||||||
query.setFirstResult(offset);
|
|
||||||
}
|
|
||||||
if (limit > -1) {
|
|
||||||
query.setMaxResults(limit);
|
|
||||||
}
|
|
||||||
|
|
||||||
return buildList(query.getResultList());
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<FeedEntryWithStatus> getEntries(List<FeedCategory> categories,
|
|
||||||
User user, boolean unreadOnly) {
|
|
||||||
return getEntries(categories, user, unreadOnly, -1, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<FeedEntryWithStatus> getEntries(List<FeedCategory> categories,
|
|
||||||
User user, boolean unreadOnly, int offset, int limit) {
|
|
||||||
String queryName = null;
|
|
||||||
if (unreadOnly) {
|
|
||||||
queryName = "Entry.unreadByCategories";
|
|
||||||
} else {
|
|
||||||
queryName = "Entry.allByCategories";
|
|
||||||
}
|
|
||||||
Query query = em.createNamedQuery(queryName);
|
|
||||||
query.setParameter("categories", categories);
|
|
||||||
query.setParameter("userId", user.getId());
|
|
||||||
query.setParameter("user", user);
|
|
||||||
if (offset > -1) {
|
|
||||||
query.setFirstResult(offset);
|
|
||||||
}
|
|
||||||
if (limit > -1) {
|
|
||||||
query.setMaxResults(limit);
|
|
||||||
}
|
|
||||||
return buildList(query.getResultList());
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("rawtypes")
|
|
||||||
private List<FeedEntryWithStatus> buildList(List list) {
|
|
||||||
Set<FeedEntryWithStatus> result = Sets.newLinkedHashSet();
|
|
||||||
for (Object object : list) {
|
|
||||||
Object[] array = (Object[]) object;
|
|
||||||
FeedEntry entry = (FeedEntry) array[0];
|
|
||||||
FeedEntryStatus status = (FeedEntryStatus) array[1];
|
|
||||||
FeedEntryWithStatus fews = new FeedEntryWithStatus(entry, status);
|
|
||||||
result.add(fews);
|
|
||||||
}
|
|
||||||
return Lists.newArrayList(result);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,37 +1,172 @@
|
|||||||
package com.commafeed.backend.dao;
|
package com.commafeed.backend.dao;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.ejb.Stateless;
|
import javax.ejb.Stateless;
|
||||||
|
import javax.inject.Inject;
|
||||||
import javax.persistence.NoResultException;
|
import javax.persistence.NoResultException;
|
||||||
|
import javax.persistence.Query;
|
||||||
|
import javax.persistence.TypedQuery;
|
||||||
|
|
||||||
import com.commafeed.backend.model.FeedEntry;
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
|
||||||
|
import com.commafeed.backend.model.Feed;
|
||||||
|
import com.commafeed.backend.model.FeedCategory;
|
||||||
import com.commafeed.backend.model.FeedEntryStatus;
|
import com.commafeed.backend.model.FeedEntryStatus;
|
||||||
import com.commafeed.backend.model.User;
|
import com.commafeed.backend.model.User;
|
||||||
import com.commafeed.frontend.utils.ModelFactory.MF;
|
import com.google.api.client.util.Lists;
|
||||||
import com.uaihebert.factory.EasyCriteriaFactory;
|
import com.google.api.client.util.Maps;
|
||||||
import com.uaihebert.model.EasyCriteria;
|
|
||||||
|
|
||||||
@Stateless
|
@Stateless
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public class FeedEntryStatusService extends GenericDAO<FeedEntryStatus> {
|
public class FeedEntryStatusService extends GenericDAO<FeedEntryStatus> {
|
||||||
|
|
||||||
public List<FeedEntryStatus> findAll(User user) {
|
@Inject
|
||||||
return findByField(MF.i(proxy().getUser()), user);
|
FeedCategoryService feedCategoryService;
|
||||||
}
|
|
||||||
|
|
||||||
public FeedEntryStatus getStatus(User user, FeedEntry entry) {
|
public FeedEntryStatus findById(User user, Long id) {
|
||||||
EasyCriteria<FeedEntryStatus> criteria = EasyCriteriaFactory
|
TypedQuery<FeedEntryStatus> query = em.createNamedQuery(
|
||||||
.createQueryCriteria(em, getType());
|
"EntryStatus.byId", FeedEntryStatus.class);
|
||||||
criteria.andEquals(MF.i(proxy().getUser()), user);
|
query.setParameter("user", user);
|
||||||
criteria.andEquals(MF.i(proxy().getEntry()), entry);
|
query.setParameter("id", id);
|
||||||
|
|
||||||
FeedEntryStatus status = null;
|
FeedEntryStatus status = null;
|
||||||
try {
|
try {
|
||||||
status = criteria.getSingleResult();
|
status = query.getSingleResult();
|
||||||
} catch (NoResultException e) {
|
} catch (NoResultException e) {
|
||||||
status = null;
|
status = null;
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<FeedEntryStatus> getStatusesByKeywords(User user,
|
||||||
|
String keywords) {
|
||||||
|
return getStatusesByKeywords(user, keywords, -1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<FeedEntryStatus> getStatusesByKeywords(User user,
|
||||||
|
String keywords, int offset, int limit) {
|
||||||
|
TypedQuery<FeedEntryStatus> query = em.createNamedQuery(
|
||||||
|
"EntryStatus.allByKeywords", FeedEntryStatus.class);
|
||||||
|
query.setParameter("user", user);
|
||||||
|
|
||||||
|
String joinedKeywords = StringUtils.join(
|
||||||
|
keywords.toLowerCase().split(" "), "%");
|
||||||
|
query.setParameter("keywords", "%" + joinedKeywords + "%");
|
||||||
|
if (offset > -1) {
|
||||||
|
query.setFirstResult(offset);
|
||||||
|
}
|
||||||
|
if (limit > -1) {
|
||||||
|
query.setMaxResults(limit);
|
||||||
|
}
|
||||||
|
return query.getResultList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<FeedEntryStatus> getStatuses(User user, boolean unreadOnly) {
|
||||||
|
return getStatuses(user, unreadOnly, -1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<FeedEntryStatus> getStatuses(User user, boolean unreadOnly,
|
||||||
|
int offset, int limit) {
|
||||||
|
String queryName = unreadOnly ? "EntryStatus.unread"
|
||||||
|
: "EntryStatus.all";
|
||||||
|
TypedQuery<FeedEntryStatus> query = em.createNamedQuery(queryName,
|
||||||
|
FeedEntryStatus.class);
|
||||||
|
query.setParameter("user", user);
|
||||||
|
if (offset > -1) {
|
||||||
|
query.setFirstResult(offset);
|
||||||
|
}
|
||||||
|
if (limit > -1) {
|
||||||
|
query.setMaxResults(limit);
|
||||||
|
}
|
||||||
|
return query.getResultList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map between subscriptionId and unread count
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
public Map<Long, Long> getUnreadCount(User user) {
|
||||||
|
Map<Long, Long> map = Maps.newHashMap();
|
||||||
|
Query query = em.createNamedQuery("EntryStatus.unreadCounts");
|
||||||
|
query.setParameter("user", user);
|
||||||
|
List resultList = query.getResultList();
|
||||||
|
for (Object o : resultList) {
|
||||||
|
Object[] array = (Object[]) o;
|
||||||
|
map.put((Long) array[0], (Long) array[1]);
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<FeedEntryStatus> getStatuses(Feed feed, User user,
|
||||||
|
boolean unreadOnly) {
|
||||||
|
return getStatuses(feed, user, unreadOnly, -1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<FeedEntryStatus> getStatuses(Feed feed, User user,
|
||||||
|
boolean unreadOnly, int offset, int limit) {
|
||||||
|
String queryName = unreadOnly ? "EntryStatus.unreadByFeed"
|
||||||
|
: "EntryStatus.allByFeed";
|
||||||
|
TypedQuery<FeedEntryStatus> query = em.createNamedQuery(queryName,
|
||||||
|
FeedEntryStatus.class);
|
||||||
|
query.setParameter("feed", feed);
|
||||||
|
query.setParameter("user", user);
|
||||||
|
if (offset > -1) {
|
||||||
|
query.setFirstResult(offset);
|
||||||
|
}
|
||||||
|
if (limit > -1) {
|
||||||
|
query.setMaxResults(limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
return query.getResultList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<FeedEntryStatus> getStatuses(List<FeedCategory> categories,
|
||||||
|
User user, boolean unreadOnly) {
|
||||||
|
return getStatuses(categories, user, unreadOnly, -1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<FeedEntryStatus> getStatuses(List<FeedCategory> categories,
|
||||||
|
User user, boolean unreadOnly, int offset, int limit) {
|
||||||
|
String queryName = unreadOnly ? "EntryStatus.unreadByCategories"
|
||||||
|
: "EntryStatus.allByCategories";
|
||||||
|
TypedQuery<FeedEntryStatus> query = em.createNamedQuery(queryName,
|
||||||
|
FeedEntryStatus.class);
|
||||||
|
query.setParameter("categories", categories);
|
||||||
|
query.setParameter("user", user);
|
||||||
|
if (offset > -1) {
|
||||||
|
query.setFirstResult(offset);
|
||||||
|
}
|
||||||
|
if (limit > -1) {
|
||||||
|
query.setMaxResults(limit);
|
||||||
|
}
|
||||||
|
return query.getResultList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void markFeedEntries(User user, Feed feed) {
|
||||||
|
List<FeedEntryStatus> statuses = getStatuses(feed, user, true);
|
||||||
|
update(markList(statuses));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void markCategoryEntries(User user, List<FeedCategory> categories) {
|
||||||
|
List<FeedEntryStatus> statuses = getStatuses(categories, user, true);
|
||||||
|
update(markList(statuses));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void markAllEntries(User user) {
|
||||||
|
List<FeedEntryStatus> statuses = getStatuses(user, true);
|
||||||
|
update(markList(statuses));
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<FeedEntryStatus> markList(List<FeedEntryStatus> statuses) {
|
||||||
|
List<FeedEntryStatus> list = Lists.newArrayList();
|
||||||
|
for (FeedEntryStatus status : statuses) {
|
||||||
|
if (!status.isRead()) {
|
||||||
|
status.setRead(true);
|
||||||
|
list.add(status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,13 @@ public class FeedSubscriptionService extends GenericDAO<FeedSubscription> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public List<FeedSubscription> findAll(User user) {
|
public List<FeedSubscription> findAll(User user) {
|
||||||
return findByField(MF.i(proxy().getUser()), user);
|
EasyCriteria<FeedSubscription> criteria = createCriteria();
|
||||||
|
criteria.andEquals(MF.i(proxy().getUser()), user);
|
||||||
|
|
||||||
|
criteria.innerJoinFetch(MF.i(proxy().getFeed()));
|
||||||
|
criteria.innerJoinFetch(MF.i(proxy().getUser()));
|
||||||
|
criteria.leftJoinFetch(MF.i(proxy().getCategory()));
|
||||||
|
return criteria.getResultList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<FeedSubscription> findWithoutCategories(User user) {
|
public List<FeedSubscription> findWithoutCategories(User user) {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.commafeed.backend.dao;
|
package com.commafeed.backend.dao;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
@@ -37,12 +38,16 @@ public abstract class GenericDAO<T extends AbstractModel> implements
|
|||||||
em.persist(object);
|
em.persist(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update(T... objects) {
|
public void update(List<T> objects) {
|
||||||
for (Object object : objects) {
|
for (Object object : objects) {
|
||||||
em.merge(object);
|
em.merge(object);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void update(T... objects) {
|
||||||
|
update(Arrays.asList(objects));
|
||||||
|
}
|
||||||
|
|
||||||
public void saveOrUpdate(AbstractModel m) {
|
public void saveOrUpdate(AbstractModel m) {
|
||||||
if (m.getId() == null) {
|
if (m.getId() == null) {
|
||||||
em.persist(m);
|
em.persist(m);
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ public class FeedEntryStatus extends AbstractModel {
|
|||||||
|
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
@JoinColumn(nullable = false)
|
@JoinColumn(nullable = false)
|
||||||
private User user;
|
private FeedSubscription subscription;
|
||||||
|
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
@JoinColumn(nullable = false)
|
@JoinColumn(nullable = false)
|
||||||
@@ -23,12 +23,12 @@ public class FeedEntryStatus extends AbstractModel {
|
|||||||
private boolean read;
|
private boolean read;
|
||||||
private boolean starred;
|
private boolean starred;
|
||||||
|
|
||||||
public User getUser() {
|
public FeedSubscription getSubscription() {
|
||||||
return user;
|
return subscription;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUser(User user) {
|
public void setSubscription(FeedSubscription subscription) {
|
||||||
this.user = user;
|
this.subscription = subscription;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FeedEntry getEntry() {
|
public FeedEntry getEntry() {
|
||||||
|
|||||||
@@ -1,59 +0,0 @@
|
|||||||
package com.commafeed.backend.model.extended;
|
|
||||||
|
|
||||||
import org.apache.commons.lang.builder.EqualsBuilder;
|
|
||||||
import org.apache.commons.lang.builder.HashCodeBuilder;
|
|
||||||
|
|
||||||
import com.commafeed.backend.model.FeedEntry;
|
|
||||||
import com.commafeed.backend.model.FeedEntryStatus;
|
|
||||||
|
|
||||||
public class FeedEntryWithStatus {
|
|
||||||
private FeedEntry entry;
|
|
||||||
private FeedEntryStatus status;
|
|
||||||
|
|
||||||
public FeedEntryWithStatus(FeedEntry entry, FeedEntryStatus status) {
|
|
||||||
this.entry = entry;
|
|
||||||
this.status = status;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return new HashCodeBuilder(17, 37).append(entry.getId())
|
|
||||||
.append(status == null ? null : status.getId()).toHashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (obj == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (obj == this) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (obj.getClass() != getClass()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
FeedEntryWithStatus rhs = (FeedEntryWithStatus) obj;
|
|
||||||
return new EqualsBuilder()
|
|
||||||
.append(status == null ? null : status.getId(),
|
|
||||||
rhs.status == null ? null : rhs.status.getId())
|
|
||||||
.append(entry.getId(), rhs.entry.getId()).isEquals();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public FeedEntry getEntry() {
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEntry(FeedEntry entry) {
|
|
||||||
this.entry = entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
public FeedEntryStatus getStatus() {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStatus(FeedEntryStatus status) {
|
|
||||||
this.status = status;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -38,7 +38,7 @@ public class GoogleImportRedirectPage extends WebPage {
|
|||||||
builder.addParameter("redirect_uri", redirectUri);
|
builder.addParameter("redirect_uri", redirectUri);
|
||||||
builder.addParameter("response_type", "code");
|
builder.addParameter("response_type", "code");
|
||||||
builder.addParameter("scope", SCOPE);
|
builder.addParameter("scope", SCOPE);
|
||||||
builder.addParameter("approval_prompt", "force");
|
builder.addParameter("approval_prompt", "auto");
|
||||||
builder.addParameter("client_id", clientId);
|
builder.addParameter("client_id", clientId);
|
||||||
builder.addParameter("state",
|
builder.addParameter("state",
|
||||||
String.valueOf(CommaFeedSession.get().getUser().getId()));
|
String.valueOf(CommaFeedSession.get().getUser().getId()));
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package com.commafeed.frontend.rest.resources;
|
package com.commafeed.frontend.rest.resources;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
@@ -19,6 +18,7 @@ import javax.ws.rs.core.Response.Status;
|
|||||||
|
|
||||||
import org.apache.wicket.ThreadContext;
|
import org.apache.wicket.ThreadContext;
|
||||||
import org.apache.wicket.authentication.IAuthenticationStrategy;
|
import org.apache.wicket.authentication.IAuthenticationStrategy;
|
||||||
|
import org.apache.wicket.authroles.authorization.strategies.role.Roles;
|
||||||
import org.apache.wicket.protocol.http.servlet.ServletWebRequest;
|
import org.apache.wicket.protocol.http.servlet.ServletWebRequest;
|
||||||
import org.apache.wicket.protocol.http.servlet.ServletWebResponse;
|
import org.apache.wicket.protocol.http.servlet.ServletWebResponse;
|
||||||
import org.apache.wicket.request.cycle.RequestCycle;
|
import org.apache.wicket.request.cycle.RequestCycle;
|
||||||
@@ -94,11 +94,13 @@ public abstract class AbstractREST {
|
|||||||
CommaFeedSession session = (CommaFeedSession) app
|
CommaFeedSession session = (CommaFeedSession) app
|
||||||
.fetchCreateAndSetSession(cycle);
|
.fetchCreateAndSetSession(cycle);
|
||||||
|
|
||||||
IAuthenticationStrategy authenticationStrategy = app
|
if (session.getUser() == null) {
|
||||||
.getSecuritySettings().getAuthenticationStrategy();
|
IAuthenticationStrategy authenticationStrategy = app
|
||||||
String[] data = authenticationStrategy.load();
|
.getSecuritySettings().getAuthenticationStrategy();
|
||||||
if (data != null && data.length > 1) {
|
String[] data = authenticationStrategy.load();
|
||||||
session.signIn(data[0], data[1]);
|
if (data != null && data.length > 1) {
|
||||||
|
session.signIn(data[0], data[1]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -137,11 +139,10 @@ public abstract class AbstractREST {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkRole(User user, SecurityCheck annotation) {
|
private boolean checkRole(User user, SecurityCheck annotation) {
|
||||||
Set<Role> roles = userRoleService.getRoles(user);
|
Roles roles = CommaFeedSession.get().getRoles();
|
||||||
if (!roles.contains(annotation.value())) {
|
boolean authorized = roles.hasAnyRole(new Roles(annotation.value()
|
||||||
return false;
|
.name()));
|
||||||
}
|
return authorized;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -134,7 +134,8 @@ public class AdminUsersREST extends AbstractREST {
|
|||||||
return Response.status(Status.FORBIDDEN)
|
return Response.status(Status.FORBIDDEN)
|
||||||
.entity("You cannot delete the admin user.").build();
|
.entity("You cannot delete the admin user.").build();
|
||||||
}
|
}
|
||||||
feedEntryStatusService.delete(feedEntryStatusService.findAll(user));
|
feedEntryStatusService.delete(feedEntryStatusService.getStatuses(user,
|
||||||
|
false));
|
||||||
feedSubscriptionService.delete(feedSubscriptionService.findAll(user));
|
feedSubscriptionService.delete(feedSubscriptionService.findAll(user));
|
||||||
feedCategoryService.delete(feedCategoryService.findAll(user));
|
feedCategoryService.delete(feedCategoryService.findAll(user));
|
||||||
userSettingsService.delete(userSettingsService.findByUser(user));
|
userSettingsService.delete(userSettingsService.findByUser(user));
|
||||||
|
|||||||
@@ -1,29 +1,25 @@
|
|||||||
package com.commafeed.frontend.rest.resources;
|
package com.commafeed.frontend.rest.resources;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import javax.ws.rs.DefaultValue;
|
import javax.ws.rs.DefaultValue;
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.QueryParam;
|
import javax.ws.rs.QueryParam;
|
||||||
|
import javax.ws.rs.WebApplicationException;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
import javax.ws.rs.core.Response.Status;
|
import javax.ws.rs.core.Response.Status;
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
|
||||||
import com.commafeed.backend.model.Feed;
|
|
||||||
import com.commafeed.backend.model.FeedCategory;
|
import com.commafeed.backend.model.FeedCategory;
|
||||||
import com.commafeed.backend.model.FeedEntry;
|
import com.commafeed.backend.model.FeedEntry;
|
||||||
import com.commafeed.backend.model.FeedEntryStatus;
|
import com.commafeed.backend.model.FeedEntryStatus;
|
||||||
import com.commafeed.backend.model.FeedSubscription;
|
import com.commafeed.backend.model.FeedSubscription;
|
||||||
import com.commafeed.backend.model.extended.FeedEntryWithStatus;
|
|
||||||
import com.commafeed.frontend.model.Entries;
|
import com.commafeed.frontend.model.Entries;
|
||||||
import com.commafeed.frontend.model.Entry;
|
import com.commafeed.frontend.model.Entry;
|
||||||
import com.google.common.base.Function;
|
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
|
|
||||||
@Path("entries")
|
@Path("entries")
|
||||||
public class EntriesREST extends AbstractREST {
|
public class EntriesREST extends AbstractREST {
|
||||||
@@ -59,34 +55,37 @@ public class EntriesREST extends AbstractREST {
|
|||||||
if (subscription != null) {
|
if (subscription != null) {
|
||||||
entries.setName(subscription.getTitle());
|
entries.setName(subscription.getTitle());
|
||||||
entries.setMessage(subscription.getFeed().getMessage());
|
entries.setMessage(subscription.getFeed().getMessage());
|
||||||
entries.getEntries().addAll(
|
|
||||||
buildEntries(subscription, offset, limit, unreadOnly));
|
List<FeedEntryStatus> unreadEntries = feedEntryStatusService
|
||||||
|
.getStatuses(subscription.getFeed(), getUser(),
|
||||||
|
unreadOnly, offset, limit);
|
||||||
|
for (FeedEntryStatus status : unreadEntries) {
|
||||||
|
entries.getEntries().add(buildEntry(status));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
List<FeedSubscription> subs = feedSubscriptionService
|
|
||||||
.findAll(getUser());
|
|
||||||
Map<Long, FeedSubscription> subMapping = Maps.uniqueIndex(subs,
|
|
||||||
new Function<FeedSubscription, Long>() {
|
|
||||||
public Long apply(FeedSubscription sub) {
|
|
||||||
return sub.getFeed().getId();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (ALL.equals(id)) {
|
if (ALL.equals(id)) {
|
||||||
entries.setName("All");
|
entries.setName("All");
|
||||||
entries.getEntries().addAll(
|
List<FeedEntryStatus> unreadEntries = feedEntryStatusService
|
||||||
buildEntries(subMapping, offset, limit, unreadOnly));
|
.getStatuses(getUser(), unreadOnly, offset, limit);
|
||||||
|
for (FeedEntryStatus status : unreadEntries) {
|
||||||
|
entries.getEntries().add(buildEntry(status));
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
FeedCategory feedCategory = feedCategoryService.findById(
|
FeedCategory feedCategory = feedCategoryService.findById(
|
||||||
getUser(), Long.valueOf(id));
|
getUser(), Long.valueOf(id));
|
||||||
if (feedCategory != null) {
|
if (feedCategory != null) {
|
||||||
List<FeedCategory> childrenCategories = feedCategoryService
|
List<FeedCategory> childrenCategories = feedCategoryService
|
||||||
.findAllChildrenCategories(getUser(), feedCategory);
|
.findAllChildrenCategories(getUser(), feedCategory);
|
||||||
entries.getEntries().addAll(
|
List<FeedEntryStatus> unreadEntries = feedEntryStatusService
|
||||||
buildEntries(childrenCategories, subMapping,
|
.getStatuses(childrenCategories, getUser(),
|
||||||
offset, limit, unreadOnly));
|
unreadOnly, offset, limit);
|
||||||
|
for (FeedEntryStatus status : unreadEntries) {
|
||||||
|
entries.getEntries().add(buildEntry(status));
|
||||||
|
}
|
||||||
entries.setName(feedCategory.getName());
|
entries.setName(feedCategory.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -96,79 +95,21 @@ public class EntriesREST extends AbstractREST {
|
|||||||
return entries;
|
return entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Entry> buildEntries(Map<Long, FeedSubscription> subMapping,
|
private Entry buildEntry(FeedEntryStatus status) {
|
||||||
int offset, int limit, boolean unreadOnly) {
|
|
||||||
List<Entry> entries = Lists.newArrayList();
|
|
||||||
|
|
||||||
List<FeedEntryWithStatus> unreadEntries = feedEntryService.getEntries(
|
|
||||||
getUser(), unreadOnly, offset, limit);
|
|
||||||
for (FeedEntryWithStatus feedEntry : unreadEntries) {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Entry> buildEntries(FeedSubscription subscription, int offset,
|
|
||||||
int limit, boolean unreadOnly) {
|
|
||||||
List<Entry> entries = Lists.newArrayList();
|
|
||||||
|
|
||||||
List<FeedEntryWithStatus> unreadEntries = feedEntryService.getEntries(
|
|
||||||
subscription.getFeed(), getUser(), unreadOnly, offset, limit);
|
|
||||||
for (FeedEntryWithStatus feedEntry : unreadEntries) {
|
|
||||||
entries.add(populateEntry(buildEntry(feedEntry), subscription));
|
|
||||||
}
|
|
||||||
|
|
||||||
return entries;
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Entry> buildEntries(List<FeedCategory> categories,
|
|
||||||
Map<Long, FeedSubscription> subMapping, int offset, int limit,
|
|
||||||
boolean unreadOnly) {
|
|
||||||
List<Entry> entries = Lists.newArrayList();
|
|
||||||
|
|
||||||
List<FeedEntryWithStatus> unreadEntries = feedEntryService.getEntries(
|
|
||||||
categories, getUser(), unreadOnly, offset, limit);
|
|
||||||
for (FeedEntryWithStatus feedEntry : unreadEntries) {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Entry buildEntry(FeedEntryWithStatus feedEntryWithStatus) {
|
|
||||||
Entry entry = new Entry();
|
Entry entry = new Entry();
|
||||||
|
|
||||||
FeedEntry feedEntry = feedEntryWithStatus.getEntry();
|
FeedEntry feedEntry = status.getEntry();
|
||||||
entry.setId(String.valueOf(feedEntry.getId()));
|
entry.setId(String.valueOf(status.getId()));
|
||||||
entry.setTitle(feedEntry.getTitle());
|
entry.setTitle(feedEntry.getTitle());
|
||||||
entry.setContent(feedEntry.getContent());
|
entry.setContent(feedEntry.getContent());
|
||||||
entry.setDate(feedEntry.getUpdated());
|
entry.setDate(feedEntry.getUpdated());
|
||||||
entry.setUrl(feedEntry.getUrl());
|
entry.setUrl(feedEntry.getUrl());
|
||||||
|
|
||||||
FeedEntryStatus status = feedEntryWithStatus.getStatus();
|
entry.setRead(status.isRead());
|
||||||
entry.setRead(status == null ? false : status.isRead());
|
|
||||||
|
|
||||||
return entry;
|
entry.setFeedName(status.getSubscription().getTitle());
|
||||||
}
|
entry.setFeedId(String.valueOf(status.getSubscription().getId()));
|
||||||
|
|
||||||
private Entry populateEntry(Entry entry, FeedSubscription sub) {
|
|
||||||
entry.setFeedName(sub.getTitle());
|
|
||||||
entry.setFeedId(String.valueOf(sub.getId()));
|
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,70 +122,40 @@ public class EntriesREST extends AbstractREST {
|
|||||||
Preconditions.checkNotNull(read);
|
Preconditions.checkNotNull(read);
|
||||||
|
|
||||||
if (type == Type.entry) {
|
if (type == Type.entry) {
|
||||||
FeedEntry entry = feedEntryService.findById(Long.valueOf(id));
|
FeedEntryStatus status = feedEntryStatusService.findById(getUser(),
|
||||||
markEntry(entry, read);
|
Long.valueOf(id));
|
||||||
|
status.setRead(read);
|
||||||
|
feedEntryStatusService.update(status);
|
||||||
} else if (type == Type.feed) {
|
} else if (type == Type.feed) {
|
||||||
if (read) {
|
if (read) {
|
||||||
Feed feed = feedSubscriptionService.findById(Long.valueOf(id))
|
FeedSubscription subscription = feedSubscriptionService
|
||||||
.getFeed();
|
.findById(getUser(), Long.valueOf(id));
|
||||||
List<FeedEntryWithStatus> entries = feedEntryService
|
feedEntryStatusService.markFeedEntries(getUser(),
|
||||||
.getEntries(feed, getUser(), true);
|
subscription.getFeed());
|
||||||
for (FeedEntryWithStatus entry : entries) {
|
|
||||||
markEntry(entry, read);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return Response.status(Status.FORBIDDEN)
|
throw new WebApplicationException(Response.status(
|
||||||
.entity("Operation not supported").build();
|
Status.INTERNAL_SERVER_ERROR).build());
|
||||||
}
|
}
|
||||||
} else if (type == Type.category) {
|
} else if (type == Type.category) {
|
||||||
if (read) {
|
if (read) {
|
||||||
List<FeedEntryWithStatus> entries = null;
|
|
||||||
|
|
||||||
if (ALL.equals(id)) {
|
if (ALL.equals(id)) {
|
||||||
entries = feedEntryService.getEntries(getUser(), true);
|
feedEntryStatusService.markAllEntries(getUser());
|
||||||
} else {
|
} else {
|
||||||
FeedCategory feedCategory = feedCategoryService.findById(
|
List<FeedCategory> categories = feedCategoryService
|
||||||
getUser(), Long.valueOf(id));
|
.findAllChildrenCategories(getUser(),
|
||||||
List<FeedCategory> childrenCategories = feedCategoryService
|
feedCategoryService.findById(getUser(),
|
||||||
.findAllChildrenCategories(getUser(), feedCategory);
|
Long.valueOf(id)));
|
||||||
|
feedEntryStatusService.markCategoryEntries(getUser(),
|
||||||
entries = feedEntryService.getEntries(childrenCategories,
|
categories);
|
||||||
getUser(), true);
|
|
||||||
}
|
|
||||||
for (FeedEntryWithStatus entry : entries) {
|
|
||||||
markEntry(entry, read);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return Response.status(Status.FORBIDDEN)
|
throw new WebApplicationException(Response.status(
|
||||||
.entity("Operation not supported").build();
|
Status.INTERNAL_SERVER_ERROR).build());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Response.ok(Status.OK).build();
|
return Response.ok(Status.OK).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void markEntry(FeedEntry entry, boolean read) {
|
|
||||||
FeedEntryStatus status = feedEntryStatusService.getStatus(getUser(),
|
|
||||||
entry);
|
|
||||||
if (status == null) {
|
|
||||||
status = new FeedEntryStatus();
|
|
||||||
status.setUser(getUser());
|
|
||||||
status.setEntry(entry);
|
|
||||||
}
|
|
||||||
status.setRead(read);
|
|
||||||
feedEntryStatusService.saveOrUpdate(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void markEntry(FeedEntryWithStatus entryWithStatus, boolean read) {
|
|
||||||
FeedEntryStatus status = entryWithStatus.getStatus();
|
|
||||||
if (status == null) {
|
|
||||||
status = new FeedEntryStatus();
|
|
||||||
status.setUser(getUser());
|
|
||||||
status.setEntry(entryWithStatus.getEntry());
|
|
||||||
}
|
|
||||||
status.setRead(read);
|
|
||||||
feedEntryStatusService.saveOrUpdate(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Path("search")
|
@Path("search")
|
||||||
@GET
|
@GET
|
||||||
public Entries searchEntries(@QueryParam("keywords") String keywords) {
|
public Entries searchEntries(@QueryParam("keywords") String keywords) {
|
||||||
@@ -252,27 +163,11 @@ public class EntriesREST extends AbstractREST {
|
|||||||
|
|
||||||
Entries entries = new Entries();
|
Entries entries = new Entries();
|
||||||
|
|
||||||
List<FeedSubscription> subs = feedSubscriptionService
|
|
||||||
.findAll(getUser());
|
|
||||||
Map<Long, FeedSubscription> subMapping = Maps.uniqueIndex(subs,
|
|
||||||
new Function<FeedSubscription, Long>() {
|
|
||||||
public Long apply(FeedSubscription sub) {
|
|
||||||
return sub.getFeed().getId();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
List<Entry> list = Lists.newArrayList();
|
List<Entry> list = Lists.newArrayList();
|
||||||
List<FeedEntryWithStatus> entriesWithStatus = feedEntryService
|
List<FeedEntryStatus> entriesStatus = feedEntryStatusService
|
||||||
.getEntriesByKeywords(getUser(), keywords);
|
.getStatusesByKeywords(getUser(), keywords);
|
||||||
for (FeedEntryWithStatus feedEntry : entriesWithStatus) {
|
for (FeedEntryStatus status : entriesStatus) {
|
||||||
FeedSubscription sub = null;
|
list.add(buildEntry(status));
|
||||||
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);
|
entries.setName("Search for : " + keywords);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.commafeed.frontend.rest.resources;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
@@ -164,16 +165,19 @@ public class SubscriptionsREST extends AbstractREST {
|
|||||||
List<FeedCategory> categories = feedCategoryService.findAll(getUser());
|
List<FeedCategory> categories = feedCategoryService.findAll(getUser());
|
||||||
List<FeedSubscription> subscriptions = feedSubscriptionService
|
List<FeedSubscription> subscriptions = feedSubscriptionService
|
||||||
.findAll(getUser());
|
.findAll(getUser());
|
||||||
|
Map<Long, Long> unreadCount = feedEntryStatusService
|
||||||
|
.getUnreadCount(getUser());
|
||||||
|
|
||||||
Category root = buildCategory(null, categories, subscriptions);
|
Category root = buildCategory(null, categories, subscriptions,
|
||||||
|
unreadCount);
|
||||||
root.setId("all");
|
root.setId("all");
|
||||||
root.setName("All");
|
root.setName("All");
|
||||||
|
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
Category buildCategory(Long id, List<FeedCategory> categories,
|
private Category buildCategory(Long id, List<FeedCategory> categories,
|
||||||
List<FeedSubscription> subscriptions) {
|
List<FeedSubscription> subscriptions, Map<Long, Long> unreadCount) {
|
||||||
Category category = new Category();
|
Category category = new Category();
|
||||||
category.setId(String.valueOf(id));
|
category.setId(String.valueOf(id));
|
||||||
category.setExpanded(true);
|
category.setExpanded(true);
|
||||||
@@ -183,7 +187,7 @@ public class SubscriptionsREST extends AbstractREST {
|
|||||||
|| (c.getParent() != null && ObjectUtils.equals(c
|
|| (c.getParent() != null && ObjectUtils.equals(c
|
||||||
.getParent().getId(), id))) {
|
.getParent().getId(), id))) {
|
||||||
Category child = buildCategory(c.getId(), categories,
|
Category child = buildCategory(c.getId(), categories,
|
||||||
subscriptions);
|
subscriptions, unreadCount);
|
||||||
child.setId(String.valueOf(c.getId()));
|
child.setId(String.valueOf(c.getId()));
|
||||||
child.setName(c.getName());
|
child.setName(c.getName());
|
||||||
child.setExpanded(!c.isCollapsed());
|
child.setExpanded(!c.isCollapsed());
|
||||||
@@ -206,9 +210,8 @@ public class SubscriptionsREST extends AbstractREST {
|
|||||||
sub.setName(subscription.getTitle());
|
sub.setName(subscription.getTitle());
|
||||||
sub.setMessage(subscription.getFeed().getMessage());
|
sub.setMessage(subscription.getFeed().getMessage());
|
||||||
sub.setFeedUrl(subscription.getFeed().getLink());
|
sub.setFeedUrl(subscription.getFeed().getLink());
|
||||||
long size = feedEntryService.getUnreadCount(
|
Long size = unreadCount.get(subscription.getId());
|
||||||
subscription.getFeed(), getUser());
|
sub.setUnread(size == null ? 0 : size);
|
||||||
sub.setUnread(size);
|
|
||||||
category.getFeeds().add(sub);
|
category.getFeeds().add(sub);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,34 +10,39 @@
|
|||||||
</named-query>
|
</named-query>
|
||||||
|
|
||||||
<named-query name="Entry.byGuids">
|
<named-query name="Entry.byGuids">
|
||||||
<query>select DISTINCT e from FeedEntry e LEFT JOIN FETCH e.feeds where e.guid in (:guids) order by e.updated desc</query>
|
<query>select DISTINCT e from FeedEntry e JOIN FETCH e.feeds where e.guid in (:guids)</query>
|
||||||
</named-query>
|
</named-query>
|
||||||
|
|
||||||
<named-query name="Entry.unread">
|
<named-query name="EntryStatus.byId">
|
||||||
<query>select e, s from FeedEntry e LEFT JOIN e.statuses s WITH (s.user.id=:userId) LEFT JOIN FETCH e.feeds 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</query>
|
<query>select s from FeedEntryStatus s where s.subscription.user=:user and s.id=:id</query>
|
||||||
</named-query>
|
|
||||||
<named-query name="Entry.all">
|
|
||||||
<query>select e, s from FeedEntry e LEFT JOIN e.statuses s WITH (s.user.id=:userId)LEFT JOIN FETCH e.feeds where exists (select s2 from FeedSubscription s2 where s2.user=:user and s2.feed member of e.feeds) order by e.updated desc</query>
|
|
||||||
</named-query>
|
</named-query>
|
||||||
|
|
||||||
<named-query name="Entry.unreadByFeed">
|
<named-query name="EntryStatus.unread">
|
||||||
<query>select e, s from FeedEntry e LEFT JOIN e.statuses s WITH (s.user.id=:userId) LEFT JOIN FETCH e.feeds 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</query>
|
<query>select s from FeedEntryStatus s where s.subscription.user=:user and s.read=false order by s.entry.updated desc</query>
|
||||||
</named-query>
|
</named-query>
|
||||||
<named-query name="Entry.unreadByFeedCount">
|
<named-query name="EntryStatus.all">
|
||||||
<query>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)</query>
|
<query>select s from FeedEntryStatus s where s.subscription.user=:user order by s.entry.updated desc</query>
|
||||||
</named-query>
|
|
||||||
<named-query name="Entry.allByFeed">
|
|
||||||
<query>select e, s from FeedEntry e LEFT JOIN e.statuses s WITH (s.user.id=:userId) LEFT JOIN FETCH e.feeds where :feed member of e.feeds order by e.updated desc</query>
|
|
||||||
</named-query>
|
</named-query>
|
||||||
|
|
||||||
<named-query name="Entry.unreadByCategories">
|
<named-query name="EntryStatus.unreadByFeed">
|
||||||
<query>select e, s from FeedEntry e LEFT JOIN e.statuses s WITH (s.user.id=:userId) LEFT JOIN FETCH e.feeds 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</query>
|
<query>select s from FeedEntryStatus s where s.subscription.user=:user and s.subscription.feed=:feed and s.read=false order by s.entry.updated desc</query>
|
||||||
</named-query>
|
</named-query>
|
||||||
<named-query name="Entry.allByCategories">
|
<named-query name="EntryStatus.unreadCounts">
|
||||||
<query>select e, s from FeedEntry e LEFT JOIN e.statuses s WITH (s.user.id=:userId) LEFT JOIN FETCH e.feeds 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</query>
|
<query>select s.subscription.id, count(s) from FeedEntryStatus s where s.subscription.user=:user and s.read=false group by s.subscription.id</query>
|
||||||
|
</named-query>
|
||||||
|
<named-query name="EntryStatus.allByFeed">
|
||||||
|
<query>select s from FeedEntryStatus s where s.subscription.user=:user and s.subscription.feed=:feed order by s.entry.updated desc</query>
|
||||||
</named-query>
|
</named-query>
|
||||||
|
|
||||||
<named-query name="Entry.allByKeywords">
|
<named-query name="EntryStatus.unreadByCategories">
|
||||||
<query>select e, s from FeedEntry e LEFT JOIN e.statuses s WITH (s.user.id=:userId) LEFT JOIN FETCH e.feeds 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</query>
|
<query>select s from FeedEntryStatus s where s.subscription.user=:user and s.subscription.category in (:categories) and s.read=false order by s.entry.updated desc</query>
|
||||||
</named-query>
|
</named-query>
|
||||||
|
<named-query name="EntryStatus.allByCategories">
|
||||||
|
<query>select s from FeedEntryStatus s where s.subscription.user=:user and s.subscription.category in (:categories) order by s.entry.updated desc</query>
|
||||||
|
</named-query>
|
||||||
|
|
||||||
|
<named-query name="EntryStatus.allByKeywords">
|
||||||
|
<query>select s from FeedEntryStatus s where s.subscription.user=:user and (lower(s.entry.content) like :keywords or lower(s.entry.title) like :keywords) order by s.entry.updated desc</query>
|
||||||
|
</named-query>
|
||||||
|
|
||||||
</entity-mappings>
|
</entity-mappings>
|
||||||
@@ -5,11 +5,12 @@
|
|||||||
http://java.sun.com/xml/ns/persistence
|
http://java.sun.com/xml/ns/persistence
|
||||||
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
|
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
|
||||||
<persistence-unit name="primary">
|
<persistence-unit name="primary">
|
||||||
<provider>org.hibernate.ejb.HibernatePersistence</provider>
|
<provider>org.hibernate.ejb.HibernatePersistence</provider>
|
||||||
<jta-data-source>${jpa.datasource.name}</jta-data-source>
|
<jta-data-source>${jpa.datasource.name}</jta-data-source>
|
||||||
<properties>
|
<properties>
|
||||||
<property name="hibernate.hbm2ddl.auto" value="update" />
|
<property name="hibernate.hbm2ddl.auto" value="update" />
|
||||||
<property name="hibernate.show_sql" value="${jpa.show_sql}" />
|
<property name="hibernate.show_sql" value="${jpa.show_sql}" />
|
||||||
|
<property name="hibernate.default_batch_fetch_size" value="100" />
|
||||||
</properties>
|
</properties>
|
||||||
</persistence-unit>
|
</persistence-unit>
|
||||||
</persistence>
|
</persistence>
|
||||||
Reference in New Issue
Block a user