All Downloads are FREE. Search and download functionalities are using the official Maven repository.

global.maplink.trip.schema.v2.problem.TollRequest Maven / Gradle / Ivy

There is a newer version: 1.5.14
Show newest version
package global.maplink.trip.schema.v2.problem;

import global.maplink.commons.TransponderOperator;
import global.maplink.toll.schema.Billing;
import global.maplink.toll.schema.TollVehicleType;
import global.maplink.trip.schema.v1.exception.violations.VariableAxlesOverlappingViolation;
import global.maplink.trip.schema.v1.exception.violations.VariableAxlesSiteIdNotFoundInProblem;
import global.maplink.validations.Validable;
import global.maplink.validations.ValidationViolation;
import lombok.*;

import java.util.*;
import java.util.stream.Collectors;

import static global.maplink.trip.schema.v1.exception.TripErrorType.*;
import static java.util.Objects.isNull;
import static lombok.AccessLevel.PRIVATE;

@Data
@Builder
@RequiredArgsConstructor
@NoArgsConstructor(force = true, access = PRIVATE)
public class TollRequest implements Validable {
    private static final String SITE_NOT_USED = "site not used";
    private static final String SITE_USED_AS_FROM_SITE_ID = "site used as fromSiteId";
    private static final String SITE_USED_AS_TO_SITE_ID = "site used as toSiteId";
    private static final String SITE_USED_AS_MIDDLE_SITE = "site used as middle site";

    private final TollVehicleType vehicleType;
    @Builder.Default
    private final Billing billing = Billing.DEFAULT;
    @Builder.Default
    private final Set transponderOperators = new HashSet<>(Collections.singletonList(TransponderOperator.SEM_PARAR));
    @Singular
    private final List variableAxles = Collections.emptyList();

    @Override
    public List validate() {
        List errors = new ArrayList<>();
        if (vehicleType == null) {
            errors.add(TOLL_PARAMETERS_DOES_NOT_HAVE_VEHICLE_TYPE);
        }
        return errors;
    }

    public List validateVariableAxles(final List sites){
        List errors = new ArrayList<>();

        if (variableAxles == null || sites.isEmpty()) {
            return errors;
        }

        List problemSites = getProblemSites(sites);
        Map sitesStatusMap = createVirginSitesStatusMap(problemSites);

        for (LegVariableAxles legVariableAxles : variableAxles) {
            String fromSiteId = legVariableAxles.getFromSiteId();
            String toSiteId = legVariableAxles.getToSiteId();
            TollVehicleType newVehicleType = legVariableAxles.getNewVehicleType();

            errors.addAll(legVariableAxles.validate());

            if (isNull(fromSiteId) || isNull(toSiteId)) {
                return errors;
            }

            if (newVehicleType == null){
                errors.add(MISSING_NEW_VEHICLE_TYPE);
                return errors;
            }

            if (!problemSites.contains(fromSiteId)) {
                errors.add(new VariableAxlesSiteIdNotFoundInProblem(fromSiteId));
                return errors;
            }

            if (!problemSites.contains(toSiteId)) {
                errors.add(new VariableAxlesSiteIdNotFoundInProblem(toSiteId));
                return errors;
            }

            if (fromSiteId.equalsIgnoreCase(problemSites.get(problemSites.size() - 1))) {
                errors.add(VARIABLE_AXLES_FROMSITEID_POINTING_TO_LAST_SITE);
                return errors;
            }

            if (isToSiteIdBeforeFromSiteId(fromSiteId, toSiteId, problemSites)){
                errors.add(TOSITEID_BEFORE_FROMSITEID);
                return errors;
            }

            List legSites = getLegSites(fromSiteId, toSiteId, problemSites);

            if (existsOverlap(fromSiteId, toSiteId, legSites, sitesStatusMap)) {
                errors.add(new VariableAxlesOverlappingViolation(fromSiteId, toSiteId));
                return errors;
            } else {
                sitesStatusMap.put(fromSiteId, SITE_USED_AS_FROM_SITE_ID);
                sitesStatusMap.put(toSiteId, SITE_USED_AS_TO_SITE_ID);
                for (int i = 1; i < legSites.size() - 1; i++) {
                    sitesStatusMap.put(legSites.get(i), SITE_USED_AS_MIDDLE_SITE);
                }
            }
        }
        return errors;
    }

    private boolean isToSiteIdBeforeFromSiteId(String fromSiteId, String toSiteId, List problemSites){
        int fromSiteIdIndex = problemSites.indexOf(fromSiteId);
        int toSiteIdIndex = problemSites.indexOf(toSiteId);

        return  toSiteIdIndex < fromSiteIdIndex;
    }

    private List getProblemSites(final List sites) {

        return sites.stream()
                .filter(Objects::nonNull)
                .map(SitePoint::getSiteId)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
    }

    private Map createVirginSitesStatusMap(List problemSites) {
        Map map = new HashMap<>(problemSites.size());
        for (String site : problemSites) {
            map.put(site, SITE_NOT_USED);
        }
        return map;
    }

    private List getLegSites(String fromSiteId, String toSiteId, List problemSites) {
        return problemSites.subList(problemSites.indexOf(fromSiteId), problemSites.indexOf(toSiteId) + 1);
    }

    private boolean existsOverlap(
            String fromSiteId,
            String toSiteId,
            List legSites,
            Map sitesStatusMap
    ) {
        for (String site : legSites) {
            if (site.equalsIgnoreCase(fromSiteId) && sitesStatusMap.get(site)
                    .equalsIgnoreCase(SITE_USED_AS_MIDDLE_SITE)) {
                return true;
            }

            if (site.equalsIgnoreCase(toSiteId) && sitesStatusMap.get(site)
                    .equalsIgnoreCase(SITE_USED_AS_MIDDLE_SITE)) {
                return true;
            }

            if (site.equalsIgnoreCase(fromSiteId) && sitesStatusMap.get(site)
                    .equalsIgnoreCase(SITE_USED_AS_FROM_SITE_ID)) {
                return true;
            }

            if (!site.equalsIgnoreCase(fromSiteId) && !site.equalsIgnoreCase(toSiteId) && !sitesStatusMap.get(site)
                    .equalsIgnoreCase(SITE_NOT_USED)) {
                return true;
            }
        }
        return false;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy