![JAR search and dependency download from the Maven repository](/logo.png)
org.mvel2.ast.InlineCollectionNode Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of tbel Show documentation
Show all versions of tbel Show documentation
TBEL is a powerful expression language for ThingsBoard platform user-defined functions.
Original implementation is based on MVEL.
/**
* MVEL 2.0
* Copyright (C) 2007 The Codehaus
* Mike Brock, Dhanji Prasanna, John Graham, Mark Proctor
*
* 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.mvel2.ast;
import org.mvel2.CompileException;
import org.mvel2.MVEL;
import org.mvel2.ParserContext;
import org.mvel2.integration.VariableResolverFactory;
import org.mvel2.optimizers.AccessorOptimizer;
import org.mvel2.optimizers.OptimizerFactory;
import org.mvel2.util.CollectionParser;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import static org.mvel2.util.ParseTools.*;
/**
* @author Christopher Brock
*/
public class InlineCollectionNode extends ASTNode {
private Object collectionGraph;
int trailingStart;
int trailingOffset;
public InlineCollectionNode(char[] expr, int start, int end, int fields, ParserContext pctx) {
super(expr, start, end, fields | INLINE_COLLECTION, pctx);
if ((fields & COMPILE_IMMEDIATE) != 0) {
parseGraph(true, null, pctx);
try {
AccessorOptimizer ao = OptimizerFactory.getThreadAccessorOptimizer();
accessor = ao.optimizeCollection(pctx, collectionGraph, egressType, expr, trailingStart, trailingOffset, null, null, null);
egressType = ao.getEgressType();
}
finally {
OptimizerFactory.clearThreadAccessorOptimizer();
}
}
}
public InlineCollectionNode(char[] expr, int start, int end, int fields, Class type, ParserContext pctx) {
super(expr, start, end, fields | INLINE_COLLECTION, pctx);
this.egressType = type;
if ((fields & COMPILE_IMMEDIATE) != 0) {
try {
parseGraph(true, type, pctx);
AccessorOptimizer ao = OptimizerFactory.getThreadAccessorOptimizer();
accessor = ao.optimizeCollection(pctx, collectionGraph, egressType, expr, this.trailingStart, trailingOffset, null, null, null);
egressType = ao.getEgressType();
}
finally {
OptimizerFactory.clearThreadAccessorOptimizer();
}
}
}
public Object getReducedValueAccelerated(Object ctx, Object thisValue, VariableResolverFactory factory) {
if (accessor != null) {
return accessor.getValue(ctx, thisValue, factory);
}
else {
try {
AccessorOptimizer ao = OptimizerFactory.getThreadAccessorOptimizer();
if (collectionGraph == null) parseGraph(true, null, null);
accessor = ao.optimizeCollection(pCtx, collectionGraph,
egressType, expr, trailingStart, trailingOffset, ctx, thisValue, factory);
egressType = ao.getEgressType();
return accessor.getValue(ctx, thisValue, factory);
}
finally {
OptimizerFactory.clearThreadAccessorOptimizer();
}
}
}
public Object getReducedValue(Object ctx, Object thisValue, VariableResolverFactory factory) {
parseGraph(false, egressType, pCtx);
return execGraph(collectionGraph, egressType, ctx, factory);
}
private void parseGraph(boolean compile, Class type, ParserContext pCtx) {
CollectionParser parser = new CollectionParser();
if (type == null) {
collectionGraph = ((List) parser.parseCollection(expr, start, offset, compile, pCtx)).get(0);
}
else {
collectionGraph = ((List) parser.parseCollection(expr, start, offset, compile, type, pCtx)).get(0);
}
trailingStart = parser.getCursor() + 2;
trailingOffset = offset - (trailingStart - start);
if (this.egressType == null) this.egressType = collectionGraph.getClass();
}
private Object execGraph(Object o, Class type, Object ctx, VariableResolverFactory factory) {
if (o instanceof List) {
ArrayList list = new ArrayList(((List) o).size());
for (Object item : (List) o) {
list.add(execGraph(item, type, ctx, factory));
}
return list;
}
else if (o instanceof Map) {
HashMap map = new LinkedHashMap();
for (Object item : ((Map) o).keySet()) {
Object key = item;
if (key instanceof String && ((String) key).trim().length() > 0 && !((String) key).startsWith("'")) {
try {
key = Integer.parseInt((String) key);
} catch (NumberFormatException e) {}
} else {
key = execGraph(key, type, ctx, factory);
}
map.put(key, execGraph(((Map) o).get(item), type, ctx, factory));
}
return map;
}
else if (o instanceof Object[]) {
int dim = 0;
if (type != null) {
String nm = type.getName();
while (nm.charAt(dim) == '[') dim++;
}
else {
type = Object[].class;
dim = 1;
}
Object newArray = Array.newInstance(getSubComponentType(type), ((Object[]) o).length);
try {
Class cls = dim > 1 ? findClass(null, repeatChar('[', dim - 1) + "L" + getBaseComponentType(type).getName() + ";", pCtx) : type;
int c = 0;
for (Object item : (Object[]) o) {
Array.set(newArray, c++, execGraph(item, cls, ctx, factory));
}
return newArray;
}
catch (IllegalArgumentException e) {
throw new CompileException("type mismatch in array", expr, start, e);
}
catch (ClassNotFoundException e) {
throw new RuntimeException("this error should never throw:" + getBaseComponentType(type).getName(), e);
}
}
else {
if (type.isArray()) {
return MVEL.eval((String) o, ctx, factory, getBaseComponentType(type));
}
else {
return MVEL.eval((String) o, ctx, factory);
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy