Update mvel2 dependency
This commit is contained in:
		
							parent
							
								
									830a612bf8
								
							
						
					
					
						commit
						4607d89369
					
				@ -85,7 +85,7 @@
 | 
			
		||||
            <artifactId>commons-lang3</artifactId>
 | 
			
		||||
        </dependency>
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>org.mvel</groupId>
 | 
			
		||||
            <groupId>org.thingsboard</groupId>
 | 
			
		||||
            <artifactId>mvel2</artifactId>
 | 
			
		||||
        </dependency>
 | 
			
		||||
        <dependency>
 | 
			
		||||
 | 
			
		||||
@ -22,15 +22,15 @@ import com.google.common.util.concurrent.MoreExecutors;
 | 
			
		||||
import lombok.Getter;
 | 
			
		||||
import lombok.SneakyThrows;
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import org.mvel2.ExecutionContext;
 | 
			
		||||
import org.mvel2.MVEL;
 | 
			
		||||
import org.mvel2.ParserContext;
 | 
			
		||||
import org.mvel2.optimizers.AccessorOptimizer;
 | 
			
		||||
import org.mvel2.SandboxedParserContext;
 | 
			
		||||
import org.mvel2.optimizers.OptimizerFactory;
 | 
			
		||||
import org.springframework.beans.factory.annotation.Value;
 | 
			
		||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
 | 
			
		||||
import org.springframework.scheduling.annotation.Scheduled;
 | 
			
		||||
import org.springframework.stereotype.Service;
 | 
			
		||||
import org.springframework.util.ReflectionUtils;
 | 
			
		||||
import org.thingsboard.common.util.ThingsBoardExecutors;
 | 
			
		||||
import org.thingsboard.script.api.AbstractScriptInvokeService;
 | 
			
		||||
import org.thingsboard.script.api.ScriptType;
 | 
			
		||||
@ -101,12 +101,9 @@ public class DefaultMvelInvokeService extends AbstractScriptInvokeService implem
 | 
			
		||||
    @PostConstruct
 | 
			
		||||
    public void init() {
 | 
			
		||||
        super.init();
 | 
			
		||||
        Field field = ReflectionUtils.findField(OptimizerFactory.class, "accessorCompilers");
 | 
			
		||||
        ReflectionUtils.makeAccessible(field);
 | 
			
		||||
        Map<String, AccessorOptimizer> accessorCompilers = (Map<String, AccessorOptimizer>) field.get(null);
 | 
			
		||||
        accessorCompilers.put(OptimizerFactory.SAFE_REFLECTIVE, new TbReflectiveAccessorOptimizer());
 | 
			
		||||
 | 
			
		||||
        parserContext = new ParserContext(new TbMvelParserConfiguration());
 | 
			
		||||
        OptimizerFactory.setDefaultOptimizer(OptimizerFactory.SAFE_REFLECTIVE);
 | 
			
		||||
        parserContext = new SandboxedParserContext();
 | 
			
		||||
        parserContext.addImport("JSON", TbJson.class);
 | 
			
		||||
        executor = MoreExecutors.listeningDecorator(ThingsBoardExecutors.newWorkStealingPool(2, "mvel-executor"));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -159,7 +156,9 @@ public class DefaultMvelInvokeService extends AbstractScriptInvokeService implem
 | 
			
		||||
                throw new TbScriptException(scriptId, TbScriptException.ErrorCode.OTHER, null, new RuntimeException("Script not found!"));
 | 
			
		||||
            }
 | 
			
		||||
            try {
 | 
			
		||||
                return MVEL.executeExpression(script.getCompiledScript(), script.createVars(args));
 | 
			
		||||
                ExecutionContext executionContext = new ExecutionContext();
 | 
			
		||||
                // TODO:
 | 
			
		||||
                return MVEL.executeExpression(script.getCompiledScript(), executionContext, script.createVars(args));
 | 
			
		||||
            } catch (OutOfMemoryError e) {
 | 
			
		||||
                Runtime.getRuntime().gc();
 | 
			
		||||
                throw new TbScriptException(scriptId, TbScriptException.ErrorCode.OTHER, script.getScriptBody(), new RuntimeException("Memory error!"));
 | 
			
		||||
 | 
			
		||||
@ -16,6 +16,8 @@
 | 
			
		||||
package org.thingsboard.script.api.mvel;
 | 
			
		||||
 | 
			
		||||
import com.fasterxml.jackson.databind.JsonNode;
 | 
			
		||||
import org.mvel2.ExecutionContext;
 | 
			
		||||
import org.mvel2.util.ArgsRepackUtil;
 | 
			
		||||
import org.thingsboard.common.util.JacksonUtil;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
@ -28,13 +30,13 @@ public class TbJson {
 | 
			
		||||
        return value != null ? JacksonUtil.toString(value) : "null";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static Object parse(String value) throws IOException {
 | 
			
		||||
    public static Object parse(ExecutionContext ctx, String value) throws IOException {
 | 
			
		||||
        if (value != null) {
 | 
			
		||||
            JsonNode node = JacksonUtil.toJsonNode(value);
 | 
			
		||||
            if (node.isObject()) {
 | 
			
		||||
                return JacksonUtil.convertValue(node, Map.class);
 | 
			
		||||
                return ArgsRepackUtil.repack(ctx, JacksonUtil.convertValue(node, Map.class));
 | 
			
		||||
            } else if (node.isArray()) {
 | 
			
		||||
                return JacksonUtil.convertValue(node, List.class);
 | 
			
		||||
                return ArgsRepackUtil.repack(ctx, JacksonUtil.convertValue(node, List.class));
 | 
			
		||||
            } else if (node.isDouble()) {
 | 
			
		||||
                return node.doubleValue();
 | 
			
		||||
            } else if (node.isLong()) {
 | 
			
		||||
 | 
			
		||||
@ -1,65 +0,0 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright © 2016-2022 The Thingsboard Authors
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed 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.thingsboard.script.api.mvel;
 | 
			
		||||
 | 
			
		||||
import org.mvel2.compiler.Accessor;
 | 
			
		||||
import org.mvel2.compiler.ExecutableAccessor;
 | 
			
		||||
import org.mvel2.compiler.ExecutableStatement;
 | 
			
		||||
import org.mvel2.integration.VariableResolverFactory;
 | 
			
		||||
import org.mvel2.optimizers.impl.refl.collection.ExprValueAccessor;
 | 
			
		||||
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
public class TbMapCreator implements Accessor {
 | 
			
		||||
    private Accessor[] keys;
 | 
			
		||||
    private Accessor[] vals;
 | 
			
		||||
    private int size;
 | 
			
		||||
 | 
			
		||||
    public Object getValue(Object ctx, Object elCtx, VariableResolverFactory variableFactory) {
 | 
			
		||||
        Map map = new HashMap<>(size * 2);
 | 
			
		||||
        for (int i = size - 1; i != -1; i--) {
 | 
			
		||||
            //noinspection unchecked
 | 
			
		||||
            map.put(getKey(i, ctx, elCtx, variableFactory), vals[i].getValue(ctx, elCtx, variableFactory));
 | 
			
		||||
        }
 | 
			
		||||
        return map;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private Object getKey(int index, Object ctx, Object elCtx, VariableResolverFactory variableFactory) {
 | 
			
		||||
        Accessor keyAccessor = keys[index];
 | 
			
		||||
        if (keyAccessor instanceof ExprValueAccessor) {
 | 
			
		||||
            ExecutableStatement executableStatement = ((ExprValueAccessor) keyAccessor).stmt;
 | 
			
		||||
            if (executableStatement instanceof ExecutableAccessor) {
 | 
			
		||||
                return ((ExecutableAccessor) executableStatement).getNode().getName();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return keys[index].getValue(ctx, elCtx, variableFactory);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public TbMapCreator(Accessor[] keys, Accessor[] vals) {
 | 
			
		||||
        this.size = (this.keys = keys).length;
 | 
			
		||||
        this.vals = vals;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Object setValue(Object ctx, Object elCtx, VariableResolverFactory variableFactory, Object value) {
 | 
			
		||||
        // not implemented
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Class getKnownEgressType() {
 | 
			
		||||
        return Map.class;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,92 +0,0 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright © 2016-2022 The Thingsboard Authors
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed 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.thingsboard.script.api.mvel;
 | 
			
		||||
 | 
			
		||||
import org.mvel2.compiler.AbstractParser;
 | 
			
		||||
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
import java.net.URLClassLoader;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
public class TbMvelClassLoader extends URLClassLoader {
 | 
			
		||||
 | 
			
		||||
    private static final Set<String> allowedClasses = new HashSet<>();
 | 
			
		||||
    private static final Set<String> allowedPackages = new HashSet<>();
 | 
			
		||||
 | 
			
		||||
    static {
 | 
			
		||||
 | 
			
		||||
        AbstractParser.LITERALS.remove("System");
 | 
			
		||||
        AbstractParser.LITERALS.remove("Runtime");
 | 
			
		||||
        AbstractParser.LITERALS.remove("Class");
 | 
			
		||||
        AbstractParser.LITERALS.remove("ClassLoader");
 | 
			
		||||
        AbstractParser.LITERALS.remove("Thread");
 | 
			
		||||
        AbstractParser.LITERALS.remove("Compiler");
 | 
			
		||||
        AbstractParser.LITERALS.remove("ThreadLocal");
 | 
			
		||||
        AbstractParser.LITERALS.remove("SecurityManager");
 | 
			
		||||
 | 
			
		||||
        AbstractParser.CLASS_LITERALS.remove("System");
 | 
			
		||||
        AbstractParser.CLASS_LITERALS.remove("Runtime");
 | 
			
		||||
        AbstractParser.CLASS_LITERALS.remove("Class");
 | 
			
		||||
        AbstractParser.CLASS_LITERALS.remove("ClassLoader");
 | 
			
		||||
        AbstractParser.CLASS_LITERALS.remove("Thread");
 | 
			
		||||
        AbstractParser.CLASS_LITERALS.remove("Compiler");
 | 
			
		||||
        AbstractParser.CLASS_LITERALS.remove("ThreadLocal");
 | 
			
		||||
        AbstractParser.CLASS_LITERALS.remove("SecurityManager");
 | 
			
		||||
        AbstractParser.CLASS_LITERALS.put("JSON", TbJson.class);
 | 
			
		||||
        AbstractParser.LITERALS.put("JSON", TbJson.class);
 | 
			
		||||
 | 
			
		||||
        AbstractParser.CLASS_LITERALS.values().forEach(val -> allowedClasses.add(((Class) val).getName()));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static {
 | 
			
		||||
        allowedPackages.add("org.mvel2");
 | 
			
		||||
        allowedPackages.add("java.util");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public TbMvelClassLoader() {
 | 
			
		||||
        super(new URL[0], Thread.currentThread().getContextClassLoader());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
 | 
			
		||||
        if (!classNameAllowed(name)) {
 | 
			
		||||
            throw new ClassNotFoundException();
 | 
			
		||||
        }
 | 
			
		||||
        return super.loadClass(name, resolve);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Class<?> loadClass(String name) throws ClassNotFoundException {
 | 
			
		||||
        if (!classNameAllowed(name)) {
 | 
			
		||||
            throw new ClassNotFoundException();
 | 
			
		||||
        }
 | 
			
		||||
        return super.loadClass(name);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private boolean classNameAllowed(String name) {
 | 
			
		||||
        if (allowedClasses.contains(name)) {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        for (String pkgName : allowedPackages) {
 | 
			
		||||
            if (name.startsWith(pkgName)) {
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -1,37 +0,0 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright © 2016-2022 The Thingsboard Authors
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed 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.thingsboard.script.api.mvel;
 | 
			
		||||
 | 
			
		||||
import org.mvel2.ParserConfiguration;
 | 
			
		||||
import org.mvel2.integration.VariableResolverFactory;
 | 
			
		||||
 | 
			
		||||
public class TbMvelParserConfiguration extends ParserConfiguration {
 | 
			
		||||
 | 
			
		||||
    private static final long serialVersionUID = 5558151976348875590L;
 | 
			
		||||
 | 
			
		||||
    TbMvelParserConfiguration() {
 | 
			
		||||
        setClassLoader(new TbMvelClassLoader());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public VariableResolverFactory getVariableFactory(VariableResolverFactory factory) {
 | 
			
		||||
        if (Thread.interrupted()) {
 | 
			
		||||
            throw new RuntimeException("Thread is interrupted!");
 | 
			
		||||
        }
 | 
			
		||||
        return new TbMvelResolverFactory(factory);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -1,35 +0,0 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright © 2016-2022 The Thingsboard Authors
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed 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.thingsboard.script.api.mvel;
 | 
			
		||||
 | 
			
		||||
import org.mvel2.integration.VariableResolver;
 | 
			
		||||
import org.mvel2.integration.VariableResolverFactory;
 | 
			
		||||
import org.mvel2.integration.impl.StackResetResolverFactory;
 | 
			
		||||
 | 
			
		||||
public class TbMvelResolverFactory extends StackResetResolverFactory {
 | 
			
		||||
 | 
			
		||||
    public TbMvelResolverFactory(VariableResolverFactory delegate) {
 | 
			
		||||
        super(delegate);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public VariableResolver getVariableResolver(String name) {
 | 
			
		||||
        if (Thread.interrupted()) {
 | 
			
		||||
            throw new RuntimeException("Thread is interrupted!");
 | 
			
		||||
        }
 | 
			
		||||
        return super.getVariableResolver(name);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,120 +0,0 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright © 2016-2022 The Thingsboard Authors
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed 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.thingsboard.script.api.mvel;
 | 
			
		||||
 | 
			
		||||
import org.mvel2.ParserContext;
 | 
			
		||||
import org.mvel2.compiler.Accessor;
 | 
			
		||||
import org.mvel2.integration.VariableResolverFactory;
 | 
			
		||||
import org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer;
 | 
			
		||||
import org.mvel2.optimizers.impl.refl.collection.ArrayCreator;
 | 
			
		||||
import org.mvel2.optimizers.impl.refl.collection.ExprValueAccessor;
 | 
			
		||||
import org.mvel2.optimizers.impl.refl.collection.ListCreator;
 | 
			
		||||
import org.mvel2.optimizers.impl.refl.nodes.Union;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
import static org.mvel2.util.CompilerTools.expectType;
 | 
			
		||||
import static org.mvel2.util.ParseTools.findClass;
 | 
			
		||||
import static org.mvel2.util.ParseTools.getBaseComponentType;
 | 
			
		||||
import static org.mvel2.util.ParseTools.getSubComponentType;
 | 
			
		||||
import static org.mvel2.util.ParseTools.repeatChar;
 | 
			
		||||
 | 
			
		||||
public class TbReflectiveAccessorOptimizer extends ReflectiveAccessorOptimizer {
 | 
			
		||||
    private Object ctx;
 | 
			
		||||
    private Class returnType;
 | 
			
		||||
    private VariableResolverFactory variableFactory;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Accessor optimizeCollection(ParserContext pCtx, Object o, Class type, char[] property, int start, int offset,
 | 
			
		||||
                                       Object ctx, Object thisRef, VariableResolverFactory factory) {
 | 
			
		||||
        this.start = this.cursor = start;
 | 
			
		||||
        this.length = start + offset;
 | 
			
		||||
        this.returnType = type;
 | 
			
		||||
        this.ctx = ctx;
 | 
			
		||||
        this.variableFactory = factory;
 | 
			
		||||
        this.pCtx = pCtx;
 | 
			
		||||
 | 
			
		||||
        Accessor root = _getAccessor(o, returnType);
 | 
			
		||||
 | 
			
		||||
        if (property != null && length > start) {
 | 
			
		||||
            return new Union(pCtx, root, property, cursor, offset);
 | 
			
		||||
        } else {
 | 
			
		||||
            return root;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private Accessor _getAccessor(Object o, Class type) {
 | 
			
		||||
        if (o instanceof List) {
 | 
			
		||||
            Accessor[] a = new Accessor[((List) o).size()];
 | 
			
		||||
            int i = 0;
 | 
			
		||||
 | 
			
		||||
            for (Object item : (List) o) {
 | 
			
		||||
                a[i++] = _getAccessor(item, type);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            returnType = List.class;
 | 
			
		||||
 | 
			
		||||
            return new ListCreator(a);
 | 
			
		||||
        } else if (o instanceof Map) {
 | 
			
		||||
            Accessor[] k = new Accessor[((Map) o).size()];
 | 
			
		||||
            Accessor[] v = new Accessor[k.length];
 | 
			
		||||
            int i = 0;
 | 
			
		||||
 | 
			
		||||
            for (Object item : ((Map) o).keySet()) {
 | 
			
		||||
                k[i] = _getAccessor(item, type); // key
 | 
			
		||||
                v[i++] = _getAccessor(((Map) o).get(item), type); // value
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            returnType = Map.class;
 | 
			
		||||
 | 
			
		||||
            return new TbMapCreator(k, v);
 | 
			
		||||
        } else if (o instanceof Object[]) {
 | 
			
		||||
            Accessor[] a = new Accessor[((Object[]) o).length];
 | 
			
		||||
            int i = 0;
 | 
			
		||||
            int dim = 0;
 | 
			
		||||
 | 
			
		||||
            if (type != null) {
 | 
			
		||||
                String nm = type.getName();
 | 
			
		||||
                while (nm.charAt(dim) == '[') dim++;
 | 
			
		||||
            } else {
 | 
			
		||||
                type = Object[].class;
 | 
			
		||||
                dim = 1;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            try {
 | 
			
		||||
                Class base = getBaseComponentType(type);
 | 
			
		||||
                Class cls = dim > 1 ? findClass(null, repeatChar('[', dim - 1) + "L" + base.getName() + ";", pCtx)
 | 
			
		||||
                        : type;
 | 
			
		||||
 | 
			
		||||
                for (Object item : (Object[]) o) {
 | 
			
		||||
                    expectType(pCtx, a[i++] = _getAccessor(item, cls), base, true);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                return new ArrayCreator(a, getSubComponentType(type));
 | 
			
		||||
            } catch (ClassNotFoundException e) {
 | 
			
		||||
                throw new RuntimeException("this error should never throw:" + getBaseComponentType(type).getName(), e);
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            if (returnType == null) returnType = Object.class;
 | 
			
		||||
            if (type.isArray()) {
 | 
			
		||||
                return new ExprValueAccessor((String) o, type, ctx, variableFactory, pCtx);
 | 
			
		||||
            } else {
 | 
			
		||||
                return new ExprValueAccessor((String) o, Object.class, ctx, variableFactory, pCtx);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										4
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								pom.xml
									
									
									
									
									
								
							@ -77,7 +77,7 @@
 | 
			
		||||
        <zookeeper.version>3.5.5</zookeeper.version>
 | 
			
		||||
        <protobuf.version>3.17.2</protobuf.version>
 | 
			
		||||
        <grpc.version>1.42.1</grpc.version>
 | 
			
		||||
        <mvel.version>2.4.14.Final</mvel.version>
 | 
			
		||||
        <mvel.version>2.4.16TB</mvel.version>
 | 
			
		||||
        <lombok.version>1.18.18</lombok.version>
 | 
			
		||||
        <paho.client.version>1.2.4</paho.client.version>
 | 
			
		||||
        <netty.version>4.1.75.Final</netty.version>
 | 
			
		||||
@ -1575,7 +1575,7 @@
 | 
			
		||||
                <version>${grpc.version}</version>
 | 
			
		||||
            </dependency>
 | 
			
		||||
            <dependency>
 | 
			
		||||
                <groupId>org.mvel</groupId>
 | 
			
		||||
                <groupId>org.thingsboard</groupId>
 | 
			
		||||
                <artifactId>mvel2</artifactId>
 | 
			
		||||
                <version>${mvel.version}</version>
 | 
			
		||||
            </dependency>
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user