Skip to content

Commit

Permalink
Merge pull request #1 from sergeev-alexander/controllers-films-users
Browse files Browse the repository at this point in the history
commit 1.0
  • Loading branch information
Alexander Sergeev authored Nov 7, 2023
2 parents 666a0c9 + f898006 commit 916de53
Show file tree
Hide file tree
Showing 15 changed files with 475 additions and 0 deletions.
54 changes: 54 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>ru.yandex.practicum</groupId>
<artifactId>filmorate</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>filmorate</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package ru.yandex.practicum.filmorate;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class FilmorateApplication {

public static void main(String[] args) {
SpringApplication.run(FilmorateApplication.class, args);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package ru.yandex.practicum.filmorate.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import ru.yandex.practicum.filmorate.exception.ItemNotPresentException;
import ru.yandex.practicum.filmorate.model.Film;

import javax.validation.Valid;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@RestController
public class FilmController {


private final Map<Integer, Film> filmMap = new HashMap<>();
private Integer filmIdCounter = 1;

@GetMapping("/films")
public List<Film> getAllFilms() {
return new ArrayList<>(filmMap.values());
}

@PostMapping("/films")
public Film postFilm(@Valid @RequestBody Film film) {
film.setId(filmIdCounter++);
filmMap.put(film.getId(), film);
log.info("Added new film: {}", film);
return film;
}

@PutMapping("/films")
public Film putFilm(@Valid @RequestBody Film film) {
if (film.getId() == null || !filmMap.containsKey(film.getId())) {
log.error("Film validation error : There's no film with {} id!", film.getId());
throw new ItemNotPresentException("There's no film with " + film.getId() + " id!");
}
filmMap.put(film.getId(), film);
log.info("Updated film: {}", film);
return film;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package ru.yandex.practicum.filmorate.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import ru.yandex.practicum.filmorate.exception.ItemNotPresentException;
import ru.yandex.practicum.filmorate.model.User;

import javax.validation.Valid;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@RestController
public class UserController {

private final Map<Integer, User> userMap = new HashMap<>();
private Integer idCounter = 1;

@GetMapping("/users")
public List<User> getAllUsers() {
return new ArrayList<>(userMap.values());
}

@PostMapping("/users")
public User postUser(@Valid @RequestBody User user) {
user.setId(idCounter++);
userNameCheck(user);
userMap.put(user.getId(), user);
log.info("Added new user: {}", user);
return user;
}

@PutMapping("/users")
public User putUser(@Valid @RequestBody User user) {
if (user.getId() == null || !userMap.containsKey(user.getId())) {
log.error("User validation error : There's no user with {} id!", user.getId());
throw new ItemNotPresentException("There's no user with " + user.getId() + " id!");
}
userNameCheck(user);
userMap.put(user.getId(), user);
log.info("Updated user: {}", user);
return user;
}

private void userNameCheck(User user) {
if (null == user.getName() || user.getName().isBlank()) {
user.setName(user.getLogin());
}
}

}

Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package ru.yandex.practicum.filmorate.exception;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.*;
import ru.yandex.practicum.filmorate.FilmorateApplication;
import ru.yandex.practicum.filmorate.controller.FilmController;
import ru.yandex.practicum.filmorate.controller.UserController;

import java.util.HashMap;
import java.util.Map;

@RestControllerAdvice
public class ErrorHandlingController {

@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public Map<String, String> autoValidationHendle(MethodArgumentNotValidException e) {
Map<String, String> response = new HashMap<>();
for (FieldError error : e.getBindingResult().getFieldErrors()) {
response.put(error.getField(), error.getDefaultMessage());
}
Class<?> loggerPath = FilmorateApplication.class;
if ("user".equals(e.getObjectName())) {
loggerPath = UserController.class;
} else if ("film".equals(e.getObjectName())) {
loggerPath = FilmController.class;
}
Logger logger = LoggerFactory.getLogger(loggerPath);
logger.error("{} validation error: {}", loggerPath.getSimpleName(), response.entrySet());
return response;
}

@ExceptionHandler(ItemNotPresentException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public Map<String, String> itemNotPresentHandle(ItemNotPresentException e) {
Map<String, String> response = new HashMap<>();
response.put("id", e.getMessage());
return response;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package ru.yandex.practicum.filmorate.exception;

public class ItemNotPresentException extends RuntimeException {

public ItemNotPresentException(String message) {
super(message);
}

}
31 changes: 31 additions & 0 deletions src/main/java/ru/yandex/practicum/filmorate/model/Film.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package ru.yandex.practicum.filmorate.model;

import lombok.Data;
import ru.yandex.practicum.filmorate.validation.ReleaseDateValidation;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Positive;
import javax.validation.constraints.Size;
import java.time.LocalDate;

@Data
public class Film {

private Integer id;

@NotBlank(message = "Name field is empty!")
private String name;

@NotNull
@Size(max = 200, message = "Description field must be less 200 characters!")
private String description;

@ReleaseDateValidation(message = "Release date is before 28.12.1895!")
private LocalDate releaseDate;

@NotNull
@Positive(message = "Duration field must be positive!")
private Long duration;

}
27 changes: 27 additions & 0 deletions src/main/java/ru/yandex/practicum/filmorate/model/User.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package ru.yandex.practicum.filmorate.model;

import lombok.Data;

import javax.validation.constraints.*;
import java.time.LocalDate;

@Data
public class User {

private Integer id;

@NotBlank(message = "Email field is empty!")
@Email(message = "Wrong email format!")
private String email;

@NotBlank(message = "Login field is empty!")
@Pattern(regexp = "^\\S+$", message = "Login field should be without whitespaces!")
private String login;

private String name;

@NotNull
@PastOrPresent(message = "Birthday field must contain a past date!")
private LocalDate birthday;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package ru.yandex.practicum.filmorate.validation;

public enum IdBelonging {

USER_ID, FILM_ID

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package ru.yandex.practicum.filmorate.validation;

import javax.validation.Constraint;
import javax.validation.Payload;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

@Target(FIELD)
@Retention(RUNTIME)
@Constraint(validatedBy = ReleaseDateValidator.class)
@Documented
public @interface ReleaseDateValidation {

String message() default "Default ReleaseDateValidation message";

Class<?>[] groups() default {};

Class<? extends Payload>[] payload() default {};

}

Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package ru.yandex.practicum.filmorate.validation;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

import java.time.LocalDate;

public class ReleaseDateValidator implements ConstraintValidator<ReleaseDateValidation, LocalDate> {

public static final LocalDate FIRST_FILM_RELEASE_DATE = LocalDate.of(1895, 12, 28);

@Override
public boolean isValid(LocalDate releaseDate, ConstraintValidatorContext constraintValidatorContext) {
return releaseDate != null && !releaseDate.isBefore(FIRST_FILM_RELEASE_DATE);
}

}

Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package ru.yandex.practicum.filmorate;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class FilmorateApplicationTests {

@Test
void contextLoads() {
}

}
Loading

0 comments on commit 916de53

Please sign in to comment.