| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.rocketmq.streams.script.operator.expression; |
| |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| import org.apache.rocketmq.streams.common.context.IMessage; |
| import org.apache.rocketmq.streams.common.topology.model.AbstractRule; |
| import org.apache.rocketmq.streams.common.utils.CollectionUtil; |
| import org.apache.rocketmq.streams.common.utils.PrintUtil; |
| import org.apache.rocketmq.streams.script.context.FunctionContext; |
| import org.apache.rocketmq.streams.script.parser.imp.FunctionParser; |
| import org.apache.rocketmq.streams.script.service.IScriptExpression; |
| import org.apache.rocketmq.streams.script.service.IScriptParamter; |
| import org.apache.rocketmq.streams.serviceloader.ServiceLoaderComponent; |
| |
| /** |
| * 条件函数,支持if elseif else 每一个部分又是用IScriptExpression来表达。 执行流程,如果if成功执行then,循环执行elseif,最后执行else |
| */ |
| public class GroupScriptExpression implements IScriptExpression { |
| |
| private IScriptExpression ifExpresssion; |
| |
| private List<IScriptExpression> thenExpresssions; |
| |
| private List<IScriptExpression> elseExpressions; |
| |
| private String scriptParameterStr; |
| protected List<? extends AbstractRule> rules; |
| |
| protected List<GroupScriptExpression> elseIfExpressions = new ArrayList<>(); |
| |
| private static final String TAB = FunctionParser.TAB; |
| |
| protected List<IScriptExpression> beforeExpressions; |
| protected List<IScriptExpression> afterExpressions; |
| |
| private transient ICaseDependentParser caseDependentParser; |
| |
| @Override |
| public Object getScriptParamter(IMessage message, FunctionContext context) { |
| return this.executeExpression(message, context); |
| } |
| |
| @Override |
| public String getScriptParameterStr() { |
| return scriptParameterStr; |
| } |
| |
| @Override |
| public Object executeExpression(IMessage channelMessage, FunctionContext context) { |
| if (beforeExpressions != null) { |
| for (IScriptExpression scriptExpression : beforeExpressions) { |
| scriptExpression.executeExpression(channelMessage, context); |
| } |
| } |
| |
| Boolean result = (Boolean) ifExpresssion.executeExpression(channelMessage, context); |
| Object value = null; |
| if (result) { |
| if (thenExpresssions != null) { |
| for (IScriptExpression scriptExpression : thenExpresssions) { |
| scriptExpression.executeExpression(channelMessage, context); |
| } |
| } |
| return executeAfterExpression(channelMessage, context); |
| } |
| if (elseIfExpressions != null && elseIfExpressions.size() > 0) { |
| for (int i = elseIfExpressions.size() - 1; i >= 0; i--) { |
| GroupScriptExpression expression = elseIfExpressions.get(i); |
| boolean success = (Boolean) expression.ifExpresssion.executeExpression(channelMessage, context); |
| if (success) { |
| if (expression.thenExpresssions != null) { |
| for (IScriptExpression scriptExpression : expression.thenExpresssions) { |
| value = scriptExpression.executeExpression(channelMessage, context); |
| } |
| } |
| return executeAfterExpression(channelMessage, context); |
| } |
| } |
| } |
| |
| if (elseExpressions != null) { |
| for (IScriptExpression scriptExpression : elseExpressions) { |
| scriptExpression.executeExpression(channelMessage, context); |
| return executeAfterExpression(channelMessage, context); |
| } |
| } |
| return null; |
| } |
| |
| protected Object executeAfterExpression(IMessage channelMessage, FunctionContext context) { |
| Object object = null; |
| if (afterExpressions != null) { |
| for (IScriptExpression scriptExpression : afterExpressions) { |
| object = scriptExpression.executeExpression(channelMessage, context); |
| } |
| } |
| return object; |
| } |
| |
| @Override |
| public List<IScriptParamter> getScriptParamters() { |
| return null; |
| } |
| |
| @Override |
| public String getFunctionName() { |
| return "condition"; |
| } |
| |
| @Override |
| public String getExpressionDescription() { |
| return toString(); |
| } |
| |
| @Override |
| public String toString() { |
| StringBuilder sb = new StringBuilder(); |
| if (ifExpresssion != null) { |
| sb.append(ifExpresssion.toString()); |
| } |
| |
| if (thenExpresssions != null) { |
| sb.append("{" + PrintUtil.LINE); |
| boolean isFirst = true; |
| for (IScriptExpression scriptExpression : thenExpresssions) { |
| sb.append(TAB + scriptExpression + ";" + PrintUtil.LINE); |
| } |
| sb.append("}"); |
| } |
| if (elseExpressions != null) { |
| sb.append("else{" + PrintUtil.LINE); |
| for (IScriptExpression expression : this.elseExpressions) { |
| sb.append(TAB + expression + ";" + PrintUtil.LINE); |
| } |
| sb.append("}"); |
| } |
| |
| return sb.toString(); |
| } |
| |
| @Override |
| public List<String> getDependentFields() { |
| List<GroupScriptExpression> list = new ArrayList<>(); |
| list.add(this); |
| if (elseIfExpressions != null) { |
| list.addAll(elseIfExpressions); |
| } |
| List<String> dependentFields = new ArrayList<>(); |
| for (GroupScriptExpression groupScriptExpression : list) { |
| List<String> fields = groupScriptExpression.getDependentFieldsInner(); |
| if (fields != null) { |
| dependentFields.addAll(fields); |
| } |
| } |
| return dependentFields; |
| |
| } |
| |
| @Override |
| public Set<String> getNewFieldNames() { |
| List<GroupScriptExpression> list = new ArrayList<>(); |
| list.add(this); |
| if (elseIfExpressions != null) { |
| list.addAll(elseIfExpressions); |
| } |
| Set<String> newFields = new HashSet<>(); |
| for (GroupScriptExpression groupScriptExpression : list) { |
| Set<String> fields = groupScriptExpression.getNewFieldNamesInner(); |
| if (fields != null) { |
| newFields.addAll(fields); |
| } |
| } |
| return newFields; |
| } |
| |
| protected List<String> getDependentFieldsInner() { |
| List<String> fieldNames = new ArrayList<>(); |
| List<IScriptExpression> parameters = new ArrayList<>(); |
| if (ifExpresssion != null) { |
| parameters.add(ifExpresssion); |
| } |
| if (thenExpresssions != null) { |
| parameters.addAll(thenExpresssions); |
| } |
| if (elseIfExpressions != null) { |
| parameters.addAll(elseIfExpressions); |
| } |
| ICaseDependentParser caseDependentParser = loadCaseDependentParser(); |
| if (parameters != null && parameters.size() > 0) { |
| for (IScriptExpression scriptExpression : parameters) { |
| List<String> names = null; |
| if (caseDependentParser != null && caseDependentParser.isCaseFunction(scriptExpression)) { |
| names = new ArrayList<>(caseDependentParser.getDependentFields(scriptExpression)); |
| } else { |
| names = scriptExpression.getDependentFields(); |
| } |
| if (names != null) { |
| fieldNames.addAll(names); |
| } |
| } |
| } |
| return fieldNames; |
| } |
| |
| protected Set<String> getNewFieldNamesInner() { |
| Set<String> set = new HashSet<>(); |
| List<IScriptExpression> parameters = new ArrayList<>(); |
| if (thenExpresssions != null) { |
| parameters.addAll(thenExpresssions); |
| } |
| if (elseIfExpressions != null) { |
| parameters.addAll(elseIfExpressions); |
| } |
| if (parameters != null && parameters.size() > 0) { |
| for (IScriptParamter scriptParamter : parameters) { |
| Set<String> names = scriptParamter.getNewFieldNames(); |
| if (names != null) { |
| set.addAll(names); |
| } |
| } |
| } |
| return set; |
| } |
| |
| protected ICaseDependentParser loadCaseDependentParser() { |
| if (this.caseDependentParser != null) { |
| return this.caseDependentParser; |
| } |
| synchronized (this) { |
| if (caseDependentParser != null) { |
| return this.caseDependentParser; |
| } |
| ServiceLoaderComponent caseServiceLoader = ServiceLoaderComponent.getInstance(ICaseDependentParser.class); |
| |
| List<ICaseDependentParser> caseDependentParsers = caseServiceLoader.loadService(); |
| ICaseDependentParser caseDependentParser = null; |
| if (caseDependentParsers != null && caseDependentParsers.size() > 0) { |
| caseDependentParser = caseDependentParsers.get(0); |
| } |
| return caseDependentParser; |
| } |
| |
| } |
| |
| public void setIfExpresssion(IScriptExpression ifExpresssion) { |
| this.ifExpresssion = ifExpresssion; |
| } |
| |
| public void setThenExpresssions(List<IScriptExpression> thenExpresssions) { |
| this.thenExpresssions = thenExpresssions; |
| } |
| |
| public void setElseExpressions(List<IScriptExpression> elseExpressions) { |
| this.elseExpressions = elseExpressions; |
| } |
| |
| public void setScriptParameterStr(String scriptParameterStr) { |
| this.scriptParameterStr = scriptParameterStr; |
| } |
| |
| public List<GroupScriptExpression> getElseIfExpressions() { |
| return elseIfExpressions; |
| } |
| |
| public void setElseIfExpressions(List<GroupScriptExpression> elseIfExpressions) { |
| this.elseIfExpressions = elseIfExpressions; |
| } |
| |
| public IScriptExpression getIfExpresssion() { |
| return ifExpresssion; |
| } |
| |
| public List<IScriptExpression> getBeforeExpressions() { |
| return beforeExpressions; |
| } |
| |
| public void setBeforeExpressions( |
| List<IScriptExpression> beforeExpressions) { |
| this.beforeExpressions = beforeExpressions; |
| } |
| |
| public List<IScriptExpression> getAfterExpressions() { |
| return afterExpressions; |
| } |
| |
| public void setAfterExpressions( |
| List<IScriptExpression> afterExpressions) { |
| this.afterExpressions = afterExpressions; |
| } |
| |
| public List<IScriptExpression> getElseExpressions() { |
| return elseExpressions; |
| } |
| |
| public List<? extends AbstractRule> getRules() { |
| return rules; |
| } |
| |
| public void setRules(List<? extends AbstractRule> rules) { |
| this.rules = rules; |
| } |
| |
| public List<IScriptExpression> getThenExpresssions() { |
| return thenExpresssions; |
| } |
| |
| public Map<? extends String, ? extends List<String>> getBeforeDependents() { |
| Map<String, List<String>> map = new HashMap<>(); |
| if (CollectionUtil.isEmpty(beforeExpressions)) { |
| return map; |
| } |
| |
| for (IScriptExpression scriptExpression : beforeExpressions) { |
| if (CollectionUtil.isNotEmpty(scriptExpression.getNewFieldNames())) { |
| map.put(scriptExpression.getNewFieldNames().iterator().next(), scriptExpression.getDependentFields()); |
| } |
| } |
| return map; |
| } |
| } |