-
Notifications
You must be signed in to change notification settings - Fork 0
Add controllers #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 11 commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
078e02d
fix models
avnovik a74ce1e
added Dto
avnovik 5793b5e
added Mapper
avnovik 43aff9f
fix UserController
avnovik 5805d0c
added tests
avnovik 31ba51b
added item controller create + test
avnovik bc35bd9
added item controller + test
avnovik 1527467
fix for postman test
avnovik 1a4b521
added ErrorHandler & fix+clean code
avnovik c61ebbf
added mapper
avnovik ea663a9
added stream
avnovik 8ee1d65
added repository and some fix
avnovik File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,21 @@ | ||
| package ru.practicum.shareit.booking; | ||
|
|
||
| import java.time.LocalDateTime; | ||
|
|
||
| import lombok.Data; | ||
| import ru.practicum.shareit.item.model.Item; | ||
| import ru.practicum.shareit.user.model.User; | ||
|
|
||
| /** | ||
| * TODO Sprint add-bookings. | ||
| * Модель бронирования вещи. | ||
| * Описывает период бронирования, вещь, арендатора и текущий статус. | ||
| */ | ||
| @Data | ||
| public class Booking { | ||
| private Long id; | ||
| private LocalDateTime start; | ||
| private LocalDateTime end; | ||
| private Item item; | ||
| private User booker; | ||
| private BookingStatus status; | ||
| } |
11 changes: 11 additions & 0 deletions
11
src/main/java/ru/practicum/shareit/booking/BookingStatus.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| package ru.practicum.shareit.booking; | ||
|
|
||
| /** | ||
| * Статусы бронирования. | ||
| */ | ||
| public enum BookingStatus { | ||
| WAITING, | ||
| APPROVED, | ||
| REJECTED, | ||
| CANCELED | ||
| } |
51 changes: 51 additions & 0 deletions
51
src/main/java/ru/practicum/shareit/exceptions/ErrorHandler.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| package ru.practicum.shareit.exceptions; | ||
|
|
||
| import lombok.extern.slf4j.Slf4j; | ||
| import org.springframework.http.HttpStatus; | ||
| import org.springframework.web.bind.MethodArgumentNotValidException; | ||
| import org.springframework.web.bind.annotation.ExceptionHandler; | ||
| import org.springframework.web.bind.annotation.ResponseStatus; | ||
| import org.springframework.web.bind.annotation.RestControllerAdvice; | ||
|
|
||
| /** | ||
| * Глобальный обработчик исключений. | ||
| */ | ||
| @Slf4j | ||
| @RestControllerAdvice | ||
| public class ErrorHandler { | ||
|
|
||
| @ExceptionHandler({MethodArgumentNotValidException.class}) | ||
| @ResponseStatus(HttpStatus.BAD_REQUEST) | ||
| public ErrorResponse handleValidationException(final Exception e) { | ||
| log.warn("Ошибка валидации объекта"); | ||
| return new ErrorResponse(e.getMessage()); | ||
| } | ||
|
|
||
| @ExceptionHandler(NotFoundException.class) | ||
| @ResponseStatus(HttpStatus.NOT_FOUND) | ||
| public ErrorResponse handleNotFoundException(final NotFoundException e) { | ||
| log.warn("Объект не найден"); | ||
| return new ErrorResponse(e.getMessage()); | ||
| } | ||
|
|
||
| @ExceptionHandler(SecurityException.class) | ||
| @ResponseStatus(HttpStatus.FORBIDDEN) | ||
| public ErrorResponse handleSecurityException(final SecurityException e) { | ||
| log.warn("Доступ запрещён"); | ||
| return new ErrorResponse(e.getMessage()); | ||
| } | ||
|
|
||
| @ExceptionHandler(IllegalStateException.class) | ||
| @ResponseStatus(HttpStatus.CONFLICT) | ||
| public ErrorResponse handleIllegalStateException(final IllegalStateException e) { | ||
| log.warn("Конфликт данных"); | ||
| return new ErrorResponse(e.getMessage()); | ||
| } | ||
|
|
||
| @ExceptionHandler(IllegalArgumentException.class) | ||
| @ResponseStatus(HttpStatus.BAD_REQUEST) | ||
| public ErrorResponse handleIllegalArgumentException(final IllegalArgumentException e) { | ||
| log.warn("Некорректный запрос"); | ||
| return new ErrorResponse(e.getMessage()); | ||
| } | ||
| } |
13 changes: 13 additions & 0 deletions
13
src/main/java/ru/practicum/shareit/exceptions/ErrorResponse.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| package ru.practicum.shareit.exceptions; | ||
|
|
||
| import lombok.Getter; | ||
| import lombok.RequiredArgsConstructor; | ||
|
|
||
| /** | ||
| * DTO ошибки для возврата клиенту. | ||
| */ | ||
| @Getter | ||
| @RequiredArgsConstructor | ||
| public class ErrorResponse { | ||
| private final String error; | ||
| } |
7 changes: 7 additions & 0 deletions
7
src/main/java/ru/practicum/shareit/exceptions/NotFoundException.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| package ru.practicum.shareit.exceptions; | ||
|
|
||
| public class NotFoundException extends RuntimeException { | ||
| public NotFoundException(String message) { | ||
| super(message); | ||
| } | ||
| } |
39 changes: 36 additions & 3 deletions
39
src/main/java/ru/practicum/shareit/item/ItemController.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,12 +1,45 @@ | ||
| package ru.practicum.shareit.item; | ||
|
|
||
| import org.springframework.web.bind.annotation.RequestMapping; | ||
| import org.springframework.web.bind.annotation.RestController; | ||
| import jakarta.validation.Valid; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.web.bind.annotation.*; | ||
| import ru.practicum.shareit.item.dto.ItemDto; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| /** | ||
| * TODO Sprint add-controllers. | ||
| * REST-контроллер для работы с вещами. | ||
| */ | ||
| @RestController | ||
| @RequestMapping("/items") | ||
| @RequiredArgsConstructor | ||
| public class ItemController { | ||
| private final ItemService itemService; | ||
|
|
||
| @PostMapping | ||
| public ItemDto create(@RequestHeader("X-Sharer-User-Id") Long userId, @Valid @RequestBody ItemDto itemDto) { | ||
| return itemService.create(userId, itemDto); | ||
| } | ||
|
|
||
| @PatchMapping("/{itemId}") | ||
| public ItemDto update(@RequestHeader("X-Sharer-User-Id") Long userId, | ||
| @PathVariable Long itemId, | ||
| @RequestBody ItemDto itemDto) { | ||
| return itemService.update(userId, itemId, itemDto); | ||
| } | ||
|
|
||
| @GetMapping("/{itemId}") | ||
| public ItemDto getById(@PathVariable Long itemId) { | ||
| return itemService.getById(itemId); | ||
| } | ||
|
|
||
| @GetMapping | ||
| public List<ItemDto> getAllByOwner(@RequestHeader("X-Sharer-User-Id") Long userId) { | ||
| return itemService.getAllByOwner(userId); | ||
| } | ||
|
|
||
| @GetMapping("/search") | ||
| public List<ItemDto> search(@RequestParam String text) { | ||
| return itemService.search(text); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| package ru.practicum.shareit.item; | ||
|
|
||
| import ru.practicum.shareit.item.dto.ItemDto; | ||
| import ru.practicum.shareit.item.model.Item; | ||
| import lombok.experimental.UtilityClass; | ||
| import ru.practicum.shareit.user.model.User; | ||
|
|
||
| @UtilityClass | ||
| public class ItemMapper { | ||
|
|
||
| /** | ||
| * Преобразует {@link Item} в {@link ItemDto}. | ||
| */ | ||
| public static ItemDto toItemDto(Item item) { | ||
| if (item == null) { | ||
| return null; | ||
| } | ||
|
|
||
| ItemDto dto = new ItemDto(); | ||
| dto.setId(item.getId()); | ||
| dto.setName(item.getName()); | ||
| dto.setDescription(item.getDescription()); | ||
| dto.setAvailable(item.getAvailable()); | ||
| dto.setOwnerId(item.getOwner() != null ? item.getOwner().getId() : null); | ||
| dto.setRequestId(item.getRequest() != null ? item.getRequest().getId() : null); | ||
| return dto; | ||
| } | ||
|
|
||
| /** | ||
| * Преобразует {@link ItemDto} в {@link Item}. | ||
| */ | ||
| public static Item toItem(ItemDto dto, Long ownerId) { | ||
|
avnovik marked this conversation as resolved.
Outdated
|
||
| if (dto == null) { | ||
| return null; | ||
| } | ||
|
|
||
| Item item = new Item(); | ||
| item.setName(dto.getName()); | ||
| item.setDescription(dto.getDescription()); | ||
| item.setAvailable(dto.getAvailable()); | ||
|
|
||
| if (ownerId != null) { | ||
| User owner = new User(); | ||
|
avnovik marked this conversation as resolved.
Outdated
|
||
| owner.setId(ownerId); | ||
| item.setOwner(owner); | ||
| } | ||
|
|
||
| return item; | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| package ru.practicum.shareit.item; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| import ru.practicum.shareit.item.dto.ItemDto; | ||
|
|
||
| /** | ||
| * Сервис для операций с вещами. | ||
| */ | ||
| public interface ItemService { | ||
|
|
||
| /** Создаёт вещь. */ | ||
| ItemDto create(Long userId, ItemDto itemDto); | ||
|
|
||
| /** Обновляет вещь. */ | ||
| ItemDto update(Long userId, Long itemId, ItemDto itemDto); | ||
|
|
||
| /** Возвращает вещь по id. */ | ||
| ItemDto getById(Long itemId); | ||
|
|
||
| /** Возвращает список вещей владельца. */ | ||
| List<ItemDto> getAllByOwner(Long userId); | ||
|
|
||
| /** Ищет доступные вещи по тексту в названии или описании. */ | ||
| List<ItemDto> search(String text); | ||
| } |
98 changes: 98 additions & 0 deletions
98
src/main/java/ru/practicum/shareit/item/ItemServiceImpl.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,98 @@ | ||
| package ru.practicum.shareit.item; | ||
|
|
||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.stereotype.Service; | ||
| import ru.practicum.shareit.exceptions.NotFoundException; | ||
| import ru.practicum.shareit.item.dto.ItemDto; | ||
| import ru.practicum.shareit.item.model.Item; | ||
| import ru.practicum.shareit.user.UserService; | ||
|
|
||
| import java.util.List; | ||
| import java.util.Map; | ||
| import java.util.concurrent.ConcurrentHashMap; | ||
| import java.util.concurrent.atomic.AtomicLong; | ||
|
|
||
| /** | ||
| * In-memory реализация {@link ItemService}. | ||
| */ | ||
| @Service | ||
| @RequiredArgsConstructor | ||
| public class ItemServiceImpl implements ItemService { | ||
| private final UserService userService; | ||
| private final Map<Long, Item> items = new ConcurrentHashMap<>(); | ||
|
avnovik marked this conversation as resolved.
Outdated
|
||
| private final AtomicLong nextId = new AtomicLong(1); | ||
|
avnovik marked this conversation as resolved.
Outdated
|
||
|
|
||
| @Override | ||
| public ItemDto create(Long userId, ItemDto itemDto) { | ||
| userService.getById(userId); | ||
| Item item = ItemMapper.toItem(itemDto, userId); | ||
| Long id = nextId.getAndIncrement(); | ||
| item.setId(id); | ||
|
|
||
| items.put(id, item); | ||
| return ItemMapper.toItemDto(item); | ||
| } | ||
|
|
||
| @Override | ||
| public ItemDto update(Long userId, Long itemId, ItemDto itemDto) { | ||
| Item existing = items.get(itemId); | ||
| if (existing == null) { | ||
| throw new NotFoundException("Item with id=" + itemId + " not found"); | ||
| } | ||
|
|
||
| Long ownerId = existing.getOwner() != null ? existing.getOwner().getId() : null; | ||
| if (ownerId == null || !ownerId.equals(userId)) { | ||
| throw new SecurityException("Only owner can update item with id=" + itemId); | ||
| } | ||
|
|
||
| if (itemDto.getName() != null) { | ||
| existing.setName(itemDto.getName()); | ||
| } | ||
| if (itemDto.getDescription() != null) { | ||
| existing.setDescription(itemDto.getDescription()); | ||
| } | ||
| if (itemDto.getAvailable() != null) { | ||
| existing.setAvailable(itemDto.getAvailable()); | ||
| } | ||
|
|
||
| return ItemMapper.toItemDto(existing); | ||
| } | ||
|
|
||
| @Override | ||
| public ItemDto getById(Long itemId) { | ||
| Item item = items.get(itemId); | ||
| if (item == null) { | ||
| throw new NotFoundException("Item with id=" + itemId + " not found"); | ||
| } | ||
| return ItemMapper.toItemDto(item); | ||
| } | ||
|
|
||
| @Override | ||
| public List<ItemDto> getAllByOwner(Long userId) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Нужно добавить проверку, есть ли у нас такой пользователь в хранилище There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Не подправлено замечание |
||
| return items.values().stream() | ||
| .filter(item -> { | ||
| Long ownerId = item.getOwner() != null ? item.getOwner().getId() : null; | ||
| return userId.equals(ownerId); | ||
| }) | ||
| .map(ItemMapper::toItemDto) | ||
| .toList(); | ||
| } | ||
|
|
||
| @Override | ||
| public List<ItemDto> search(String text) { | ||
| if (text == null || text.isBlank()) { | ||
| return List.of(); | ||
| } | ||
|
|
||
| String query = text.toLowerCase(); | ||
| return items.values().stream() | ||
| .filter(item -> !Boolean.FALSE.equals(item.getAvailable())) | ||
| .filter(item -> { | ||
| String name = item.getName() != null ? item.getName().toLowerCase() : ""; | ||
| String description = item.getDescription() != null ? item.getDescription().toLowerCase() : ""; | ||
| return name.contains(query) || description.contains(query); | ||
| }) | ||
| .map(ItemMapper::toItemDto) | ||
| .toList(); | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,25 @@ | ||
| package ru.practicum.shareit.item.dto; | ||
|
|
||
| import jakarta.validation.constraints.NotNull; | ||
| import jakarta.validation.constraints.NotBlank; | ||
| import lombok.Data; | ||
|
|
||
| /** | ||
| * TODO Sprint add-controllers. | ||
| * DTO вещи. | ||
| * Используется для обмена данными о вещи через REST. | ||
| */ | ||
| @Data | ||
| public class ItemDto { | ||
| private Long id; | ||
|
|
||
| @NotBlank | ||
| private String name; | ||
|
|
||
| @NotBlank | ||
| private String description; | ||
|
|
||
| @NotNull | ||
| private Boolean available; | ||
| private Long ownerId; | ||
| private Long requestId; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,19 @@ | ||
| package ru.practicum.shareit.item.model; | ||
|
|
||
| import lombok.Data; | ||
| import ru.practicum.shareit.request.ItemRequest; | ||
| import ru.practicum.shareit.user.model.User; | ||
|
|
||
| /** | ||
| * TODO Sprint add-controllers. | ||
| * Модель вещи. | ||
| * Описывает вещь, которую владелец может сдавать в аренду. | ||
| */ | ||
| @Data | ||
| public class Item { | ||
| private Long id; | ||
| private String name; | ||
| private String description; | ||
| private Boolean available; | ||
| private User owner; | ||
| private ItemRequest request; | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.