com.javaid.bolaky.domain.pools.entity.Pool.java Source code

Java tutorial

Introduction

Here is the source code for com.javaid.bolaky.domain.pools.entity.Pool.java

Source

package com.javaid.bolaky.domain.pools.entity;

import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.MapKeyColumn;
import javax.persistence.MapKeyEnumerated;
import javax.persistence.OneToMany;
import javax.persistence.PersistenceException;
import javax.persistence.PrePersist;
import javax.persistence.Table;
import javax.validation.ConstraintViolation;
import javax.validation.Valid;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import javax.validation.constraints.NotNull;

import org.apache.commons.collections15.CollectionUtils;
import org.apache.commons.collections15.Predicate;
import org.apache.commons.collections15.map.ListOrderedMap;
import org.apache.commons.collections15.set.ListOrderedSet;
import org.apache.commons.collections15.set.UnmodifiableSet;
import org.hibernate.annotations.Parameter;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import org.hibernate.annotations.TypeDefs;
import org.hibernate.validator.constraints.NotEmpty;

import com.javaid.bolaky.domain.jpa.entity.AbstractTimestampUsernameEntity;
import com.javaid.bolaky.domain.pools.entity.enumerated.AgeGroup;
import com.javaid.bolaky.domain.pools.entity.enumerated.DayOfWeek;
import com.javaid.bolaky.domain.pools.entity.enumerated.Gender;
import com.javaid.bolaky.domain.pools.entity.enumerated.PoolStatus;
import com.javaid.bolaky.domain.pools.entity.enumerated.PoolType;
import com.javaid.bolaky.domain.pools.enumerated.PoolsError;
import com.javaid.bolaky.domain.pools.hibernate.constraint.NumberOfPassengersCheck;
import com.javaid.bolaky.domain.pools.hibernate.constraint.PoolEndDate;
import com.javaid.bolaky.domain.pools.hibernate.constraint.SeatAvailability;
import com.javaid.bolaky.domain.pools.hibernate.group.MandatoryDataRules;

@Entity
@Table(name = "POOL")
@TypeDefs({
        @TypeDef(name = "hibernate_persistentDateTime", typeClass = org.joda.time.contrib.hibernate.PersistentDateTime.class),
        @TypeDef(name = "persistence_Local_Date", typeClass = org.joda.time.contrib.hibernate.PersistentLocalDate.class),
        @TypeDef(name = "persistence_Local_Time", typeClass = org.joda.time.contrib.hibernate.PersistentLocalTimeAsTime.class),
        @TypeDef(name = "pool_gender_user_types", typeClass = com.javaid.bolaky.domain.hibernate.jpa.enumeration.GenericEnumUserType.class, parameters = @Parameter(name = "type", value = "com.javaid.bolaky.domain.pools.entity.enumerated.Gender")),
        @TypeDef(name = "pool_status_user_types", typeClass = com.javaid.bolaky.domain.hibernate.jpa.enumeration.GenericEnumUserType.class, parameters = @Parameter(name = "type", value = "com.javaid.bolaky.domain.pools.entity.enumerated.PoolStatus")),
        @TypeDef(name = "pool_age_group_user_types", typeClass = com.javaid.bolaky.domain.hibernate.jpa.enumeration.GenericEnumUserType.class, parameters = @Parameter(name = "type", value = "com.javaid.bolaky.domain.pools.entity.enumerated.AgeGroup")),
        @TypeDef(name = "pool_user_types", typeClass = com.javaid.bolaky.domain.hibernate.jpa.enumeration.GenericEnumUserType.class, parameters = @Parameter(name = "type", value = "com.javaid.bolaky.domain.pools.entity.enumerated.PoolType")) })
@SeatAvailability(groups = MandatoryDataRules.class)
@PoolEndDate(groups = MandatoryDataRules.class)
@NumberOfPassengersCheck(groups = MandatoryDataRules.class)
public class Pool extends AbstractTimestampUsernameEntity {

    private static final long serialVersionUID = 9210101505830391192L;

    @Id
    @Column(name = "POOL_ID")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long poolId;

    @NotNull(message = "P10", groups = MandatoryDataRules.class)
    @Column(name = "USERNAME")
    private String username;

    @NotNull(message = "P11", groups = MandatoryDataRules.class)
    @NotEmpty(message = "P11", groups = MandatoryDataRules.class)
    @Column(name = "POOL_NAME")
    private String poolName;

    @Type(type = "yes_no")
    @Column(name = "COMPLETED")
    private Boolean completed;

    @NotNull(message = "P12", groups = MandatoryDataRules.class)
    @Type(type = "yes_no")
    @Column(name = "SHARE_COST")
    private Boolean shareCost;

    @NotNull(message = "P20", groups = MandatoryDataRules.class)
    @Column(name = "POOL_TYPE")
    @Type(type = "pool_user_types")
    private PoolType poolType;

    @NotNull(message = "P30", groups = MandatoryDataRules.class)
    @Type(type = "yes_no")
    @Column(name = "VALID_LICENSE_INDICATOR")
    private Boolean validLicense;

    @NotNull(message = "P40", groups = MandatoryDataRules.class)
    @Type(type = "yes_no")
    @Column(name = "SMOKER_INDICATOR")
    private Boolean smoker;

    @NotNull(message = "P50", groups = MandatoryDataRules.class)
    @Type(type = "yes_no")
    @Column(name = "ONE_WAY_TRAVEL_INDICATOR")
    private Boolean oneWayTravel;

    @Column(name = "NUMBER_OF_CURRENT_PASSENGER")
    private Integer numberOfCurrentPassengers = 0;

    @NotNull(message = "P60", groups = MandatoryDataRules.class)
    @Type(type = "pool_gender_user_types")
    @Column(name = "PREFFERED_GENDER_TO_TRAVEL_WITH")
    private Gender prefferedGenderToTravelWith;

    @NotNull(message = "P61", groups = MandatoryDataRules.class)
    @Type(type = "pool_gender_user_types")
    @Column(name = "GENDER")
    private Gender gender;

    @NotNull(message = "P63", groups = MandatoryDataRules.class)
    @Type(type = "pool_age_group_user_types")
    @Column(name = "AGE_GROUP")
    private AgeGroup ageGroup;

    @Column(name = "USER_POOL_ADDITIONAL_DETAILS")
    private String userPoolAdditionalDetails;

    @Type(type = "pool_status_user_types")
    @Column(name = "POOL_STATUS_INDICATOR")
    private PoolStatus poolStatus = PoolStatus.DRAFT;

    @ElementCollection
    @Column(name = "AVAILABLE_SEATS")
    @MapKeyColumn(name = "DAY_OF_WEEK")
    @MapKeyEnumerated(EnumType.STRING)
    @CollectionTable(name = "SEATS_TRAVEL_DAYS", joinColumns = { @JoinColumn(name = "POOL_ID") })
    private Map<DayOfWeek, Integer> travelDaysAndAvailableSeats = new ListOrderedMap<DayOfWeek, Integer>();

    @Valid
    @Embedded
    private VehicleInfo vehicleInfo = new VehicleInfo();

    @Valid
    @Embedded
    private StartingPointInfo startingPointInfo = new StartingPointInfo();;

    @Valid
    @Embedded
    private DestinationInfo destinationInfo = new DestinationInfo();

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "pool")
    private Set<Passenger> passengers = new ListOrderedSet<Passenger>();

    public Pool() {
        super();
    }

    public Long getPoolId() {
        return poolId;
    }

    public String getPoolName() {
        return poolName;
    }

    public Boolean isCompleted() {
        return completed;
    }

    public Boolean getShareCost() {
        return shareCost;
    }

    public Gender getGender() {
        return gender;
    }

    public AgeGroup getAgeGroup() {
        return ageGroup;
    }

    public String getUsername() {
        return username;
    }

    public PoolType getPoolType() {
        return poolType;
    }

    public Boolean getValidLicense() {
        return validLicense;
    }

    public Boolean getSmoker() {
        return smoker;
    }

    public Boolean getOneWayTravel() {
        return oneWayTravel;
    }

    public Integer getNumberOfCurrentPassengers() {
        return numberOfCurrentPassengers;
    }

    public Gender getPrefferedGenderToTravelWith() {
        return prefferedGenderToTravelWith;
    }

    public String getUserPoolAdditionalDetails() {
        return userPoolAdditionalDetails;
    }

    public PoolStatus getPoolStatus() {
        return poolStatus;
    }

    public Map<DayOfWeek, Integer> getTravelDaysAndAvailableSeats() {
        return travelDaysAndAvailableSeats;
    }

    public Integer getAvailableSeatsForADay(DayOfWeek dayOfWeek) {

        if (travelDaysAndAvailableSeats.containsKey(dayOfWeek)) {

            for (Entry<DayOfWeek, Integer> entry : travelDaysAndAvailableSeats.entrySet()) {

                if (entry.getKey().equals(dayOfWeek)) {
                    return entry.getValue();
                }
            }
        }

        return null;
    }

    public VehicleInfo getVehicleInfo() {
        return vehicleInfo;
    }

    public StartingPointInfo getStartingPointInfo() {
        return startingPointInfo;
    }

    public DestinationInfo getDestinationInfo() {
        return destinationInfo;
    }

    public Set<Passenger> getPassengers() {
        return passengers;
    }

    public void setPoolId(Long poolId) {
        this.poolId = poolId;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public void setPoolName(String poolName) {
        this.poolName = poolName;
    }

    public void setCompleted(Boolean completed) {
        this.completed = completed;
    }

    public void setShareCost(Boolean shareCost) {
        this.shareCost = shareCost;
    }

    public void setGender(Gender gender) {
        this.gender = gender;
    }

    public void setAgeGroup(AgeGroup ageGroup) {
        this.ageGroup = ageGroup;
    }

    public void setPoolType(PoolType poolType) {
        this.poolType = poolType;
    }

    public void setValidLicense(Boolean validLicense) {
        this.validLicense = validLicense;
    }

    public void setSmoker(Boolean smoker) {
        this.smoker = smoker;
    }

    public void setOneWayTravel(Boolean oneWayTravel) {
        this.oneWayTravel = oneWayTravel;
    }

    public void setNumberOfCurrentPassengers(Integer numberOfCurrentPassengers) {
        this.numberOfCurrentPassengers = numberOfCurrentPassengers;
    }

    protected void setPoolStatus(PoolStatus poolStatus) {
        this.poolStatus = poolStatus;
    }

    public void setPrefferedGenderToTravelWith(Gender prefferedGenderToTravelWith) {
        this.prefferedGenderToTravelWith = prefferedGenderToTravelWith;
    }

    public void setUserPoolAdditionalDetails(String userPoolAdditionalDetails) {
        this.userPoolAdditionalDetails = userPoolAdditionalDetails;
    }

    public void addAvailableSeatsForADay(DayOfWeek dayOfWeek, Integer availableSeats) {

        if (travelDaysAndAvailableSeats.containsKey(dayOfWeek)) {
            travelDaysAndAvailableSeats.remove(dayOfWeek);
        }
        travelDaysAndAvailableSeats.put(dayOfWeek, availableSeats);
    }

    public void addAdditionalSeatsForADay(DayOfWeek dayOfWeek, Integer availableSeatsToAdd) {

        if (travelDaysAndAvailableSeats.containsKey(dayOfWeek)) {
            Set<Entry<DayOfWeek, Integer>> entries = travelDaysAndAvailableSeats.entrySet();
            Iterator<Entry<DayOfWeek, Integer>> iterator = entries.iterator();

            while (iterator.hasNext()) {

                Entry<DayOfWeek, Integer> entry = iterator.next();

                if (entry.getKey().equals(dayOfWeek)) {
                    entry.setValue(entry.getValue() + availableSeatsToAdd);
                }

                break;
            }
        }
    }

    public void addPassengers(final Passenger passenger) {

        if (passenger != null) {
            passenger.setPool(this);
        }

        Predicate<Passenger> predicate = new Predicate<Passenger>() {

            public boolean evaluate(Passenger passengerFromList) {

                boolean match = false;
                if (passenger != null && passengerFromList != null
                        && passengerFromList.getUsername().equalsIgnoreCase(passenger.getUsername())) {
                    match = true;
                }
                return match;
            }
        };

        Passenger existingPassenger = CollectionUtils.find(passengers, predicate);

        if (existingPassenger == null) {

            this.passengers.add(passenger);
        } else {

            if (passenger != null && !passenger.getPassengerRequestInfos().isEmpty()) {

                for (PassengerRequestInfo passengerRequestInfo : passenger.getPassengerRequestInfos()) {

                    existingPassenger.addPassengerRequestInfo(passengerRequestInfo);
                }
            }
        }
    }

    private Set<PoolsError> validate() {

        Set<PoolsError> poolsErrors = new ListOrderedSet<PoolsError>();
        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        Validator validator = factory.getValidator();
        Set<ConstraintViolation<Pool>> constraintViolations = validator.validate(this, MandatoryDataRules.class);

        for (ConstraintViolation<Pool> constraintViolation : constraintViolations) {

            poolsErrors.add(PoolsError.getPoolsError(constraintViolation.getMessage()));
        }

        return UnmodifiableSet.decorate(poolsErrors);
    }

    public Set<PoolsError> activate() {

        Set<PoolsError> poolsErrors = null;

        if (this.poolStatus.equals(PoolStatus.ACTIVE) || this.poolStatus.equals(PoolStatus.DRAFT)
                || this.poolStatus.equals(PoolStatus.CANCELLED)) {

            poolsErrors = this.validate();

            if (poolsErrors != null && poolsErrors.isEmpty()) {
                this.poolStatus = PoolStatus.ACTIVE;
            }
        }

        return poolsErrors;
    }

    public void cancelled() {

        if (this.poolStatus.equals(PoolStatus.ACTIVE) || this.poolStatus.equals(PoolStatus.DRAFT)
                || this.poolStatus.equals(PoolStatus.CANCELLED)) {

            this.poolStatus = PoolStatus.CANCELLED;
        }
    }

    public void completed() {

        if (this.poolStatus.equals(PoolStatus.DRAFT) || this.poolStatus.equals(PoolStatus.ACTIVE)) {

            final Set<PoolsError> poolsErrors = this.validate();
            final String startingDateFutureErrorCode = "P120";
            final String endDateFutureErrorCode = "P171";

            Predicate<PoolsError> startingDateErrorCodePredicate = new Predicate<PoolsError>() {

                public boolean evaluate(PoolsError poolsError) {
                    return poolsError.getErrorCode().equalsIgnoreCase(startingDateFutureErrorCode);
                }
            };

            Predicate<PoolsError> endDateErrorCodePredicate = new Predicate<PoolsError>() {

                public boolean evaluate(PoolsError poolsError) {
                    return poolsError.getErrorCode().equalsIgnoreCase(endDateFutureErrorCode);
                }
            };

            if (CollectionUtils.exists(poolsErrors, startingDateErrorCodePredicate)
                    && CollectionUtils.exists(poolsErrors, endDateErrorCodePredicate)) {

                this.poolStatus = PoolStatus.COMPLETED;
            }
        }
    }

    @PrePersist
    public void checkPoolState() {

        if (this.poolStatus.equals(PoolStatus.DRAFT)) {
            throw new PersistenceException("cannot persist a pool in a draft state");
        }
    }
}