ReservationsController.java
@RequestMapping(method = RequestMethod.POST)
String reserve(@Validated ReservationForm form, BindingResult bindingResult,
@DateTimeFormat(iso=DateTimeFormat.ISO.DATE) @PathVariable("date") LocalDate date,
@PathVariable("roomId") Integer roomId, Model model) {
if(bindingResult.hasErrors()) {
return reserveForm(date, roomId, model);
}
ReservableRoom reservableRoom = new ReservableRoom(
new ReservableRoomId(roomId, date));
Reservation reservation = new Reservation();
reservation.setStarttime(form.getStartTime());
reservation.setEndTime(form.getEndTime());
reservation.setReservableRoom(reservableRoom);
reservation.setUser(dummyUser());
try {
reservationService.reserve(reservation);
}
catch (UnavailableReservationException | AlreadyReservedException e) {
model.addAttribute("error", e.getMessage());
return reserveForm(date, roomId, model);
}
return "redirect:/reservations/{date}/{roomId}";
}
@RequestMapping(method = RequestMethod.POST, params = "cancel")
String cancel(@RequestParam("reservationId") Integer reservationId,
@PathVariable("roomId") Integer roomId,
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE) @PathVariable("date") LocalDate date,
Model model) {
User user = dummyUser();
try {
reservationService.cancel(reservationId, user);
}
catch (IllegalStateException e) {
model.addAttribute("error", e.getMessage());
return reserveForm(date, roomId, model);
}
return "redirect:/reservations/{date}/{roomId}";
}
ThirtyMinutesUnit.java
package mrs.app.reservation;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.*;
import javax.validation.*;
@Documented
@Constraint(validatedBy = {ThirtyMinutesUnitValidator.class})
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
@Retention(RINTIME)
public @interface ThirtyMinutesUnit {
String message() default "{mrs.app.reservation.ThirtyMinutesUnit.message}";
Class<?>[]groups() default {};
Class<? extends Playload>[]playload() default {};
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
@Retention(RUNTIME)
@Documented
public @interface List {
ThirtyMinutesUnit[]value();
}
}
ThirtyMinutesUnitValidator.java
package mrs.app.reservation;
import java.time.LocalTime;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class ThirtyMinutesUnitValidator
implements ConstraintValidator<ThirtyMinutesUnit, LocalTime>{
@Override
public void initialize(ThirtyMinutesUnit constraintAnnotation) {
}
@Override
public boolean isValid(LocalTime value, ConstraintValidatorContext context) {
if(value == null) {
return true;
}
return value.getMinute() % 30 == 0;
}
}
EndTimeMuustBeAfterStartTime.java
package mrs.app.reservation;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.*;
import javax.validation.*;
@Documented
@Constraint(validatedBy = {EndTimeMustBeAfterStartTimeValidator.class})
@Target({TYPE, ANNOTATION_TYPE})
@Retention(RUNTIME)
public @interface EntTimeMustBeAfterStartTime{
String message() default "{mrs.app.reservation.EndTimeMustBeAfterStartTime.message}";
Class<?>[]groups() default{};
Class<? extends Playload>[]payload() default {};
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
@Retention(RUNTIME)
@Documented
public @interface List {
EndTimeMustBeAfterStartTime[]value();
}
}
EndTimeMustBeAfterStartTimeValidator.java
package mrs.app.reservation;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class EndTimeMustBeAfterStartTimeValidator
implements ConstraintValidator<EndTimeMustBeAfterStartTime, ReservationForm>{
private String message;
@Override
public void initialize(EndTimeMustBeAfterStartTime constraintAnnotation) {
message = constraintAnnotation.message();
}
@Override
public boolean isValid(ReservationForm value, ConstraintValidatorContext context) {
if(value.getStarttime() == null || value.getEndTime() == null) {
return true;
}
boolean isEndTimeMustBeAfterStartTime = value.getEndTime().isAfter(value.getStartTime());
if(!isEndTimeMustBeAfterStartTime) {
context.disableDefaultConstraintViolation();
context.buildConstraintViolationWithTemplate(message).addPropertyNode("endTime").addConstraintViolation();
}
return isEndTimeMustBeAfterStartTime;
}
}
うーむ、ちょっと混乱してきたな。