package org.openlca.app.results.contributions.locations; import java.util.Collections; import java.util.List; import org.openlca.app.components.ResultTypeSelection.EventHandler; import org.openlca.app.db.Database; import org.openlca.app.util.CostResultDescriptor; import org.openlca.app.util.Labels; import org.openlca.core.database.CurrencyDao; import org.openlca.core.model.Currency; import org.openlca.core.model.Location; import org.openlca.core.model.descriptors.BaseDescriptor; import org.openlca.core.model.descriptors.FlowDescriptor; import org.openlca.core.model.descriptors.ImpactCategoryDescriptor; import org.openlca.core.results.ContributionItem; import org.openlca.core.results.ContributionResultProvider; import org.openlca.core.results.ContributionSet; import org.openlca.core.results.LocationContribution; import org.openlca.util.Strings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; class SelectionHandler implements EventHandler { private LocationPage page; private ContributionResultProvider<?> result; private LocationContribution calculator; private TreeContentBuilder inputBuilder; SelectionHandler(LocationPage page) { this.page = page; this.result = page.result; this.inputBuilder = new TreeContentBuilder(page); calculator = new LocationContribution(result); } @Override public void flowSelected(FlowDescriptor flow) { if (calculator == null || flow == null) return; String unit = Labels.getRefUnit(flow, result.cache); ContributionSet<Location> set = calculator.calculate(flow); double total = result.getTotalFlowResult(flow).value; setData(set, flow, total, unit); } @Override public void impactCategorySelected(ImpactCategoryDescriptor impact) { if (calculator == null || impact == null) return; String unit = impact.getReferenceUnit(); ContributionSet<Location> set = calculator.calculate(impact); double total = result.getTotalImpactResult(impact).value; setData(set, impact, total, unit); } @Override public void costResultSelected(CostResultDescriptor cost) { if (calculator == null || cost == null) return; String unit = getCurrency(); if (cost.forAddedValue) { ContributionSet<Location> set = calculator.addedValues(); double total = result.getTotalCostResult(); total = total == 0 ? 0 : -total; setData(set, cost, total, unit); } else { ContributionSet<Location> set = calculator.netCosts(); double total = result.getTotalCostResult(); setData(set, cost, total, unit); } } private String getCurrency() { try { CurrencyDao dao = new CurrencyDao(Database.get()); Currency ref = dao.getReferenceCurrency(); if (ref == null) return "?"; else return ref.code != null ? ref.code : ref.getName(); } catch (Exception e) { Logger log = LoggerFactory.getLogger(getClass()); log.error("failed to get reference currency", e); return "?"; } } private void setData(ContributionSet<Location> set, BaseDescriptor selection, double total, String unit) { List<LocationItem> items = inputBuilder.build(set, selection, total); Collections.sort(items, (item1, item2) -> { if (item1.contribution == null || item2.contribution == null) return 0; ContributionItem<Location> c1 = item1.contribution; ContributionItem<Location> c2 = item2.contribution; if (Math.abs(c1.share - c2.share) > 1e-20) return Double.compare(c2.share, c1.share); else return Strings.compare( Labels.getDisplayName(c1.item), Labels.getDisplayName(c2.item)); }); page.setInput(items, unit); } }