/**
   * Getting by Category Example URL: http://localhost:8080/webstore/products/smartphone
   *
   * @param model
   * @param productCategory
   * @return
   */
  @RequestMapping("/{category}")
  public String getProductsByCategory(
      Model model, @PathVariable("category") String productCategory) {
    List<Product> products = productService.getProductsByCategory(productCategory);

    if (null == products || products.isEmpty()) {
      throw new NoProductFoundException();
    }

    model.addAttribute("products", productService.getProductsByCategory(productCategory));
    return "products";
  }
  /**
   * Example URL: http://localhost:8080/webstore/products/filter/tablet/price;low=200;high= 400
   *
   * @param model
   * @param productCategory
   * @param filterParams
   * @return
   */
  @RequestMapping("filter/{category}/{price}")
  public String filterProductsByCategoryAndPrice(
      Model model,
      @PathVariable("category") String productCategory,
      @MatrixVariable(pathVar = "price") Map<String, List<String>> priceRange) {

    List<Product> finalResults = new ArrayList<Product>();

    finalResults = productService.getProductsByCategory(productCategory);
    finalResults.retainAll(productService.getProductsByPriceFilter(priceRange));

    model.addAttribute("products", finalResults);
    return "products";
  }
  /**
   * Example URL: http://localhost:8080/webstore/products/pricefilter/price;low=150;high= 400
   *
   * @param model
   * @param productCategory
   * @param filterParams
   * @return
   */
  @RequestMapping("/pricefilter/{price}")
  public String filterProductsByPrice(
      Model model, @MatrixVariable(pathVar = "price") Map<String, List<String>> priceRange) {

    model.addAttribute("products", productService.getProductsByPriceFilter(priceRange));
    return "products";
  }
  /**
   * Example URL: http://localhost:8080/webstore/products/add
   *
   * <p>Called when a POST is requested
   *
   * @param newProduct
   * @return
   */
  @RequestMapping(value = "/add", method = RequestMethod.POST)
  public String processAddNewProductForm(
      @ModelAttribute("newProduct") @Valid Product newProduct,
      BindingResult result,
      HttpServletRequest request) {
    if (result.hasErrors()) {
      return "addProduct";
    }

    String[] suppressedFields = result.getSuppressedFields();
    if (suppressedFields.length > 0) {
      throw new RuntimeException(
          "Attempting to bind disallowed fields: "
              + StringUtils.arrayToCommaDelimitedString(suppressedFields));
    }

    MultipartFile productImage = newProduct.getProductImage();
    MultipartFile productManual = newProduct.getProductManual();

    String rootDirectory = request.getSession().getServletContext().getRealPath("/");

    if (productImage != null && !productImage.isEmpty()) {
      try {
        productImage.transferTo(
            new File(rootDirectory + "resources\\images\\" + newProduct.getProductId() + ".jpg"));
      } catch (Exception e) {
        throw new RuntimeException("Product Image saving failed", e);
      }
    }

    if (productManual != null && !productManual.isEmpty()) {
      try {
        productManual.transferTo(
            new File(rootDirectory + "resources\\pdf\\" + newProduct.getProductId() + ".pdf"));
      } catch (Exception e) {
        throw new RuntimeException("Product Manual saving failed", e);
      }
    }

    productService.addProduct(newProduct);
    return "redirect:/products";
  }
 /**
  * Retrieving via HTTP GET Example URL: http://localhost:8080/webstore/products/product?id=P7888
  *
  * @param productId
  * @param model
  * @return
  */
 @RequestMapping("/product")
 public String getProductById(Model model, @RequestParam("id") String productId) {
   model.addAttribute("product", productService.getProductById(productId));
   return "product";
 }
 /**
  * Using a MatrixVariable Example URL:
  * http://localhost:8080/webstore/products/filter/ByCriteria;brand=apple, dell;category=laptop
  *
  * @param filterParams
  * @param model
  * @return
  */
 @RequestMapping("/filter/{ByCriteria}")
 public String getProductsByFilter(
     @MatrixVariable(pathVar = "ByCriteria") Map<String, List<String>> filterParams, Model model) {
   model.addAttribute("products", productService.getProductsByFilter(filterParams));
   return "products";
 }
 @RequestMapping("/all")
 public String allProducts(Model model) {
   model.addAttribute("products", productService.getAllProducts());
   return "products";
 }