package sagan.blog.support;
import sagan.blog.Post;
import sagan.blog.PostCategory;
import sagan.blog.PostMovedException;
import sagan.support.DateFactory;
import sagan.support.nav.Navigation;
import sagan.support.nav.PageableFactory;
import sagan.support.nav.PaginationInfo;
import java.util.List;
import org.joda.time.LocalDate;
import org.joda.time.YearMonth;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.view.RedirectView;
import sagan.support.nav.Section;
import static org.springframework.web.bind.annotation.RequestMethod.*;
/**
* Controller that handles read-only blog actions, e.g. listing, paging, and showing
* individual published {@link Post}s. See {@link BlogAdminController} for administrative
* operations.
*/
@Controller
@RequestMapping("/blog")
@Navigation(Section.BLOG)
class BlogController {
private final BlogService service;
private final DateFactory dateFactory;
@Autowired
public BlogController(BlogService service, DateFactory dateFactory) {
this.service = service;
this.dateFactory = dateFactory;
}
@RequestMapping(value = "/{year:\\d+}/{month:\\d+}/{day:\\d+}/{slug}", method = { GET, HEAD })
public String showPost(@PathVariable String year, @PathVariable String month, @PathVariable String day,
@PathVariable String slug, Model model) {
String publicSlug = String.format("%s/%s/%s/%s", year, month, day, slug);
Post post = service.getPublishedPost(publicSlug);
model.addAttribute("post", PostView.of(post, dateFactory));
model.addAttribute("categories", PostCategory.values());
model.addAttribute("activeCategory", post.getCategory().getDisplayName());
model.addAttribute("disqusShortname", service.getDisqusShortname());
return "blog/show";
}
@RequestMapping(value = "", method = { GET, HEAD })
public String listPublishedPosts(Model model, @RequestParam(defaultValue = "1") int page) {
Pageable pageRequest = PageableFactory.forLists(page);
Page<Post> result = service.getPublishedPosts(pageRequest);
return renderListOfPosts(result, model, "All Posts");
}
@RequestMapping(value = "/category/{category}", method = { GET, HEAD })
public String listPublishedPostsForCategory(@PathVariable("category") PostCategory category, Model model,
@RequestParam(defaultValue = "1", value = "page") int page) {
Pageable pageRequest = PageableFactory.forLists(page);
Page<Post> result = service.getPublishedPosts(category, pageRequest);
return renderListOfPosts(result, model, category.getDisplayName());
}
@RequestMapping(value = "/broadcasts", method = { GET, HEAD })
public String listPublishedBroadcasts(Model model, @RequestParam(defaultValue = "1", value = "page") int page) {
Pageable pageRequest = PageableFactory.forLists(page);
Page<Post> result = service.getPublishedBroadcastPosts(pageRequest);
return renderListOfPosts(result, model, "Broadcasts");
}
@RequestMapping(value = "/{year:\\d+}/{month:\\d+}/{day:\\d+}", method = { GET, HEAD })
public String listPublishedPostsForDate(@PathVariable int year, @PathVariable int month, @PathVariable int day,
@RequestParam(defaultValue = "1", value = "page") int page, Model model) {
Pageable pageRequest = PageableFactory.forLists(page);
Page<Post> result = service.getPublishedPostsByDate(year, month, day, pageRequest);
LocalDate date = new LocalDate(year, month, day);
model.addAttribute("title", "Archive for " + date.toString("MMMM dd, yyyy"));
return renderListOfPosts(result, model, "All Posts");
}
@RequestMapping(value = "/{year:\\d+}/{month:\\d+}", method = { GET, HEAD })
public String listPublishedPostsForYearAndMonth(@PathVariable int year, @PathVariable int month,
@RequestParam(defaultValue = "1", value = "page") int page,
Model model) {
Pageable pageRequest = PageableFactory.forLists(page);
Page<Post> result = service.getPublishedPostsByDate(year, month, pageRequest);
YearMonth yearMonth = new YearMonth(year, month);
model.addAttribute("title", "Archive for " + yearMonth.toString("MMMM yyyy"));
return renderListOfPosts(result, model, "All Posts");
}
@RequestMapping(value = "/{year:\\d+}", method = { GET, HEAD })
public String listPublishedPostsForYear(@PathVariable int year,
@RequestParam(defaultValue = "1", value = "page") int page, Model model) {
Pageable pageRequest = PageableFactory.forLists(page);
Page<Post> result = service.getPublishedPostsByDate(year, pageRequest);
model.addAttribute("title", String.format("Archive for %d", year));
return renderListOfPosts(result, model, "All Posts");
}
@ExceptionHandler
public RedirectView handle(PostMovedException moved) {
RedirectView redirect = new RedirectView();
redirect.setStatusCode(HttpStatus.MOVED_PERMANENTLY);
redirect.setUrl("/blog/" + moved.getPublicSlug());
return redirect;
}
private String renderListOfPosts(Page<Post> page, Model model, String activeCategory) {
Page<PostView> postViewPage = PostView.pageOf(page, dateFactory);
List<PostView> posts = postViewPage.getContent();
model.addAttribute("activeCategory", activeCategory);
model.addAttribute("categories", PostCategory.values());
model.addAttribute("posts", posts);
model.addAttribute("paginationInfo", new PaginationInfo(postViewPage));
model.addAttribute("disqusShortname", service.getDisqusShortname());
return "blog/index";
}
}