Skip to content

Commit

Permalink
commit 1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Sergeev-Alexander committed Nov 13, 2023
1 parent 916de53 commit ff7d27c
Show file tree
Hide file tree
Showing 14 changed files with 392 additions and 56 deletions.
Original file line number Diff line number Diff line change
@@ -1,46 +1,61 @@
package ru.yandex.practicum.filmorate.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import ru.yandex.practicum.filmorate.exception.ItemNotPresentException;
import ru.yandex.practicum.filmorate.model.Film;
import ru.yandex.practicum.filmorate.service.FilmService;
import ru.yandex.practicum.filmorate.storage.film.FilmStorage;

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 {

FilmStorage filmStorage;
FilmService filmService;

private final Map<Integer, Film> filmMap = new HashMap<>();
private Integer filmIdCounter = 1;
@Autowired
public FilmController(FilmStorage filmStorage, FilmService filmService) {
this.filmStorage = filmStorage;
this.filmService = filmService;
}

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

@GetMapping("/films/{id}")
public Film getFilmById(@PathVariable Integer id) {
return filmStorage.getFilmById(id);
}

@GetMapping("/films/popular")
public List<Film> getPopularFilms(@RequestParam(defaultValue = "10") Integer count) {
return filmService.getPopularFilms(count);
}

@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;
return filmStorage.postFilm(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;
return filmStorage.putFilm(film);
}

@PutMapping("/films/{id}/like/{userId}")
public void putLike(@PathVariable Integer id, @PathVariable Integer userId) {
filmService.putLike(id, userId);
}

@DeleteMapping("/films/{id}/like/{userId}")
public void deleteLike(@PathVariable Integer id, @PathVariable Integer userId) {
filmService.deleteLike(id, userId);
}

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

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import ru.yandex.practicum.filmorate.exception.ItemNotPresentException;
import ru.yandex.practicum.filmorate.model.User;
import ru.yandex.practicum.filmorate.service.UserService;
import ru.yandex.practicum.filmorate.storage.user.UserStorage;

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;
UserStorage userStorage;
UserService userService;

@Autowired
public UserController(UserStorage userStorage, UserService userService) {
this.userStorage = userStorage;
this.userService = userService;
}

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

@GetMapping("/users/{id}")
public User getUserById(@PathVariable Integer id) {
return userStorage.getUserById(id);
}

@GetMapping("users/{id}/friends")
public List<User> getAllUserFriends(@PathVariable Integer id) {
return userService.getAllUserFriends(id);
}

@GetMapping("/users/{id}/friends/common/{otherId}")
public List<User> getUsersCommonFriends(@PathVariable Integer id, @PathVariable Integer otherId) {
return userService.getUsersCommonFriends(id, otherId);
}

@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;
return userStorage.postUser(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;
return userStorage.putUser(user);
}

private void userNameCheck(User user) {
if (null == user.getName() || user.getName().isBlank()) {
user.setName(user.getLogin());
}
@PutMapping("/users/{id}/friends/{friendId}")
public void putNewFriend(@PathVariable Integer id, @PathVariable Integer friendId) {
userStorage.putNewFriend(id, friendId);
}

}
@DeleteMapping("/users/{id}/friends/{friendId}")
public void deleteFriend(@PathVariable Integer id, @PathVariable Integer friendId) {
userStorage.deleteFriend(id, friendId);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,24 @@
import org.springframework.http.HttpStatus;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
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;
import java.util.Objects;

@RestControllerAdvice
public class ErrorHandlingController {

@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public Map<String, String> autoValidationHendle(MethodArgumentNotValidException e) {
@ResponseStatus(HttpStatus.BAD_REQUEST)
public Map<String, String> validationHendle(MethodArgumentNotValidException e) {
Map<String, String> response = new HashMap<>();
for (FieldError error : e.getBindingResult().getFieldErrors()) {
response.put(error.getField(), error.getDefaultMessage());
Expand All @@ -35,11 +39,36 @@ public Map<String, String> autoValidationHendle(MethodArgumentNotValidException
}

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

@ExceptionHandler(MethodArgumentTypeMismatchException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public Map<String, String> typeMismatchHandle(MethodArgumentTypeMismatchException e) {
Map<String, String> response = new HashMap<>();
Class<?> loggerPath = FilmorateApplication.class;
if (Objects.requireNonNull(e.getParameter().getMethod()).getDeclaringClass().equals(FilmController.class)) {
loggerPath = FilmController.class;
}
if (Objects.requireNonNull(e.getParameter().getMethod()).getDeclaringClass().equals(UserController.class)) {
loggerPath = UserController.class;
}
Logger logger = LoggerFactory.getLogger(loggerPath);
response.put(e.getParameter().getParameter().getName(), "Parameter type mismatch!");
logger.error("Parameter type mismatch in {}.{}() field: {}",
loggerPath.getSimpleName(),
e.getParameter().getMethod().getName(),
e.getParameter().getParameter().getName());
return response;
}

@ExceptionHandler(Throwable.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public Map<String, String> otherExceptonsHandle(MethodArgumentTypeMismatchException e) {
return Map.of(e.getName(), String.valueOf(e.getCause()));
}
}
4 changes: 4 additions & 0 deletions src/main/java/ru/yandex/practicum/filmorate/model/Film.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import javax.validation.constraints.Positive;
import javax.validation.constraints.Size;
import java.time.LocalDate;
import java.util.HashSet;
import java.util.Set;

@Data
public class Film {
Expand All @@ -28,4 +30,6 @@ public class Film {
@Positive(message = "Duration field must be positive!")
private Long duration;

private Set<Integer> likes = new HashSet<>();

}
4 changes: 4 additions & 0 deletions src/main/java/ru/yandex/practicum/filmorate/model/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

import javax.validation.constraints.*;
import java.time.LocalDate;
import java.util.HashSet;
import java.util.Set;

@Data
public class User {
Expand All @@ -24,4 +26,6 @@ public class User {
@PastOrPresent(message = "Birthday field must contain a past date!")
private LocalDate birthday;

private Set<Integer> friends = new HashSet<>();

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

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import ru.yandex.practicum.filmorate.model.Film;
import ru.yandex.practicum.filmorate.storage.film.FilmStorage;
import ru.yandex.practicum.filmorate.storage.user.UserStorage;

import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class FilmService {

private final FilmStorage filmStorage;
private final UserStorage userStorage;

@Autowired
public FilmService(FilmStorage filmStorage, UserStorage userStorage) {
this.filmStorage = filmStorage;
this.userStorage = userStorage;
}

public void putLike(Integer id, Integer userId) {
filmStorage.presenceCheck(id);
userStorage.presenceCheck(userId);
filmStorage.getFilmById(id).getLikes().add(userId);
log.info("User {} liked film {}", userId, id);
}

public void deleteLike(Integer id, Integer userId) {
filmStorage.presenceCheck(id);
userStorage.presenceCheck(userId);
filmStorage.getFilmById(id).getLikes().remove(userId);
log.info("User {} unliked film {}", userId, id);
}

public List<Film> getPopularFilms(Integer count) {
List<Film> filmList = filmStorage.getAllFilms().stream()
.sorted(Comparator.comparing(film -> film.getLikes().size(), Comparator.nullsLast(Comparator.reverseOrder())))
.collect(Collectors.toList());
if (filmList.size() > count) {
log.info("Showed popular films {}", filmList.subList(0, count));
return filmList.subList(0, count);
}
log.info("Showed popular films {}", filmList);
return filmList;
}

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

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import ru.yandex.practicum.filmorate.model.User;
import ru.yandex.practicum.filmorate.storage.user.UserStorage;

import java.util.ArrayList;
import java.util.List;

@Service
public class UserService {

private final UserStorage userStorage;

@Autowired
public UserService(UserStorage userStorage) {
this.userStorage = userStorage;
}

public List<User> getAllUserFriends(Integer id) {
User user = userStorage.getUserById(id);
ArrayList<User> friendsList = new ArrayList<>();
if (user.getFriends() == null) {
return friendsList;
}
for (Integer friendId : user.getFriends()) {
friendsList.add(userStorage.getUserById(friendId));
}
return friendsList;
}

public List<User> getUsersCommonFriends(Integer id, Integer otherId) {
userStorage.presenceCheck(id);
userStorage.presenceCheck(otherId);
List<User> commonFriends = new ArrayList<>();
for(User friend : getAllUserFriends(id)) {
if (getAllUserFriends(otherId).contains(friend)) {
commonFriends.add(friend);
}
}
return commonFriends;
}

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

import ru.yandex.practicum.filmorate.model.Film;

import java.util.List;

public interface FilmStorage {

List<Film> getAllFilms();

Film getFilmById(Integer id);

Film postFilm(Film film);

Film putFilm(Film film);

void presenceCheck(Integer id);

}
Loading

0 comments on commit ff7d27c

Please sign in to comment.