Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,32 @@
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.1.2</version>
<configuration>
<configLocation>checkstyle.xml</configLocation>
<failOnViolation>true</failOnViolation>
<logViolationsToConsole>true</logViolationsToConsole>
<includeTestSourceDirectory>true</includeTestSourceDirectory>
</configuration>
<executions>
<execution>
<goals>
<goal>check</goal>
</goals>
<phase>compile</phase>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.puppycrawl.tools</groupId>
<artifactId>checkstyle</artifactId>
<version>10.3</version>
</dependency>
</dependencies>
</plugin>
</plugins>
<pluginManagement>
<plugins>
Expand Down
1 change: 0 additions & 1 deletion src/main/java/ru/practicum/shareit/ShareItApp.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,4 @@ public class ShareItApp {
public static void main(String[] args) {
SpringApplication.run(ShareItApp.class, args);
}

}
7 changes: 0 additions & 7 deletions src/main/java/ru/practicum/shareit/booking/Booking.java

This file was deleted.

8 changes: 8 additions & 0 deletions src/main/java/ru/practicum/shareit/booking/BookingStatus.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package ru.practicum.shareit.booking;

public enum BookingStatus {
WAITING,
APPROVED,
REJECTED,
CANCELED
}
22 changes: 19 additions & 3 deletions src/main/java/ru/practicum/shareit/booking/dto/BookingDto.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,23 @@
package ru.practicum.shareit.booking.dto;

/**
* TODO Sprint add-bookings.
*/
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Data;
import lombok.experimental.FieldDefaults;
import ru.practicum.shareit.booking.BookingStatus;
import ru.practicum.shareit.item.model.Item;
import ru.practicum.shareit.user.model.User;

import java.time.LocalDateTime;

@Data
@Builder
@FieldDefaults(level = AccessLevel.PRIVATE)
public class BookingDto {
Long id;
LocalDateTime start;
LocalDateTime end;
Item item;
User booker;
BookingStatus status;
}
23 changes: 23 additions & 0 deletions src/main/java/ru/practicum/shareit/booking/model/Booking.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package ru.practicum.shareit.booking.model;

import lombok.AccessLevel;
import lombok.Builder;
import lombok.Data;
import lombok.experimental.FieldDefaults;
import ru.practicum.shareit.booking.BookingStatus;
import ru.practicum.shareit.item.model.Item;
import ru.practicum.shareit.user.model.User;

import java.time.LocalDateTime;

@Data
@Builder
@FieldDefaults(level = AccessLevel.PRIVATE)
public class Booking {
Long id;
LocalDateTime start;
LocalDateTime end;
Item item;
User booker;
BookingStatus status;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package ru.practicum.shareit.exception;

public class DuplicateValidationException extends RuntimeException {
public DuplicateValidationException(String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package ru.practicum.shareit.exception;

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice
@Slf4j
public class ExceptionsHandler {

@ExceptionHandler(NotFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public ErrorResponse handleNotFoundError(NotFoundException exception) {
log.warn("Не найдена сущность для запроса {}", exception.getMessage());
return new ErrorResponse("Не найдено", exception.getMessage());
}

@ExceptionHandler(DuplicateValidationException.class)
@ResponseStatus(HttpStatus.CONFLICT)
public ErrorResponse handleDuplicateError(DuplicateValidationException exception) {
log.error("Конфликт данных {}", exception.getMessage());
return new ErrorResponse("Дупликация информации:", exception.getMessage());
}

@ExceptionHandler(ForbiddenException.class)
@ResponseStatus(HttpStatus.FORBIDDEN)
public ErrorResponse handleForbiddenError(ForbiddenException exception) {
log.error("Попытка запроса на лицом с недостаточными правами {}", exception.getMessage());
return new ErrorResponse("Доступ запрещен:", exception.getMessage());
}

public record ErrorResponse(String error, String details) {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package ru.practicum.shareit.exception;

public class ForbiddenException extends RuntimeException {
public ForbiddenException(String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package ru.practicum.shareit.exception;

public class NotFoundException extends RuntimeException {
public NotFoundException(String message) {
super(message);
}
}
49 changes: 44 additions & 5 deletions src/main/java/ru/practicum/shareit/item/ItemController.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,51 @@
package ru.practicum.shareit.item;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import jakarta.validation.Valid;
import jakarta.validation.constraints.Positive;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.*;
import ru.practicum.shareit.item.dto.ItemDto;
import ru.practicum.shareit.item.dto.UpdateItemDto;
import ru.practicum.shareit.item.service.ItemService;

import java.util.Collection;

/**
* TODO Sprint add-controllers.
*/
@RestController
@RequestMapping("/items")
@AllArgsConstructor
public class ItemController {

private static final String USER_ID_HEADER = "X-Sharer-User-Id";
private final ItemService itemService;

@GetMapping
public Collection<ItemDto> getAllByUser(@RequestHeader(USER_ID_HEADER) Long userId) {
return itemService.getAllByUser(userId);
}

@GetMapping("/{itemId}")
public ItemDto getById(@RequestHeader(USER_ID_HEADER) Long userId,
@PathVariable Long itemId) {
return itemService.getById(userId, itemId);
}

@PostMapping
public ItemDto create(@RequestHeader(USER_ID_HEADER) Long userId,
@RequestBody @Valid ItemDto item) {
return itemService.create(userId, item);
}

@PatchMapping("/{itemId}")
public ItemDto update(@RequestHeader(USER_ID_HEADER) Long userId,
@PathVariable @Positive Long itemId,
@RequestBody @Valid UpdateItemDto item) {
return itemService.update(userId, itemId, item);
}

@GetMapping("/search")
public Collection<ItemDto> search(@RequestHeader(USER_ID_HEADER) Long userId,
@RequestParam(name = "text") String text) {
return itemService.search(userId, text);
}

}
21 changes: 18 additions & 3 deletions src/main/java/ru/practicum/shareit/item/dto/ItemDto.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,22 @@
package ru.practicum.shareit.item.dto;

/**
* TODO Sprint add-controllers.
*/
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Data;
import lombok.experimental.FieldDefaults;

@Data
@Builder
@FieldDefaults(level = AccessLevel.PRIVATE)
public class ItemDto {
Long id;
@NotBlank
String name;
@NotBlank
String description;
@NotNull
Boolean available;
Long requestId;
}
13 changes: 13 additions & 0 deletions src/main/java/ru/practicum/shareit/item/dto/UpdateItemDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package ru.practicum.shareit.item.dto;

import lombok.AccessLevel;
import lombok.Data;
import lombok.experimental.FieldDefaults;

@Data
@FieldDefaults(level = AccessLevel.PRIVATE)
public class UpdateItemDto {
String name;
String description;
Boolean available;
}
28 changes: 28 additions & 0 deletions src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package ru.practicum.shareit.item.mapper;

import lombok.experimental.UtilityClass;
import ru.practicum.shareit.item.dto.ItemDto;
import ru.practicum.shareit.item.model.Item;

@UtilityClass
public class ItemMapper {

public ItemDto toItemDto(Item item) {
return ItemDto.builder()
.id(item.getId())
.name(item.getName())
.description(item.getDescription())
.available(item.isAvailable())
.requestId(item.getRequest() == null ? null : item.getRequest().getId())
.build();
}

public Item toItem(ItemDto itemDto) {
return Item.builder()
.id(itemDto.getId())
.name(itemDto.getName())
.description(itemDto.getDescription())
.available(itemDto.getAvailable())
.build();
}
}
19 changes: 16 additions & 3 deletions src/main/java/ru/practicum/shareit/item/model/Item.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
package ru.practicum.shareit.item.model;

/**
* TODO Sprint add-controllers.
*/
import lombok.*;
import lombok.experimental.FieldDefaults;
import ru.practicum.shareit.request.ItemRequest;
import ru.practicum.shareit.user.model.User;

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE)
public class Item {
Long id;
String name;
String description;
boolean available;
User owner;
ItemRequest request;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package ru.practicum.shareit.item.repository;

import org.springframework.stereotype.Repository;
import ru.practicum.shareit.item.dto.UpdateItemDto;
import ru.practicum.shareit.item.model.Item;

import java.util.*;

@Repository
public class InMemoryItemRepository implements ItemRepository {

private final HashMap<Long, Item> items = new HashMap<>();

@Override
public Optional<Item> getById(Long itemId) {
return Optional.ofNullable(items.get(itemId));
}

@Override
public Collection<Item> getByUserId(Long id) {
return items.values().stream()
.filter(item -> Objects.equals(item.getOwner().getId(), id))
.toList();
}

@Override
public Item create(Item item) {
item.setId(generateNextId());
items.put(item.getId(), item);
return item;
}

@Override
public Item update(Item item, UpdateItemDto updateItem) {
if (updateItem.getName() != null && !updateItem.getName().isBlank()) {
item.setName(updateItem.getName());
}

if (updateItem.getDescription() != null && !updateItem.getDescription().isBlank()) {
item.setDescription(updateItem.getDescription());
}

if (updateItem.getAvailable() != null) {
item.setAvailable(updateItem.getAvailable());
}
return item;
}

@Override
public Collection<Item> searchItems(String text) {
if (text.isBlank()) return Collections.emptyList();

return items.values().stream()
.filter(Item::isAvailable)
.filter(item -> item.getName().toLowerCase().contains(text.toLowerCase()) ||
item.getDescription().toLowerCase().contains(text.toLowerCase()))
.toList();
}

private Long generateNextId() {
Long nextId = items.keySet().stream()
.max(Long::compareTo)
.orElse(0L);
return ++nextId;
}
}
Loading