package de.ppi.samples.fuwesta.frontend; import java.util.List; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.propertyeditors.StringTrimmerEditor; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.util.CollectionUtils; import org.springframework.validation.BindingResult; import org.springframework.validation.Validator; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.InitBinder; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import de.ppi.fuwesta.spring.mvc.bind.ServletBindingService; import de.ppi.fuwesta.spring.mvc.util.PageWrapper; import de.ppi.fuwesta.spring.mvc.util.ResourceNotFoundException; import de.ppi.samples.fuwesta.model.Post; import de.ppi.samples.fuwesta.model.Tag; import de.ppi.samples.fuwesta.model.User; import de.ppi.samples.fuwesta.service.api.PostService; /** * Controller for Create, Read, Update and Delete for the model Post. * */ @Controller() public class PostCRUDController implements InitializingBean { /** * The default view. */ private static final String POST_FORM = "example/post/postform"; /** * The partial view. */ private static final String PARTIAL_POST_FORM = "example/post/partialpostform"; /** * The Logger for the controller. */ private static final Logger LOG = LoggerFactory .getLogger(PostCRUDController.class); /** * Small service which helps to bind requestdata to an object. */ @Resource(shareable = false) private ServletBindingService servletBindingService; /** * The PostService instance. */ @Resource private PostService postService; /** * The generic validator. */ @Resource private Validator mvcValidator; /** * Added a {@link StringTrimmerEditor}. * * @param binder the WebDataBinder */ @InitBinder public void initBinder(final WebDataBinder binder) { binder.registerCustomEditor(String.class, new StringTrimmerEditor(true)); } /** * {@inheritDoc} */ @Override public void afterPropertiesSet() throws Exception { servletBindingService.registerCustomEditor(String.class, new StringTrimmerEditor(true)); } /** * List all posts. * * @param model the model. * @param pageRequest attributes for pagination. * @return String which defines the next page. */ @RequestMapping(value = { URL.Post.HOME, URL.Post.LIST }, method = RequestMethod.GET) public String list(Model model, Pageable pageRequest) { final PageWrapper<Post> postList = new PageWrapper<Post>(postService.getPost(pageRequest), URL.Post.LIST); if (postList.getSize() == 0) { LOG.info("No post found redirect to create"); return URL.redirect(URL.Post.CREATE); } model.addAttribute("pageRequest", pageRequest); model.addAttribute("postList", postList); return "example/post/list"; } /** * Create a new post form. * * @param model the model. * @return String which defines the next page. */ @RequestMapping(value = URL.Post.CREATE, method = RequestMethod.GET) public String create(Model model) { if (postService.getNrOfPosts() == 0) { model.addAttribute("message", "post.list_empty"); } addStandardModelData(new Post(), URL.Post.CREATE, false, postService.getAllUsers(), postService.getAllActiveTags(), model); return POST_FORM; } /** * Insert a new post. * * @param post the post. * @param result the binding result. * @param model the model. * @return String which defines the next page. */ @RequestMapping(value = URL.Post.CREATE, method = RequestMethod.POST) public String insert(@ModelAttribute("post") Post post, BindingResult result, Model model) { mvcValidator.validate(post, result); if (result.hasErrors()) { addStandardModelData(post, URL.Post.CREATE, false, postService.getAllUsers(), postService.getAllActiveTags(), model); return POST_FORM; } LOG.debug("Create Post: " + post); postService.save(post); return URL.redirect(URL.Post.LIST); } /** * Create confirmation for deleting a post. * * @param postId the Id of the post. * @param model the datamodel. * @return String which defines the next page. */ @RequestMapping(value = URL.Post.DELETE, method = RequestMethod.GET) public String deleteConfirm(@PathVariable(URL.Post.P_POSTID) Long postId, Model model) { LOG.debug("Confirm delete PostId: " + postId); model.addAttribute("deleteURL", URL.filledURL(URL.Post.DELETE, postId)); model.addAttribute("cancelURL", URL.filledURL(URL.Post.LIST)); return "example/confirmDelete"; } /** * Delete a post. * * @param postId the Id of the post. * @return String which defines the next page. */ @RequestMapping(value = URL.Post.DELETE, method = { RequestMethod.DELETE, RequestMethod.POST }) public String delete(@PathVariable(URL.Post.P_POSTID) Long postId) { LOG.debug("Delete PostId: " + postId); postService.delete(postId); LOG.debug("Deleted PostId: " + postId); return URL.redirect(URL.Post.LIST); } /** * Show a post. * * @param post der Post. * @param model the model. * @return String which defines the next page. */ @RequestMapping(value = URL.Post.SHOW, method = RequestMethod.GET) public String show(@PathVariable(URL.Post.P_POSTID) Post post, Model model) { LOG.debug("Show PostId: " + post.getId()); addStandardModelData(post, URL.Post.SHOW, true, postService.getAllUsers(), postService.getAllActiveTags(), model); return POST_FORM; } /** * Edit a post. * * @param postId the Id of the post. * @param model the model. * @return String which defines the next page. */ @RequestMapping(value = URL.Post.EDIT, method = RequestMethod.GET) public String edit(@PathVariable(URL.Post.P_POSTID) Long postId, Model model) { LOG.debug("Edit PostId: " + postId); Post post = postService.read(postId); if (post == null) { throw new ResourceNotFoundException("Post with id " + postId + " doesn't exist."); } List<Tag> allTags = getAllTags(post); addStandardModelData(post, URL.filledURL(URL.Post.EDIT, post.getId()), false, postService.getAllUsers(), allTags, model); return POST_FORM; } /** * Edit a post partial, i.e. the simple fields. * * @param postId the Id of the post. * @param model the model. * @return String which defines the next page. */ @RequestMapping(value = URL.Post.PARTIALEDIT, method = RequestMethod.GET) public String editSimpleFields( @PathVariable(URL.Post.P_POSTID) Long postId, Model model) { LOG.debug("Edit partial PostId: " + postId); Post post = postService.read(postId); if (post == null) { throw new ResourceNotFoundException("Post with id " + postId + " doesn't exist."); } addStandardModelData(post, URL.filledURL(URL.Post.PARTIALEDIT, post.getId()), false, null, null, model); return PARTIAL_POST_FORM; } /** * Get all active tags and tags which are used in the current post. * * @param post the current post. * @return all active tags and tags which are used in the current post. */ private List<Tag> getAllTags(Post post) { List<Tag> allTags = postService.getAllActiveTags(); if (post != null && !CollectionUtils.isEmpty(post.getTags())) { for (Tag tag : post.getTags()) { if (!allTags.contains(tag)) { allTags.add(tag); } } } return allTags; } /** * Update the post. * * @param post the post. * @param result the bindingsresult. * @param model the model * @return String which defines the next page. */ @RequestMapping(value = URL.Post.EDIT, method = RequestMethod.POST) public String update(@ModelAttribute("post") Post post, BindingResult result, Model model) { mvcValidator.validate(post, result); if (result.hasErrors()) { final List<Tag> allTags = getAllTags(post); addStandardModelData(post, URL.filledURL(URL.Post.EDIT, post.getId()), false, postService.getAllUsers(), allTags, model); return POST_FORM; } LOG.debug("Update Post: " + post); postService.save(post); return URL.redirect(URL.Post.LIST); } /** * Update the post. * * @param post the post. * @param request the request with the data. * @param model the model * @return String which defines the next page. */ @RequestMapping(value = URL.Post.PARTIALEDIT, method = RequestMethod.POST) public String updatePartial(@RequestParam("id") Post post, HttpServletRequest request, Model model) { if (servletBindingService.bindAndValidate(request, model, post, "post") .hasErrors()) { addStandardModelData(post, URL.filledURL(URL.Post.PARTIALEDIT, post.getId()), false, null, null, model); return PARTIAL_POST_FORM; } LOG.debug("Update Post: " + post); postService.save(post); return URL.redirect(URL.Post.LIST); } /** * Adds the standard model data. * * @param post the post * @param url the action URL. * @param disabled true if the data should be only show. * @param userList list of all user. * @param tagList list of all tags. * @param model the model */ private void addStandardModelData(Post post, String url, boolean disabled, List<User> userList, List<Tag> tagList, Model model) { LOG.info("Post: {}", post); if (post == null) { throw new ResourceNotFoundException(); } model.addAttribute("post", post); model.addAttribute("disabled", Boolean.valueOf(disabled)); model.addAttribute("url", url); model.addAttribute("users", userList); model.addAttribute("tags", tagList); } }