com.webbfontaine.valuewebb.irms.impl.risk.data.RiskResultCollector.java Source code

Java tutorial

Introduction

Here is the source code for com.webbfontaine.valuewebb.irms.impl.risk.data.RiskResultCollector.java

Source

/*
 * Copyrights 2002-2013 Webb Fontaine
 * Developer: Sargis Harutyunyan
 * Date: 08 avr. 2013
 * This software is the proprietary information of Webb Fontaine.
 * Its use is subject to License terms.
 */
package com.webbfontaine.valuewebb.irms.impl.risk.data;

import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Ordering;
import com.google.common.primitives.Ints;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.webbfontaine.twm.urmcore.utils.Preconditions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static com.google.common.collect.FluentIterable.from;
import static com.google.common.collect.Iterables.size;
import static java.util.Collections.unmodifiableMap;

public class RiskResultCollector {

    private static final Logger LOGGER = LoggerFactory.getLogger(RiskResultCollector.class);

    private final Ordering<RiskColor> colorOrdering = new RiskColorOrdering();

    private final Ordering<RiskResult> resultOrdering = new ResultOrdering();

    private final List<ListenableFuture<List<RiskResult>>> futures = Lists.newArrayListWithExpectedSize(64);

    private List<List<RiskResult>> results;

    private Optional<RiskColor> finalColor;

    private int hitsCount;

    private Map<String, Collection<RiskResult>> groupedSelectedResults;

    public void add(ListenableFuture<List<RiskResult>> futureResult) {
        futures.add(futureResult);
    }

    public Optional<RiskColor> finalRiskColor() {
        checkState();

        return finalColor;
    }

    public Iterable<RiskResult> getRiskResults() {
        checkState();

        return from(getGroupedRiskResults().entrySet()).transformAndConcat(
                new Function<Map.Entry<String, Collection<RiskResult>>, Iterable<RiskResult>>() {
                    @Override
                    public Iterable<RiskResult> apply(Map.Entry<String, Collection<RiskResult>> input) {
                        return input.getValue();
                    }
                });
    }

    public Map<String, Collection<RiskResult>> getGroupedRiskResults() {
        checkState();

        return unmodifiableMap(groupedSelectedResults);
    }

    public int getHitsCount() {
        checkState();

        return hitsCount;
    }

    public void calculateResults() {
        if (results == null) {

            LOGGER.trace("Calculating 'Risk Collector' state based on results: {}", results);

            ListenableFuture<List<List<RiskResult>>> future = Futures.allAsList(futures);
            results = Futures.getUnchecked(future);

            finalColor = getHighestColor();

            hitsCount = size(nonEmptyResults(results));

            groupedSelectedResults = groupByCriterionName();

            LOGGER.trace("'Risk Collector' state, finalColor: {}, hitsCount: {}, groupedSelectedResults: {}",
                    new Object[] { finalColor, hitsCount, groupedSelectedResults });
        }
    }

    private Optional<RiskColor> getHighestColor() {
        Set<RiskColor> colors = riskColorsFromResults(results);
        if (Iterables.isEmpty(colors)) {
            return Optional.absent();
        }

        return Optional.of(colorOrdering.greatestOf(colors, 1).get(0));
    }

    private static Set<RiskColor> riskColorsFromResults(Iterable<List<RiskResult>> results) {
        return from(results).transformAndConcat(new Function<List<RiskResult>, Iterable<RiskResult>>() {
            @Override
            public Iterable<RiskResult> apply(List<RiskResult> input) {
                return input;
            }
        }).transform(new Function<RiskResult, RiskColor>() {
            @Override
            public RiskColor apply(@Nullable RiskResult input) {
                Preconditions.checkNotNull(input);
                return input.getColor();
            }
        }).toSet();
    }

    private Map<String, Collection<RiskResult>> groupByCriterionName() {
        Map<String, Collection<RiskResult>> grouped = Maps.newHashMap();

        for (List<RiskResult> list : nonEmptyResults(results)) {
            Preconditions.checkState(!list.isEmpty());

            Iterable<RiskResult> selectedResults = selectedOnly(list);
            if (notEmpty(selectedResults)) {
                grouped.put(list.get(0).getRuleName(), resultOrdering.sortedCopy(selectedResults));
            }
        }
        return grouped;
    }

    private static Iterable<List<RiskResult>> nonEmptyResults(Iterable<List<RiskResult>> results) {
        return from(results).filter(new Predicate<List<RiskResult>>() {
            @Override
            public boolean apply(@Nonnull List<RiskResult> input) {
                return !input.isEmpty();
            }
        });
    }

    private void checkState() {
        if (results == null) {
            throw new RuntimeException(
                    "Results was not fixed please call calculateResults() method before trying to access RiskCollector state");
        }
    }

    private static <T> boolean notEmpty(Iterable<T> selectedResults) {
        return !Iterables.isEmpty(selectedResults);
    }

    private static Iterable<RiskResult> selectedOnly(Iterable<RiskResult> list) {
        return from(list).filter(selected());
    }

    private static Predicate<RiskResult> selected() {
        return new SelectedPredicate();
    }

    private static class SelectedPredicate implements Predicate<RiskResult> {
        @Override
        public boolean apply(RiskResult input) {
            return input.getColor() != RiskColor.NONE;
        }
    }

    private static class RiskColorOrdering extends Ordering<RiskColor> implements Serializable {

        private static final long serialVersionUID = -2303019885181982090L;

        @Override
        public int compare(RiskColor left, RiskColor right) {
            return Ints.compare(left.getPriority(), right.getPriority());
        }
    }

    private static class ResultOrdering extends Ordering<RiskResult> implements Serializable {

        private static final long serialVersionUID = 6103077687334193308L;

        @Override
        public int compare(RiskResult left, RiskResult right) {
            return Ints.compare(left.getItem(), right.getItem());
        }
    }

}