/*
* JBoss, Home of Professional Open Source
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jboss.seam.wiki.core.feeds;
import org.jboss.seam.Component;
import org.jboss.seam.annotations.AutoCreate;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.log.Log;
import org.jboss.seam.wiki.core.model.*;
import org.jboss.seam.wiki.core.ui.WikiURLRenderer;
import org.jboss.seam.wiki.core.dao.WikiNodeDAO;
import javax.persistence.EntityManager;
import javax.persistence.EntityNotFoundException;
import javax.persistence.NoResultException;
import java.util.Date;
import java.util.List;
import java.util.Iterator;
import java.util.ArrayList;
/**
* DAO for feeds.
* <p>
* Uses the <tt>restrictedEntityManager</tt> because it is used in the context of
* directory/document/comment editing (same PC).
* </p>
* <p>
*
* @author Christian Bauer
*
*/
@Name("feedDAO")
@AutoCreate
public class FeedDAO {
@Logger static Log log;
@In protected EntityManager restrictedEntityManager;
/* ############################# FINDERS ################################ */
public List<Feed> findAllFeeds() {
return restrictedEntityManager
.createQuery("select f from Feed f")
.setHint("org.hibernate.cacheable", true)
.getResultList();
}
public List<WikiFeed> findWikiFeeds() {
return restrictedEntityManager
.createQuery("select f from WikiFeed f join fetch f.directory d order by d.createdOn asc")
.setHint("org.hibernate.cacheable", true)
.getResultList();
}
public Feed findFeed(Long feedId) {
try {
return (Feed) restrictedEntityManager
.createQuery("select f from Feed f where f.id = :id")
.setParameter("id", feedId)
.setHint("org.hibernate.cacheable", true)
.getSingleResult();
} catch (EntityNotFoundException ex) {
} catch (NoResultException ex) {}
return null;
}
public List<WikiFeed> findFeeds(WikiDocument document) {
if (document == null || document.getId() == null) throw new IllegalArgumentException("document is null or unsaved");
return restrictedEntityManager
.createQuery(
"select distinct f from WikiDocumentFeedEntry fe, WikiFeed f join f.feedEntries allFe " +
" where fe.document = :doc and fe = allFe order by f.publishedDate desc"
)
.setParameter("doc", document)
.getResultList();
}
public List<WikiFeed> findFeeds(WikiComment comment) {
if (comment == null || comment.getId() == null) throw new IllegalArgumentException("comment is null or unsaved");
return restrictedEntityManager
.createQuery(
"select distinct f from WikiCommentFeedEntry fe, WikiFeed f join f.feedEntries allFe " +
" where fe.comment = :comment and fe = allFe order by f.publishedDate desc"
)
.setParameter("comment", comment)
.getResultList();
}
public List<WikiFeed> findParentFeeds(WikiDirectory startDir, boolean includeSiteFeed) {
WikiDirectory currentDir = WikiNodeDAO.instance().findWikiDirectory(startDir.getId()); // Use restricted PC!
List<WikiFeed> feeds = new ArrayList();
if (currentDir.getParent() == null && currentDir.getFeed() != null) {
feeds.add(currentDir.getFeed());
}
while (currentDir.getParent() != null) {
if (currentDir.getFeed() != null)
feeds.add(currentDir.getFeed());
currentDir = (WikiDirectory)currentDir.getParent();
}
if (includeSiteFeed) {
WikiDirectory wikiRoot = (WikiDirectory)Component.getInstance("wikiRoot");
feeds.add(WikiNodeDAO.instance().findWikiDirectory(wikiRoot.getId()).getFeed()); // Use restricted PC!
}
return feeds;
}
public WikiDocumentFeedEntry findFeedEntry(WikiDocument document) {
try {
return (WikiDocumentFeedEntry)restrictedEntityManager
.createQuery("select fe from WikiDocumentFeedEntry fe where fe.document = :document")
.setParameter("document", document)
.getSingleResult();
} catch (EntityNotFoundException ex) {
} catch (NoResultException ex) {}
return null;
}
public WikiCommentFeedEntry findFeedEntry(WikiComment comment) {
try {
return (WikiCommentFeedEntry)restrictedEntityManager
.createQuery("select fe from WikiCommentFeedEntry fe where fe.comment = :comment")
.setParameter("comment", comment)
.getSingleResult();
} catch (EntityNotFoundException ex) {
} catch (NoResultException ex) {}
return null;
}
public List<FeedEntry> findLastFeedEntries(Long feedId, int maxResults) {
return (List<FeedEntry>) restrictedEntityManager
.createQuery("select fe from Feed f join f.feedEntries fe where f.id = :feedId order by fe.updatedDate desc")
.setParameter("feedId", feedId)
.setMaxResults(maxResults)
.getResultList();
}
public boolean isOnSiteFeed(WikiDocument document) {
if (document == null || document.getId() == null) throw new IllegalArgumentException("document is null or unsaved");
Long count = (Long)restrictedEntityManager
.createQuery("select count(fe) from WikiDocumentFeedEntry fe, WikiFeed f join f.feedEntries allFe " +
" where f = :feed and fe.document = :doc and fe = allFe")
.setParameter("feed", ((WikiDirectory)Component.getInstance("wikiRoot")).getFeed() )
.setParameter("doc", document)
.setHint("org.hibernate.cacheable", true)
.getSingleResult();
return count != 0;
}
/* ############################# FEED CUD ################################ */
public void createFeed(WikiDirectory dir) {
WikiURLRenderer urlRenderer = (WikiURLRenderer)Component.getInstance(WikiURLRenderer.class);
WikiFeed feed = new WikiFeed();
feed.setDirectory(dir);
feed.setLink(urlRenderer.renderURL(dir));
feed.setAuthor(dir.getCreatedBy().getFullname());
feed.setTitle(dir.getName());
feed.setDescription(dir.getDescription());
dir.setFeed(feed);
}
public void updateFeed(WikiDirectory dir) {
WikiURLRenderer urlRenderer = (WikiURLRenderer)Component.getInstance(WikiURLRenderer.class);
dir.getFeed().setLink(urlRenderer.renderURL(dir));
dir.getFeed().setTitle(dir.getName());
dir.getFeed().setAuthor(dir.getCreatedBy().getFullname());
dir.getFeed().setDescription(dir.getDescription());
}
public void removeFeed(WikiDirectory dir) {
restrictedEntityManager.remove(dir.getFeed());
dir.setFeed(null);
}
/* ############################# FEEDENTRY CUD ################################ */
public void createFeedEntry(WikiDirectory parentDir, WikiNode node, FeedEntry feedEntry, boolean pushOnSiteFeed) {
List<WikiFeed> feeds = findParentFeeds(parentDir, pushOnSiteFeed);
// Now create a feedentry and link it to all the feeds
if (feeds.size() >0) {
log.debug("persisting new feed entry for: " + node);
restrictedEntityManager.persist(feedEntry);
for (Feed feed : feeds) {
log.debug("linking new feed entry with feed: " + feed.getId());
feed.getFeedEntries().add(feedEntry);
}
} else {
log.debug("no available feeds found");
}
}
public void updateFeedEntry(WikiDirectory parentDir, WikiNode node, FeedEntry feedEntry, boolean pushOnSiteFeed) {
log.debug("updating feed entry: " + feedEntry.getId());
feedEntry.setUpdatedDate(new Date());
// Link feed entry with all feeds (there might be new feeds since this feed entry was created)
List<WikiFeed> feeds = findParentFeeds(parentDir, pushOnSiteFeed);
for (Feed feed : feeds) {
log.debug("linking feed entry with feed: " + feed.getId());
feed.getFeedEntries().add(feedEntry);
}
}
public void removeFeedEntry(List<WikiFeed> feeds, FeedEntry feedEntry) {
if (feedEntry == null) return;
// Unlink feed entry from all feeds
for (Feed feed : feeds) {
log.debug("remove feed entry from feed: " + feed);
feed.getFeedEntries().remove(feedEntry);
}
log.debug("deleting feed entry");
restrictedEntityManager.remove(feedEntry);
}
public void purgeOldFeedEntries(Date olderThan) {
log.debug("cleaning up feed entries older than: " + olderThan);
// Clean up _all_ feed entries that are older than N days
List<Feed> feedsWithOutdatedEntries =
restrictedEntityManager
.createQuery("select distinct f from FeedEntry fe, WikiFeed f join f.feedEntries allFe " +
" where fe = allFe and fe.publishedDate < :oldestDate")
.setParameter("oldestDate", olderThan)
.getResultList();
for (Feed feed : feedsWithOutdatedEntries) {
log.debug("feed has outdated entries: " + feed);
Iterator<FeedEntry> it = feed.getFeedEntries().iterator();
while (it.hasNext()) {
FeedEntry feedEntry = it.next();
if (feedEntry.getPublishedDate().compareTo(olderThan) < 0) {
log.debug("removing outdated feed entry: " + feedEntry);
it.remove(); // Unlink from feed
restrictedEntityManager.remove(feedEntry);
}
}
}
}
}