package com.dodo.blog.server.impl;
import com.comvai.services.persistence.LowLevel;
import com.comvai.services.persistence.PersistenceManager;
import com.comvai.services.persistence.criteria.Criteria;
import com.comvai.services.persistence.criteria.Order;
import com.comvai.services.persistence.criteria.Restrictions;
import com.dodo.blog.exception.UserAlreadyRated;
import com.dodo.blog.model.Article;
import com.dodo.blog.model.Category;
import com.dodo.blog.model.Rate;
import com.dodo.blog.model.Tag;
import com.dodo.blog.request.ArticlesRequest;
import com.dodo.blog.server.ArticleService;
import com.dodo.blog.server.CategoryService;
import com.dodo.blog.server.TagService;
import org.apache.commons.lang.StringUtils;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
/**
* @author <a href="mailto:pohorelec@comvai.com">Jozef Pohorelec</a>
*/
public class ArticleServiceBean
extends AbstractServiceBean
implements ArticleService
{
private final TagService tagService;
private final CategoryService categoryService;
@Inject
public ArticleServiceBean( @LowLevel PersistenceManager datastore, CategoryService categoryService, TagService tagService )
{
super( datastore );
this.categoryService = categoryService;
this.tagService = tagService;
}
@Override
public void saveArticle( Article article )
{
save( article );
}
@Override
public Article getArticleById( Long articleId )
{
return datastore.find( Article.class, articleId );
}
@Override
public List<Article> getArticles( ArticlesRequest request )
{
if ( request.getTag() != null )
{
List<Article> tagList = new ArrayList<Article>();
Tag tag = tagService.getTagByNormalizedName( request.getTag() );
// return empty result if tag was not found
if ( tag == null )
{
return tagList;
}
tagList.addAll( getTagList( "tag_1", request, tag ) );
tagList.addAll( getTagList( "tag_2", request, tag ) );
tagList.addAll( getTagList( "tag_3", request, tag ) );
tagList.addAll( getTagList( "tag_4", request, tag ) );
tagList.addAll( getTagList( "tag_5", request, tag ) );
Collections.sort( tagList, new Comparator<Article>()
{
@Override
public int compare( Article o1, Article o2 )
{
return o2.getCreatedDate().compareTo( o1.getCreatedDate() );
}
} );
if ( tagList.size() > request.getMaxRows() )
{
return tagList.subList( 0, request.getMaxRows() );
}
else
{
return tagList;
}
}
else
{
Criteria<Article> criteria = Criteria.create( Article.class );
processCriteria( criteria, request );
if ( request.getCategory() != null )
{
Category category = categoryService.getCategoryByNormalizedName( request.getCategory() );
// return empty result if category was not found
if ( category == null )
{
return new ArrayList<Article>();
}
criteria.addCriteria( Restrictions.eq( "category", category.getId() ) );
}
if ( request.isPublished() != null )
{
criteria.addCriteria( Restrictions.eq( "published", true ) );
}
if ( !StringUtils.isBlank( request.getYear() ) )
{
criteria.addCriteria( Restrictions.eq( "year", request.getYear() ) );
}
if ( !StringUtils.isBlank( request.getMonth() ) )
{
criteria.addCriteria( Restrictions.eq( "month", request.getMonth() ) );
}
if ( !StringUtils.isBlank( request.getDay() ) )
{
criteria.addCriteria( Restrictions.eq( "day", request.getDay() ) );
}
return datastore.list( criteria );
}
}
@Override
public List<Article> getMostViewedArticles()
{
Criteria<Article> criteria = Criteria.create( Article.class );
criteria.addCriteria( Restrictions.eq( "published", true ) );
criteria.addOrderRule( "viewed", Order.DESC );
criteria.setMaxResults( 5 );
return datastore.list( criteria );
}
@Override
public List<Article> getBestRatedArticles()
{
Criteria<Article> criteria = Criteria.create( Article.class );
criteria.addCriteria( Restrictions.eq( "published", true ) );
criteria.addOrderRule( "rate", Order.DESC );
criteria.setMaxResults( 5 );
return datastore.list( criteria );
}
@Override
public List<Article> getRecentArticles()
{
Criteria<Article> criteria = Criteria.create( Article.class );
criteria.addCriteria( Restrictions.eq( "published", true ) );
criteria.addOrderRule( "publishedDate", Order.DESC );
criteria.setMaxResults( 5 );
return datastore.list( criteria );
}
private List<Article> getTagList( String tagProperty, ArticlesRequest request, Tag tag )
{
Criteria<Article> criteria = Criteria.create( Article.class );
processCriteria( criteria, request );
criteria.addCriteria( Restrictions.eq( tagProperty, tag.getId() ) );
if ( request.isPublished() != null )
{
criteria.addCriteria( Restrictions.eq( "published", true ) );
}
return datastore.list( criteria );
}
@Override
public void deleteArticle( Long articleId )
{
datastore.delete( Article.class, articleId );
}
@Override
public Article rate( Long articleId, Long accountId, Long rate ) throws UserAlreadyRated
{
if ( isArticleRated( articleId, accountId ) )
{
throw new UserAlreadyRated();
}
Article article = getArticleById( articleId );
if ( article != null && accountId != null )
{
// rate article
article.incrementRate( rate );
save( article );
// create Rate entity that holds info whether user already voted for this article or not
save( new Rate( articleId, accountId ) );
}
return article;
}
@Override
public boolean isArticleRated( Long articleId, Long accountId )
{
Criteria<Rate> criteria = Criteria.create( Rate.class );
criteria.addCriteria( Restrictions.eq( "articleId", articleId ) );
criteria.addCriteria( Restrictions.eq( "accountId", accountId ) );
return datastore.list( criteria ).size() > 0;
}
@Override
public void publishArticle( Long articleId )
{
Article article = getArticleById( articleId );
article.setPublished( true );
article.setPublishedDate( new Date() );
saveArticle( article );
}
@Override
public void hideArticle( Long articleId )
{
Article article = getArticleById( articleId );
article.setPublished( false );
article.setPublishedDate( null );
saveArticle( article );
}
}