All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.scudata.expression.mfn.cursor.Groupx Maven / Gradle / Ivy

Go to download

SPL(Structured Process Language) A programming language specially for structured data computing.

There is a newer version: 20240823
Show newest version
package com.scudata.expression.mfn.cursor;

import java.util.ArrayList;

import com.scudata.common.MessageManager;
import com.scudata.common.RQException;
import com.scudata.dm.Context;
import com.scudata.dm.cursor.ICursor;
import com.scudata.dm.op.New;
import com.scudata.expression.CursorFunction;
import com.scudata.expression.Expression;
import com.scudata.expression.Gather;
import com.scudata.expression.IParam;
import com.scudata.expression.ParamInfo2;
import com.scudata.resources.EngineMessage;
import com.scudata.util.CursorUtil;
import com.scudata.util.EnvUtil;

/**
 * ?????ۼƷ?ʽ???α????????????ܣ????س??α?
 * cs.groupx(x:F,??;y:G??;n)
 * @author RunQian
 *
 */
public class Groupx extends CursorFunction {
	public Object calculate(Context ctx) {
		if (param == null) {
			MessageManager mm = EngineMessage.get();
			throw new RQException("groupx" + mm.getMessage("function.missingParam"));
		}
		
		ArrayList gathers = new ArrayList(); // ͳ?ƾۺϺ???
		ArrayList poss = new ArrayList(); // ???????ʽ????Ӧ?ۺϺ????б??ĵڼ????ۺϺ???

		IParam sub0;
		IParam sub1 = null;
		IParam sub2 = null;
		
		if (param.getType() == IParam.Semicolon) {
			int size = param.getSubSize();
			if (size > 3) {
				MessageManager mm = EngineMessage.get();
				throw new RQException("groupx" + mm.getMessage("function.invalidParam"));
			}
			
			sub0 = param.getSub(0);
			if (sub0 == null) {
				MessageManager mm = EngineMessage.get();
				throw new RQException("groupx" + mm.getMessage("function.invalidParam"));
			}
			
			sub1 = param.getSub(1);
			if (size > 2) {
				sub2 = param.getSub(2);
			}
		} else {
			sub0 = param;
		}
		
		Expression []exps;
		String []names = null;
		Expression []newExps = null;
		String []newNames = null;

		ParamInfo2 pi0 = ParamInfo2.parse(sub0, "groupx", true, false);
		exps = pi0.getExpressions1();
		names = pi0.getExpressionStrs2();

		if (sub1 != null) {
			ParamInfo2 pi1 = ParamInfo2.parse(sub1, "groupx", true, false);
			newExps = pi1.getExpressions1();
			newNames = pi1.getExpressionStrs2();
		}

		double n = -1;
		Expression gexp = null;
		if (sub2 == null) {
		} else if (sub2.isLeaf()) {
			Object obj;
			if (option == null || option.indexOf('g') == -1) {
				obj = sub2.getLeafExpression().calculate(ctx);
				if (obj instanceof Number) {
					n = ((Number)obj).doubleValue();
				} else {
					MessageManager mm = EngineMessage.get();
					throw new RQException("groupx" + mm.getMessage("function.paramTypeError"));
				}
			} else {
				gexp = sub2.getLeafExpression();
			}
		} else {
			MessageManager mm = EngineMessage.get();
			throw new RQException("groupx" + mm.getMessage("function.invalidParam"));
		}
		
		// ???????ʽ?;ۺϱ???ʽ?ij???
		int	nlen = null == newExps ? 0 : newExps.length;
		int elen = null == exps ? 0 : exps.length;
		// ????????ʽ?еľۺϺ???
		for (int i = 0; i < nlen; i++) {
			int size = gathers.size();
			gathers.addAll(Expression.getSpecFunc(newExps[i], Gather.class));
			if (size == gathers.size())
				gathers.add(newExps[i]);
			poss.add(gathers.size());
		}
		
		// ?????м?ۺϱ???ʽ
		Expression[] tempExps = new Expression[gathers.size()];
		String[] tempNames	= newNames;
		for (int i = 0; i < tempExps.length; i++) {
			Object obj = gathers.get(i);
			if (obj instanceof Gather) {
				Gather gather = (Gather)gathers.get(i);
				tempExps[i] = new Expression(cs, ctx, gather.getFunctionString());
			} else {
				tempExps[i] = (Expression)gathers.get(i);
			}
		}
		
		// new ?α?ı???ʽ
		Expression[] senExps = new Expression[elen+nlen];
		String strExp = null;	// ?ϱ???ʽ?ַ?????
		int index = 0;	// ?ϱ???ʽ??????
		New op = null;	// ???ӵ?new??????
		
		// ?????ϱ???ʽ??ת??Ϊ?µ?new??ͳ???б???ʽ
		boolean exCal	= false;	// ?ж??Ƿ??־ۺϱ???ʽ
		if (null != newExps) {
			strExp = newExps[index].toString();
		}
		
		for (int i = 0; i < tempExps.length; i++) {
			if (i >= poss.get(index)) {
				senExps[index+elen] = new Expression(cs, ctx, strExp);
				index++;
				strExp = newExps[index].toString();
			}
			String funStr = "#" + (i+elen+1);
			strExp = Expression.replaceFunc(strExp, tempExps[i].toString(), funStr);
			if (!strExp.equals(funStr)) {
				exCal = true;
			}
		}
		
		// @b???????ȥ???????ֶ?
		boolean bopt = option != null && option.indexOf('b') != -1;
		
		if (exCal) {
			tempNames = null;
			// ??д???????ʽ
			for (int i = 1; i <= elen; i++) {
				String funStr = "#" + i;
				senExps[i-1] = new Expression(cs, ctx, funStr);
			}
			
			if (senExps.length > 0)	// ???һ??????ʽ??????
				senExps[index+elen] = new Expression(cs, ctx, strExp);
			
			// ????ͳһ??????
			String[] senNames	= new String[names.length + newNames.length];
			for (int i = 0; i < names.length; i++) {
				senNames[i] = names[i];
			}
			for (int i =  0; i < newNames.length; i++) {
				if (null == newNames[i]) {
					senNames[i+names.length] = newExps[i].toString();
				} else
					senNames[i+names.length] = newNames[i];
			}
			
			// ????new??????
			if (bopt) {
				Expression []alterExps = new Expression[nlen];
				String []alterNames = new String[nlen];
				System.arraycopy(senExps, elen, alterExps, 0, nlen);
				System.arraycopy(senNames, elen, alterNames, 0, nlen);
				op = new New(this, alterExps, alterNames, null);
			} else {
				op = new New(this, senExps, senNames, null);
			}
		} else if (bopt) {
			Expression []alterExps = new Expression[nlen];
			for (int i = 0, q = elen + 1; i < nlen; ++i, ++q) {
				alterExps[i] = new Expression(ctx, "#" + q);
			}
			
			op = new New(this, alterExps, new String[nlen], null);
		}
		
		int capacity;
		if (n > 1) {
			capacity = (int)n;
		} else {
			int fcount = exps == null ? 0 : exps.length;
			if (newExps != null) fcount += newExps.length;
			capacity = EnvUtil.getCapacity(fcount);
			if (n > 0) {
				capacity *= n;
			}
		}
		
		ICursor	result;
		if (gexp != null) {
			result = CursorUtil.groupx_g(cursor, gexp, exps, names, tempExps, tempNames, option, ctx);
		} else {
			result = cursor.groupx(exps, names, tempExps, tempNames, option, ctx, capacity);
		}
		
		if (op != null) {
			result.addOperation(op, ctx);
		}
		
		return result;
	}
}