add Platform and Brand DTOs, mappers, and controllers; update security configuration for CORS
This commit is contained in:
@@ -4,9 +4,11 @@ import fr.gameovergne.api.service.security.JpaUserDetailsService;
|
|||||||
import fr.gameovergne.api.service.security.filter.JwtAuthFilter;
|
import fr.gameovergne.api.service.security.filter.JwtAuthFilter;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
import org.springframework.security.authentication.AuthenticationManager;
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
import org.springframework.security.authentication.AuthenticationProvider;
|
import org.springframework.security.authentication.AuthenticationProvider;
|
||||||
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
|
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
|
||||||
|
import org.springframework.security.config.Customizer;
|
||||||
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
|
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
|
||||||
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
@@ -17,8 +19,10 @@ import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
|||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
import org.springframework.security.web.SecurityFilterChain;
|
import org.springframework.security.web.SecurityFilterChain;
|
||||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||||
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
import org.springframework.web.cors.CorsConfiguration;
|
||||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
import org.springframework.web.cors.CorsConfigurationSource;
|
||||||
|
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableWebSecurity
|
@EnableWebSecurity
|
||||||
@@ -36,35 +40,37 @@ public class SecurityConfig {
|
|||||||
@Bean
|
@Bean
|
||||||
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
||||||
http
|
http
|
||||||
|
.cors(Customizer.withDefaults())
|
||||||
.csrf(AbstractHttpConfigurer::disable)
|
.csrf(AbstractHttpConfigurer::disable)
|
||||||
.authorizeHttpRequests(authz -> authz
|
.authorizeHttpRequests(authz -> authz
|
||||||
|
.requestMatchers(HttpMethod.OPTIONS, "/**").permitAll() // autoriser les preflight
|
||||||
.requestMatchers("/api/auth/**").permitAll()
|
.requestMatchers("/api/auth/**").permitAll()
|
||||||
.requestMatchers("/api/users/**").authenticated()
|
.requestMatchers("/api/users/**").authenticated()
|
||||||
.requestMatchers("/api/brands/**").authenticated()
|
.requestMatchers("/api/brands/**").permitAll()
|
||||||
|
.requestMatchers("/api/platforms/**").permitAll()
|
||||||
.anyRequest().permitAll()
|
.anyRequest().permitAll()
|
||||||
)
|
)
|
||||||
|
|
||||||
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
||||||
.authenticationProvider(authenticationProvider())
|
.authenticationProvider(authenticationProvider())
|
||||||
.addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class)
|
.addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class)
|
||||||
|
|
||||||
.httpBasic(AbstractHttpConfigurer::disable)
|
.httpBasic(AbstractHttpConfigurer::disable)
|
||||||
.formLogin(AbstractHttpConfigurer::disable);
|
.formLogin(AbstractHttpConfigurer::disable);
|
||||||
|
|
||||||
return http.build();
|
return http.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public WebMvcConfigurer corsConfigurer() {
|
public CorsConfigurationSource corsConfigurationSource() {
|
||||||
return new WebMvcConfigurer() {
|
CorsConfiguration config = new CorsConfiguration();
|
||||||
@Override
|
config.setAllowedOrigins(Arrays.asList("http://localhost:4200", "http://127.0.0.1:4200"));
|
||||||
public void addCorsMappings(CorsRegistry registry) {
|
config.setAllowedMethods(Arrays.asList("GET","POST","PUT","DELETE","OPTIONS"));
|
||||||
registry.addMapping("/**")
|
config.setAllowedHeaders(Arrays.asList("Authorization","Content-Type","Accept"));
|
||||||
.allowedOrigins("http://localhost:4200", "http://127.0.0.1:4200")
|
config.setExposedHeaders(Arrays.asList("Authorization"));
|
||||||
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
|
config.setAllowCredentials(true);
|
||||||
.allowedHeaders("*")
|
|
||||||
.allowCredentials(true);
|
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
||||||
}
|
source.registerCorsConfiguration("/**", config);
|
||||||
};
|
return source;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
package fr.gameovergne.api.controller.app;
|
package fr.gameovergne.api.controller.app;
|
||||||
|
|
||||||
|
import fr.gameovergne.api.dto.app.BrandDTO;
|
||||||
|
import fr.gameovergne.api.mapper.app.BrandMapper;
|
||||||
import fr.gameovergne.api.model.app.Brand;
|
import fr.gameovergne.api.model.app.Brand;
|
||||||
import fr.gameovergne.api.service.app.BrandService;
|
import fr.gameovergne.api.service.app.BrandService;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
@@ -13,10 +16,12 @@ import java.util.List;
|
|||||||
public class BrandController {
|
public class BrandController {
|
||||||
|
|
||||||
private final BrandService brandService;
|
private final BrandService brandService;
|
||||||
|
private final BrandMapper brandMapper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public BrandController(BrandService brandService) {
|
public BrandController(BrandService brandService, BrandMapper brandMapper) {
|
||||||
this.brandService = brandService;
|
this.brandService = brandService;
|
||||||
|
this.brandMapper = brandMapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping
|
@GetMapping
|
||||||
@@ -32,12 +37,14 @@ public class BrandController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping
|
@PostMapping
|
||||||
public void saveBrand(@RequestBody Brand brand) {
|
public void saveBrand(@RequestBody BrandDTO brandDTO) {
|
||||||
brandService.saveBrand(brand);
|
brandService.saveBrand(brandMapper.fromDto(brandDTO));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PutMapping("/{id}")
|
@PutMapping("/{id}")
|
||||||
public ResponseEntity<Brand> updateBrand(@PathVariable Long id, @RequestBody Brand brand) {
|
public ResponseEntity<Brand> updateBrand(@PathVariable Long id, @RequestBody BrandDTO brandDTO) {
|
||||||
|
Brand brand = brandMapper.fromDto(brandDTO);
|
||||||
|
brand.setId(id);
|
||||||
return brandService.getBrandById(id)
|
return brandService.getBrandById(id)
|
||||||
.map(existingBrand -> brandService.updateBrand(brand)
|
.map(existingBrand -> brandService.updateBrand(brand)
|
||||||
.map(ResponseEntity::ok)
|
.map(ResponseEntity::ok)
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
package fr.gameovergne.api.controller.app;
|
||||||
|
|
||||||
|
import fr.gameovergne.api.dto.app.PlatformDTO;
|
||||||
|
import fr.gameovergne.api.mapper.app.PlatformMapper;
|
||||||
|
import fr.gameovergne.api.model.app.Platform;
|
||||||
|
import fr.gameovergne.api.service.app.PlatformService;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/platforms")
|
||||||
|
public class PlatformController {
|
||||||
|
|
||||||
|
private final PlatformService platformService;
|
||||||
|
private final PlatformMapper platformMapper;
|
||||||
|
|
||||||
|
public PlatformController(PlatformService platformService, PlatformMapper platformMapper) {
|
||||||
|
this.platformService = platformService;
|
||||||
|
this.platformMapper = platformMapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
public List<PlatformDTO> getAllPlatforms() {
|
||||||
|
return platformService.getAllPlatforms()
|
||||||
|
.stream()
|
||||||
|
.map(platformMapper::toDto)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public ResponseEntity<Platform> getPlatformById(@PathVariable Long id) {
|
||||||
|
return platformService.getPlatformById(id)
|
||||||
|
.map(ResponseEntity::ok)
|
||||||
|
.orElse(ResponseEntity.notFound().build());
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping
|
||||||
|
public void savePlatform(@RequestBody PlatformDTO platformDTO) {
|
||||||
|
platformService.savePlatform(platformMapper.fromDto(platformDTO));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping("/{id}")
|
||||||
|
public ResponseEntity<Platform> updatePlatform(@PathVariable Long id, @RequestBody PlatformDTO platformDTO) {
|
||||||
|
Platform platform = platformMapper.fromDto(platformDTO);
|
||||||
|
platform.setId(id);
|
||||||
|
return platformService.getPlatformById(id)
|
||||||
|
.map(existingPlatform -> platformService.updatePlatform(platform)
|
||||||
|
.map(ResponseEntity::ok)
|
||||||
|
.orElse(ResponseEntity.notFound().build()))
|
||||||
|
.orElse(ResponseEntity.notFound().build());
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/{id}")
|
||||||
|
public ResponseEntity<Platform> deletePlatformById(@PathVariable Long id) {
|
||||||
|
return platformService.deletePlatformById(id)
|
||||||
|
.map(platform -> ResponseEntity.ok().body(platform))
|
||||||
|
.orElse(ResponseEntity.notFound().build());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -27,7 +27,6 @@ public class AuthController {
|
|||||||
|
|
||||||
@PostMapping("/register")
|
@PostMapping("/register")
|
||||||
public ResponseEntity<AuthResponse> register(@RequestBody UserDTO dto) {
|
public ResponseEntity<AuthResponse> register(@RequestBody UserDTO dto) {
|
||||||
System.out.println("Registering: " + dto);
|
|
||||||
return authService.register(UserMapper.fromDto(dto))
|
return authService.register(UserMapper.fromDto(dto))
|
||||||
.map((ResponseEntity::ok))
|
.map((ResponseEntity::ok))
|
||||||
.orElse(ResponseEntity.badRequest().build());
|
.orElse(ResponseEntity.badRequest().build());
|
||||||
@@ -35,7 +34,6 @@ public class AuthController {
|
|||||||
|
|
||||||
@PostMapping("/login")
|
@PostMapping("/login")
|
||||||
public ResponseEntity<AuthResponse> authenticate(@RequestBody AuthRequest request, HttpServletResponse response) {
|
public ResponseEntity<AuthResponse> authenticate(@RequestBody AuthRequest request, HttpServletResponse response) {
|
||||||
System.out.println("Authenticating: " + request);
|
|
||||||
return authService.authenticate(request)
|
return authService.authenticate(request)
|
||||||
.map(authResponse -> createAuthResponse(authResponse, response))
|
.map(authResponse -> createAuthResponse(authResponse, response))
|
||||||
.orElse(ResponseEntity.badRequest().build());
|
.orElse(ResponseEntity.badRequest().build());
|
||||||
|
|||||||
15
api/src/main/java/fr/gameovergne/api/dto/app/BrandDTO.java
Normal file
15
api/src/main/java/fr/gameovergne/api/dto/app/BrandDTO.java
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package fr.gameovergne.api.dto.app;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class BrandDTO {
|
||||||
|
|
||||||
|
@JsonProperty("name")
|
||||||
|
private String name;
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package fr.gameovergne.api.dto.app;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class PlatformDTO {
|
||||||
|
|
||||||
|
@JsonProperty("name")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@JsonProperty("brand")
|
||||||
|
private BrandDTO brandDTO;
|
||||||
|
}
|
||||||
@@ -12,6 +12,5 @@ public class UserDTO {
|
|||||||
private String lastName;
|
private String lastName;
|
||||||
private String username;
|
private String username;
|
||||||
private String email;
|
private String email;
|
||||||
private String password; // Note: In a real application, avoid sending passwords in DTOs
|
|
||||||
private String role;
|
private String role;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package fr.gameovergne.api.mapper.app;
|
||||||
|
|
||||||
|
import fr.gameovergne.api.dto.app.BrandDTO;
|
||||||
|
import fr.gameovergne.api.model.app.Brand;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class BrandMapper {
|
||||||
|
|
||||||
|
public Brand fromDto(BrandDTO brandDTO) {
|
||||||
|
if (brandDTO == null) return null;
|
||||||
|
Brand brand = new Brand();
|
||||||
|
brand.setName(brandDTO.getName());
|
||||||
|
return brand;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BrandDTO toDto(Brand brand) {
|
||||||
|
if (brand == null) return null;
|
||||||
|
BrandDTO brandDTO = new BrandDTO();
|
||||||
|
brandDTO.setName(brand.getName());
|
||||||
|
return brandDTO;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package fr.gameovergne.api.mapper.app;
|
||||||
|
|
||||||
|
import fr.gameovergne.api.dto.app.BrandDTO;
|
||||||
|
import fr.gameovergne.api.dto.app.PlatformDTO;
|
||||||
|
import fr.gameovergne.api.model.app.Platform;
|
||||||
|
import fr.gameovergne.api.service.app.BrandService;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class PlatformMapper {
|
||||||
|
|
||||||
|
private final BrandService brandService;
|
||||||
|
|
||||||
|
public PlatformMapper(BrandService brandService) {
|
||||||
|
this.brandService = brandService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Platform fromDto(PlatformDTO platformDTO) {
|
||||||
|
if (platformDTO == null) return null;
|
||||||
|
Platform platform = new Platform();
|
||||||
|
platform.setName(platformDTO.getName());
|
||||||
|
if (platformDTO.getBrandDTO() != null && platformDTO.getBrandDTO().getName() != null) {
|
||||||
|
platform.setBrand(this.brandService.getBrandByName(platformDTO.getBrandDTO().getName()).orElse(null));
|
||||||
|
} else {
|
||||||
|
platform.setBrand(null);
|
||||||
|
}
|
||||||
|
return platform;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PlatformDTO toDto(Platform platform) {
|
||||||
|
if (platform == null) return null;
|
||||||
|
PlatformDTO platformDTO = new PlatformDTO();
|
||||||
|
platformDTO.setName(platform.getName());
|
||||||
|
if (platform.getBrand() != null) {
|
||||||
|
platformDTO.setBrandDTO(new BrandDTO(platform.getBrand().getName()));
|
||||||
|
} else {
|
||||||
|
platformDTO.setBrandDTO(null);
|
||||||
|
}
|
||||||
|
return platformDTO;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,7 +12,6 @@ public class UserMapper {
|
|||||||
user.setLastName(userDTO.getLastName());
|
user.setLastName(userDTO.getLastName());
|
||||||
user.setUsername(userDTO.getUsername());
|
user.setUsername(userDTO.getUsername());
|
||||||
user.setEmail(userDTO.getEmail());
|
user.setEmail(userDTO.getEmail());
|
||||||
user.setPassword(userDTO.getPassword());
|
|
||||||
user.setRole(Role.valueOf(userDTO.getRole() != null ? userDTO.getRole() : "USER"));
|
user.setRole(Role.valueOf(userDTO.getRole() != null ? userDTO.getRole() : "USER"));
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package fr.gameovergne.api.model.app;
|
package fr.gameovergne.api.model.app;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
|
||||||
import com.fasterxml.jackson.annotation.JsonManagedReference;
|
import com.fasterxml.jackson.annotation.JsonManagedReference;
|
||||||
|
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
import jakarta.validation.constraints.NotBlank;
|
import jakarta.validation.constraints.NotBlank;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
@@ -13,6 +15,7 @@ import java.util.List;
|
|||||||
@Data
|
@Data
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
|
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
|
||||||
@Table(name = "brands")
|
@Table(name = "brands")
|
||||||
public class Brand {
|
public class Brand {
|
||||||
|
|
||||||
@@ -25,6 +28,5 @@ public class Brand {
|
|||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
@OneToMany(mappedBy = "brand", cascade = CascadeType.ALL, orphanRemoval = true)
|
@OneToMany(mappedBy = "brand", cascade = CascadeType.ALL, orphanRemoval = true)
|
||||||
@JsonManagedReference
|
|
||||||
private List<Platform> platforms;
|
private List<Platform> platforms;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package fr.gameovergne.api.model.app;
|
package fr.gameovergne.api.model.app;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
|
||||||
import com.fasterxml.jackson.annotation.JsonManagedReference;
|
import com.fasterxml.jackson.annotation.JsonManagedReference;
|
||||||
|
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
import jakarta.validation.constraints.NotBlank;
|
import jakarta.validation.constraints.NotBlank;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
@@ -14,6 +16,7 @@ import java.util.List;
|
|||||||
@Data
|
@Data
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
|
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
|
||||||
@Table(name = "categories")
|
@Table(name = "categories")
|
||||||
public class Category {
|
public class Category {
|
||||||
|
|
||||||
@@ -26,6 +29,5 @@ public class Category {
|
|||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
@OneToMany(mappedBy = "category", cascade = CascadeType.ALL, orphanRemoval = true)
|
@OneToMany(mappedBy = "category", cascade = CascadeType.ALL, orphanRemoval = true)
|
||||||
@JsonManagedReference
|
|
||||||
private List<Product> products;
|
private List<Product> products;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package fr.gameovergne.api.model.app;
|
package fr.gameovergne.api.model.app;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonBackReference;
|
import com.fasterxml.jackson.annotation.JsonBackReference;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
|
||||||
|
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
|
||||||
import fr.gameovergne.api.model.user.User;
|
import fr.gameovergne.api.model.user.User;
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
import jakarta.validation.constraints.NotBlank;
|
import jakarta.validation.constraints.NotBlank;
|
||||||
@@ -14,6 +16,7 @@ import java.util.List;
|
|||||||
@Data
|
@Data
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
|
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
|
||||||
@Table(name = "images")
|
@Table(name = "images")
|
||||||
public class Image {
|
public class Image {
|
||||||
|
|
||||||
@@ -35,7 +38,6 @@ public class Image {
|
|||||||
joinColumns = @JoinColumn(name = "image_id"),
|
joinColumns = @JoinColumn(name = "image_id"),
|
||||||
inverseJoinColumns = @JoinColumn(name = "user_id")
|
inverseJoinColumns = @JoinColumn(name = "user_id")
|
||||||
)
|
)
|
||||||
@JsonBackReference
|
|
||||||
private List<User> users;
|
private List<User> users;
|
||||||
|
|
||||||
@ManyToMany(fetch = FetchType.EAGER, cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
|
@ManyToMany(fetch = FetchType.EAGER, cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
package fr.gameovergne.api.model.app;
|
package fr.gameovergne.api.model.app;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonBackReference;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
|
||||||
import com.fasterxml.jackson.annotation.JsonManagedReference;
|
import com.fasterxml.jackson.annotation.JsonManagedReference;
|
||||||
|
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
import jakarta.validation.constraints.NotBlank;
|
import jakarta.validation.constraints.NotBlank;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
@@ -13,6 +16,7 @@ import java.util.List;
|
|||||||
@Data
|
@Data
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
|
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
|
||||||
@Table(name = "platforms")
|
@Table(name = "platforms")
|
||||||
public class Platform {
|
public class Platform {
|
||||||
|
|
||||||
@@ -29,6 +33,5 @@ public class Platform {
|
|||||||
private Brand brand;
|
private Brand brand;
|
||||||
|
|
||||||
@OneToMany(mappedBy = "platform", cascade = CascadeType.ALL, orphanRemoval = true)
|
@OneToMany(mappedBy = "platform", cascade = CascadeType.ALL, orphanRemoval = true)
|
||||||
@JsonManagedReference
|
|
||||||
private List<Product> products;
|
private List<Product> products;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package fr.gameovergne.api.model.app;
|
package fr.gameovergne.api.model.app;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonBackReference;
|
import com.fasterxml.jackson.annotation.JsonBackReference;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
|
||||||
|
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
import jakarta.validation.constraints.NotBlank;
|
import jakarta.validation.constraints.NotBlank;
|
||||||
import jakarta.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
@@ -15,6 +17,7 @@ import java.util.List;
|
|||||||
@Data
|
@Data
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
|
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
|
||||||
@Table(name = "products")
|
@Table(name = "products")
|
||||||
public class Product {
|
public class Product {
|
||||||
|
|
||||||
@@ -39,12 +42,10 @@ public class Product {
|
|||||||
|
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
@JoinColumn(name = "category_id")
|
@JoinColumn(name = "category_id")
|
||||||
@JsonBackReference
|
|
||||||
private Category category;
|
private Category category;
|
||||||
|
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
@JoinColumn(name = "platform_id")
|
@JoinColumn(name = "platform_id")
|
||||||
@JsonBackReference
|
|
||||||
private Platform platform;
|
private Platform platform;
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package fr.gameovergne.api.repository.app;
|
||||||
|
|
||||||
|
import fr.gameovergne.api.model.app.Platform;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public interface PlatformRepository extends JpaRepository<Platform, Long> {
|
||||||
|
Optional<Platform> findById(Long id);
|
||||||
|
Optional<Platform> findByName(String name);
|
||||||
|
}
|
||||||
@@ -1,11 +1,13 @@
|
|||||||
package fr.gameovergne.api.service.app;
|
package fr.gameovergne.api.service.app;
|
||||||
|
|
||||||
import fr.gameovergne.api.model.app.Brand;
|
import fr.gameovergne.api.model.app.Brand;
|
||||||
|
import fr.gameovergne.api.model.app.Platform;
|
||||||
import fr.gameovergne.api.repository.app.BrandRepository;
|
import fr.gameovergne.api.repository.app.BrandRepository;
|
||||||
import jakarta.transaction.Transactional;
|
import jakarta.transaction.Transactional;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@@ -42,7 +44,20 @@ public class BrandService {
|
|||||||
public Optional<Brand> updateBrand(Brand brand) {
|
public Optional<Brand> updateBrand(Brand brand) {
|
||||||
return brandRepository.findById(brand.getId()).map(existingBrand -> {
|
return brandRepository.findById(brand.getId()).map(existingBrand -> {
|
||||||
existingBrand.setName(brand.getName());
|
existingBrand.setName(brand.getName());
|
||||||
existingBrand.setPlatforms(brand.getPlatforms());
|
|
||||||
|
List<Platform> newPlatforms = brand.getPlatforms();
|
||||||
|
if (newPlatforms != null) {
|
||||||
|
if (existingBrand.getPlatforms() == null) {
|
||||||
|
existingBrand.setPlatforms(new ArrayList<>());
|
||||||
|
} else {
|
||||||
|
existingBrand.getPlatforms().clear();
|
||||||
|
}
|
||||||
|
for (Platform p : newPlatforms) {
|
||||||
|
p.setBrand(existingBrand);
|
||||||
|
existingBrand.getPlatforms().add(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return brandRepository.save(existingBrand);
|
return brandRepository.save(existingBrand);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
package fr.gameovergne.api.service.app;
|
||||||
|
|
||||||
|
import fr.gameovergne.api.model.app.Platform;
|
||||||
|
import fr.gameovergne.api.model.app.Product;
|
||||||
|
import fr.gameovergne.api.repository.app.PlatformRepository;
|
||||||
|
import jakarta.transaction.Transactional;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class PlatformService {
|
||||||
|
|
||||||
|
private final PlatformRepository platformRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public PlatformService(PlatformRepository platformRepository) {
|
||||||
|
this.platformRepository = platformRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public void savePlatform(Platform platform) {
|
||||||
|
if (platform.getId() == null) {
|
||||||
|
platformRepository.save(platform);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Platform> getAllPlatforms() {
|
||||||
|
return platformRepository.findAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<Platform> getPlatformById(Long id) {
|
||||||
|
return platformRepository.findById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<Platform> getPlatformByName(String name) {
|
||||||
|
return platformRepository.findByName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public Optional<Platform> updatePlatform(Platform platform) {
|
||||||
|
return platformRepository.findById(platform.getId()).map(existingPlatform -> {
|
||||||
|
existingPlatform.setName(platform.getName());
|
||||||
|
existingPlatform.setBrand(platform.getBrand());
|
||||||
|
List<Product> newProducts = platform.getProducts();
|
||||||
|
if (newProducts != null) {
|
||||||
|
if (existingPlatform.getProducts() == null) {
|
||||||
|
existingPlatform.setProducts(new ArrayList<>());
|
||||||
|
} else {
|
||||||
|
existingPlatform.getProducts().clear();
|
||||||
|
}
|
||||||
|
for (Product p : newProducts) {
|
||||||
|
p.setPlatform(existingPlatform);
|
||||||
|
existingPlatform.getProducts().add(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return platformRepository.save(existingPlatform);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public Optional<Platform> deletePlatformById(Long id) {
|
||||||
|
Optional<Platform> platform = platformRepository.findById(id);
|
||||||
|
platform.ifPresent(platformRepository::delete);
|
||||||
|
return platform;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@ spring.application.name=api
|
|||||||
|
|
||||||
server.port=3000
|
server.port=3000
|
||||||
|
|
||||||
spring.datasource.url=jdbc:mysql://192.168.20.112:3306/gameovergne_app?useSSL=false&allowPublicKeyRetrieval=true
|
spring.datasource.url=jdbc:mysql://localhost:3306/gameovergne_app?useSSL=false&allowPublicKeyRetrieval=true
|
||||||
spring.datasource.username=gameovergne
|
spring.datasource.username=gameovergne
|
||||||
spring.datasource.password=gameovergne
|
spring.datasource.password=gameovergne
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user