Backend part is done.

This commit is contained in:
Yuee Shiness 2023-05-23 15:46:50 +04:00
parent bbdcd30900
commit 5576f9e59e
48 changed files with 3222 additions and 295 deletions

Binary file not shown.

Binary file not shown.

BIN
.gradle/workspace-id.txt Normal file

Binary file not shown.

Binary file not shown.

2
.idea/compiler.xml generated
View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="11" />
<bytecodeTargetLevel target="17" />
</component>
</project>

6
.idea/encodings.xml generated Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/data.mv.db" charset="windows-1251" />
</component>
</project>

2
.idea/misc.xml generated
View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="17" project-jdk-type="JavaSDK" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK" />
</project>

View File

@ -17,6 +17,8 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'com.h2database:h2:2.1.214'
implementation 'junit:junit:4.13.2'
implementation 'org.springdoc:springdoc-openapi-ui:1.6.5'
implementation 'org.hibernate.validator:hibernate-validator'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

Binary file not shown.

2412
data.trace.db Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,42 @@
package ru.ulstu.is.sbapp.Customer.Controller;
import org.springframework.web.bind.annotation.*;
import ru.ulstu.is.sbapp.Customer.Service.CustomerService;
import java.util.List;
@RestController
@RequestMapping("/customer")
public class CustomerController {
private final CustomerService customerService;
public CustomerController(CustomerService customerService)
{
this.customerService = customerService;
}
@GetMapping("/{id}")
public CustomerDTO getCustomer(@PathVariable Long id) {
return new CustomerDTO(customerService.findCustomer(id));
}
@GetMapping
public List<CustomerDTO> getCustomers() {
return customerService.findAllCustomers().stream().map(CustomerDTO::new).toList();
}
@PostMapping
public CustomerDTO createCustomer(@RequestParam("fullName") String fullName, @RequestParam("password") String password ) {
return new CustomerDTO(customerService.addCustomer(fullName,password));
}
@PutMapping("/{id}")
public CustomerDTO updateCustomer(@PathVariable Long id, @RequestParam("fullName") String fullName) {
return new CustomerDTO(customerService.updateCustomer(id,fullName));
}
@DeleteMapping("/{id}")
public CustomerDTO deleteCustomer(@PathVariable Long id) {
return new CustomerDTO(customerService.deleteCustomer(id));
}
}

View File

@ -0,0 +1,47 @@
package ru.ulstu.is.sbapp.Customer.Controller;
import ru.ulstu.is.sbapp.Customer.Model.Customer;
import ru.ulstu.is.sbapp.Movie.Controller.MovieDTO;
import java.util.List;
public class CustomerDTO {
private final long id;
private final String first_name;
private final String middle_name;
private final String last_name;
private final String password;
private final List<MovieDTO> movies;
public CustomerDTO(Customer customer) {
this.id = customer.getId();
this.first_name = customer.getFirst_name();
this.middle_name = customer.getMiddle_name();
this.last_name = customer.getLast_name();
this.password = customer.getPassword();
this.movies = customer.getMovies().stream().map(MovieDTO::new).toList();
}
public long getID() {
return id;
}
public String getFirst_name() {
return first_name;
}
public String getLast_name() {
return last_name;
}
public String getMiddle_name() {
return middle_name;
}
public String getPassword() {
return password;
}
public List<MovieDTO> getMovies() {
return movies;
}
}

View File

@ -0,0 +1,7 @@
package ru.ulstu.is.sbapp.Customer.Exception;
public class CustomerNotFoundException extends RuntimeException{
public CustomerNotFoundException(Long id){
super(String.format("Customer with id [%s] is not found", id));
}
}

View File

@ -1,10 +1,13 @@
package ru.ulstu.is.sbapp.Models;
package ru.ulstu.is.sbapp.Customer.Model;
import ru.ulstu.is.sbapp.Movie.Model.Movie;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import javax.validation.constraints.NotBlank;
@Entity
public class Customer
@ -12,13 +15,17 @@ public class Customer
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(nullable = false)
@Column
@NotBlank(message = "Firstname can't be null or empty")
private String first_name;
@Column(nullable = false)
@Column
@NotBlank(message = "Lastname can't be null or empty")
private String last_name;
@Column()
@Column
private String middle_name;
@Column
@NotBlank(message = "Password can't be empty")
private String password;
@OneToMany(fetch = FetchType.EAGER)
private List<Movie> movies;
@ -27,11 +34,12 @@ public class Customer
{
}
public Customer(String fullName)
public Customer(String fullName,String password)
{
String[] partsName = fullName.split(" ");
this.first_name = partsName[0];
this.last_name = partsName[1];
this.password = password;
if(partsName.length == 3)
{
this.middle_name = partsName[2];
@ -43,6 +51,7 @@ public class Customer
{
return id;
}
public String getPassword() {return password;}
public String getFirst_name()
{

View File

@ -0,0 +1,7 @@
package ru.ulstu.is.sbapp.Customer.Repository;
import org.springframework.data.jpa.repository.JpaRepository;
import ru.ulstu.is.sbapp.Customer.Model.Customer;
public interface CustomerRepository extends JpaRepository<Customer, Long> {
}

View File

@ -0,0 +1,98 @@
package ru.ulstu.is.sbapp.Customer.Service;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import ru.ulstu.is.sbapp.Customer.Exception.CustomerNotFoundException;
import ru.ulstu.is.sbapp.Customer.Model.Customer;
import ru.ulstu.is.sbapp.Customer.Repository.CustomerRepository;
import ru.ulstu.is.sbapp.Utilities.validation.ValidatorUtil;
import javax.persistence.EntityNotFoundException;
import java.util.List;
import java.util.Optional;
@Service
public class CustomerService
{
private final CustomerRepository customerRepository;
private final ValidatorUtil validatorUtil;
public CustomerService(CustomerRepository customerRepository, ValidatorUtil validatorUtil) {
this.customerRepository = customerRepository;
this.validatorUtil = validatorUtil;
}
@Transactional
public Customer addCustomer(String fullName,String password)
{
if(!StringUtils.hasText(fullName))
{
throw new IllegalArgumentException("Customer's name or surname is missing");
}
if(!StringUtils.hasText(password))
{
throw new IllegalArgumentException("Customer's name or surname is missing");
}
final Customer customer = new Customer(fullName,password);
validatorUtil.validate(customer);
return customerRepository.save(customer);
}
@Transactional(readOnly = true)
public Customer findCustomer(Long id)
{
final Optional<Customer> student = customerRepository.findById(id);
return student.orElseThrow(() -> new CustomerNotFoundException(id));
}
@Transactional(readOnly = true)
public List<Customer> findAllCustomers()
{
return customerRepository.findAll();
}
@Transactional
public Customer updateCustomer(Long id, String fullName)
{
if(!StringUtils.hasText(fullName))
{
throw new IllegalArgumentException("Customer's name or surname is missing");
}
final Optional<Customer> customer = customerRepository.findById(id);
if(customer.isEmpty())
{
throw new CustomerNotFoundException(id);
}
final Customer specificCustomer = customer.get();
specificCustomer.setFirst_name(fullName);
specificCustomer.setLast_name(fullName);
specificCustomer.setMiddle_name(fullName);
validatorUtil.validate(specificCustomer);
return customerRepository.save(specificCustomer);
}
@Transactional
public Customer deleteCustomer(Long id)
{
final Optional<Customer> customer = customerRepository.findById(id);
if(customer.isEmpty())
{
throw new CustomerNotFoundException(id);
}
final Customer specificCustomer = customer.get();
customerRepository.delete(specificCustomer);
return specificCustomer;
}
@Transactional
public void deleteAllCustomers()
{
customerRepository.deleteAll();
}
}

View File

@ -0,0 +1,42 @@
package ru.ulstu.is.sbapp.Genre.Controller;
import org.springframework.web.bind.annotation.*;
import ru.ulstu.is.sbapp.Genre.Service.GenreService;
import java.util.List;
@RestController
@RequestMapping("/genre")
public class GenreContoller {
private final GenreService genreService;
public GenreContoller(GenreService genreService) {
this.genreService = genreService;
}
@GetMapping("/{id}")
public GenreDTO getGenre(@PathVariable Long id) {
return new GenreDTO(genreService.findGenre(id));
}
@GetMapping
public List<GenreDTO> getGenres() {
return genreService.findAllGenres().stream()
.map(GenreDTO::new)
.toList();
}
@PostMapping
public GenreDTO createGenre(@RequestParam("name") String name) {
return new GenreDTO(genreService.addGenre(name));
}
@PutMapping("/{id}")
public GenreDTO updateGenre(@PathVariable Long id,
@RequestParam("name") String name) {
return new GenreDTO(genreService.updateGenre(id,name));
}
@DeleteMapping("/{id}")
public GenreDTO deleteGenre(@PathVariable Long id) {
return new GenreDTO(genreService.deleteGenre(id));
}
}

View File

@ -0,0 +1,29 @@
package ru.ulstu.is.sbapp.Genre.Controller;
import ru.ulstu.is.sbapp.Genre.Model.Genre;
import ru.ulstu.is.sbapp.Movie.Controller.MovieDTO;
import java.util.List;
public class GenreDTO {
private final Long id;
private final String name;
private final List<MovieDTO> movies;
public GenreDTO(Genre genre) {
this.id = genre.getId();
this.name = genre.getName();
this.movies = genre.getMovies().stream().map(MovieDTO::new).toList();
}
public long getID() {
return id;
}
public String getName() {
return name;
}
public List<MovieDTO> getMovies() {
return movies;
}
}

View File

@ -0,0 +1,11 @@
package ru.ulstu.is.sbapp.Genre.Exception;
public class GenreNotFoundException extends RuntimeException{
public GenreNotFoundException(Long id){
super(String.format("Genre with id [%s] is not found", id));
}
public GenreNotFoundException(String name){
super(String.format("Genre with name [%s] is not found", name));
}
}

View File

@ -1,6 +1,9 @@
package ru.ulstu.is.sbapp.Models;
package ru.ulstu.is.sbapp.Genre.Model;
import ru.ulstu.is.sbapp.Movie.Model.Movie;
import javax.persistence.*;
import javax.validation.constraints.NotBlank;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@ -11,7 +14,8 @@ public class Genre
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(nullable = false)
@Column
@NotBlank(message = "Genre's can't be null or empty")
private String name;
@OneToMany(fetch = FetchType.EAGER, mappedBy = "genre")

View File

@ -0,0 +1,16 @@
package ru.ulstu.is.sbapp.Genre.Repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import ru.ulstu.is.sbapp.Genre.Model.Genre;
import ru.ulstu.is.sbapp.Movie.Model.Movie;
import java.util.List;
import java.util.Optional;
public interface GenreRepository extends JpaRepository<Genre,Long> {
@Query("SELECT g FROM Genre g WHERE g.name LIKE genre")
Optional<Genre> findByName(@Param("genre")String genreName);
}

View File

@ -0,0 +1,98 @@
package ru.ulstu.is.sbapp.Genre.Service;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import ru.ulstu.is.sbapp.Customer.Repository.CustomerRepository;
import ru.ulstu.is.sbapp.Genre.Exception.GenreNotFoundException;
import ru.ulstu.is.sbapp.Genre.Model.Genre;
import ru.ulstu.is.sbapp.Genre.Repository.GenreRepository;
import javax.persistence.EntityManager;
import javax.persistence.EntityNotFoundException;
import javax.persistence.PersistenceContext;
import ru.ulstu.is.sbapp.Utilities.validation.ValidatorUtil;
import java.util.List;
import java.util.Optional;
@Service
public class GenreService
{
private final GenreRepository genreRepository;
private final ValidatorUtil validatorUtil;
public GenreService(GenreRepository genreRepository, ValidatorUtil validatorUtil) {
this.genreRepository = genreRepository;
this.validatorUtil = validatorUtil;
}
@Transactional
public Genre addGenre(String name) {
if(!StringUtils.hasText(name))
{
throw new IllegalArgumentException("Genre's name is missing");
}
final Genre genre = new Genre(name);
validatorUtil.validate(genre);
return genreRepository.save(genre);
}
@Transactional(readOnly = true)
public Genre findGenre(Long id) {
final Optional<Genre> genre = genreRepository.findById(id);
return genre.orElseThrow(() -> new GenreNotFoundException(id));
}
@Transactional(readOnly = true)
public Genre findGenreByName(String name)
{
final Optional<Genre> genre = genreRepository.findByName(name);
return genre.orElseThrow(() -> new GenreNotFoundException(name));
}
@Transactional(readOnly = true)
public List<Genre> findAllGenres()
{
return genreRepository.findAll();
}
@Transactional
public Genre updateGenre(Long id, String name) {
if(!StringUtils.hasText(name))
{
throw new IllegalArgumentException("Genre's name is missing");
}
final Optional<Genre> genre = genreRepository.findById(id);
if(genre.isEmpty())
{
throw new GenreNotFoundException(id);
}
Genre specificGenre = genre.get();
specificGenre.setName(name);
validatorUtil.validate(genre);
return genreRepository.save(specificGenre);
}
@Transactional
public Genre deleteGenre(Long id) {
final Optional<Genre> genre = genreRepository.findById(id);
if(genre.isEmpty())
{
throw new GenreNotFoundException(id);
}
Genre specificGenre = genre.get();
specificGenre.getMovies().clear();
genreRepository.delete(specificGenre);
return specificGenre;
}
@Transactional
public void deleteAllGenres() {
genreRepository.deleteAll();
}
}

View File

@ -0,0 +1,49 @@
package ru.ulstu.is.sbapp.Movie.Controller;
import org.springframework.web.bind.annotation.*;
import ru.ulstu.is.sbapp.Movie.Service.MovieService;
import java.util.List;
@RestController
@RequestMapping("/movie")
public class MovieController {
private final MovieService movieService;
public MovieController(MovieService movieService) {
this.movieService = movieService;
}
@GetMapping("/{id}")
public MovieDTO getMovie(@PathVariable Long id) {
return new MovieDTO(movieService.findMovie(id));
}
@GetMapping
public List<MovieDTO> getMovies() {
return movieService.findAllMovies().stream()
.map(MovieDTO::new)
.toList();
}
@GetMapping("/{genre}")
public List<MovieDTO> getSpecificMovies(@RequestParam("genre") String genreName) {
return movieService.findAllSpecificMovies(genreName).stream()
.map(MovieDTO::new)
.toList();
}
@PostMapping
public MovieDTO createMovie(@RequestParam("title") String title, @RequestParam("length") int length, @RequestParam("score") double score, @RequestParam("genre") Long genreId, @RequestParam("customer") Long customerId) {
return new MovieDTO(movieService.addMovie(title,length,score,genreId,customerId));
}
@PutMapping("/{id}")
public MovieDTO updateMovie(@PathVariable Long id,
@RequestParam("title") String title,@RequestParam("length") int length,@RequestParam("score") double score ) {
return new MovieDTO(movieService.updateMovie(id,title,length,score));
}
@DeleteMapping("/{customerId}/{id}")
public MovieDTO deleteMovie(@PathVariable("customerId") Long customerId,@PathVariable Long id) {
return new MovieDTO(movieService.deleteMovie(id,customerId));
}
}

View File

@ -0,0 +1,38 @@
package ru.ulstu.is.sbapp.Movie.Controller;
import ru.ulstu.is.sbapp.Genre.Model.Genre;
import ru.ulstu.is.sbapp.Movie.Model.Movie;
import java.util.List;
public class MovieDTO {
private final Long id;
private final String title;
private final int length;
private final double score;
private final Genre genre;
public MovieDTO(Movie movie) {
this.id = movie.getId();
this.title = movie.getTitle();
this.length = movie.getLength();
this.score = movie.getScore();
this.genre = movie.getGenre();
}
public long getID() {
return id;
}
public String getTitle() {
return title;
}
public int getLength() {
return length;
}
public double getScore() {
return score;
}
public Genre getGenre() {
return genre;
}
}

View File

@ -0,0 +1,7 @@
package ru.ulstu.is.sbapp.Movie.Exception;
public class MovieNotFoundException extends RuntimeException{
public MovieNotFoundException(Long id){
super(String.format("Movie with id [%s] is not found", id));
}
}

View File

@ -1,8 +1,9 @@
package ru.ulstu.is.sbapp.Models;
package ru.ulstu.is.sbapp.Movie.Model;
import ru.ulstu.is.sbapp.Genre.Model.Genre;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
import javax.validation.constraints.NotBlank;
import java.util.Objects;
@Entity
@ -11,11 +12,14 @@ public class Movie
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(nullable = false)
@Column
@NotBlank(message = "Movie's title can't be null or empty")
private String title;
@Column(nullable = false)
@Column
@NotBlank(message = "Movie's length can't be null or empty")
private int length;
@Column(nullable = false)
@Column
@NotBlank(message = "Movie's score can't be null or empty")
private double score;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "genre_fk")
@ -49,9 +53,9 @@ public class Movie
this.title = title;
}
public String getLength()
public int getLength()
{
return Integer.toString(length);
return length;
}
public void setLength(int length)
@ -59,9 +63,9 @@ public class Movie
this.length = length;
}
public String getScore()
public double getScore()
{
return Double.toString(score);
return score;
}
public void setScore(Double score)

View File

@ -0,0 +1,14 @@
package ru.ulstu.is.sbapp.Movie.Repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import ru.ulstu.is.sbapp.Genre.Model.Genre;
import ru.ulstu.is.sbapp.Movie.Model.Movie;
import java.util.List;
public interface MovieRepository extends JpaRepository<Movie,Long> {
@Query("SELECT m FROM Movie m WHERE :specGenre LIKE m.genre")
List<Movie> findByGenre(@Param("specGenre") Genre genre);
}

View File

@ -0,0 +1,136 @@
package ru.ulstu.is.sbapp.Movie.Service;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import ru.ulstu.is.sbapp.Customer.Exception.CustomerNotFoundException;
import ru.ulstu.is.sbapp.Customer.Model.Customer;
import ru.ulstu.is.sbapp.Customer.Repository.CustomerRepository;
import ru.ulstu.is.sbapp.Genre.Exception.GenreNotFoundException;
import ru.ulstu.is.sbapp.Genre.Model.Genre;
import ru.ulstu.is.sbapp.Genre.Repository.GenreRepository;
import ru.ulstu.is.sbapp.Movie.Exception.MovieNotFoundException;
import ru.ulstu.is.sbapp.Movie.Model.Movie;
import ru.ulstu.is.sbapp.Movie.Repository.MovieRepository;
import ru.ulstu.is.sbapp.Utilities.validation.ValidatorUtil;
import java.util.List;
import java.util.Optional;
@Service
public class MovieService
{
private final MovieRepository movieRepository;
private final GenreRepository genreRepository;
private final CustomerRepository customerRepository;
private final ValidatorUtil validatorUtil;
public MovieService(MovieRepository movieRepository, GenreRepository genreRepository, CustomerRepository customerRepository, ValidatorUtil validatorUtil) {
this.movieRepository = movieRepository;
this.validatorUtil = validatorUtil;
this.genreRepository = genreRepository;
this.customerRepository = customerRepository;
}
@Transactional
public Movie addMovie(String title, int length, double score, Long genre, Long customer)
{
if(!StringUtils.hasText(title) || length == 0 || score == 0 || genre == 0 || customer == 0)
{
throw new IllegalArgumentException("Some of the movie's properties are incorrect.");
}
final Optional<Genre> specGenre = genreRepository.findById(genre);
final Optional<Customer> specCustomer = customerRepository.findById(customer);
if(specGenre.isEmpty())
{
throw new GenreNotFoundException(genre);
}
final Movie movie = new Movie(title,length,score,specGenre.get());
movie.getGenre().getMovies().add(movie);
if(specCustomer.isEmpty())
{
throw new CustomerNotFoundException(customer);
}
specCustomer.get().getMovies().add(movie);
validatorUtil.validate(movie);
return movieRepository.save(movie);
}
@Transactional(readOnly = true)
public Movie findMovie(Long id)
{
final Optional<Movie> movie = movieRepository.findById(id);
return movie.orElseThrow(() -> new MovieNotFoundException(id));
}
@Transactional(readOnly = true)
public List<Movie> findAllMovies()
{
return movieRepository.findAll();
}
@Transactional
public Movie updateMovie(Long id, String title, int length, double score)
{
if(!StringUtils.hasText(title) || length == 0 || score == 0)
{
throw new IllegalArgumentException("Some of the movie's properties are incorrect.");
}
final Optional<Movie> movie = movieRepository.findById(id);
if(movie.isEmpty())
{
throw new MovieNotFoundException(id);
}
Movie specificMovie = movie.get();
Genre specificGenre = movie.get().getGenre();
specificMovie.setLength(length);
specificMovie.setGenre(specificGenre);
specificMovie.setTitle(title);
specificMovie.setScore(score);
return movieRepository.save(specificMovie);
}
@Transactional
public Movie deleteMovie(Long id, Long customerId)
{
final Optional<Movie> movie = movieRepository.findById(id);
if(movie.isEmpty())
{
throw new MovieNotFoundException(id);
}
Movie specificMovie = movie.get();
specificMovie.getGenre().getMovies().remove(specificMovie);
final Optional<Customer> customer = customerRepository.findById(customerId);
if(customer.isEmpty())
{
throw new CustomerNotFoundException(id);
}
customer.get().getMovies().remove(specificMovie);
movieRepository.delete(specificMovie);
return specificMovie;
}
@Transactional
public List<Movie> findAllSpecificMovies(String genreName)
{
return movieRepository.findByGenre(genreRepository.findByName(genreName).get());
}
@Transactional
public void deleteAllMovies()
{
movieRepository.deleteAll();
}
}

View File

@ -2,10 +2,12 @@ package ru.ulstu.is.sbapp;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
@SpringBootApplication
@ComponentScan(basePackages = { "ru.ulstu.is.sbapp.Movie","ru.ulstu.is.sbapp.Customer","ru.ulstu.is.sbapp.Genre"})
public class SbappApplication {
public static void main(String[] args) {

View File

@ -1,75 +0,0 @@
package ru.ulstu.is.sbapp.Services;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import ru.ulstu.is.sbapp.Models.Customer;
import javax.persistence.EntityManager;
import javax.persistence.EntityNotFoundException;
import javax.persistence.PersistenceContext;
import java.util.List;
@Service
public class CustomerService
{
@PersistenceContext
private EntityManager em;
@Transactional
public Customer addCustomer(String fullName)
{
if(!StringUtils.hasText(fullName))
{
throw new IllegalArgumentException("Customer's name or surname is missing");
}
final Customer customer = new Customer(fullName);
em.persist(customer);
return customer;
}
@Transactional(readOnly = true)
public Customer findCustomer(Long id)
{
final Customer customer = em.find(Customer.class,id);
if(customer == null)
{
throw new EntityNotFoundException(String.format("Customer with id [%s] is not found", id));
}
return customer;
}
@Transactional(readOnly = true)
public List<Customer> findAllCustomers()
{
return em.createQuery("select c from Customer c",Customer.class).getResultList();
}
@Transactional
public Customer updateCustomer(Long id, String fullName)
{
if(!StringUtils.hasText(fullName))
{
throw new IllegalArgumentException("Customer's name or surname is missing");
}
final Customer specificCustomer = findCustomer(id);
specificCustomer.setFirst_name(fullName);
specificCustomer.setLast_name(fullName);
specificCustomer.setMiddle_name(fullName);
return em.merge(specificCustomer);
}
@Transactional
public Customer deleteCustomer(Long id)
{
final Customer specificCustomer = findCustomer(id);
em.remove(specificCustomer);
return specificCustomer;
}
@Transactional
public void deleteAllCustomers()
{
em.createQuery("delete from Customer").executeUpdate();
}
}

View File

@ -1,73 +0,0 @@
package ru.ulstu.is.sbapp.Services;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import ru.ulstu.is.sbapp.Models.Genre;
import javax.persistence.EntityManager;
import javax.persistence.EntityNotFoundException;
import javax.persistence.PersistenceContext;
import java.util.List;
@Service
public class GenreService
{
@PersistenceContext
private EntityManager em;
@Transactional
public Genre addGenre(String name)
{
if(!StringUtils.hasText(name))
{
throw new IllegalArgumentException("Genre's name is missing");
}
final Genre genre = new Genre(name);
em.persist(genre);
return genre;
}
@Transactional(readOnly = true)
public Genre findGenre(Long id)
{
final Genre specificGenre = em.find(Genre.class,id);
if(specificGenre == null)
{
throw new EntityNotFoundException(String.format("Genre with id [%s] is not found", id));
}
return specificGenre;
}
@Transactional(readOnly = true)
public List<Genre> findAllGenres()
{
return em.createQuery("select g from Genre g",Genre.class).getResultList();
}
@Transactional
public Genre updateGenre(Long id, String name)
{
if(!StringUtils.hasText(name))
{
throw new IllegalArgumentException("Genre's name is missing");
}
final Genre specificGenre = findGenre(id);
specificGenre.setName(name);
return em.merge(specificGenre);
}
@Transactional
public Genre deleteGenre(Long id)
{
final Genre specificGenre = findGenre(id);
em.remove(specificGenre);
return specificGenre;
}
@Transactional
public void deleteAllGenres()
{
em.createQuery("delete from Genre").executeUpdate();
}
}

View File

@ -1,89 +0,0 @@
package ru.ulstu.is.sbapp.Services;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import ru.ulstu.is.sbapp.Models.Movie;
import ru.ulstu.is.sbapp.Models.Customer;
import ru.ulstu.is.sbapp.Models.Genre;
import javax.persistence.EntityManager;
import javax.persistence.EntityNotFoundException;
import javax.persistence.PersistenceContext;
import java.util.List;
@Service
public class MovieService
{
@PersistenceContext
private EntityManager em;
@Transactional
public Movie addMovie(String title, int length, double score, Genre genre, Customer customer)
{
if(!StringUtils.hasText(title) || length == 0 || score == 0 || genre == null || customer == null)
{
throw new IllegalArgumentException("Some of the movie's properties are incorrect.");
}
final Movie movie = new Movie(title,length,score,genre);
movie.getGenre().getMovies().add(movie);
customer.getMovies().add(movie);
em.persist(movie);
return movie;
}
@Transactional(readOnly = true)
public Movie findMovie(Long id)
{
final Movie specificMovie = em.find(Movie.class, id);
if(specificMovie == null)
{
throw new EntityNotFoundException(String.format("Movie with id [%s] is not found", id));
}
return specificMovie;
}
@Transactional(readOnly = true)
public List<Movie> findAllMovies()
{
return em.createQuery("select m from Movie m",Movie.class).getResultList();
}
@Transactional
public Movie updateMovie(Long id, String title, int length, double score, Genre genre)
{
if(!StringUtils.hasText(title) || length == 0 || score == 0 || genre == null)
{
throw new IllegalArgumentException("Some of the movie's properties are incorrect.");
}
final Movie specificMovie = findMovie(id);
specificMovie.setLength(length);
specificMovie.setGenre(genre);
specificMovie.setTitle(title);
specificMovie.setScore(score);
return em.merge(specificMovie);
}
@Transactional
public Movie deleteMovie(Long id, Customer customer)
{
final Movie specificMovie = findMovie(id);
specificMovie.getGenre().getMovies().remove(specificMovie);
customer.getMovies().remove(specificMovie);
em.remove(specificMovie);
return specificMovie;
}
@Transactional
public List<Movie> findAllSpecificMovies(Genre specGenre)
{
return em.createQuery("SELECT m FROM Movie m WHERE m.genre = :genre",Movie.class).setParameter("genre",specGenre).getResultList();
}
@Transactional
public void deleteAllMovies()
{
em.createQuery("delete from Movie").executeUpdate();
}
}

View File

@ -0,0 +1,42 @@
package ru.ulstu.is.sbapp.Utilities.error;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import ru.ulstu.is.sbapp.Customer.Exception.CustomerNotFoundException;
import ru.ulstu.is.sbapp.Genre.Exception.GenreNotFoundException;
import ru.ulstu.is.sbapp.Movie.Exception.MovieNotFoundException;
import ru.ulstu.is.sbapp.Utilities.validation.ValidationException;
import java.util.stream.Collectors;
@ControllerAdvice
public class AdviceController {
@ExceptionHandler({
MovieNotFoundException.class,
GenreNotFoundException.class,
CustomerNotFoundException.class,
ValidationException.class
})
public ResponseEntity<Object> handleException(Throwable e) {
return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Object> handleBindException(MethodArgumentNotValidException e) {
final ValidationException validationException = new ValidationException(
e.getBindingResult().getAllErrors().stream()
.map(DefaultMessageSourceResolvable::getDefaultMessage)
.collect(Collectors.toSet()));
return handleException(validationException);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<Object> handleUnknownException(Throwable e) {
e.printStackTrace();
return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}

View File

@ -0,0 +1,9 @@
package ru.ulstu.is.sbapp.Utilities.validation;
import java.util.Set;
public class ValidationException extends RuntimeException {
public ValidationException(Set<String> errors) {
super(String.join("\n", errors));
}
}

View File

@ -0,0 +1,30 @@
package ru.ulstu.is.sbapp.Utilities.validation;
import org.springframework.stereotype.Component;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import java.util.Set;
import java.util.stream.Collectors;
@Component
public class ValidatorUtil {
private final Validator validator;
public ValidatorUtil() {
try (ValidatorFactory factory = Validation.buildDefaultValidatorFactory()) {
this.validator = factory.getValidator();
}
}
public <T> void validate(T object) {
final Set<ConstraintViolation<T>> errors = validator.validate(object);
if (!errors.isEmpty()) {
throw new ValidationException(errors.stream()
.map(ConstraintViolation::getMessage)
.collect(Collectors.toSet()));
}
}
}

View File

@ -1,14 +1,13 @@
package ru.ulstu.is.sbapp;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import ru.ulstu.is.sbapp.Models.Customer;
import ru.ulstu.is.sbapp.Services.CustomerService;
import ru.ulstu.is.sbapp.Customer.Model.Customer;
import ru.ulstu.is.sbapp.Customer.Service.CustomerService;
import javax.persistence.EntityNotFoundException;
import java.util.List;
@ -25,7 +24,7 @@ public class JpaCustomerTests
void testCustomerCreate()
{
customerService.deleteAllCustomers();
final Customer customer = customerService.addCustomer("Nikita Lisov");
final Customer customer = customerService.addCustomer("Nikita Lisov","1234");
log.info(customer.toString());
Assertions.assertNotNull(customer.getId());
}
@ -34,7 +33,7 @@ public class JpaCustomerTests
void testCustomerRead()
{
customerService.deleteAllCustomers();
final Customer customer = customerService.addCustomer("Nikita Lisov");
final Customer customer = customerService.addCustomer("Nikita Lisov","1234");
log.info(customer.toString());
final Customer findCustomer = customerService.findCustomer(customer.getId());
log.info(findCustomer.toString());
@ -52,8 +51,8 @@ public class JpaCustomerTests
void testCustomerReadAll()
{
customerService.deleteAllCustomers();
customerService.addCustomer("Nikita Lisov");
customerService.addCustomer("Evelina Aust Sergeevna");
customerService.addCustomer("Nikita Lisov","1234");
customerService.addCustomer("Evelina Aust Sergeevna","12345");
final List<Customer> customers = customerService.findAllCustomers();
log.info(customers.toString());
Assertions.assertEquals(customers.size(), 2);
@ -72,7 +71,7 @@ public class JpaCustomerTests
void testCustomerChanges()
{
customerService.deleteAllCustomers();
final Customer customer = customerService.addCustomer("Nikita Lisov");
final Customer customer = customerService.addCustomer("Nikita Lisov","1234");
log.info(customer.toString());
final Customer changedCustomer = customerService.updateCustomer(customer.getId(),"Evelina Potter");
log.info(changedCustomer.toString());
@ -84,8 +83,8 @@ public class JpaCustomerTests
{
customerService.deleteAllCustomers();
final Customer customer1 = customerService.addCustomer("Nikita Lisov");
final Customer customer2 = customerService.addCustomer("Evelina Potter");
final Customer customer1 = customerService.addCustomer("Nikita Lisov","1234");
final Customer customer2 = customerService.addCustomer("Evelina Potter","12345");
customerService.deleteCustomer(customer1.getId());
Assertions.assertThrows(EntityNotFoundException.class, () -> customerService.findCustomer(customer1.getId()));

View File

@ -6,9 +6,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import ru.ulstu.is.sbapp.Models.Customer;
import ru.ulstu.is.sbapp.Models.Genre;
import ru.ulstu.is.sbapp.Services.GenreService;
import ru.ulstu.is.sbapp.Genre.Model.Genre;
import ru.ulstu.is.sbapp.Genre.Service.GenreService;
import javax.persistence.EntityNotFoundException;
import java.util.List;

View File

@ -6,12 +6,12 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import ru.ulstu.is.sbapp.Services.MovieService;
import ru.ulstu.is.sbapp.Models.Movie;
import ru.ulstu.is.sbapp.Models.Customer;
import ru.ulstu.is.sbapp.Services.CustomerService;
import ru.ulstu.is.sbapp.Models.Genre;
import ru.ulstu.is.sbapp.Services.GenreService;
import ru.ulstu.is.sbapp.Movie.Service.MovieService;
import ru.ulstu.is.sbapp.Movie.Model.Movie;
import ru.ulstu.is.sbapp.Customer.Model.Customer;
import ru.ulstu.is.sbapp.Customer.Service.CustomerService;
import ru.ulstu.is.sbapp.Genre.Model.Genre;
import ru.ulstu.is.sbapp.Genre.Service.GenreService;
import javax.persistence.EntityNotFoundException;
import java.util.ArrayList;
@ -39,10 +39,10 @@ public class JpaMovieTests
final Genre genre = genreService.addGenre("Fantasy");
log.info(genre.toString());
final Customer customer = customerService.addCustomer("Nikita Lisov");
final Customer customer = customerService.addCustomer("Nikita Lisov","1234");
log.info(customer.toString());
final Movie movie = movieService.addMovie("Arcane",36,4.5, genre, customer);
final Movie movie = movieService.addMovie("Arcane",36,4.5, genre.getId(), customer.getId());
log.info(movie.toString());
Assertions.assertNotNull(movie.getId());
@ -59,10 +59,10 @@ public class JpaMovieTests
final Genre genre = genreService.addGenre("Fantasy");
log.info(genre.toString());
final Customer customer = customerService.addCustomer("Nikita Lisov");
final Customer customer = customerService.addCustomer("Nikita Lisov","1234");
log.info(customer.toString());
final Movie movie = movieService.addMovie("Arcane",36,4.5, genre, customer);
final Movie movie = movieService.addMovie("Arcane",36,4.5, genre.getId(), customer.getId());
log.info(movie.toString());
@ -82,9 +82,9 @@ public class JpaMovieTests
final Genre genre = genreService.addGenre("Fantasy");
log.info(genre.toString());
final Customer customer = customerService.addCustomer("Nikita Lisov");
final Customer customer = customerService.addCustomer("Nikita Lisov","1234");
log.info(customer.toString());
final Movie movie = movieService.addMovie("Arcane",36,4.5, genre, customer);
final Movie movie = movieService.addMovie("Arcane",36,4.5, genre.getId(), customer.getId());
log.info(movie.toString());
log.info(customer.getMovies().toString());
@ -104,10 +104,10 @@ public class JpaMovieTests
final Genre genre = genreService.addGenre("Fantasy");
log.info(genre.toString());
final Customer customer = customerService.addCustomer("Nikita Lisov");
final Customer customer = customerService.addCustomer("Nikita Lisov","1234");
log.info(customer.toString());
final Movie movie = movieService.addMovie("Arcane",36,4.5, genre, customer);
final Movie movie = movieService.addMovie("Arcane",36,4.5, genre.getId(), customer.getId());
log.info(movie.toString());
final List<Movie> movies = movieService.findAllMovies();
@ -126,16 +126,16 @@ public class JpaMovieTests
final Genre genre = genreService.addGenre("Fantasy");
log.info(genre.toString());
final Customer customer1 = customerService.addCustomer("Nikita Lisov");
final Customer customer1 = customerService.addCustomer("Nikita Lisov","1234");
log.info(customer1.toString());
final Customer customer2 = customerService.addCustomer("Evelina Potter");
final Customer customer2 = customerService.addCustomer("Evelina Potter","5678");
log.info(customer2.toString());
final Movie movie1 = movieService.addMovie("Arcane",36,4.5, genre, customer1);
final Movie movie1 = movieService.addMovie("Arcane",36,4.5, genre.getId(), customer1.getId());
log.info(movie1.toString());
final Movie movie2 = movieService.addMovie("Harry Potter",128,10.0, genre, customer2);
final Movie movie2 = movieService.addMovie("Harry Potter",128,10.0, genre.getId(), customer2.getId());
log.info(movie2.toString());
final List<Movie> movies = movieService.findAllMovies();
@ -180,23 +180,23 @@ public class JpaMovieTests
final Genre genre2 = genreService.addGenre("Sci-Fi");
log.info(genre2.toString());
final Customer customer = customerService.addCustomer("Nikita Lisov");
final Customer customer = customerService.addCustomer("Nikita Lisov","1234");
log.info(customer.toString());
final Movie movie1 = movieService.addMovie("Arcane",36,4.5, genre1, customer);
final Movie movie1 = movieService.addMovie("Arcane",36,4.5, genre1.getId(), customer.getId());
log.info(movie1.toString());
final Movie movie2 = movieService.addMovie("Harry Potter",128,10.0, genre1, customer);
final Movie movie2 = movieService.addMovie("Harry Potter",128,10.0, genre1.getId(), customer.getId());
log.info(movie2.toString());
final Movie movie3 = movieService.addMovie("Interstellar",2,9.5, genre2, customer);
final Movie movie3 = movieService.addMovie("Interstellar",2,9.5, genre2.getId(), customer.getId());
log.info(movie3.toString());
List<Movie> movies = new ArrayList<>(){};
movies.add(movie1);
movies.add(movie2);
List<Movie> expectedMovies = movieService.findAllSpecificMovies(genre1);
List<Movie> expectedMovies = movieService.findAllSpecificMovies(genre1.getName());
log.info(expectedMovies.toString());
Assertions.assertArrayEquals(movies.toArray(),expectedMovies.toArray());

View File

@ -1,6 +1,11 @@
spring.datasource.url=jdbc:h2:mem:testdb
spring.main.banner-mode=off
#server.port=8080
spring.datasource.url=jdbc:h2:file:./data
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.hibernate.ddl-auto=update
spring.h2.console.enabled=true
spring.h2.console.settings.trace=false
spring.h2.console.settings.web-allow-others=false