package sagan.blog.support; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Cacheable; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; import sagan.blog.Post; import sagan.blog.PostCategory; import sagan.blog.PostMovedException; import sagan.blog.PostNotFoundException; import sagan.search.support.SearchService; import sagan.support.DateFactory; import sagan.team.MemberProfile; import java.util.Collections; import java.util.Date; import java.util.List; /** * Service providing high-level, selectively cached data access and other {@link Post} * -related operations. */ @Service public class BlogService { private static final Log logger = LogFactory.getLog(BlogService.class); public static final String CACHE_NAME = "cache.blog"; public static final Class CACHE_TYPE = Post.class; public static final String CACHE_TTL = "${cache.blog.timetolive:60}"; private final PostFormAdapter postFormAdapter; private final PostRepository postRepository; private final SearchService searchService; private final DateFactory dateFactory; private final PostSearchEntryMapper mapper = new PostSearchEntryMapper(); @Value("${disqus_shortname}") private String disqusShortname; @Autowired public BlogService(PostRepository postRepository, PostFormAdapter postFormAdapter, DateFactory dateFactory, SearchService searchService) { this.postRepository = postRepository; this.postFormAdapter = postFormAdapter; this.dateFactory = dateFactory; this.searchService = searchService; } // Property methods public String getDisqusShortname() { return disqusShortname; } // Query methods public Post getPost(Long postId) { Post post = postRepository.findOne(postId); if (post == null) { throw new PostNotFoundException(postId); } return post; } public Post getPost(String title, Date createdAt) { return postRepository.findByTitleAndCreatedAt(title, createdAt); } public Page<Post> getDraftPosts(Pageable pageRequest) { return postRepository.findByDraftTrue(pageRequest); } public Page<Post> getScheduledPosts(Pageable pageRequest) { return postRepository.findByDraftFalseAndPublishAtAfter(dateFactory.now(), pageRequest); } public Page<Post> getPublishedPosts(Pageable pageRequest) { return postRepository.findByDraftFalseAndPublishAtBeforeOrderByPublishAtDesc(dateFactory.now(), pageRequest); } @Cacheable(CACHE_NAME) public Post getPublishedPost(String publicSlug) { Date now = dateFactory.now(); Post post = postRepository.findByPublicSlugAndDraftFalseAndPublishAtBefore(publicSlug, now); if (post == null) { post = postRepository.findByPublicSlugAliasesInAndDraftFalseAndPublishAtBefore( Collections.singleton(publicSlug), now); if (post != null) { throw new PostMovedException(post.getPublicSlug()); } throw new PostNotFoundException(publicSlug); } return post; } public List<Post> getAllPublishedPosts() { return postRepository.findByDraftFalseAndPublishAtBeforeOrderByPublishAtDesc(dateFactory.now()); } public Page<Post> getPublishedPostsByDate(int year, int month, int day, Pageable pageRequest) { return postRepository.findByDate(year, month, day, pageRequest); } public Page<Post> getPublishedPostsByDate(int year, int month, Pageable pageRequest) { return postRepository.findByDate(year, month, pageRequest); } public Page<Post> getPublishedPostsByDate(int year, Pageable pageRequest) { return postRepository.findByDate(year, pageRequest); } public Page<Post> getPublishedPosts(PostCategory category, Pageable pageRequest) { return postRepository.findByCategoryAndDraftFalseAndPublishAtBefore(category, dateFactory.now(), pageRequest); } public Page<Post> getPublishedBroadcastPosts(Pageable pageRequest) { return postRepository.findByBroadcastAndDraftFalseAndPublishAtBefore(true, dateFactory.now(), pageRequest); } public Page<Post> getPublishedPostsForMember(MemberProfile profile, Pageable pageRequest) { return postRepository.findByDraftFalseAndAuthorAndPublishAtBeforeOrderByPublishAtDesc(profile, dateFactory.now(), pageRequest); } public Page<Post> getAllPosts(Pageable pageRequest) { return postRepository.findAll(pageRequest); } public Post addPost(PostForm postForm, String username) { Post post = postFormAdapter.createPostFromPostForm(postForm, username); postRepository.save(post); saveToIndex(post); return post; } @CacheEvict(value = CACHE_NAME, key = "#post.publicSlug", condition="#post.publicSlug != null") public void updatePost(Post post, PostForm postForm) { postFormAdapter.updatePostFromPostForm(post, postForm); postRepository.save(post); saveToIndex(post); } @CacheEvict(value = CACHE_NAME, key = "#post.publicSlug", condition="#post.publicSlug != null") public void deletePost(Post post) { postRepository.delete(post); } private void saveToIndex(Post post) { if (post.isLiveOn(dateFactory.now())) { try { searchService.saveToIndex(mapper.map(post)); } catch (Exception e) { logger.error(e); } } } public void resummarizeAllPosts() { List<Post> posts = postRepository.findAll(); for (Post post : posts) { postFormAdapter.summarize(post); postRepository.save(post); } } public Page<Post> refreshPosts(int page, int size) { PageRequest pageRequest = new PageRequest(page, size, Sort.Direction.DESC, "id"); Page<Post> posts = postRepository.findAll(pageRequest); for (Post post : posts) { postFormAdapter.refreshPost(post); postRepository.save(post); } return posts; } }