package com.kryptnostic.directory.v1.model;
import org.joda.time.DateTime;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.base.Preconditions;
import com.kryptnostic.directory.v1.exception.ActiveReservationException;
import com.kryptnostic.directory.v1.exception.ReservationTokenMismatchException;
import com.kryptnostic.directory.v1.model.request.ReserveUserRequest;
import com.kryptnostic.kodex.v1.constants.Names;
public final class Reservation extends ReserveUserRequest {
private final UserStatus status;
private final DateTime created;
private final ReservationToken token;
private Reservation( ReservationBuilder builder ) {
super( builder.realm, builder.username, builder.email, builder.givenName );
this.status = builder.status;
this.created = builder.created;
this.token = builder.token;
}
@JsonCreator
public Reservation(
@JsonProperty( Names.REALM_FIELD ) String realm,
@JsonProperty( Names.USERNAME_FIELD ) String username,
@JsonProperty( Names.EMAIL_FIELD ) String email,
@JsonProperty( Names.GIVEN_NAME_FIELD ) String givenName,
@JsonProperty( Names.STATUS_FIELD ) UserStatus status,
@JsonProperty( Names.TIME_FIELD ) DateTime created,
@JsonProperty( Names.TOKEN_PROPERTY ) ReservationToken token ) {
super( realm, username, email, givenName );
this.status = status;
this.created = created;
this.token = token;
}
public static Reservation reserve( ReserveUserRequest request ) {
return new Reservation.ReservationBuilder( request.getRealm(), request.getUsername() )
.withGivenName( request.getGivenName() ).withEmail( request.getEmail() )
.withStatus( UserStatus.RESERVED ).createdNow().withNewToken().build();
}
public Reservation activate( ReservationToken token ) throws ReservationTokenMismatchException,
ActiveReservationException {
if ( this.status != UserStatus.RESERVED ) {
throw new ActiveReservationException();
}
if ( !this.token.equals( token ) ) {
throw new ReservationTokenMismatchException();
}
return new ReservationBuilder( this.getRealm(), this.getUsername() ).withGivenName( this.getGivenName() )
.withEmail( this.getEmail() ).withStatus( UserStatus.ACTIVE ).withToken( this.getToken() )
.createdAt( this.created ).build();
}
@JsonProperty( Names.STATUS_FIELD )
public UserStatus getStatus() {
return status;
}
@JsonProperty( Names.TOKEN_PROPERTY )
public ReservationToken getToken() {
return token;
}
@JsonProperty( Names.TIME_FIELD )
public DateTime getTimeCreated() {
return created;
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ( ( created == null ) ? 0 : created.hashCode() );
result = prime * result + ( ( status == null ) ? 0 : status.hashCode() );
result = prime * result + ( ( token == null ) ? 0 : token.hashCode() );
return result;
}
@Override
public boolean equals( Object obj ) {
if ( this == obj ) return true;
if ( !super.equals( obj ) ) return false;
if ( getClass() != obj.getClass() ) return false;
Reservation other = (Reservation) obj;
if ( created == null ) {
if ( other.created != null ) return false;
} else if ( !created.equals( other.created ) ) return false;
if ( status != other.status ) return false;
if ( token == null ) {
if ( other.token != null ) return false;
} else if ( !token.equals( other.token ) ) return false;
return true;
}
public static class ReservationBuilder {
private String realm;
private String username;
private String email;
private String givenName;
private UserStatus status;
private ReservationToken token;
private DateTime created;
public ReservationBuilder( String realm, String username ) {
this.realm = realm;
this.username = username;
}
public ReservationBuilder withToken( ReservationToken token ) {
this.token = token;
return this;
}
public ReservationBuilder withNewToken() {
this.token = ReservationToken.getSecureToken();
return this;
}
public ReservationBuilder createdAt( DateTime time ) {
this.created = time;
return this;
}
public ReservationBuilder createdNow() {
this.created = DateTime.now();
return this;
}
public ReservationBuilder withGivenName( String givenName ) {
this.givenName = givenName;
return this;
}
public ReservationBuilder withStatus( UserStatus status ) {
this.status = status;
return this;
}
public ReservationBuilder withEmail( String email ) {
this.email = email;
return this;
}
public Reservation build() {
Preconditions.checkNotNull( this.realm );
Preconditions.checkNotNull( this.username );
Preconditions.checkNotNull( this.email );
Preconditions.checkNotNull( this.givenName );
Preconditions.checkNotNull( this.status );
Preconditions.checkNotNull( this.token );
Preconditions.checkNotNull( this.created );
return new Reservation( this );
}
}
}