Java tutorial
/* * 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()); } } }