/*
* @(#)AggregateExitOperation.java 2012-8-1 下午10:00:00
*
* Copyright (c) 2011-2012 Makersoft.org all rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
*
*/
package org.makersoft.shards.strategy.exit.impl;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.makersoft.shards.strategy.exit.ExitOperation;
import org.makersoft.shards.strategy.exit.ExitOperationUtils;
import org.makersoft.shards.utils.Assert;
import org.makersoft.shards.utils.Lists;
/**
*
*/
public class AggregateExitOperation implements ExitOperation {
private final SupportedAggregations aggregate;
// private final String fieldName;
private final Log log = LogFactory.getLog(getClass());
private enum SupportedAggregations {
SUM("sum"), MIN("min"), MAX("max");
private final String aggregate;
private SupportedAggregations(String s) {
this.aggregate = s;
}
@SuppressWarnings("unused")
public String getAggregate() {
return aggregate;
}
}
public AggregateExitOperation(String statementSuffix) {
Assert.notNull(statementSuffix);
this.aggregate = SupportedAggregations.valueOf(statementSuffix.toUpperCase());
}
@Override
public List<Object> apply(List<Object> result) {
if (result.size() == 0){
return Lists.newArrayList((Object)0);
}
// String className = result.get(0).getClass().getName();
List<Object> nonNullResults = ExitOperationUtils.getNonNullList(result);
switch (aggregate) {
case MAX:
return Collections.<Object>singletonList(Collections.max(ExitOperationUtils.getComparableList(nonNullResults)) );
case MIN:
return Collections.<Object>singletonList(Collections.min(ExitOperationUtils.getComparableList(nonNullResults)));
case SUM:
return Collections.<Object>singletonList(getSum(nonNullResults,null).intValue());
default:
log.error("Aggregation Projection is unsupported: " + aggregate);
throw new UnsupportedOperationException(
"Aggregation Projection is unsupported: " + aggregate);
}
}
private BigDecimal getSum(List<Object> results, String fieldName) {
BigDecimal sum = new BigDecimal(0.0);
for (Object obj : results) {
Number num = getNumber(obj, fieldName);
sum = sum.add(new BigDecimal(num.toString()));
}
return sum;
}
private Number getNumber(Object obj, String fieldName) {
if(fieldName == null || "".equals(fieldName)){
return (Number)obj;
}
return (Number) ExitOperationUtils.getPropertyValue(obj, fieldName);
}
}