Package com.taobao.top.analysis.statistics.data.impl

Source Code of com.taobao.top.analysis.statistics.data.impl.SimpleCalculator

package com.taobao.top.analysis.statistics.data.impl;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.taobao.top.analysis.exception.AnalysisException;
import com.taobao.top.analysis.statistics.data.Alias;
import com.taobao.top.analysis.statistics.data.ICalculator;
import com.taobao.top.analysis.statistics.data.ObjectColumn;
import com.taobao.top.analysis.util.AnalysisConstants;
import com.taobao.top.analysis.util.ReportUtil;

public class SimpleCalculator implements ICalculator {
 
  /**
   *
   */
  private static final long serialVersionUID = 8024981401877328739L;
  /**
   * value表达式中的变量列表
   */
  private List<Object> bindingStack;
  /**
   * value表达式中的操作列表
   */
  private List<Byte> operatorStack;
 
  private final String value;
 
  /**
   * 关联使用的entry
   */
  private Set<String> referEntries;
 
  /**
     * @return the referEntries
     */
    public Set<String> getReferEntries() {
        return referEntries;
    }

    public String getValue() {
    return value;
  }

  public List<Object> getBindingStack() {
    return bindingStack;
  }

  public List<Byte> getOperatorStack() {
    return operatorStack;
  }
 
  public void init(Map<String, Alias> aliasPoolthrows AnalysisException{

      //从这里init的代码可以看出,分析器的配置解析规则,并非是全部读取后,然后进行一次性解析的,它的report配置是有固定顺序的
      //一旦顺序出错,则会引起出错,同时alias和entry已经#的常量,三者是不可以重名的,否则会出错,这些潜规则都是在代码里反应出的
      //后续可以对这些进行改造,毕竟这并非是一个友好而完善的解析方式

    if (value != null
        && !"".equals(value)
        && (value.indexOf("$") >= 0 || value
            .indexOf("entry(") >= 0)) {

      bindingStack = new ArrayList<Object>();
      operatorStack = new ArrayList<Byte>();
      referEntries = new HashSet<String>();

      String c = value;
      String temp;

      while (c.indexOf("$") >= 0 || c.indexOf("#") >= 0) {
        if (c.indexOf("$") >= 0) {
          if (c.indexOf("#") < 0
              || (c.indexOf("#") >= 0 && c.indexOf("$") < c
                  .indexOf("#"))) {
            c = c.substring(c.indexOf("$") + 1);
            temp = c.substring(0, c.indexOf("$"));
            c = c.substring(c.indexOf("$") + 1);

            if (aliasPool != null && aliasPool.size() > 0
                && aliasPool.get(temp) != null) {
              bindingStack.add(aliasPool.get(temp).getKey());
            } else
              if (aliasPool != null && aliasPool.size() > 0
                  && temp.indexOf(".") > 0
                  && aliasPool.get(temp.substring(0, temp.indexOf("."))) != null)
              {
                bindingStack.add(new ObjectColumn(aliasPool.get(temp.substring(0, temp.indexOf("."))).getKey(),
                  temp.substring(temp.indexOf(".")+1)));
              }
              else
                bindingStack.add(Integer.valueOf(temp));

            continue;
          }
        }

        if (c.indexOf("#") >= 0) {
          if (c.indexOf("$") < 0
              || (c.indexOf("$") >= 0 && c.indexOf("$") > c
                  .indexOf("#"))) {
            c = c.substring(c.indexOf("#") + 1);
            temp = c.substring(0, c.indexOf("#"));
            c = c.substring(c.indexOf("#") + 1);

            bindingStack.add("#" + temp);

            continue;
          }
        }

      }

      while (c.indexOf("entry(") >= 0) {
        c = c.substring(c.indexOf("entry(") + "entry(".length());
        temp = c.substring(0, c.indexOf(")"));
        c = c.substring(c.indexOf(")") + 1);
        bindingStack.add(temp);
        referEntries.add(temp);
      }

      char[] cs = value.toCharArray();

      for (char _ch : cs) {
        if (_ch == '+' || _ch == '-' || _ch == '*' || _ch == '/')
          operatorStack.add(ReportUtil.generateOperationFlag(_ch));
      }

    }
 
  }


  public SimpleCalculator(String valueExpression,
      Map<String, Alias> aliasPool) throws AnalysisException {
    this.value = valueExpression;
    init(aliasPool);
  }

  @Override
  public Object calculator(Object[] contents) {


    Object result = null;

    double left = 0;

    if (bindingStack != null
        && bindingStack.size() > 0) {
      if (bindingStack.size() > 1) {
        if (bindingStack.get(0) instanceof String && ((String)bindingStack.get(0)).startsWith("#"))
          left = Double.valueOf(((String)bindingStack.get(0)).substring(1));
        else
          if (bindingStack.get(0) instanceof ObjectColumn)
          {
            if (((ObjectColumn)bindingStack.get(0)).getcIndex() - 1 >= contents.length)
              return result;
            Object o = contents[((ObjectColumn)bindingStack.get(0)).getcIndex() - 1];
           
            o = ReportUtil.getValueFromJosnObj(o.toString(),((ObjectColumn)bindingStack.get(0)).getSubKeyName());
           
            if(o instanceof Number){
              left = ((Number) o).doubleValue();
            }else{
              left = Double.valueOf(o.toString());
            }
          }
          else
          {
            if ((Integer)bindingStack.get(0) - 1 >= contents.length)
              return result;
            Object o = contents[(Integer)bindingStack.get(0) - 1];
            if(o instanceof Number){
              left = ((Number) o).doubleValue();
            }else{
              left = Double.valueOf(o.toString());
            }
           
          }

        double right = 0;

        int size = bindingStack.size();

        for (int i = 0; i < size - 1; i++) {
          if (bindingStack.get(i + 1) instanceof String && ((String)bindingStack.get(i + 1)).startsWith("#"))
            right = Double.valueOf(((String)bindingStack.get(i + 1))
                .substring(1));
          else
            if (bindingStack.get(i + 1) instanceof ObjectColumn)
            {
             
              if (((ObjectColumn)bindingStack.get(i+1)).getcIndex() - 1 >= contents.length)
                return result;
             
              Object o = contents[((ObjectColumn)bindingStack.get(i+1)).getcIndex() - 1];
             
              o = ReportUtil.getValueFromJosnObj(o.toString(),((ObjectColumn)bindingStack.get(i+1)).getSubKeyName());
             
              if(o instanceof Number){
                right = ((Number) o).doubleValue();
              }else{
                right = Double.valueOf(o.toString());
              }
            }
            else
            {
              if ((Integer)bindingStack.get(i + 1) - 1 >= contents.length)
                return result;
              Object o = contents[(Integer)bindingStack.get(i + 1) - 1];
              if(o instanceof Number){
                right = ((Number) o).doubleValue();
              }else{
                right = Double.valueOf(o.toString());
              }
            }

          if (operatorStack.get(i) == AnalysisConstants.OPERATE_PLUS)
          {
            left += right;
            continue;
          }

          if (operatorStack.get(i) == AnalysisConstants.OPERATE_MINUS)
          {
            left -= right;
            continue;
          }

          if (operatorStack.get(i) == AnalysisConstants.OPERATE_RIDE)
          {
            left = left * right;
            continue;
          }

          if (operatorStack.get(i) == AnalysisConstants.OPERATE_DIVIDE)
          {
            left = left / right;
            continue;
          }

        }

        result = left;
      } else {
        if (bindingStack.get(0) instanceof String && ((String)bindingStack.get(0)).startsWith("#"))
          result = Double.valueOf(((String)bindingStack.get(0)).substring(1));
        else
          if (bindingStack.get(0) instanceof ObjectColumn)
          {
            if (((ObjectColumn)bindingStack.get(0)).getcIndex() - 1 >= contents.length)
              return result;
 
            result = contents[((ObjectColumn)bindingStack.get(0)).getcIndex() - 1];
                     
            result = ReportUtil.getValueFromJosnObj(result.toString(),((ObjectColumn)bindingStack.get(0)).getSubKeyName());
          }
          else
          {
            if ((Integer)bindingStack.get(0) - 1 >= contents.length)
              return result;
 
            result = contents[(Integer)bindingStack.get(0) - 1];
          }

      }

    }

    return result;
  }

}
TOP

Related Classes of com.taobao.top.analysis.statistics.data.impl.SimpleCalculator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.