package com.x.processplatform.core.express.query; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.function.DoubleSupplier; import java.util.stream.Collectors; import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.builder.CompareToBuilder; import com.x.processplatform.core.entity.query.Calculate; import com.x.processplatform.core.entity.query.CalculateCell; import com.x.processplatform.core.entity.query.CalculateEntry; import com.x.processplatform.core.entity.query.GroupEntry; import com.x.processplatform.core.entity.query.OrderEffectType; import com.x.processplatform.core.entity.query.OrderType; import com.x.processplatform.core.entity.query.Row; import com.x.processplatform.core.entity.query.Table; public class CalculateEntryTools { public static List calculateAmount(Table table, List calculateEntries) throws Exception { List list = new ArrayList<>(); for (CalculateEntry o : calculateEntries) { switch (o.getCalculateType()) { case count: list.add(new CalculateCell(o, count(table, o))); break; case sum: list.add(new CalculateCell(o, sum(table, o))); break; case average: list.add(new CalculateCell(o, average(table, o))); break; default: break; } } return list; } public static List calculate(Table table, Calculate calculate, GroupEntry groupEntry) throws Exception { List list = new ArrayList<>(); if (BooleanUtils.isTrue(calculate.getIsGroup())) { LinkedHashMap> map = new LinkedHashMap<>(); for (int i = 0; i < calculate.getCalculateEntryList().size(); i++) { CalculateEntry calculateEntry = calculate.getCalculateEntryList().get(i); Map m = groupCalcluateEntry(table, calculateEntry, groupEntry); if (i == 0) { for (Entry en : m.entrySet()) { List row = new ArrayList<>(); row.add(new CalculateCell(calculateEntry, en.getValue())); map.put(en.getKey(), row); } } else { for (Entry en : m.entrySet()) { map.get(en.getKey()).add(new CalculateCell(calculateEntry, en.getValue())); } } } for (Entry> en : map.entrySet()) { LinkedHashMap o = new LinkedHashMap<>(); o.put("group", en.getKey()); o.put("list", en.getValue()); list.add(o); } } else { for (CalculateEntry o : calculate.getCalculateEntryList()) { switch (o.getCalculateType()) { case count: list.add(new CalculateCell(o, count(table, o))); break; case sum: list.add(new CalculateCell(o, sum(table, o))); break; case average: list.add(new CalculateCell(o, average(table, o))); break; default: break; } } } return list; } private static Map groupCalcluateEntry(Table table, CalculateEntry calculateEntry, GroupEntry groupEntry) throws Exception { switch (calculateEntry.getCalculateType()) { case count: return groupCount(table, calculateEntry, groupEntry); case sum: return groupSum(table, calculateEntry, groupEntry); case average: return groupAverage(table, calculateEntry, groupEntry); default: return new LinkedHashMap(); } } private static Long count(Table table, CalculateEntry calculateEntry) throws Exception { Long result = table.stream().count(); return result; } private static Double sum(Table table, CalculateEntry calculateEntry) throws Exception { Double result = table.stream().mapToDouble(row -> row.getAsDouble(calculateEntry.getColumn())).sum(); return result; } private static Double average(Table table, CalculateEntry calculateEntry) throws Exception { DoubleSupplier ds = () -> { return 0d; }; Double result = table.stream().mapToDouble(row -> row.getAsDouble(calculateEntry.getColumn())).average() .orElseGet(ds); return result; } private static Map groupCount(Table table, CalculateEntry calculateEntry, GroupEntry groupEntry) throws Exception { Map map = new LinkedHashMap(); if ((null != groupEntry) && (groupEntry.available())) { map = table.stream() .collect(Collectors.groupingBy(row -> row.find(groupEntry.getColumn()), Collectors.counting())); } return map; } private static Map groupSum(Table table, CalculateEntry calculateEntry, GroupEntry groupEntry) throws Exception { Map map = table.stream().collect(Collectors.groupingBy(row -> row.find(groupEntry.getColumn()), Collectors.summingDouble(row -> row.getAsDouble(calculateEntry.getColumn())))); return map; } private static Map groupAverage(List rows, CalculateEntry calculateEntry, GroupEntry groupEntry) throws Exception { Map map = rows.stream().collect(Collectors.groupingBy(row -> row.find(groupEntry.getColumn()), Collectors.averagingDouble(row -> row.getAsDouble(calculateEntry.getColumn())))); return map; } private static LinkedHashMap sortGroup(LinkedHashMap linkedHashMap, CalculateEntry calculateEntry) { return linkedHashMap.entrySet().stream().sorted( (e1, e2) -> compareWith(e1, e2, calculateEntry.getOrderEffectType(), calculateEntry.getOrderType())) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new)); } public static int compareWith(Entry e1, Entry e2, OrderEffectType orderEffectType, OrderType orderType) { CompareToBuilder compareToBuilder = new CompareToBuilder(); switch (orderType) { case asc: switch (orderEffectType) { case key: compareToBuilder.append(e1.getKey(), e2.getKey()); break; case value: compareToBuilder.append(e1.getValue(), e2.getValue()); break; default: break; } break; case desc: switch (orderEffectType) { case key: compareToBuilder.append(e2.getKey(), e1.getKey()); break; case value: compareToBuilder.append(e2.getValue(), e1.getValue()); break; default: break; } break; default: break; } return compareToBuilder.toComparison(); } }