package com.chrisbaileydeveloper.bookshelf.controller; import java.io.IOException; import java.io.InputStream; import java.util.List; import java.util.Locale; import javax.servlet.http.HttpServletRequest; import javax.validation.Valid; import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.MessageSource; import org.springframework.http.MediaType; 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 org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.mvc.support.RedirectAttributes; import com.chrisbaileydeveloper.bookshelf.domain.Book; import com.chrisbaileydeveloper.bookshelf.service.BookService; import com.chrisbaileydeveloper.bookshelf.web.util.ImageUtil; import com.chrisbaileydeveloper.bookshelf.web.util.Message; import com.chrisbaileydeveloper.bookshelf.web.util.UrlUtil; @RequestMapping("/") @Controller public class BookController { final Logger logger = LoggerFactory.getLogger(BookController.class); @Autowired private BookService bookService; @Autowired private MessageSource messageSource; /** * List all books. */ @RequestMapping(method = RequestMethod.GET) public String list(Model model) { logger.info("Listing books"); List<Book> books = bookService.findAll(); model.addAttribute("books", books); logger.info("No. of books: " + books.size()); return "books/list"; } /** * Retrieve the book with the specified id. */ @RequestMapping(value = "/{id}", method = RequestMethod.GET) public String show(@PathVariable("id") Long id, Model model) { logger.info("Listing book with id: " + id); Book book = bookService.findById(id); model.addAttribute("book", book); return "books/show"; } /** * Retrieve the book with the specified id for the update form. */ @RequestMapping(value = "/update/{id}", method = RequestMethod.GET) public String updateForm(@PathVariable("id") Long id, Model model) { model.addAttribute("book", bookService.findById(id)); return "books/create"; } /** * Create a new book and place in Model attribute. */ @RequestMapping(value="/create", method=RequestMethod.GET) public String createForm(Model model) { model.addAttribute("book", new Book()); return "books/create"; } /** * Create/update a book. */ @RequestMapping(value="/create", method = RequestMethod.POST) public String create(@Valid Book book, BindingResult bindingResult, Model model, HttpServletRequest httpServletRequest, RedirectAttributes redirectAttributes, Locale locale, @RequestParam(value = "file", required = false) MultipartFile file) { if (bindingResult.hasErrors()) { model.addAttribute("book", book); return "books/create"; } logger.info("Creating/updating book"); model.asMap().clear(); redirectAttributes.addFlashAttribute("message", new Message( "success", messageSource.getMessage("book_save_success", new Object[] {}, locale))); // Process upload file if (!file.isEmpty() && (file.getContentType().equals(MediaType.IMAGE_JPEG_VALUE) || file.getContentType().equals(MediaType.IMAGE_PNG_VALUE) || file.getContentType().equals(MediaType.IMAGE_GIF_VALUE))) { logger.info("File name: " + file.getName()); logger.info("File size: " + file.getSize()); logger.info("File content type: " + file.getContentType()); byte[] fileContent = null; String imageString = null; try { InputStream inputStream = file.getInputStream(); fileContent = IOUtils.toByteArray(inputStream); // Convert byte[] into String image imageString = ImageUtil.encodeToString(fileContent); book.setPhoto(imageString); } catch (IOException ex) { logger.error("Error saving uploaded file"); book.setPhoto(ImageUtil.smallNoImage()); } } else { // File is improper type or no file was uploaded. // If book already exists, load its image into the 'book' object. if (book.getId() != null) { Book savedBook = bookService.findById(book.getId()); book.setPhoto(savedBook.getPhoto()); } else {// Else set to default no-image picture. book.setPhoto(ImageUtil.smallNoImage()); } } bookService.save(book); return "redirect:/" + UrlUtil.encodeUrlPathSegment(book.getId().toString(), httpServletRequest); } /** * Returns the photo for the book with the specified id. */ @RequestMapping(value = "/photo/{id}", method = RequestMethod.GET, produces = MediaType.IMAGE_JPEG_VALUE) @ResponseBody public byte[] downloadPhoto(@PathVariable("id") Long id) { Book book = bookService.findById(id); logger.info("Downloading photo for id: {} with size: {}", book.getId(), book.getPhoto().length()); // Convert String image into byte[] byte[] imageBytes = ImageUtil.decode(book.getPhoto()); return imageBytes; } /** * Deletes the book with the specified id. */ @RequestMapping(value = "/delete/{id}", method = RequestMethod.GET) public String delete(@PathVariable Long id, Model model, Locale locale) { logger.info("Deleting book with id: " + id); Book book = bookService.findById(id); if (book != null) { bookService.delete(book); logger.info("Book deleted successfully"); model.addAttribute("message", new Message("success", messageSource.getMessage( "book_delete_success", new Object[] {}, locale))); } List<Book> books = bookService.findAll(); model.addAttribute("books", books); return "books/list"; } @RequestMapping(value="/reset", method=RequestMethod.GET) public String resetDatabase(Model model) { logger.info("Resetting database to original state"); bookService.deleteAll(); bookService.restoreDefaultBooks(); List<Book> books = bookService.findAll(); model.addAttribute("books", books); return "books/list"; } }