Skip to content
Open
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
13 changes: 13 additions & 0 deletions src/main/java/org/unilab/uniplan/room/CustomRoomRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.unilab.uniplan.room;

import org.unilab.uniplan.room.dto.RoomResponseDto;
import java.util.List;
import java.util.Optional;
import java.util.UUID;

public interface CustomRoomRepository {

List<RoomResponseDto> findAllRoomResponses();

Optional<RoomResponseDto> findRoomResponseById(UUID id);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package org.unilab.uniplan.room;

import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import org.hibernate.query.common.JoinType;
import org.hibernate.query.criteria.HibernateCriteriaBuilder;
import org.hibernate.query.criteria.JpaCriteriaQuery;
import org.hibernate.query.criteria.JpaEntityJoin;
import org.hibernate.query.criteria.JpaRoot;
import org.unilab.uniplan.category.Category;
import org.unilab.uniplan.room.dto.RoomResponseDto;
import org.unilab.uniplan.roomcategory.RoomCategory;
import java.util.List;
import java.util.Optional;
import java.util.UUID;

public class CustomRoomRepositoryImpl implements CustomRoomRepository {

@PersistenceContext
private EntityManager entityManager;

@Override
public List<RoomResponseDto> findAllRoomResponses() {
HibernateCriteriaBuilder cb = (HibernateCriteriaBuilder) entityManager.getCriteriaBuilder();

JpaCriteriaQuery<RoomResponseDto> query = cb.createQuery(RoomResponseDto.class);

JpaRoot<Room> room = query.from(Room.class);

JpaEntityJoin<Room, RoomCategory> roomCategory =
room.join(RoomCategory.class, JoinType.LEFT);
roomCategory.on(cb.equal(roomCategory.get("room"), room));

JpaEntityJoin<RoomCategory, Category> category =
roomCategory.join(Category.class, JoinType.LEFT);
category.on(cb.equal(category, roomCategory.get("category")));

query.select(cb.construct(
RoomResponseDto.class,
room.get("id"),
room.get("faculty").get("id"),
room.get("roomNumber"),
category.get("id")
));

return entityManager.createQuery(query).getResultList();
}

@Override
public Optional<RoomResponseDto> findRoomResponseById(UUID id) {
HibernateCriteriaBuilder cb = (HibernateCriteriaBuilder) entityManager.getCriteriaBuilder();

JpaCriteriaQuery<RoomResponseDto> query = cb.createQuery(RoomResponseDto.class);

JpaRoot<Room> room = query.from(Room.class);
JpaEntityJoin<Room, RoomCategory> roomCategory =
room.join(RoomCategory.class, JoinType.LEFT);
roomCategory.on(cb.equal(roomCategory.get("room"), room));

JpaEntityJoin<RoomCategory, Category> category =
roomCategory.join(Category.class, JoinType.LEFT);
category.on(cb.equal(category, roomCategory.get("category")));

query.select(cb.construct(
RoomResponseDto.class,
room.get("id"),
room.get("faculty").get("id"),
room.get("roomNumber"),
category.get("id")
)).where(cb.equal(room.get("id"), id));

return entityManager.createQuery(query)
.getResultStream()
.findFirst();
}
}
2 changes: 1 addition & 1 deletion src/main/java/org/unilab/uniplan/room/Room.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public class Room extends BaseEntity {
@ManyToOne
@JoinColumn(name = "faculty_id", referencedColumnName = "id", nullable = false)
private Faculty faculty;

@Column(name = "room_number", nullable = false, length = 50)
private String roomNumber;

}
28 changes: 10 additions & 18 deletions src/main/java/org/unilab/uniplan/room/RoomController.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package org.unilab.uniplan.room;

import static org.springframework.http.ResponseEntity.ok;

import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
Expand All @@ -18,7 +16,6 @@
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.unilab.uniplan.room.dto.RoomDto;
import org.unilab.uniplan.room.dto.RoomRequestDto;
import org.unilab.uniplan.room.dto.RoomResponseDto;

Expand All @@ -28,39 +25,34 @@
@Tag(name = "Rooms", description = "Manage classrooms and lecture halls, including room numbers and assigned faculties")
public class RoomController {

private final RoomService roomService;
private final RoomMapper roomMapper;
private final RoomWebFacade roomWebFacade;

@PostMapping
public ResponseEntity<RoomResponseDto> createRoom(@Valid @NotNull @RequestBody final RoomRequestDto roomRequestDto) {
final RoomDto roomDto = roomService.createRoom(roomMapper.toInternalDto(roomRequestDto));

return new ResponseEntity<>(roomMapper.toResponseDto(roomDto), HttpStatus.CREATED);
public ResponseEntity<Void> createRoom(@Valid @NotNull @RequestBody final RoomRequestDto roomRequestDto) {
roomWebFacade.createRoom(roomRequestDto);
return ResponseEntity.status(HttpStatus.CREATED).build();
}

@GetMapping
public List<RoomResponseDto> getAllRooms() {
return roomMapper.toResponseDtoList(roomService.getAllRooms());
public ResponseEntity<List<RoomResponseDto>> getAllRooms() {
return ResponseEntity.ok(roomWebFacade.getAllRooms());
}

@GetMapping("/{id}")
public ResponseEntity<RoomResponseDto> getRoomById(@PathVariable final UUID id) {
final RoomDto roomDto = roomService.getRoomById(id);

return ok(roomMapper.toResponseDto(roomDto));
return ResponseEntity.ok(roomWebFacade.getRoomById(id));
}

@PutMapping("/{id}")
public ResponseEntity<RoomResponseDto> updateRoom(@PathVariable final UUID id,
@Valid @NotNull @RequestBody final RoomRequestDto roomRequestDto) {
final RoomDto internalDto = roomMapper.toInternalDto(roomRequestDto);

return ok(roomMapper.toResponseDto(roomService.updateRoom(id, internalDto)));
roomWebFacade.updateRoom(id, roomRequestDto);
return ResponseEntity.noContent().build();
}

@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteRoom(@PathVariable final UUID id) {
roomService.deleteRoom(id);
roomWebFacade.deleteRoom(id);

return ResponseEntity.noContent().build();
}
Expand Down
20 changes: 6 additions & 14 deletions src/main/java/org/unilab/uniplan/room/RoomMapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,21 @@
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget;
import org.unilab.uniplan.room.dto.RoomDto;
import org.unilab.uniplan.room.dto.RoomRequestDto;
import org.unilab.uniplan.room.dto.RoomResponseDto;

@Mapper
public interface RoomMapper {

@Mapping(source = "faculty.id", target = "facultyId")
RoomDto toDto(final Room room);

@Mapping(source = "facultyId", target = "faculty.id")
Room toEntity(final RoomDto roomDto);

@Mapping(target = "id", ignore = true)
RoomDto toInternalDto(final RoomRequestDto roomRequestDto);
Room toEntity(final RoomRequestDto roomRequestDto);

RoomResponseDto toResponseDto(final RoomDto roomDto);
@Mapping(target = "facultyId", source = "faculty.id")
RoomResponseDto toResponseDto(Room room);

List<RoomDto> toDtoList(final List<Room> rooms);
List<RoomResponseDto> toResponseDtoList(final List<Room> rooms);

List<RoomResponseDto> toResponseDtoList(final List<RoomDto> rooms);

@Mapping(source = "roomDto.facultyId", target = "faculty.id")
@Mapping(source = "facultyId", target = "faculty.id")
@Mapping(target = "id", ignore = true)
void updateEntityFromDto(final RoomDto roomDto, @MappingTarget final Room room);
void updateEntityFromDto(final RoomRequestDto roomRequestDto, @MappingTarget final Room room);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
import org.springframework.stereotype.Repository;

@Repository
public interface RoomRepository extends JpaRepository<Room, UUID> {
public interface RoomRepository extends JpaRepository<Room, UUID>, CustomRoomRepository {

}
59 changes: 19 additions & 40 deletions src/main/java/org/unilab/uniplan/room/RoomService.java
Original file line number Diff line number Diff line change
@@ -1,65 +1,44 @@
package org.unilab.uniplan.room;

import static org.unilab.uniplan.utils.ErrorConstants.ROOM_NOT_FOUND;

import java.util.List;
import java.util.Optional;
import java.util.UUID;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.unilab.uniplan.exception.ResourceNotFoundException;
import org.unilab.uniplan.room.dto.RoomDto;
import org.unilab.uniplan.common.model.BaseService;
import org.unilab.uniplan.room.dto.RoomResponseDto;

@Service
@RequiredArgsConstructor
public class RoomService {
public class RoomService implements BaseService<Room> {

private final RoomRepository roomRepository;
private final RoomMapper roomMapper;

@Transactional
public RoomDto createRoom(final RoomDto roomDto) {
final Room room = roomMapper.toEntity(roomDto);

return saveEntityAndConvertToDto(room);
}

public List<RoomDto> getAllRooms() {
return roomMapper.toDtoList(roomRepository.findAll());
@Override
public void save(final Room room) {
roomRepository.save(room);
}

public RoomDto getRoomById(final UUID id) {
return roomRepository.findById(id)
.map(roomMapper::toDto)
.orElseThrow(() -> new ResourceNotFoundException(ROOM_NOT_FOUND.getMessage(
String.valueOf(id))));
@Override
public List<Room> getAll() {
return roomRepository.findAll();
}

@Transactional
public RoomDto updateRoom(final UUID id, final RoomDto roomDto) {
return roomRepository.findById(id)
.map(existingRoom -> updateEntityAndConvertToDto(
roomDto,
existingRoom)).orElseThrow(() -> new ResourceNotFoundException(
ROOM_NOT_FOUND.getMessage(String.valueOf(id))));
@Override
public Optional<Room> getById(final UUID id) {
return roomRepository.findById(id);
}

@Transactional
public void deleteRoom(final UUID id) {
final Room room = roomRepository.findById(id)
.orElseThrow(() -> new ResourceNotFoundException(
ROOM_NOT_FOUND.getMessage(String.valueOf(id))));
@Override
public void delete(final Room room) {
roomRepository.delete(room);
}

private RoomDto updateEntityAndConvertToDto(final RoomDto dto,
final Room entity) {
roomMapper.updateEntityFromDto(dto, entity);
return saveEntityAndConvertToDto(entity);
public List<RoomResponseDto> getAllRoomResponses() {
return roomRepository.findAllRoomResponses();
}

private RoomDto saveEntityAndConvertToDto(final Room entity) {
final Room savedEntity = roomRepository.save(entity);
return roomMapper.toDto(savedEntity);
public Optional<RoomResponseDto> getRoomResponseById(final UUID id) {
return roomRepository.findRoomResponseById(id);
}
}
63 changes: 63 additions & 0 deletions src/main/java/org/unilab/uniplan/room/RoomWebFacade.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package org.unilab.uniplan.room;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.unilab.uniplan.exception.ResourceNotFoundException;
import org.unilab.uniplan.room.dto.RoomRequestDto;
import org.unilab.uniplan.room.dto.RoomResponseDto;
import java.util.List;
import java.util.UUID;
import static org.unilab.uniplan.utils.ErrorConstants.ROOM_NOT_FOUND;

@Component
@Slf4j
@RequiredArgsConstructor
public class RoomWebFacade {

private final RoomMapper roomMapper;
private final RoomService roomService;

private Room getRoomOrThrow(final UUID id) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this method is called getRoomOrThrow?
The idea of exception is that they happen unexpectedly there is no need to add that behavior in the method name.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was following the same naming convention that's already used in the other files. We can open another pr to refactor the naming across all the files?

return roomService.getById(id)
.orElseThrow(() -> new ResourceNotFoundException(ROOM_NOT_FOUND.getMessage(
String.valueOf(id))));
}

@Transactional
public void createRoom(RoomRequestDto roomRequestDto) {
Room room = roomMapper.toEntity(roomRequestDto);
roomService.save(room);
log.info("created room {} with ID: {}",
room.getRoomNumber(),
room.getId());
}

@Transactional(readOnly = true)
public List<RoomResponseDto> getAllRooms() {
return roomService.getAllRoomResponses();
}

@Transactional
public void deleteRoom(final UUID id) {
final Room room = getRoomOrThrow(id);
roomService.delete(room);
log.info("deleted room with id {}", id);
}

@Transactional(readOnly = true)
public RoomResponseDto getRoomById(final UUID id) {
return roomService.getRoomResponseById(id)
.orElseThrow(() -> new ResourceNotFoundException(ROOM_NOT_FOUND.getMessage(
String.valueOf(id))));
}

@Transactional
public void updateRoom(final UUID id, final RoomRequestDto roomRequestDto) {
final Room room = getRoomOrThrow(id);
roomMapper.updateEntityFromDto(roomRequestDto, room);
roomService.save(room);
log.info("updated room with id {}", id);
}
}
19 changes: 0 additions & 19 deletions src/main/java/org/unilab/uniplan/room/dto/RoomDto.java

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,4 @@ public record RoomRequestDto(
@NotNull(message = "Room number cannot be null")
@Size(max = 50, message = "Room number cannot exceed 50 characters")
String roomNumber
) {

}
) { }
Loading
Loading