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

com.scudata.expression.ElementRef 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;

import java.util.List;

import com.scudata.array.BoolArray;
import com.scudata.array.ConstArray;
import com.scudata.array.IArray;
import com.scudata.array.NumberArray;
import com.scudata.array.ObjectArray;
import com.scudata.cellset.INormalCell;
import com.scudata.common.MessageManager;
import com.scudata.common.RQException;
import com.scudata.dm.Context;
import com.scudata.dm.ParamList;
import com.scudata.dm.Sequence;
import com.scudata.dw.MemberFilter;
import com.scudata.resources.EngineMessage;
import com.scudata.util.Variant;

/**
 * ????Ԫ??????
 * A(2)  A([2,4])
 * @author WangXiaoJun
 *
 */
public class ElementRef extends Function {
	private Node left;
	private Expression exp;

	public ElementRef() {
		priority = PRI_SUF;
	}
	
	/**
	 * ??????ʽ????Ч?ԣ???Ч???׳??쳣
	 */
	public void checkValidity() {
		if (left == null) {
			MessageManager mm = EngineMessage.get();
			throw new RQException("()" + mm.getMessage("operator.missingleftOperation"));
		}
		
		left.checkValidity();
		if (param != null && param.isLeaf()) {
			exp = param.getLeafExpression();
		} // ??ʱ?Ȳ??׳??쳣???ȼ???left?ټ??????????????left?Ƿ?????׼ȷ????
	}

	public void setLeft(Node node) {
		left = node;
	}

	public Node getLeft() {
		return left;
	}

	protected boolean containParam(String name) {
		if (left.containParam(name)) return true;
		return super.containParam(name);
	}

	protected void getUsedParams(Context ctx, ParamList resultList) {
		left.getUsedParams(ctx, resultList);
		super.getUsedParams(ctx, resultList);
	}
	
	public void getUsedFields(Context ctx, List resultList) {
		left.getUsedFields(ctx, resultList);
		super.getUsedFields(ctx, resultList);
	}
	
	protected void getUsedCells(List resultList) {
		left.getUsedCells(resultList);
		super.getUsedCells(resultList);
	}
	
	/**
	 * ???ñ???ʽ?????ڱ???ʽ???棬???ִ??ʹ?ò?ͬ???????ģ?????????????йصĻ?????Ϣ
	 */
	public void reset() {
		left.reset();
		super.reset();
	}

	public Node optimize(Context ctx) {
		if (param != null) {
			param.optimize(ctx);
		}
		
		left = left.optimize(ctx);
		return this;
	}

	public Object calculate(Context ctx) {
		Object result1 = left.calculate(ctx);
		if (result1 == null) {
			return null;
		} else if (!(result1 instanceof Sequence)) {
			MessageManager mm = EngineMessage.get();
			throw new RQException("()" + mm.getMessage("dot.seriesLeft"));
		}

		if (exp == null) {
			MessageManager mm = EngineMessage.get();
			throw new RQException("()" + mm.getMessage("function.invalidParam"));
		}
		
		Object o = exp.calculate(ctx);
		if (o == null) {
			return null;
		} else if (o instanceof Number) {
			return ((Sequence)result1).get(((Number)o).intValue());
		} else if (o instanceof Sequence) {
			return ((Sequence)result1).get((Sequence)o);
		}

		MessageManager mm = EngineMessage.get();
		throw new RQException("()" + mm.getMessage("function.paramTypeError"));
	}
	
	/**
	 * ??????Ԫ?ظ?ֵ
	 * @param ??ֵ
	 * @param ctx ??????????
	 * @return ??ֵ
	 */
	public Object assign(Object value, Context ctx) {
		Object result1 = left.calculate(ctx);
		if (!(result1 instanceof Sequence)) {
			MessageManager mm = EngineMessage.get();
			throw new RQException("()" + mm.getMessage("dot.seriesLeft"));
		}

		if (exp == null) {
			MessageManager mm = EngineMessage.get();
			throw new RQException("()" + mm.getMessage("function.invalidParam"));
		}
		
		Sequence srcSeries = (Sequence)result1;
		int len = srcSeries.length();
		Object pval = exp.calculate(ctx);

		// Խ?籨???????Զ???
		if (pval instanceof Number) {
			int index = ((Number)pval).intValue();
			if (index > len) {
				MessageManager mm = EngineMessage.get();
				throw new RQException(index + mm.getMessage("engine.indexOutofBound"));
			}

			srcSeries.set(index, value);
		} else if (pval instanceof Sequence) {
			Sequence posSeries = (Sequence)pval;
			int count = posSeries.length();
			if (value instanceof Sequence) {
				Sequence tseq = (Sequence)value;
				if (count != tseq.length()) {
					MessageManager mm = EngineMessage.get();
					throw new RQException(mm.getMessage("engine.memCountNotMatch"));
				}

				for (int i = 1; i<= count; ++i) {
					Object posObj = posSeries.get(i);
					if (!(posObj instanceof Number)) {
						MessageManager mm = EngineMessage.get();
						throw new RQException(mm.getMessage("engine.needIntSeries"));
					}

					int index = ((Number)posObj).intValue();
					if (index > len) {
						MessageManager mm = EngineMessage.get();
						throw new RQException(index + mm.getMessage("engine.indexOutofBound"));
					}

					srcSeries.set(index, tseq.get(i));
				}
			} else {
				for (int i = 1; i<= count; ++i) {
					Object posObj = posSeries.get(i);
					if (!(posObj instanceof Number)) {
						MessageManager mm = EngineMessage.get();
						throw new RQException(mm.getMessage("engine.needIntSeries"));
					}

					int index = ((Number)posObj).intValue();
					if (index > len) {
						MessageManager mm = EngineMessage.get();
						throw new RQException(index + mm.getMessage("engine.indexOutofBound"));
					}

					srcSeries.set(index, value);
				}
			}
		} else if (pval == null) {
		} else {
			MessageManager mm = EngineMessage.get();
			throw new RQException("()" + mm.getMessage("function.paramTypeError"));
		}

		return value;
	}
	
	/**
	 * ??????Ԫ????+=????
	 * @param ֵ
	 * @param ctx ??????????
	 * @return ??ֵ
	 */
	public Object addAssign(Object value, Context ctx) {
		Object result1 = left.calculate(ctx);
		if (!(result1 instanceof Sequence)) {
			MessageManager mm = EngineMessage.get();
			throw new RQException("()" + mm.getMessage("dot.seriesLeft"));
		}

		if (exp == null) {
			MessageManager mm = EngineMessage.get();
			throw new RQException("()" + mm.getMessage("function.invalidParam"));
		}

		Sequence srcSeries = (Sequence)result1;
		int len = srcSeries.length();
		Object pval = exp.calculate(ctx);

		// Խ?籨???????Զ???
		if (pval instanceof Number) {
			int index = ((Number)pval).intValue();
			if (index > len) {
				MessageManager mm = EngineMessage.get();
				throw new RQException(index + mm.getMessage("engine.indexOutofBound"));
			}

			Object result = Variant.add(srcSeries.getMem(index), value);
			srcSeries.set(index, result);
			return result;
		} else if (pval == null) {
			return null;
		} else {
			MessageManager mm = EngineMessage.get();
			throw new RQException("()" + mm.getMessage("function.paramTypeError"));
		}
	}
	
	public IArray getFieldArray(Context ctx, FieldRef fieldRef) {
		IArray sequenceArray = left.calculateAll(ctx);
		if (exp == null) {
			MessageManager mm = EngineMessage.get();
			throw new RQException("()" + mm.getMessage("function.invalidParam"));
		}
		
		IArray posArray = exp.calculateAll(ctx);
		int len = sequenceArray.size();
		
		if (sequenceArray instanceof ConstArray) {
			Object obj = sequenceArray.get(1);
			if (obj instanceof Sequence) {
				return ((Sequence)obj).getFieldValueArray(posArray, fieldRef.getName());
			} else if (obj == null) {
				return new ConstArray(null, len);
			} else {
				MessageManager mm = EngineMessage.get();
				throw new RQException("()" + mm.getMessage("dot.seriesLeft"));
			}
		} else {
			IArray result = new ObjectArray(len);
			for (int i = 1; i <= len; ++i) {
				Object obj = sequenceArray.get(i);
				if (obj == null) {
					result.push(null);
					continue;
				} else if (!(obj instanceof Sequence)) {
					MessageManager mm = EngineMessage.get();
					throw new RQException("()" + mm.getMessage("dot.seriesLeft"));
				}
				
				Sequence sequence = (Sequence)obj;
				if (posArray instanceof NumberArray) {
					obj = sequence.get(posArray.getInt(i));
				} else {
					obj = posArray.get(i);
					if (obj instanceof Number) {
						obj = sequence.get(((Number)obj).intValue());
					} else if (obj instanceof Sequence) {
						obj = sequence.get((Sequence)obj);
					} else if (obj != null) {
						MessageManager mm = EngineMessage.get();
						throw new RQException("()" + mm.getMessage("function.paramTypeError"));
					}
				}
				
				result.push(obj);
			}
			
			return fieldRef.getFieldArray(result);
		}
	}
	
	public IArray getFieldArray(Context ctx, FieldId fieldId) {
		IArray sequenceArray = left.calculateAll(ctx);
		if (exp == null) {
			MessageManager mm = EngineMessage.get();
			throw new RQException("()" + mm.getMessage("function.invalidParam"));
		}
		
		IArray posArray = exp.calculateAll(ctx);
		int len = sequenceArray.size();
		
		if (sequenceArray instanceof ConstArray) {
			Object obj = sequenceArray.get(1);
			if (obj instanceof Sequence) {
				return ((Sequence)obj).getFieldValueArray(posArray, fieldId.getFieldIndex());
			} else if (obj == null) {
				return new ConstArray(null, len);
			} else {
				MessageManager mm = EngineMessage.get();
				throw new RQException("()" + mm.getMessage("dot.seriesLeft"));
			}
		} else {
			IArray result = new ObjectArray(len);
			for (int i = 1; i <= len; ++i) {
				Object obj = sequenceArray.get(i);
				if (obj == null) {
					result.push(null);
					continue;
				} else if (!(obj instanceof Sequence)) {
					MessageManager mm = EngineMessage.get();
					throw new RQException("()" + mm.getMessage("dot.seriesLeft"));
				}
				
				Sequence sequence = (Sequence)obj;
				if (posArray instanceof NumberArray) {
					obj = sequence.get(posArray.getInt(i));
				} else {
					obj = posArray.get(i);
					if (obj instanceof Number) {
						obj = sequence.get(((Number)obj).intValue());
					} else if (obj instanceof Sequence) {
						obj = sequence.get((Sequence)obj);
					} else if (obj != null) {
						MessageManager mm = EngineMessage.get();
						throw new RQException("()" + mm.getMessage("function.paramTypeError"));
					}
				}
				
				result.push(obj);
			}
			
			return fieldId.getFieldArray(ctx, result);
		}
	}
	
	/**
	 * ??????????еĽ??
	 * @param ctx ??????????
	 * @return IArray
	 */
	public IArray calculateAll(Context ctx) {
		IArray sequenceArray = left.calculateAll(ctx);
		if (exp == null) {
			MessageManager mm = EngineMessage.get();
			throw new RQException("()" + mm.getMessage("function.invalidParam"));
		}
		
		IArray posArray = exp.calculateAll(ctx);
		int len = sequenceArray.size();
		
		if (sequenceArray instanceof ConstArray) {
			Object obj = sequenceArray.get(1);
			if (obj == null) {
				return new ConstArray(null, len);
			} else if (!(obj instanceof Sequence)) {
				MessageManager mm = EngineMessage.get();
				throw new RQException("()" + mm.getMessage("dot.seriesLeft"));
			}
			
			Sequence sequence = (Sequence)obj;
			if (posArray instanceof NumberArray) {
				IArray result = sequence.getMemberArray((NumberArray)posArray);
				result.setTemporary(true);
				return result;
			} else {
				ObjectArray result = new ObjectArray(len);
				result.setTemporary(true);
				
				for (int i = 1; i <= len; ++i) {
					obj = posArray.get(i);
					if (obj instanceof Number) {
						obj = sequence.get(((Number)obj).intValue());
					} else if (obj instanceof Sequence) {
						obj = sequence.get((Sequence)obj);
					} else if (obj != null) {
						MessageManager mm = EngineMessage.get();
						throw new RQException("()" + mm.getMessage("function.paramTypeError"));
					}
					
					result.push(obj);
				}
				
				return result;
			}
		} else {
			IArray result = new ObjectArray(len);
			result.setTemporary(true);
			
			for (int i = 1; i <= len; ++i) {
				Object obj = sequenceArray.get(i);
				if (obj == null) {
					result.push(null);
					continue;
				} else if (!(obj instanceof Sequence)) {
					MessageManager mm = EngineMessage.get();
					throw new RQException("()" + mm.getMessage("dot.seriesLeft"));
				}
				
				Sequence sequence = (Sequence)obj;
				if (posArray.isNull(i)) {
				} else if (posArray instanceof NumberArray) {
					obj = sequence.get(posArray.getInt(i));
				} else {
					obj = posArray.get(i);
					if (obj instanceof Number) {
						obj = sequence.get(((Number)obj).intValue());
					} else if (obj instanceof Sequence) {
						obj = sequence.get((Sequence)obj);
					} else {
						MessageManager mm = EngineMessage.get();
						throw new RQException("()" + mm.getMessage("function.paramTypeError"));
					}
				}
				
				result.push(obj);
			}
			
			return result;
		}
	}
	
	/**
	 * ????signArray??ȡֵΪsign????
	 * @param ctx
	 * @param signArray ?б?ʶ????
	 * @param sign ??ʶ
	 * @return IArray
	 */
	public IArray calculateAll(Context ctx, IArray signArray, boolean sign) {
		return calculateAll(ctx);
	}
	
	/**
	 * ?????߼????????&&???Ҳ????ʽ
	 * @param ctx ??????????
	 * @param leftResult &&??????ʽ?ļ?????
	 * @return BoolArray
	 */
	public BoolArray calculateAnd(Context ctx, IArray leftResult) {
		IArray sequenceArray = left.calculateAll(ctx);
		if (exp == null) {
			MessageManager mm = EngineMessage.get();
			throw new RQException("()" + mm.getMessage("function.invalidParam"));
		}
		
		IArray posArray = exp.calculateAll(ctx);
		if (!posArray.isNumberArray()) {
			MessageManager mm = EngineMessage.get();
			throw new RQException("()" + mm.getMessage("function.paramTypeError"));
		}
		
		BoolArray result = leftResult.isTrue();
		int resultSize = result.size();
		
		if (sequenceArray instanceof ConstArray) {
			Object obj = sequenceArray.get(1);
			if (obj instanceof Sequence) {
				IArray mems = ((Sequence)obj).getMems();
				for (int i = 1; i <= resultSize; ++i) {
					if (result.isTrue(i) && (posArray.isNull(i) || mems.isFalse(posArray.getInt(i)))) {
						result.set(i, false);
					}
				}
			} else if (obj == null) {
				for (int i = 1; i <= resultSize; ++i) {
					result.set(i, false);
				}
			} else {
				MessageManager mm = EngineMessage.get();
				throw new RQException("()" + mm.getMessage("dot.seriesLeft"));
			}
		} else {
			for (int i = 1; i <= resultSize; ++i) {
				if (result.isTrue(i)) {
					Object obj = sequenceArray.get(i);
					if (obj == null) {
						result.set(i, false);
					} else if (obj instanceof Sequence) {
						Sequence sequence = (Sequence)obj;
						if (posArray.isNull(i) || !sequence.isTrue(posArray.getInt(i))) {
							result.set(i, false);
						}
					} else {
						MessageManager mm = EngineMessage.get();
						throw new RQException("()" + mm.getMessage("dot.seriesLeft"));
					}
				}
			}
		}
		
		return result;
	}

	/**
	 * ?жϸ?????ֵ??Χ?Ƿ????㵱ǰ????????ʽ
	 * @param ctx ??????????
	 * @return ȡֵ????Relation. -1??ֵ??Χ??û????????????ֵ??0??ֵ??Χ??????????????ֵ??1??ֵ??Χ??ֵ??????????
	 */
	public int isValueRangeMatch(Context ctx) {
		IArray sequenceArray = left.calculateRange(ctx);
		if (!(sequenceArray instanceof ConstArray)) {
			return Relation.PARTICALMATCH;
		}
		
		Object obj = sequenceArray.get(1);
		if (obj == null) {
			return Relation.UNMATCH;
		} else if (!(obj instanceof Sequence)) {
			MessageManager mm = EngineMessage.get();
			throw new RQException("()" + mm.getMessage("dot.seriesLeft"));
		}
		
		if (exp == null) {
			MessageManager mm = EngineMessage.get();
			throw new RQException("()" + mm.getMessage("function.invalidParam"));
		}

		IArray array = exp.calculateRange(ctx);
		if (array == null) {
			return Relation.PARTICALMATCH;
		}
		
		Sequence sequence = (Sequence)obj;
		Object maxValue = array.get(2);
		
		int end = 0;
		if (maxValue instanceof Number) {
			end = ((Number)maxValue).intValue();
		} else if (maxValue == null) {
			return Relation.UNMATCH;
		} else {
			return Relation.PARTICALMATCH;
		}
		
		Object minValue = array.get(1);
		int start = 0;
		if (minValue instanceof Number) {
			start = ((Number)minValue).intValue();
		} else if (minValue != null) {
			return Relation.PARTICALMATCH;
		}
		
		if (end < 1) {
			return Relation.UNMATCH;
		} else if (start > 0) {
			if (end - start <= MemberFilter.MAX_CHECK_NUMBER) {
				boolean hasTrue = false, hasFalse = false;
				for (int i = start; i <= end; i++) {
					if (sequence.isTrue(i)) {
						if (hasFalse) {
							return Relation.PARTICALMATCH;
						} else {
							hasTrue = true;
						}
					} else {
						if (hasTrue) {
							return Relation.PARTICALMATCH;
						} else {
							hasFalse = true;
						}
					}
				}
				
				return hasTrue ? Relation.ALLMATCH : Relation.UNMATCH;
			} else {
				return Relation.PARTICALMATCH;
			}
		} else {
			if (end - start <= MemberFilter.MAX_CHECK_NUMBER) {
				for (int i = 1; i <= end; i++) {
					if (sequence.isTrue(i)) {
						return Relation.PARTICALMATCH;
					}
				}
				
				return Relation.UNMATCH;
			} else {
				return Relation.PARTICALMATCH;
			}
		}
	}
	
	public Expression getExp() {
		return exp;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy