fr.mael.microrss.dao.impl.UserArticleDaoImpl.java Source code

Java tutorial

Introduction

Here is the source code for fr.mael.microrss.dao.impl.UserArticleDaoImpl.java

Source

/*
   Copyright  2013 Mael Le Guvel
   This work is free. You can redistribute it and/or modify it under the
   terms of the Do What The Fuck You Want To Public License, Version 2,
   as published by Sam Hocevar. See the COPYING file for more details.
*/
package fr.mael.microrss.dao.impl;

import java.io.IOException;
import java.util.List;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.queryParser.MultiFieldQueryParser;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.InvalidTokenOffsetsException;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
import org.apache.lucene.search.highlight.SimpleSpanFragmenter;
import org.apache.lucene.util.Version;
import org.hibernate.CacheMode;
import org.hibernate.Criteria;
import org.hibernate.FetchMode;
import org.hibernate.FlushMode;
import org.hibernate.Query;
import org.hibernate.ScrollMode;
import org.hibernate.ScrollableResults;
import org.hibernate.criterion.Property;
import org.hibernate.search.FullTextQuery;
import org.hibernate.search.FullTextSession;
import org.hibernate.search.Search;
import org.springframework.stereotype.Repository;

import fr.mael.microrss.dao.UserArticleDao;
import fr.mael.microrss.domain.Feed;
import fr.mael.microrss.domain.User;
import fr.mael.microrss.domain.UserArticle;
import fr.mael.microrss.domain.UserLabel;

@Repository
public class UserArticleDaoImpl extends GenericDaoImpl<UserArticle> implements UserArticleDao {

    @Override
    public List<UserArticle> articlesForFeedAndUser(User user, Feed feed, int start, int nb) {
        StringBuffer query = new StringBuffer("select ua from UserArticle ua ");
        query.append("inner join fetch ua.article a ");
        query.append("inner join fetch a.feeds f ");
        query.append("inner join f.userFeeds uf ");
        query.append("left join fetch ua.userLabels ");
        query.append("where uf.user = :user ");
        query.append("and ua.user = :user ");
        query.append("and f = :feed ");
        Query q = getSession().createQuery(query.toString());
        q.setEntity("user", user);
        q.setEntity("feed", feed);
        q.setFirstResult(start);
        q.setMaxResults(nb);
        return (List<UserArticle>) q.list();
    }

    public List<UserArticle> search(String queryStr, User user, int start, int nb)
            throws ParseException, IOException, InvalidTokenOffsetsException {
        FullTextSession searchSession = Search.getFullTextSession(getSessionFactory().getCurrentSession());
        QueryParser parser = new MultiFieldQueryParser(Version.LUCENE_31,
                new String[] { "article.content", "article.title" }, new StandardAnalyzer(Version.LUCENE_31));
        org.apache.lucene.search.Query query = parser.parse(queryStr);
        FullTextQuery hibQuery = searchSession.createFullTextQuery(query, UserArticle.class);
        Criteria fetchingStrategy = searchSession.createCriteria(UserArticle.class);
        fetchingStrategy.setFetchMode("article.feed", FetchMode.JOIN);
        fetchingStrategy.setFetchMode("userLabels", FetchMode.JOIN);
        fetchingStrategy.add(Property.forName("user").eq(user));
        hibQuery.setCriteriaQuery(fetchingStrategy);
        hibQuery.setFirstResult(start);
        hibQuery.setMaxResults(nb);

        QueryScorer scorer = new QueryScorer(query);
        SimpleHTMLFormatter formatter = new SimpleHTMLFormatter("[highlight]", "[/highlight]");
        Highlighter highlighter = new Highlighter(formatter, scorer);
        highlighter.setTextFragmenter(new SimpleSpanFragmenter(scorer, 200));

        List<UserArticle> userArticles = (List<UserArticle>) hibQuery.list();

        for (UserArticle userArticle : userArticles) {
            String highlight = highlighter.getBestFragment(new StandardAnalyzer(Version.LUCENE_32), "content",
                    userArticle.getArticle().getContent());
            if (highlight != null) {
                highlight = highlight.replaceAll("\\<.*?>", "").replace("\n", " ");
                userArticle.getArticle().setHighlight(highlight);
            }
        }

        return userArticles;
    }

    @Override
    public void read(Integer userArticleId) {
        StringBuffer query = new StringBuffer("update UserArticle ua ");
        query.append("set read = :isRead ");
        query.append("where ua.id = :articleId ");
        Query q = getSession().createQuery(query.toString());
        q.setBoolean("isRead", true);
        q.setInteger("articleId", userArticleId);
        q.executeUpdate();
    }

    public void reindex() {
        FullTextSession searchSession = null;
        searchSession = Search.getFullTextSession(getSessionFactory().getCurrentSession());
        searchSession.setFlushMode(FlushMode.MANUAL);
        searchSession.setCacheMode(CacheMode.IGNORE);
        searchSession.purgeAll(UserArticle.class);
        manageResults(UserArticle.class, searchSession);
    }

    private void manageResults(Class clazz, FullTextSession searchSession) {
        ScrollableResults results = searchSession.createCriteria(clazz).setFetchMode("article", FetchMode.JOIN)
                .setFetchSize(100).scroll(ScrollMode.FORWARD_ONLY);
        int index = 0;
        while (results.next()) {
            index++;
            searchSession.index(results.get(0));
            if (index % 100 == 0) {
                searchSession.flushToIndexes();
                searchSession.clear();
            }
        }
        searchSession.flushToIndexes();
        searchSession.clear();

    }

    @Override
    public void read(Integer[] userArticleIds) {
        StringBuffer query = new StringBuffer("update UserArticle ua ");
        query.append("set read = :isRead ");
        query.append("where ua.id in (:articleIds) ");
        Query q = getSession().createQuery(query.toString());
        q.setBoolean("isRead", true);
        q.setParameterList("articleIds", userArticleIds);
        q.executeUpdate();
    }

    @Override
    public List<UserArticle> getForLabel(UserLabel label, int start, int nb) {
        StringBuffer query = new StringBuffer("select ua from UserArticle ua ");
        query.append("left join fetch ua.userLabels ");
        query.append("inner join ua.userLabels ul ");
        query.append("where ul = :label ");
        Query q = getSession().createQuery(query.toString());
        q.setEntity("label", label);
        q.setFirstResult(start);
        q.setMaxResults(nb);
        return (List<UserArticle>) q.list();
    }

    @Override
    public void star(Integer userArticleId, boolean star) {
        StringBuffer query = new StringBuffer("update UserArticle ua ");
        query.append("set starred = :starred ");
        query.append("where ua.id = :articleId ");
        Query q = getSession().createQuery(query.toString());
        q.setBoolean("starred", star);
        q.setInteger("articleId", userArticleId);
        q.executeUpdate();
    }

    @Override
    public List<UserArticle> getStarred(User user, int start, int nb) {
        StringBuffer query = new StringBuffer("from UserArticle ua ");
        query.append("left join fetch ua.userLabels ");
        query.append("where ua.starred = :starred ");
        query.append("and ua.user = :user ");
        Query q = getSession().createQuery(query.toString());
        q.setBoolean("starred", true);
        q.setEntity("user", user);
        q.setFirstResult(start);
        q.setMaxResults(nb);
        return (List<UserArticle>) q.list();
    }

    @Override
    public Long unreadStarred(User user) {
        StringBuffer query = new StringBuffer("select count(ua) from UserArticle ua ");
        query.append("where ua.user = :user ");
        query.append("and ua.read = :read ");
        query.append("and ua.starred = :starred");
        Query q = getSession().createQuery(query.toString());
        q.setEntity("user", user);
        q.setBoolean("read", false);
        q.setBoolean("starred", true);
        return (Long) q.uniqueResult();
    }

    @Override
    public Long labelUnread(User user, UserLabel label) {
        StringBuffer query = new StringBuffer("select count(ua) from UserArticle ua ");
        query.append("inner join ua.userLabels ul ");
        query.append("where ua.user = :user ");
        query.append("and ua.read = :read ");
        query.append("and ul = :label ");
        Query q = getSession().createQuery(query.toString());
        q.setEntity("user", user);
        q.setBoolean("read", false);
        q.setEntity("label", label);
        return (Long) q.uniqueResult();
    }

}