Interface RoomMapper
-
Method Summary
Modifier and TypeMethodDescriptionconvertCommonEquipmentToDto(@NonNull Set<CommonEquipment> commonEquipment) default @NonNull RoomcreateRoom(@NonNull NewRoomDTO dto) fromDto(NewRoomDTO newRoomDTO) Converts aNewRoomDTOto aRoom.toDto(ConferenceRoom room) Converts aConferenceRoomto aRoomDTO.toSummaryDto(Room room) Converts a givenRoomto aRoomSummaryDTO.
-
Method Details
-
toDto
- Parameters:
room- The Room that shall be turned into a data-transfer object. If it is aConferenceRoom, then information will be lost, because the common equipment only exists on the ConferenceRoom class, but not on the Room class.- Returns:
- The given Room as a data-transfer object.
- Implementation Note:
- The
RoomDTO.commonEquipmentis mapped bycreateRoom(NewRoomDTO).
-
toDto
Converts aConferenceRoomto aRoomDTO.- Parameters:
room- The Room that shall be turned into a data-transfer object.- Returns:
- The given ConferenceRoom as a data-transfer object.
-
fromDto
Room fromDto(NewRoomDTO newRoomDTO) throws de.gustavblass.commons.exceptions.IllegalArgumentException Converts aNewRoomDTOto aRoom.- Parameters:
newRoomDTO- The data-transfer object to turn into a proper model object.- Returns:
- The given DTO as a proper Room. Will not have a
Room.idand noRoom.reservations. - Throws:
de.gustavblass.commons.exceptions.IllegalArgumentException- Because ofRoom.setCapacity(int).
-
toSummaryDto
Converts a givenRoomto aRoomSummaryDTO.- Parameters:
room- The Room that shall become a summarised data-transfer object.- Returns:
- The summarised data-transfer object created from the given Room.
-
createRoom
Creates a new
QuietStudyRoomorConferenceRoom, depending on theNewRoomDTO.type.Adds the
NewRoomDTO.individualEquipmentand – possibly – theNewRoomDTO.commonEquipmentto theRoom. Sets the new Room as the back-reference on the individual equipment.- Parameters:
dto- The data-transfer object which the new Room shall be based on.- Returns:
- The new Room of the correct concrete class and with the DTO's equipment.
- Implementation Note:
1. Why is this method necessary?
This method is necessary because
- MapStruct is apparently unable to choose the correct concrete implementation of the abstract Room class,
- it could not be determined how to tell MapStruct to set up the back-reference on the individual equipment,
- MapStruct is unable to map
NewRoomDTO.commonEquipmenttoConferenceRoom.commonEquipment, because the return type is the abstract Room class.
2. Why does this method not throw an exception for illegal common equipment?
As specified elsewhere,
NewRoomDTO.commonEquipmentmust only be specified ifNewRoomDTO.typeis set toRoomType.CONFERENCE_ROOM. However, if this requirement is not met, this method does not throw an exception and instead ignores the common equipment.2.1. The critical error case
This may be counterintuitive, but has a very specific reason. Imagine this scenario:
- User sets the room type to conference room.
- User selects several types of common equipment.
- User switches the room type back to
RoomType.QUIET_STUDY_ROOM. - User presses “submit”.
Then, the HTTP request would still include the common equipment from step 2 because the respective HTML input fields have not been reset. The server would yell at the user: “How dare you select any common equipment for a quiet-study room?!”
However, we absolutely do not want the user to manually unselect all the common equipment, so the common equipment must be unselected automatically for the user.
2.2. Approaches to automatically reset the input fields
CSS can only (visually) hide the common equipment's HTML input fields, but cannot change their actual values. So, in order to unset the common-equipment whenever the user switches from
RoomType.CONFERENCE_ROOMtoRoomType.QUIET_STUDY_ROOM, we would have to either …- … rely on (i.e. mandatorily require) JavaScript (which is not desirable for accessibility reasons) or
- make an HTTP request asking the server to reset the common equipment in the form.
Such an HTTP request could only be made with a special submit button.
However, if we did nothing besides adding the new submit button, the server would think that the HTTP request
serves the purpose of creating a new Room.
So, in order to tell the server that the second button is only meant to reset the common equipment, we would
either …
- … need to use a different form
actionpath (but the room-type input field can only be part of one form, so this option is impossible) or - add a special
inputHTML element, but – again – we could not modify its value dynamically.
- … need to use a different form
In other words, option 2 cannot be implemented. Only option 1 can be implemented, but would not work for any user who has disabled JavaScript.
3. Conclusion
Therefore, if we do not want to impose a JavaScript requirement on the users, we must silently discard the common equipment for quiet-study rooms.
Why does this method not throw an exception for individual equipment whose
countis zero?Once again, without JavaScript, we cannot modify the values of the individual-equipment's HTML input fields. Therefore, on the server side, we cannot distinguish between these cases:
- The user forgot to select a valid equipment count.
- The user set the
IndividualEquipment.countto zero because they want no individual equipment of thatRoomEquipment.typein the new Room.
Consequently, we can only ignore individual equipment where
count == 0.
-
convertCommonEquipmentToDto
@NonNull default @NonNull Set<String> convertCommonEquipmentToDto(@NonNull @NonNull Set<CommonEquipment> commonEquipment) Converts aSetofCommonEquipmentto a Set ofCommonEquipmentType. This is done because the only additional information a CommonEquipment object holds is a database ID, which is irrelevant when communicating the facilities of aConferenceRoom.- Parameters:
commonEquipment- The CommonEquipment that shall be reduced to the matching CommonEquipmentTypes.- Returns:
- The CommonEquipmentTypes present in the given Set.
-