diff --git a/pom.xml b/pom.xml
index 4db521a4..ea2b1dfd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -15,7 +15,7 @@
UTF-8
java:openejb/Resource/My DataSource
- false
+ true
diff --git a/src/main/java/com/commafeed/backend/dao/FeedEntryStatusService.java b/src/main/java/com/commafeed/backend/dao/FeedEntryStatusService.java
index bdb08797..4eb762cc 100644
--- a/src/main/java/com/commafeed/backend/dao/FeedEntryStatusService.java
+++ b/src/main/java/com/commafeed/backend/dao/FeedEntryStatusService.java
@@ -18,6 +18,7 @@ import org.apache.commons.lang.StringUtils;
import com.commafeed.backend.model.Feed;
import com.commafeed.backend.model.FeedCategory;
+import com.commafeed.backend.model.FeedEntryContent_;
import com.commafeed.backend.model.FeedEntryStatus;
import com.commafeed.backend.model.FeedEntryStatus_;
import com.commafeed.backend.model.FeedEntry_;
@@ -58,12 +59,7 @@ public class FeedEntryStatusService extends GenericDAO {
}
public List getStatusesByKeywords(User user,
- String keywords) {
- return getStatusesByKeywords(user, keywords, -1, -1);
- }
-
- public List getStatusesByKeywords(User user,
- String keywords, int offset, int limit) {
+ String keywords, int offset, int limit, boolean includeContent) {
String joinedKeywords = StringUtils.join(
keywords.toLowerCase().split(" "), "%");
@@ -76,13 +72,17 @@ public class FeedEntryStatusService extends GenericDAO {
predicates.add(builder.equal(root.get(FeedEntryStatus_.subscription)
.get(FeedSubscription_.user), user));
- Predicate content = builder.like(
- builder.lower(root.get(FeedEntryStatus_.entry).get(
- FeedEntry_.content)), joinedKeywords);
+ Predicate content = builder.like(builder.lower(root
+ .get(FeedEntryStatus_.entry).get(FeedEntry_.content)
+ .get(FeedEntryContent_.content)), joinedKeywords);
Predicate title = builder.like(
- builder.lower(root.get(FeedEntryStatus_.entry).get(
- FeedEntry_.title)), joinedKeywords);
+ builder.lower(root.get(FeedEntryStatus_.entry)
+ .get(FeedEntry_.content).get(FeedEntryContent_.title)),
+ joinedKeywords);
predicates.add(builder.or(content, title));
+ if (includeContent) {
+ root.fetch(FeedEntryStatus_.entry).fetch(FeedEntry_.content);
+ }
query.where(predicates.toArray(new Predicate[0]));
@@ -94,12 +94,12 @@ public class FeedEntryStatusService extends GenericDAO {
}
public List getStatuses(User user, boolean unreadOnly,
- ReadingOrder order) {
- return getStatuses(user, unreadOnly, -1, -1, order);
+ ReadingOrder order, boolean includeContent) {
+ return getStatuses(user, unreadOnly, -1, -1, order, includeContent);
}
public List getStatuses(User user, boolean unreadOnly,
- int offset, int limit, ReadingOrder order) {
+ int offset, int limit, ReadingOrder order, boolean includeContent) {
CriteriaQuery query = builder.createQuery(getType());
Root root = query.from(getType());
@@ -109,6 +109,11 @@ public class FeedEntryStatusService extends GenericDAO {
if (unreadOnly) {
predicates.add(builder.isFalse(root.get(FeedEntryStatus_.read)));
}
+
+ if (includeContent) {
+ root.fetch(FeedEntryStatus_.entry).fetch(FeedEntry_.content);
+ }
+
query.where(predicates.toArray(new Predicate[0]));
orderBy(query, root, order);
@@ -134,12 +139,14 @@ public class FeedEntryStatusService extends GenericDAO {
}
public List getStatuses(Feed feed, User user,
- boolean unreadOnly, ReadingOrder order) {
- return getStatuses(feed, user, unreadOnly, -1, -1, order);
+ boolean unreadOnly, ReadingOrder order, boolean includeContent) {
+ return getStatuses(feed, user, unreadOnly, -1, -1, order,
+ includeContent);
}
public List getStatuses(Feed feed, User user,
- boolean unreadOnly, int offset, int limit, ReadingOrder order) {
+ boolean unreadOnly, int offset, int limit, ReadingOrder order,
+ boolean includeContent) {
CriteriaQuery query = builder.createQuery(getType());
Root root = query.from(getType());
@@ -152,6 +159,11 @@ public class FeedEntryStatusService extends GenericDAO {
if (unreadOnly) {
predicates.add(builder.isFalse(root.get(FeedEntryStatus_.read)));
}
+
+ if (includeContent) {
+ root.fetch(FeedEntryStatus_.entry).fetch(FeedEntry_.content);
+ }
+
query.where(predicates.toArray(new Predicate[0]));
orderBy(query, root, order);
@@ -162,13 +174,15 @@ public class FeedEntryStatusService extends GenericDAO {
}
public List getStatuses(List categories,
- User user, boolean unreadOnly, ReadingOrder order) {
- return getStatuses(categories, user, unreadOnly, -1, -1, order);
+ User user, boolean unreadOnly, ReadingOrder order,
+ boolean includeContent) {
+ return getStatuses(categories, user, unreadOnly, -1, -1, order,
+ includeContent);
}
public List getStatuses(List categories,
User user, boolean unreadOnly, int offset, int limit,
- ReadingOrder order) {
+ ReadingOrder order, boolean includeContent) {
CriteriaQuery query = builder.createQuery(getType());
Root root = query.from(getType());
@@ -181,6 +195,11 @@ public class FeedEntryStatusService extends GenericDAO {
if (unreadOnly) {
predicates.add(builder.isFalse(root.get(FeedEntryStatus_.read)));
}
+
+ if (includeContent) {
+ root.fetch(FeedEntryStatus_.entry).fetch(FeedEntry_.content);
+ }
+
query.where(predicates.toArray(new Predicate[0]));
orderBy(query, root, order);
@@ -213,20 +232,20 @@ public class FeedEntryStatusService extends GenericDAO {
public void markFeedEntries(User user, Feed feed, Date olderThan) {
List statuses = getStatuses(feed, user, true,
- ReadingOrder.desc);
+ ReadingOrder.desc, false);
update(markList(statuses, olderThan));
}
public void markCategoryEntries(User user, List categories,
Date olderThan) {
List statuses = getStatuses(categories, user, true,
- ReadingOrder.desc);
+ ReadingOrder.desc, false);
update(markList(statuses, olderThan));
}
public void markAllEntries(User user, Date olderThan) {
List statuses = getStatuses(user, true,
- ReadingOrder.desc);
+ ReadingOrder.desc, false);
update(markList(statuses, olderThan));
}
diff --git a/src/main/java/com/commafeed/backend/feeds/FeedParser.java b/src/main/java/com/commafeed/backend/feeds/FeedParser.java
index 50edb523..0a1345b6 100644
--- a/src/main/java/com/commafeed/backend/feeds/FeedParser.java
+++ b/src/main/java/com/commafeed/backend/feeds/FeedParser.java
@@ -15,6 +15,7 @@ import org.xml.sax.InputSource;
import com.commafeed.backend.model.Feed;
import com.commafeed.backend.model.FeedEntry;
+import com.commafeed.backend.model.FeedEntryContent;
import com.google.common.base.Function;
import com.google.common.collect.Collections2;
import com.google.common.collect.Iterables;
@@ -48,17 +49,19 @@ public class FeedParser {
for (SyndEntry item : items) {
FeedEntry entry = new FeedEntry();
entry.setGuid(item.getUri());
- entry.setTitle(handleContent(item.getTitle()));
- entry.setContent(handleContent(getContent(item)));
entry.setUrl(item.getLink());
entry.setUpdated(getUpdateDate(item));
+ FeedEntryContent content = new FeedEntryContent();
+ content.setContent(handleContent(getContent(item)));
+ content.setTitle(handleContent(item.getTitle()));
SyndEnclosure enclosure = (SyndEnclosure) Iterables.getFirst(
item.getEnclosures(), null);
if (enclosure != null) {
- entry.setEnclosureUrl(enclosure.getUrl());
- entry.setEnclosureType(enclosure.getType());
+ content.setEnclosureUrl(enclosure.getUrl());
+ content.setEnclosureType(enclosure.getType());
}
+ entry.setContent(content);
feed.getEntries().add(entry);
}
@@ -103,7 +106,6 @@ public class FeedParser {
Whitelist whitelist = Whitelist.relaxed();
whitelist.addEnforcedAttribute("a", "target", "_blank");
- // TODO evaluate potential security issues
whitelist.addTags("iframe");
whitelist.addAttributes("iframe", "src", "height", "width",
"allowfullscreen", "frameborder");
diff --git a/src/main/java/com/commafeed/backend/model/FeedEntry.java b/src/main/java/com/commafeed/backend/model/FeedEntry.java
index 8aea117b..01f221ac 100644
--- a/src/main/java/com/commafeed/backend/model/FeedEntry.java
+++ b/src/main/java/com/commafeed/backend/model/FeedEntry.java
@@ -3,13 +3,15 @@ package com.commafeed.backend.model;
import java.util.Date;
import java.util.Set;
+import javax.persistence.CascadeType;
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.ManyToMany;
import javax.persistence.OneToMany;
+import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
@@ -30,18 +32,9 @@ public class FeedEntry extends AbstractModel {
@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;
-
- @Lob
- @Column(length = Integer.MAX_VALUE)
- private String content;
-
- @Column(length = 2048)
- private String enclosureUrl;
-
- @Column(length = 255)
- private String enclosureType;
+ @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, optional = false)
+ @JoinColumn(nullable = false, updatable = false)
+ private FeedEntryContent content;
@Column(length = 2048)
private String url;
@@ -65,22 +58,6 @@ public class FeedEntry extends AbstractModel {
this.guid = guid;
}
- public String getTitle() {
- return title;
- }
-
- public void setTitle(String title) {
- this.title = title;
- }
-
- public String getContent() {
- return content;
- }
-
- public void setContent(String content) {
- this.content = content;
- }
-
public String getUrl() {
return url;
}
@@ -121,20 +98,12 @@ public class FeedEntry extends AbstractModel {
this.inserted = inserted;
}
- public String getEnclosureUrl() {
- return enclosureUrl;
+ public FeedEntryContent getContent() {
+ return content;
}
- public void setEnclosureUrl(String enclosureUrl) {
- this.enclosureUrl = enclosureUrl;
- }
-
- public String getEnclosureType() {
- return enclosureType;
- }
-
- public void setEnclosureType(String enclosureType) {
- this.enclosureType = enclosureType;
+ public void setContent(FeedEntryContent content) {
+ this.content = content;
}
}
diff --git a/src/main/java/com/commafeed/backend/model/FeedEntryContent.java b/src/main/java/com/commafeed/backend/model/FeedEntryContent.java
new file mode 100644
index 00000000..119b7204
--- /dev/null
+++ b/src/main/java/com/commafeed/backend/model/FeedEntryContent.java
@@ -0,0 +1,58 @@
+package com.commafeed.backend.model;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Lob;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "FEEDENTRYCONTENTS")
+@SuppressWarnings("serial")
+public class FeedEntryContent extends AbstractModel {
+
+ @Column(length = 2048)
+ private String title;
+
+ @Lob
+ @Column(length = Integer.MAX_VALUE)
+ private String content;
+
+ @Column(length = 2048)
+ private String enclosureUrl;
+
+ @Column(length = 255)
+ private String enclosureType;
+
+ public String getContent() {
+ return content;
+ }
+
+ public void setContent(String content) {
+ this.content = content;
+ }
+
+ public String getEnclosureUrl() {
+ return enclosureUrl;
+ }
+
+ public void setEnclosureUrl(String enclosureUrl) {
+ this.enclosureUrl = enclosureUrl;
+ }
+
+ public String getEnclosureType() {
+ return enclosureType;
+ }
+
+ public void setEnclosureType(String enclosureType) {
+ this.enclosureType = enclosureType;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+}
diff --git a/src/main/java/com/commafeed/frontend/rest/resources/AdminUsersREST.java b/src/main/java/com/commafeed/frontend/rest/resources/AdminUsersREST.java
index dc56f006..b1bc8ef4 100644
--- a/src/main/java/com/commafeed/frontend/rest/resources/AdminUsersREST.java
+++ b/src/main/java/com/commafeed/frontend/rest/resources/AdminUsersREST.java
@@ -136,7 +136,7 @@ public class AdminUsersREST extends AbstractREST {
.entity("You cannot delete the admin user.").build();
}
feedEntryStatusService.delete(feedEntryStatusService.getStatuses(user,
- false, ReadingOrder.desc));
+ false, ReadingOrder.desc, false));
feedSubscriptionService.delete(feedSubscriptionService.findAll(user));
feedCategoryService.delete(feedCategoryService.findAll(user));
userSettingsService.delete(userSettingsService.findByUser(user));
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 f7832441..8f3bd7e0 100644
--- a/src/main/java/com/commafeed/frontend/rest/resources/EntriesREST.java
+++ b/src/main/java/com/commafeed/frontend/rest/resources/EntriesREST.java
@@ -63,7 +63,7 @@ public class EntriesREST extends AbstractREST {
List unreadEntries = feedEntryStatusService
.getStatuses(subscription.getFeed(), getUser(),
- unreadOnly, offset, limit, order);
+ unreadOnly, offset, limit, order, true);
for (FeedEntryStatus status : unreadEntries) {
entries.getEntries().add(buildEntry(status));
}
@@ -75,7 +75,7 @@ public class EntriesREST extends AbstractREST {
entries.setName("All");
List unreadEntries = feedEntryStatusService
.getStatuses(getUser(), unreadOnly, offset, limit,
- order);
+ order, true);
for (FeedEntryStatus status : unreadEntries) {
entries.getEntries().add(buildEntry(status));
}
@@ -88,7 +88,7 @@ public class EntriesREST extends AbstractREST {
.findAllChildrenCategories(getUser(), feedCategory);
List unreadEntries = feedEntryStatusService
.getStatuses(childrenCategories, getUser(),
- unreadOnly, offset, limit, order);
+ unreadOnly, offset, limit, order, true);
for (FeedEntryStatus status : unreadEntries) {
entries.getEntries().add(buildEntry(status));
}
@@ -106,10 +106,11 @@ public class EntriesREST extends AbstractREST {
FeedEntry feedEntry = status.getEntry();
entry.setId(String.valueOf(status.getId()));
- entry.setTitle(feedEntry.getTitle());
- entry.setContent(feedEntry.getContent());
- entry.setEnclosureUrl(status.getEntry().getEnclosureUrl());
- entry.setEnclosureType(status.getEntry().getEnclosureType());
+ entry.setTitle(feedEntry.getContent().getTitle());
+ entry.setContent(feedEntry.getContent().getContent());
+ entry.setEnclosureUrl(status.getEntry().getContent().getEnclosureUrl());
+ entry.setEnclosureType(status.getEntry().getContent()
+ .getEnclosureType());
entry.setDate(feedEntry.getUpdated());
entry.setUrl(feedEntry.getUrl());
@@ -171,14 +172,16 @@ public class EntriesREST extends AbstractREST {
@Path("search")
@GET
- public Entries searchEntries(@QueryParam("keywords") String keywords) {
+ public Entries searchEntries(@QueryParam("keywords") String keywords,
+ @DefaultValue("0") @QueryParam("offset") int offset,
+ @DefaultValue("-1") @QueryParam("limit") int limit) {
Preconditions.checkArgument(StringUtils.length(keywords) >= 3);
Entries entries = new Entries();
List list = Lists.newArrayList();
List entriesStatus = feedEntryStatusService
- .getStatusesByKeywords(getUser(), keywords);
+ .getStatusesByKeywords(getUser(), keywords, offset, limit, true);
for (FeedEntryStatus status : entriesStatus) {
list.add(buildEntry(status));
}