From c775cd9810a860d1ce337d45d8d6cfc8f20f448b Mon Sep 17 00:00:00 2001
From: manirDev <mhtnourmhtmjr@gmail.com>
Date: Wed, 23 Nov 2022 13:15:14 +0300
Subject: [PATCH] product image upload using file storage

---
 .../ProductImageGalleryController.java        | 11 ++++
 .../dto/FileDataDto.java                      | 11 ++++
 .../model/FileData.java                       | 31 ++++++++++
 .../model/Product.java                        |  4 ++
 .../repository/ImageGalleryRepository.java    |  7 +++
 .../service/ImageGalleryService.java          |  9 +++
 .../service/Impl/ImageGalleryServiceImpl.java | 60 +++++++++++++++++++
 7 files changed, 133 insertions(+)
 create mode 100644 src/main/java/com/manir/springbootecommercerestapi/dto/FileDataDto.java
 create mode 100644 src/main/java/com/manir/springbootecommercerestapi/model/FileData.java
 create mode 100644 src/main/java/com/manir/springbootecommercerestapi/repository/ImageGalleryRepository.java
 create mode 100644 src/main/java/com/manir/springbootecommercerestapi/service/ImageGalleryService.java
 create mode 100644 src/main/java/com/manir/springbootecommercerestapi/service/Impl/ImageGalleryServiceImpl.java

diff --git a/src/main/java/com/manir/springbootecommercerestapi/controller/ProductImageGalleryController.java b/src/main/java/com/manir/springbootecommercerestapi/controller/ProductImageGalleryController.java
index 028cee9..87e102e 100644
--- a/src/main/java/com/manir/springbootecommercerestapi/controller/ProductImageGalleryController.java
+++ b/src/main/java/com/manir/springbootecommercerestapi/controller/ProductImageGalleryController.java
@@ -1,5 +1,6 @@
 package com.manir.springbootecommercerestapi.controller;
 
+import com.manir.springbootecommercerestapi.service.ImageGalleryService;
 import com.manir.springbootecommercerestapi.service.ProductImageGalleryService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpStatus;
@@ -13,6 +14,8 @@ public class ProductImageGalleryController {
 
     @Autowired
     private ProductImageGalleryService productImageGalleryService;
+    @Autowired
+    private ImageGalleryService imageGalleryService;
 
 
     //add image to product api
@@ -22,4 +25,12 @@ public ResponseEntity<String> addImageToProduct(@PathVariable Long productId,
         productImageGalleryService.addImageToProduct(productId, file);
         return new ResponseEntity<>("Image  successfully added to product with id : " + productId, HttpStatus.CREATED);
     }
+
+    //add image to product using file system
+    @PostMapping("/{productId}/addImage")
+    public ResponseEntity<String> addImageToProductFileSystem(@PathVariable Long productId,
+                                                    @RequestParam("file")MultipartFile file){
+        imageGalleryService.addImageToProduct(productId, file);
+        return new ResponseEntity<>("Image  successfully added to product with id : " + productId, HttpStatus.CREATED);
+    }
 }
diff --git a/src/main/java/com/manir/springbootecommercerestapi/dto/FileDataDto.java b/src/main/java/com/manir/springbootecommercerestapi/dto/FileDataDto.java
new file mode 100644
index 0000000..0e43e9d
--- /dev/null
+++ b/src/main/java/com/manir/springbootecommercerestapi/dto/FileDataDto.java
@@ -0,0 +1,11 @@
+package com.manir.springbootecommercerestapi.dto;
+
+import lombok.Data;
+
+@Data
+public class FileDataDto {
+    private Long id;
+    private String name;
+    private String type;
+    private String filePath;
+}
diff --git a/src/main/java/com/manir/springbootecommercerestapi/model/FileData.java b/src/main/java/com/manir/springbootecommercerestapi/model/FileData.java
new file mode 100644
index 0000000..d7944ed
--- /dev/null
+++ b/src/main/java/com/manir/springbootecommercerestapi/model/FileData.java
@@ -0,0 +1,31 @@
+package com.manir.springbootecommercerestapi.model;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import javax.persistence.*;
+
+@Getter
+@Setter
+@AllArgsConstructor
+@NoArgsConstructor
+@Entity
+@Table(name = "product_images_gallery")
+public class FileData extends BaseEntity{
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+    @Column(name = "name")
+    private String name;
+    @Column(name = "type")
+    private String type;
+    @Column(name = "filePath")
+    private String filePath;
+
+    //relation with product entity
+    @ManyToOne(fetch = FetchType.EAGER)
+    @JoinColumn(name = "product_id")
+    private Product product;
+}
diff --git a/src/main/java/com/manir/springbootecommercerestapi/model/Product.java b/src/main/java/com/manir/springbootecommercerestapi/model/Product.java
index 1333432..63e32b4 100644
--- a/src/main/java/com/manir/springbootecommercerestapi/model/Product.java
+++ b/src/main/java/com/manir/springbootecommercerestapi/model/Product.java
@@ -46,6 +46,10 @@ public class Product extends BaseEntity{
     @OneToMany(mappedBy = "product", cascade = CascadeType.ALL, orphanRemoval = true)
     private Set<ImageData> images;
 
+    //relation image gallery
+    @OneToMany(mappedBy = "product", cascade = CascadeType.ALL, orphanRemoval = true)
+    private Set<FileData> productImages;
+
     //relation to product comment
     @OneToMany(mappedBy = "product", cascade = CascadeType.ALL, orphanRemoval = true)
     private Set<Comment> comments;
diff --git a/src/main/java/com/manir/springbootecommercerestapi/repository/ImageGalleryRepository.java b/src/main/java/com/manir/springbootecommercerestapi/repository/ImageGalleryRepository.java
new file mode 100644
index 0000000..f2e5cf3
--- /dev/null
+++ b/src/main/java/com/manir/springbootecommercerestapi/repository/ImageGalleryRepository.java
@@ -0,0 +1,7 @@
+package com.manir.springbootecommercerestapi.repository;
+
+import com.manir.springbootecommercerestapi.model.FileData;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface ImageGalleryRepository extends JpaRepository<FileData, Long> {
+}
diff --git a/src/main/java/com/manir/springbootecommercerestapi/service/ImageGalleryService.java b/src/main/java/com/manir/springbootecommercerestapi/service/ImageGalleryService.java
new file mode 100644
index 0000000..bf81a92
--- /dev/null
+++ b/src/main/java/com/manir/springbootecommercerestapi/service/ImageGalleryService.java
@@ -0,0 +1,9 @@
+package com.manir.springbootecommercerestapi.service;
+
+import com.manir.springbootecommercerestapi.model.FileData;
+import com.manir.springbootecommercerestapi.model.ImageData;
+import org.springframework.web.multipart.MultipartFile;
+
+public interface ImageGalleryService {
+    FileData addImageToProduct(Long productId, MultipartFile file);
+}
diff --git a/src/main/java/com/manir/springbootecommercerestapi/service/Impl/ImageGalleryServiceImpl.java b/src/main/java/com/manir/springbootecommercerestapi/service/Impl/ImageGalleryServiceImpl.java
new file mode 100644
index 0000000..3bd413b
--- /dev/null
+++ b/src/main/java/com/manir/springbootecommercerestapi/service/Impl/ImageGalleryServiceImpl.java
@@ -0,0 +1,60 @@
+package com.manir.springbootecommercerestapi.service.Impl;
+
+import com.manir.springbootecommercerestapi.exception.ResourceNotFoundException;
+import com.manir.springbootecommercerestapi.model.FileData;
+import com.manir.springbootecommercerestapi.model.Product;
+import com.manir.springbootecommercerestapi.repository.ImageGalleryRepository;
+import com.manir.springbootecommercerestapi.repository.ProductRepository;
+import com.manir.springbootecommercerestapi.service.ImageGalleryService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+@Service
+public class ImageGalleryServiceImpl implements ImageGalleryService {
+
+    private static final Path FOLDER_PATH = Paths.get("fileStorage");
+
+    @Autowired
+    private ImageGalleryRepository imageGalleryRepository;
+    @Autowired
+    private ProductRepository productRepository;
+
+
+    @Override
+    public FileData addImageToProduct(Long productId, MultipartFile file) {
+        Product product = productRepository.findById(productId).orElseThrow(
+                () -> new ResourceNotFoundException("Product", productId)
+        );
+
+        FileData  createdImage = null;
+        String filePath = FOLDER_PATH + "/" + file.getOriginalFilename();
+
+        try {
+            createdImage = imageGalleryRepository.save(uploadFile(file,product));
+            file.transferTo(new File(filePath));
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+
+        return createdImage;
+    }
+
+    private FileData uploadFile(MultipartFile file, Product product) throws IOException {
+
+        String filePath = FOLDER_PATH + "/" + file.getOriginalFilename();
+        FileData fileData = new FileData();
+        fileData.setName(file.getOriginalFilename());
+        fileData.setType(file.getContentType());
+        fileData.setFilePath(filePath);
+        fileData.setProduct(product);
+
+        return fileData;
+    }
+}
