package net.java.cargotracker.domain.model.cargo; import java.io.Serializable; import java.util.Date; import javax.persistence.Column; import javax.persistence.Embeddable; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Temporal; import javax.persistence.TemporalType; import javax.validation.constraints.NotNull; import net.java.cargotracker.domain.model.location.Location; import net.java.cargotracker.domain.shared.AbstractSpecification; import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; /** * Route specification. Describes where a cargo origin and destination is, and * the arrival deadline. */ @Embeddable public class RouteSpecification extends AbstractSpecification<Itinerary> implements Serializable { private static final long serialVersionUID = 1L; @ManyToOne @JoinColumn(name = "spec_origin_id", updatable = false) private Location origin; @ManyToOne @JoinColumn(name = "spec_destination_id") private Location destination; @Temporal(TemporalType.DATE) @Column(name = "spec_arrival_deadline") @NotNull private Date arrivalDeadline; public RouteSpecification() { } /** * @param origin origin location - can't be the same as the destination * @param destination destination location - can't be the same as the origin * @param arrivalDeadline arrival deadline */ public RouteSpecification(Location origin, Location destination, Date arrivalDeadline) { Validate.notNull(origin, "Origin is required"); Validate.notNull(destination, "Destination is required"); Validate.notNull(arrivalDeadline, "Arrival deadline is required"); Validate.isTrue(!origin.sameIdentityAs(destination), "Origin and destination can't be the same: " + origin); this.origin = origin; this.destination = destination; this.arrivalDeadline = (Date) arrivalDeadline.clone(); } public Location getOrigin() { return origin; } public Location getDestination() { return destination; } public Date getArrivalDeadline() { return new Date(arrivalDeadline.getTime()); } @Override public boolean isSatisfiedBy(Itinerary itinerary) { return itinerary != null && getOrigin().sameIdentityAs( itinerary.getInitialDepartureLocation()) && getDestination().sameIdentityAs( itinerary.getFinalArrivalLocation()) && getArrivalDeadline().after(itinerary.getFinalArrivalDate()); } private boolean sameValueAs(RouteSpecification other) { return other != null && new EqualsBuilder().append(this.origin, other.origin) .append(this.destination, other.destination) .append(this.arrivalDeadline, other.arrivalDeadline) .isEquals(); } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } RouteSpecification that = (RouteSpecification) o; return sameValueAs(that); } @Override public int hashCode() { return new HashCodeBuilder().append(this.origin) .append(this.destination).append(this.arrivalDeadline) .toHashCode(); } }