package sagan.blog.support; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import sagan.blog.Post; import sagan.blog.PostCategory; import sagan.blog.PostFormat; import sagan.support.DateFactory; import sagan.support.nav.PageableFactory; import sagan.support.nav.PaginationInfo; import sagan.team.MemberProfile; import sagan.team.support.TeamRepository; import java.security.Principal; import java.util.Collections; import javax.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import static org.springframework.web.bind.annotation.RequestMethod.*; /** * Controller that handles administrative blog actions, e.g. creating, editing and * deleting posts. Per rules in {@code sagan.SecurityConfig}, authentication is required * for all requests. See {@link BlogController} for public, read-only operations. */ @Controller @RequestMapping("/admin/blog") class BlogAdminController { private BlogService service; private TeamRepository teamRepository; private DateFactory dateFactory; @Autowired public BlogAdminController(BlogService service, TeamRepository teamRepository, DateFactory dateFactory) { this.service = service; this.teamRepository = teamRepository; this.dateFactory = dateFactory; } @RequestMapping(value = "", method = { GET, HEAD }) public String dashboard(Model model, @RequestParam(defaultValue = "1") int page) { Page<PostView> postViewPage = PostView.pageOf(service.getPublishedPosts(PageableFactory.forDashboard(page)), dateFactory); model.addAttribute("posts", postViewPage); model.addAttribute("paginationInfo", new PaginationInfo(postViewPage)); if(page == 1) { model.addAttribute("drafts", PostView.pageOf(service.getDraftPosts(PageableFactory.all()), dateFactory)); model.addAttribute("scheduled", PostView.pageOf(service.getScheduledPosts(PageableFactory.all()), dateFactory)); } else { Page<PostView> emptyPage = new PageImpl<PostView>(Collections.emptyList(), PageableFactory.all(), 0); model.addAttribute("drafts", emptyPage); model.addAttribute("scheduled", emptyPage); } return "admin/blog/index"; } @RequestMapping(value = "/new", method = { GET, HEAD }) public String newPost(Model model) { model.addAttribute("postForm", new PostForm()); model.addAttribute("categories", PostCategory.values()); model.addAttribute("formats", PostFormat.values()); return "admin/blog/new"; } @RequestMapping(value = "/{postId:[0-9]+}{slug:.*}/edit", method = { GET, HEAD }) public String editPost(@PathVariable Long postId, @PathVariable String slug, Model model) { Post post = service.getPost(postId); PostForm postForm = new PostForm(post); String path = PostView.of(post, dateFactory).getPath(); model.addAttribute("categories", PostCategory.values()); model.addAttribute("formats", PostFormat.values()); model.addAttribute("postForm", postForm); model.addAttribute("post", post); model.addAttribute("path", path); return "admin/blog/edit"; } @RequestMapping(value = "/{postId:[0-9]+}{slug:.*}", method = { GET, HEAD }) public String showPost(@PathVariable Long postId, @PathVariable String slug, Model model) { model.addAttribute("post", PostView.of(service.getPost(postId), dateFactory)); return "admin/blog/show"; } @RequestMapping(value = "", method = { POST }) public String createPost(Principal principal, @Valid PostForm postForm, BindingResult bindingResult, Model model) { if (bindingResult.hasErrors()) { model.addAttribute("categories", PostCategory.values()); model.addAttribute("formats", PostFormat.values()); return "admin/blog/new"; } else { MemberProfile memberProfile = teamRepository.findById(new Long(principal.getName())); try { Post post = service.addPost(postForm, memberProfile.getUsername()); PostView postView = PostView.of(post, dateFactory); return "redirect:" + postView.getPath() + "/edit"; } catch (DataIntegrityViolationException ex) { model.addAttribute("categories", PostCategory.values()); model.addAttribute("postForm", postForm); bindingResult.rejectValue("title", "duplicate_post", "A blog post with this publication date and title already exists"); return "admin/blog/new"; } } } @RequestMapping(value = "/{postId:[0-9]+}{slug:.*}/edit", method = PUT) public String updatePost(@PathVariable Long postId, @Valid PostForm postForm, BindingResult bindingResult, Model model) { Post post = service.getPost(postId); if (!bindingResult.hasErrors()) { service.updatePost(post, postForm); } PostView postView = PostView.of(post, dateFactory); String path = postView.getPath(); model.addAttribute("categories", PostCategory.values()); model.addAttribute("formats", PostFormat.values()); model.addAttribute("post", post); model.addAttribute("path", path); return "/admin/blog/edit"; } @RequestMapping(value = "/{postId:[0-9]+}{slug:.*}", method = DELETE) public String deletePost(@PathVariable Long postId) { Post post = service.getPost(postId); service.deletePost(post); return "redirect:/admin/blog"; } @RequestMapping(value = "resummarize", method = POST) public String resummarizeAllBlogPosts() { service.resummarizeAllPosts(); return "redirect:/admin/blog"; } @RequestMapping(value = "refreshblogposts", method = POST) @ResponseBody public String refreshBlogPosts( @RequestParam(value="page", defaultValue = "1", required = false) int page, @RequestParam(value="size", defaultValue = "10", required = false) int size) { Page<Post> posts = service.refreshPosts(page, size); return String.format("{page: %s, pageSize: %s, totalPages: %s, totalElements: %s}", posts.getNumber(), posts.getSize(), posts.getTotalPages(), posts.getTotalElements()); } }