[Git][java-team/mvel][master] 8 commits: Switch to debhelper-compat = 12.
Markus Koschany
gitlab at salsa.debian.org
Mon Aug 26 22:50:12 BST 2019
Markus Koschany pushed to branch master at Debian Java Maintainers / mvel
Commits:
4886e092 by Markus Koschany at 2019-08-26T19:48:39Z
Switch to debhelper-compat = 12.
- - - - -
75bf8b1e by Markus Koschany at 2019-08-26T19:48:51Z
Declare compliance with Debian Policy 4.4.0.
- - - - -
9bfc5319 by Markus Koschany at 2019-08-26T19:49:20Z
Use canonical VCS URI.
- - - - -
ebeaa511 by Markus Koschany at 2019-08-26T19:49:45Z
Remove get-orig-source target.
- - - - -
4856310a by Markus Koschany at 2019-08-26T19:51:49Z
New upstream version 2.4.4
- - - - -
71a4ef95 by Markus Koschany at 2019-08-26T19:51:54Z
Update upstream source from tag 'upstream/2.4.4'
Update to upstream version '2.4.4'
with Debian dir 43c6d95b5dbd0320573f6b9c52547e3f3b5d6732
- - - - -
20e674f7 by Markus Koschany at 2019-08-26T19:56:00Z
Update changelog
- - - - -
1c71b409 by Markus Koschany at 2019-08-26T20:09:54Z
Do not build libmvel-java-doc anymore. The package is empty because the
javadoc plugin fails to build the documentation. Just ignoring the javadoc
errors is not sufficient anymore.
- - - - -
29 changed files:
- debian/changelog
- − debian/compat
- debian/control
- − debian/libmvel-java-doc.doc-base.api
- − debian/libmvel-java-doc.install
- − debian/patches/java9.patch
- debian/patches/series
- debian/rules
- pom.xml
- src/main/java/org/mvel2/ast/BinaryOperation.java
- src/main/java/org/mvel2/compiler/AbstractParser.java
- src/main/java/org/mvel2/compiler/ExpressionCompiler.java
- src/main/java/org/mvel2/jsr223/MvelScriptEngineFactory.java
- src/main/java/org/mvel2/optimizers/impl/asm/ASMAccessorOptimizer.java
- src/main/java/org/mvel2/optimizers/impl/refl/ReflectiveAccessorOptimizer.java
- src/main/java/org/mvel2/optimizers/impl/refl/nodes/DynamicFunctionAccessor.java
- src/main/java/org/mvel2/util/CompilerTools.java
- src/main/java/org/mvel2/util/FastList.java
- src/main/java/org/mvel2/util/ParseTools.java
- src/main/java/org/mvel2/util/PropertyTools.java
- + src/test/java/org/mvel2/compiler/CollectionElementByIndexTest.java
- + src/test/java/org/mvel2/compiler/MvelCompileExpNullSafeTest.java
- src/test/java/org/mvel2/tests/core/CoreConfidenceTests.java
- src/test/java/org/mvel2/tests/core/FunctionsTest.java
- + src/test/java/org/mvel2/tests/core/MvelArrayTest.java
- + src/test/java/org/mvel2/tests/core/PrimitiveTypesTest.java
- src/test/java/org/mvel2/tests/core/PropertyAccessTests.java
- + src/test/java/org/mvel2/tests/core/res/Member.java
- + src/test/java/org/mvel2/tests/core/res/SharedFuncLib.java
Changes:
=====================================
debian/changelog
=====================================
@@ -1,3 +1,16 @@
+mvel (2.4.4-1) unstable; urgency=medium
+
+ * Team upload.
+ * New upstream version 2.4.4.
+ * Switch to debhelper-compat = 12.
+ * Declare compliance with Debian Policy 4.4.0.
+ * Use canonical VCS URI.
+ * Do not build libmvel-java-doc anymore. The package is empty because the
+ javadoc plugin fails to build the documentation. Just ignoring the javadoc
+ errors with Java 9+ is not sufficient anymore.
+
+ -- Markus Koschany <apo at debian.org> Mon, 26 Aug 2019 21:52:42 +0200
+
mvel (2.4.0-1) unstable; urgency=medium
* Team upload.
=====================================
debian/compat deleted
=====================================
@@ -1 +0,0 @@
-10
=====================================
debian/control
=====================================
@@ -5,7 +5,7 @@ Maintainer: Debian Java Maintainers <pkg-java-maintainers at lists.alioth.debian.or
Uploaders:
Damien Raude-Morvan <drazzib at debian.org>
Build-Depends:
- debhelper (>= 10),
+ debhelper-compat (= 12),
default-jdk,
default-jdk-doc,
junit4,
@@ -17,9 +17,9 @@ Build-Depends:
libsurefire-java (>= 2.4.3),
libxstream-java,
maven-debian-helper
-Standards-Version: 4.1.2
-Vcs-Git: https://anonscm.debian.org/git/pkg-java/mvel.git
-Vcs-Browser: https://anonscm.debian.org/cgit/pkg-java/mvel.git
+Standards-Version: 4.4.0
+Vcs-Git: https://salsa.debian.org/java-team/mvel.git
+Vcs-Browser: https://salsa.debian.org/java-team/mvel
Homepage: https://github.com/mvel/mvel/
Package: libmvel-java
@@ -36,21 +36,3 @@ Description: expression language for Java-based applications - Library
In addition to being an expression language, MVEL also comes packaged with an
templating system similar to Velocity and FreeMarker.
-Package: libmvel-java-doc
-Architecture: all
-Section: doc
-Depends:
- ${maven:DocDepends},
- ${misc:Depends}
-Recommends:
- ${maven:DocOptionalDepends}
-Suggests:
- libmvel-java
-Description: expression language for Java-based applications - Javadoc
- MVEL may be useful as an extension to anything from use in JSP Tag Libraries,
- to the configuration facilities of your library/framework.
- .
- In addition to being an expression language, MVEL also comes packaged with an
- templating system similar to Velocity and FreeMarker.
- .
- This package provides the API documentation for libmvel-java.
=====================================
debian/libmvel-java-doc.doc-base.api deleted
=====================================
@@ -1,10 +0,0 @@
-Document: libmvel-java
-Title: API Javadoc for MVEL
-Author: MVEL developers
-Abstract: This is the API Javadoc provided for the
- libmvel-java library.
-Section: Programming
-
-Format: HTML
-Index: /usr/share/doc/libmvel-java/api/index.html
-Files: /usr/share/doc/libmvel-java/api/*
=====================================
debian/libmvel-java-doc.install deleted
=====================================
@@ -1 +0,0 @@
-target/apidocs/* usr/share/doc/libmvel-java/api
=====================================
debian/patches/java9.patch deleted
=====================================
@@ -1,30 +0,0 @@
-From: Markus Koschany <apo at debian.org>
-Date: Sat, 2 Dec 2017 09:54:39 +0100
-Subject: java9
-
-Work around FTBFS with Java 9 by ignoring the doclint errors.
-
-Bug-Debian: https://bugs.debian.org/875775
-Forwarded: no
----
- pom.xml | 7 +++++++
- 1 file changed, 7 insertions(+)
-
-diff --git a/pom.xml b/pom.xml
-index dbed0b0..fdb10b9 100644
---- a/pom.xml
-+++ b/pom.xml
-@@ -80,6 +80,13 @@
- </extensions>
-
- <plugins>
-+ <plugin>
-+ <groupId>org.apache.maven.plugins</groupId>
-+ <artifactId>maven-javadoc-plugin</artifactId>
-+ <configuration>
-+ <failOnError>false</failOnError>
-+ </configuration>
-+ </plugin>
- <plugin>
- <artifactId>maven-enforcer-plugin</artifactId>
- <version>1.0</version>
=====================================
debian/patches/series
=====================================
@@ -1,2 +1 @@
use_system_asm.diff
-java9.patch
=====================================
debian/rules
=====================================
@@ -8,6 +8,3 @@ export JAVA_HOME = /usr/lib/jvm/default-java
override_dh_clean:
dh_clean
rm -Rf META-INF
-
-get-orig-source:
- uscan --download-current-version --force-download --repack --compression xz
=====================================
pom.xml
=====================================
@@ -5,7 +5,7 @@
<groupId>org.mvel</groupId>
<artifactId>mvel2</artifactId>
<packaging>jar</packaging>
- <version>2.4.0.Final</version>
+ <version>2.4.4.Final</version>
<name>mvel</name>
<url>http://mvel.codehaus.org/</url>
@@ -31,7 +31,7 @@
<connection>scm:git:git at github.com:mvel/mvel.git</connection>
<url>scm:git:git at github.com:mvel/mvel.git</url>
<developerConnection>scm:git:git at github.com:mvel/mvel.git</developerConnection>
- <tag>mvel2-2.4.0.Final</tag>
+ <tag>mvel2-2.4.4.Final</tag>
</scm>
<issueManagement>
<system>jira</system>
@@ -229,6 +229,9 @@
<include>build.properties</include>
</includes>
</resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
</resources>
</build>
=====================================
src/main/java/org/mvel2/ast/BinaryOperation.java
=====================================
@@ -73,8 +73,16 @@ public class BinaryOperation extends BooleanNode {
egressType = getReturnTypeFromOp(operation, this.left.egressType, this.right.egressType);
if (!ctx.isStrongTyping()) break;
- if (!left.getEgressType().isAssignableFrom(right.getEgressType()) && !right.getEgressType().isAssignableFrom(left.getEgressType())) {
- if (right.isLiteral() && canConvert(left.getEgressType(), right.getEgressType())) {
+ final boolean leftIsAssignableFromRight = left.getEgressType().isAssignableFrom(right.getEgressType());
+ final boolean rightIsAssignableFromLeft = right.getEgressType().isAssignableFrom(left.getEgressType());
+
+ if (!leftIsAssignableFromRight && !rightIsAssignableFromLeft) {
+
+ // Convert literals only when passing from String to Character or from Float to Double
+ final boolean requiresConversion = right.getEgressType() == String.class || (
+ right.getEgressType() == Double.class && ( left.getEgressType() == Float.class || left.getEgressType() == float.class ) );
+
+ if (right.isLiteral() && requiresConversion && canConvert(left.getEgressType(), right.getEgressType())) {
Class targetType = isAritmeticOperation(operation) ? egressType : left.getEgressType();
this.right = new LiteralNode(convert(right.getReducedValueAccelerated(null, null, null), targetType), pCtx);
} else if ( !(areCompatible(left.getEgressType(), right.getEgressType()) ||
=====================================
src/main/java/org/mvel2/compiler/AbstractParser.java
=====================================
@@ -113,6 +113,7 @@ public class AbstractParser implements Parser, Serializable {
protected int fields;
+ protected static final int OP_NOT_LITERAL = -3;
protected static final int OP_OVERFLOW = -2;
protected static final int OP_TERMINATE = -1;
protected static final int OP_RESET_FRAME = 0;
@@ -2407,8 +2408,6 @@ public class AbstractParser implements Parser, Serializable {
* need to stop if this is not a literal.
*/
if (compileMode && !tk.isLiteral()) {
-
-
splitAccumulator.push(tk, new OperatorNode(operator2, expr, st, pCtx));
return OP_OVERFLOW;
}
@@ -2416,6 +2415,7 @@ public class AbstractParser implements Parser, Serializable {
dStack.push(operator = operator2, tk.getReducedValue(ctx, ctx, variableFactory));
while (true) {
+ ASTNode previousToken = tk;
// look ahead again
if ((tk = nextToken()) != null && (operator2 = tk.getOperator()) != -1
&& operator2 != END_OF_STMT && PTABLE[operator2] > PTABLE[operator]) {
@@ -2428,7 +2428,12 @@ public class AbstractParser implements Parser, Serializable {
/**
* This operator is of higher precedence, or the same level precedence. push to the RHS.
*/
- dStack.push(operator = operator2, nextToken().getReducedValue(ctx, ctx, variableFactory));
+ ASTNode nextToken = nextToken();
+ if (compileMode && !nextToken.isLiteral()) {
+ splitAccumulator.push(nextToken, new OperatorNode(operator2, expr, st, pCtx));
+ return OP_OVERFLOW;
+ }
+ dStack.push(operator = operator2, nextToken.getReducedValue(ctx, ctx, variableFactory));
continue;
}
@@ -2498,6 +2503,10 @@ public class AbstractParser implements Parser, Serializable {
}
default:
+ if (compileMode && !tk.isLiteral()) {
+ stk.push(operator, tk);
+ return OP_NOT_LITERAL;
+ }
stk.push(operator, tk.getReducedValue(ctx, ctx, variableFactory));
}
}
=====================================
src/main/java/org/mvel2/compiler/ExpressionCompiler.java
=====================================
@@ -123,7 +123,7 @@ public class ExpressionCompiler extends AbstractParser {
fields |= COMPILE_IMMEDIATE;
- while ((tk = nextToken()) != null) {
+ main_loop: while ((tk = nextToken()) != null) {
/**
* If this is a debug symbol, just add it and continue.
*/
@@ -199,7 +199,7 @@ public class ExpressionCompiler extends AbstractParser {
stk.push(tkLA2.getLiteralValue(), op = tkOp2.getOperator());
if (isArithmeticOperator(op)) {
- compileReduce(op, astBuild);
+ if (!compileReduce(op, astBuild)) continue main_loop;
}
else {
reduce();
@@ -327,7 +327,7 @@ public class ExpressionCompiler extends AbstractParser {
private boolean compileReduce(int opCode, ASTLinkedList astBuild) {
switch (arithmeticFunctionReduction(opCode)) {
- case -1:
+ case OP_TERMINATE:
/**
* The reduction failed because we encountered a non-literal,
* so we must now back out and cleanup.
@@ -341,7 +341,7 @@ public class ExpressionCompiler extends AbstractParser {
verify(pCtx, (ASTNode) splitAccumulator.pop())
);
return false;
- case -2:
+ case OP_OVERFLOW:
/**
* Back out completely, pull everything back off the stack and add the instructions
* to the output payload as they are.
@@ -353,6 +353,13 @@ public class ExpressionCompiler extends AbstractParser {
astBuild.addTokenNode(new LiteralNode(stk.pop(), pCtx), operator);
astBuild.addTokenNode(rightValue, (OperatorNode) splitAccumulator.pop());
astBuild.addTokenNode(verify(pCtx, (ASTNode) splitAccumulator.pop()));
+ return false;
+ case OP_NOT_LITERAL:
+ ASTNode tkLA2 = (ASTNode) stk.pop();
+ Integer tkOp2 = (Integer) stk.pop();
+ astBuild.addTokenNode(new LiteralNode(getStackValueResult(), pCtx));
+ astBuild.addTokenNode(new OperatorNode(tkOp2, expr, st, pCtx), verify(pCtx, tkLA2));
+ return false;
}
return true;
}
=====================================
src/main/java/org/mvel2/jsr223/MvelScriptEngineFactory.java
=====================================
@@ -1,6 +1,7 @@
package org.mvel2.jsr223;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import javax.script.ScriptEngine;
@@ -14,14 +15,25 @@ public class MvelScriptEngineFactory implements ScriptEngineFactory {
private static final String LANGUAGE_NAME = "mvel";
private static final String LANGUAGE_VERSION = MVEL.VERSION;
- private static final List<String> NAMES = new ArrayList<String>();
- private static final List<String> EXTENSIONS = new ArrayList<String>();
- private static final List<String> MIME_TYPES = new ArrayList<String>();
+ private static final List<String> NAMES;
+ private static final List<String> EXTENSIONS;
+ private static final List<String> MIME_TYPES;
+
+ static {
+ List<String> n = new ArrayList<String>(1);
+ n.add(LANGUAGE_NAME);
+ NAMES = Collections.unmodifiableList(n);
+
+ EXTENSIONS = NAMES;
+
+ n = new ArrayList<String>(1);
+ n.add("application/x-"+LANGUAGE_NAME);
+ MIME_TYPES = Collections.unmodifiableList(n);
+ }
private static final MvelScriptEngine MVEL_SCRIPT_ENGINE = new MvelScriptEngine();
public MvelScriptEngineFactory() {
- NAMES.add(LANGUAGE_NAME);
}
@Override
=====================================
src/main/java/org/mvel2/optimizers/impl/asm/ASMAccessorOptimizer.java
=====================================
@@ -121,7 +121,9 @@ public class ASMAccessorOptimizer extends AbstractOptimizer implements AccessorO
} else if (javaVersion.startsWith("1.6")
|| javaVersion.startsWith("1.7")
|| javaVersion.startsWith("1.8")
- || javaVersion.startsWith("9")) {
+ || javaVersion.startsWith("9")
+ || javaVersion.startsWith("10")
+ || javaVersion.startsWith("11")) {
OPCODES_VERSION = Opcodes.V1_6;
} else {
OPCODES_VERSION = Opcodes.V1_2;
=====================================
src/main/java/org/mvel2/optimizers/impl/refl/ReflectiveAccessorOptimizer.java
=====================================
@@ -377,7 +377,7 @@ public class ReflectiveAccessorOptimizer extends AbstractOptimizer implements Ac
if (cursor < end) {
if (nullSafe) {
int os = expr[cursor] == '.' ? 1 : 0;
- addAccessorNode(new NullSafe(expr, cursor + os, length - cursor - os, pCtx));
+ addAccessorNode(new NullSafe(expr, cursor + os, end - cursor - os, pCtx));
if (curr == null) break;
}
if (curr == null) throw new NullPointerException();
@@ -806,17 +806,16 @@ public class ReflectiveAccessorOptimizer extends AbstractOptimizer implements Ac
return ((CharSequence) ctx).charAt((Integer) idx);
}
- else {
+ else if (ctx instanceof Class) {
TypeDescriptor tDescr = new TypeDescriptor(expr, this.start, length, 0);
if (tDescr.isArray()) {
Class cls = getClassReference((Class) ctx, tDescr, variableFactory, pCtx);
rootNode = new StaticReferenceAccessor(cls);
return cls;
}
-
- throw new CompileException("illegal use of []: unknown type: "
- + ctx.getClass().getName(), this.expr, this.start);
}
+ throw new CompileException("illegal use of []: unknown type: "
+ + ctx.getClass().getName(), this.expr, this.start);
}
=====================================
src/main/java/org/mvel2/optimizers/impl/refl/nodes/DynamicFunctionAccessor.java
=====================================
@@ -19,6 +19,7 @@
package org.mvel2.optimizers.impl.refl.nodes;
import org.mvel2.ast.Function;
+import org.mvel2.ast.FunctionInstance;
import org.mvel2.compiler.Accessor;
import org.mvel2.integration.VariableResolverFactory;
@@ -34,7 +35,12 @@ public class DynamicFunctionAccessor extends BaseAccessor {
public Object getValue(Object ctx, Object elCtx, VariableResolverFactory variableFactory) {
Object[] parms = null;
- Function function = (Function) ctx;
+ Function function;
+ if (ctx instanceof FunctionInstance){
+ function = ((FunctionInstance)ctx).getFunction();
+ } else {
+ function = (Function)ctx;
+ }
if (parameters != null && parameters.length != 0) {
parms = new Object[parameters.length];
=====================================
src/main/java/org/mvel2/util/CompilerTools.java
=====================================
@@ -103,7 +103,7 @@ public class CompilerTools {
bo = null;
boolean inv = tkOp.isOperator(Operator.SUB);
- boolean reduc = isReductionOpportunity(tkOp, tk2);
+ boolean reduc = tk.isLiteral() && isReductionOpportunity(tkOp, tk2);
boolean p_inv = false;
while (reduc) {
=====================================
src/main/java/org/mvel2/util/FastList.java
=====================================
@@ -18,13 +18,17 @@
package org.mvel2.util;
-import org.mvel2.ImmutableElementException;
-
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
-import java.util.*;
+import java.util.AbstractList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+import org.mvel2.ImmutableElementException;
public class FastList<E> extends AbstractList<E> implements Externalizable {
private E[] elements;
@@ -168,14 +172,14 @@ public class FastList<E> extends AbstractList<E> implements Externalizable {
public ListIterator<E> listIterator() {
return new ListIterator<E>() {
- private int i = 0;
+ private int i = -1;
public boolean hasNext() {
- return i < size;
+ return i < size-1;
}
public E next() {
- return elements[i++];
+ return elements[++i];
}
public boolean hasPrevious() {
@@ -183,7 +187,7 @@ public class FastList<E> extends AbstractList<E> implements Externalizable {
}
public E previous() {
- return elements[i--];
+ return elements[--i];
}
public int nextIndex() {
=====================================
src/main/java/org/mvel2/util/ParseTools.java
=====================================
@@ -320,7 +320,7 @@ public class ParseTools {
if (arguments[i] == null) {
if (!actualParamType.isPrimitive()) {
- score += 6;
+ score += 7;
}
else {
score = 0;
@@ -328,15 +328,18 @@ public class ParseTools {
}
}
else if (actualParamType == arguments[i]) {
- score += 7;
+ score += 8;
}
else if (actualParamType.isPrimitive() && boxPrimitive(actualParamType) == arguments[i]) {
- score += 6;
+ score += 7;
}
else if (arguments[i].isPrimitive() && unboxPrimitive(arguments[i]) == actualParamType) {
- score += 6;
+ score += 7;
}
else if (actualParamType.isAssignableFrom(arguments[i])) {
+ score += 6;
+ }
+ else if (isPrimitiveSubtype(arguments[i], actualParamType)) {
score += 5;
}
else if (isNumericallyCoercible(arguments[i], actualParamType)) {
@@ -1065,6 +1068,22 @@ public class ParseTools {
return code;
}
+ private static boolean isPrimitiveSubtype( Class argument, Class<?> actualParamType ) {
+ if (!actualParamType.isPrimitive()) {
+ return false;
+ }
+ Class<?> primitiveArgument = unboxPrimitive(argument);
+ if (!primitiveArgument.isPrimitive()) {
+ return false;
+ }
+ return ( actualParamType == double.class && primitiveArgument == float.class ) ||
+ ( actualParamType == float.class && primitiveArgument == long.class ) ||
+ ( actualParamType == long.class && primitiveArgument == int.class ) ||
+ ( actualParamType == int.class && primitiveArgument == char.class ) ||
+ ( actualParamType == int.class && primitiveArgument == short.class ) ||
+ ( actualParamType == short.class && primitiveArgument == byte.class );
+ }
+
public static boolean isNumericallyCoercible(Class target, Class parm) {
Class boxedTarget = target.isPrimitive() ? boxPrimitive(target) : target;
@@ -2175,7 +2194,7 @@ public class ParseTools {
public static Class forNameWithInner(String className, ClassLoader classLoader) throws ClassNotFoundException {
try {
- return Class.forName(className, true, classLoader);
+ return classLoader.loadClass( className );
} catch (ClassNotFoundException cnfe) {
return findInnerClass( className, classLoader, cnfe );
}
@@ -2185,7 +2204,7 @@ public class ParseTools {
for (int lastDotPos = className.lastIndexOf('.'); lastDotPos > 0; lastDotPos = className.lastIndexOf('.')) {
className = className.substring(0, lastDotPos) + "$" + className.substring(lastDotPos+1);
try {
- return Class.forName(className, true, classLoader);
+ return classLoader.loadClass( className );
} catch (ClassNotFoundException e) { /* ignore */ }
}
throw cnfe;
=====================================
src/main/java/org/mvel2/util/PropertyTools.java
=====================================
@@ -97,6 +97,13 @@ public class PropertyTools {
String getter = ReflectionUtil.getGetter(property);
Method candidate = null;
+
+ if (Collection.class.isAssignableFrom(clazz) && "isEmpty".equals(isGet)) {
+ try {
+ return Collection.class.getMethod("isEmpty");
+ } catch (NoSuchMethodException ignore) {}
+ }
+
for (Method meth : clazz.getMethods()) {
if ((meth.getModifiers() & PUBLIC) != 0 && (meth.getModifiers() & STATIC) == 0 && meth.getParameterTypes().length == 0
&& (getter.equals(meth.getName()) || property.equals(meth.getName()) || ((isGet.equals(meth.getName()) || simpleIsGet.equals(meth.getName())) && meth.getReturnType() == boolean.class)
=====================================
src/test/java/org/mvel2/compiler/CollectionElementByIndexTest.java
=====================================
@@ -0,0 +1,31 @@
+package org.mvel2.compiler;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.mvel2.CompileException;
+import org.mvel2.MVEL;
+
+import static org.junit.internal.matchers.StringContains.containsString;
+
+/**
+ * @author Anton Rybochkin (anton.rybochkin at axibase.com)
+ */
+public class CollectionElementByIndexTest {
+ @Rule
+ public ExpectedException expectException = ExpectedException.none();
+
+ @Test
+ public void testGetElementByIndexInSet() {
+ expectException.expect(CompileException.class);
+ expectException.expectMessage(containsString("unknown type: java.util.Collections$SingletonSet"));
+ final Map<String, Set<String>> map = Collections.singletonMap("set", Collections.singleton("test"));
+ final Serializable ser = MVEL.compileExpression("set[0]");
+ MVEL.executeExpression(ser, map);
+ }
+}
=====================================
src/test/java/org/mvel2/compiler/MvelCompileExpNullSafeTest.java
=====================================
@@ -0,0 +1,133 @@
+package org.mvel2.compiler;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.Test;
+import org.mvel2.MVEL;
+import org.mvel2.compiler.CompiledExpression;
+import org.mvel2.compiler.ExpressionCompiler;
+
+/**
+ * @author Viswa Ramamoorthy (viswaramamoorthy at yahoo.com)
+ */
+public class MvelCompileExpNullSafeTest
+{
+ @Test
+ public void testMvelCompileNullSafeNullFirst() {
+ String expression = "((parentGroup != null) && ($.?child.firstName in parentGroup.parentList if $.?child.firstName != null).size() > 0)";
+ ExpressionCompiler compiler = new ExpressionCompiler(expression, true);
+ CompiledExpression compiledExpression = compiler.compile();
+
+ ParentGroup pGroup = new ParentGroup();
+ List<Parent> list = new ArrayList<Parent>();
+ Parent parent = new Parent();
+ parent.setChild(null);
+ list.add(parent);
+ pGroup.setParentList(list);
+
+ Boolean result = (Boolean)MVEL.executeExpression(compiledExpression, Collections.<String, Object>singletonMap("parentGroup", pGroup));
+ assert result == false;
+
+ Child child = new Child();
+ child.setFirstName("vlaa");
+
+ pGroup = new ParentGroup();
+ list = new ArrayList<Parent>();
+ parent = new Parent();
+ parent.setChild(child);
+ list.add(parent);
+ child = new Child();
+ child.setFirstName(null);
+ parent = new Parent();
+ parent.setChild(child);
+ list.add(parent);
+ pGroup.setParentList(list);
+
+ result = (Boolean)MVEL.executeExpression(compiledExpression, Collections.<String, Object>singletonMap("parentGroup", pGroup));
+ assert result == true;
+ }
+
+ @Test
+ public void testMvelCompileNullSafeNullSecond() {
+ String expression = "((parentGroup != null) && ($.?child.firstName in parentGroup.parentList if $.?child.firstName != null).size() > 0)";
+ ExpressionCompiler compiler = new ExpressionCompiler(expression, true);
+ CompiledExpression compiledExpression = compiler.compile();
+
+ Child child = new Child();
+ child.setFirstName("vlaa");
+
+ ParentGroup pGroup = new ParentGroup();
+ List<Parent> list = new ArrayList<Parent>();
+ Parent parent = new Parent();
+ parent.setChild(child);
+ list.add(parent);
+ child = new Child();
+ child.setFirstName(null);
+ parent = new Parent();
+ parent.setChild(child);
+ list.add(parent);
+ pGroup.setParentList(list);
+
+ Boolean result = (Boolean)MVEL.executeExpression(compiledExpression, Collections.<String, Object>singletonMap("parentGroup", pGroup));
+ assert result == true;
+
+ pGroup = new ParentGroup();
+ list = new ArrayList<Parent>();
+ parent = new Parent();
+ parent.setChild(null);
+ list.add(parent);
+ pGroup.setParentList(list);
+
+ result = (Boolean)MVEL.executeExpression(compiledExpression, Collections.<String, Object>singletonMap("parentGroup", pGroup));
+ assert result == false;
+
+ }
+
+ public class Child {
+ private String firstName;
+ private String lastName;
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+ }
+
+ public class Parent {
+ private Child child;
+
+ public Child getChild() {
+ return child;
+ }
+
+ public void setChild(Child child) {
+ this.child = child;
+ }
+ }
+
+ public class ParentGroup {
+ private List<Parent> parentList;
+
+ public List<Parent> getParentList() {
+ return parentList;
+ }
+
+ public void setParentList(List<Parent> parentList) {
+ this.parentList = parentList;
+ }
+
+ }
+}
=====================================
src/test/java/org/mvel2/tests/core/CoreConfidenceTests.java
=====================================
@@ -27,6 +27,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;
+import java.util.concurrent.atomic.AtomicInteger;
import junit.framework.TestCase;
import org.mvel2.CompileException;
@@ -82,7 +83,15 @@ import org.mvel2.util.ParseTools;
import org.mvel2.util.ReflectionUtil;
import static java.util.Collections.unmodifiableCollection;
-import static org.mvel2.MVEL.*;
+
+import static org.mvel2.MVEL.compileExpression;
+import static org.mvel2.MVEL.compileSetExpression;
+import static org.mvel2.MVEL.eval;
+import static org.mvel2.MVEL.evalToBoolean;
+import static org.mvel2.MVEL.executeExpression;
+import static org.mvel2.MVEL.executeSetExpression;
+import static org.mvel2.MVEL.parseMacros;
+import static org.mvel2.MVEL.setProperty;
import static org.mvel2.util.ParseTools.loadFromFile;
@SuppressWarnings({"ALL"})
@@ -4018,17 +4027,6 @@ public class CoreConfidenceTests extends AbstractTest {
assertFalse(result);
}
- public void testDhanji2() {
- String ex =
- "name = null;\n" +
- "$_1 = ?name.?toLowerCase();\n";
-
-
- Serializable s = MVEL.compileExpression(ex);
-
- MVEL.executeExpression(s, new HashMap());
- }
-
public void testPrimitiveNumberCoercion() {
final ParserContext parserContext = new ParserContext();
parserContext.setStrictTypeEnforcement(true);
@@ -4158,6 +4156,44 @@ public class CoreConfidenceTests extends AbstractTest {
System.out.println(result);
}
+ public void testPrimitiveNumberCoercionDuringDivisionShouldWorkOnBothSide() {
+ final ParserContext parserContext = new ParserContext();
+ parserContext.setStrictTypeEnforcement(true);
+ parserContext.setStrongTyping(true);
+ parserContext.addInput("a", int.class);
+ parserContext.addInput("b", int.class);
+
+ int a = 1;
+ int b = 2;
+ Object res = a / b;
+ System.out.printf("Result class Java: %s\nResult value: %s\n", res.getClass(), res);
+ Object resBoolean = a / b < 0.99;
+ System.out.println("Result Boolean: " + resBoolean);
+
+ Serializable constantDoubleLeft = MVEL.compileExpression("0.99 >= a / b", parserContext);
+ Object resultLeft = MVEL.executeExpression(constantDoubleLeft, new HashMap() {{
+ put("a", 1);
+ put("b", 2);
+ }});
+ assertEquals(true, resultLeft);
+ Serializable constantDoubleRight = MVEL.compileExpression("a / b < 0.99", parserContext);
+ Object resultRight = MVEL.executeExpression(constantDoubleRight, new HashMap() {{
+ put("a", 1);
+ put("b", 2);
+ }});
+ assertEquals(true, resultRight);
+
+ parserContext.addInput("c", double.class);
+ parserContext.addInput("d", double.class);
+ Serializable constantIntRight = MVEL.compileExpression("c / d > 0", parserContext);
+ Object resultRightInt = MVEL.executeExpression(constantIntRight, new HashMap() {{
+ put("c", 1);
+ put("d", 2);
+ }});
+ assertEquals(true, resultRightInt);
+
+ }
+
public void testUntypedClone() {
String expression = "obj.clone();";
ParserContext context = new ParserContext();
@@ -4325,6 +4361,9 @@ public class CoreConfidenceTests extends AbstractTest {
Map vars = new HashMap() {{ put("ch", 'a'); }};
assertEquals(true, MVEL.executeExpression(MVEL.compileExpression("ch == \"a\"", pctx), vars));
assertEquals(false, MVEL.executeExpression(MVEL.compileExpression("ch == \"b\"", pctx), vars));
+
+// assertEquals(true, MVEL.executeExpression(MVEL.compileExpression("\"a\" == ch", pctx), vars));
+// assertEquals(false, MVEL.executeExpression(MVEL.compileExpression("\"b\" == ch", pctx), vars));
}
public void testFieldNameWithUnderscore() {
@@ -4616,4 +4655,45 @@ public class CoreConfidenceTests extends AbstractTest {
fail("parse of this expression should raise an error");
} catch (Exception e) { }
}
+
+ public void testPrimitiveSubtyping() {
+ ParserConfiguration conf = new ParserConfiguration();
+ ParserContext pctx = new ParserContext( conf );
+ pctx.setStrictTypeEnforcement(true);
+ pctx.setStrongTyping(true);
+ BigDecimal result = (BigDecimal)MVEL.executeExpression(MVEL.compileExpression("java.math.BigDecimal.valueOf(100)", pctx), new HashMap());
+ assertEquals("100", result.toString());
+ }
+
+ public void testUseVariableFactoryWithArithmeticOperation() {
+ checkOperation("3 + 4 * i.get()", 43);
+ checkOperation("2 * 3 + 4 * i.get()", 46);
+ checkOperation("1 + 2 * 3 + i.get()", 17);
+ checkOperation("2 * 3 + 4 * i.get()", 46);
+ checkOperation("1 + 2 * 3 + 4 * i.get()", 47);
+ checkOperation("1 + 2 * 3 + i.get() * 4", 47);
+ checkOperation("1 + 2 * 3 + i.get() + 4", 21);
+ checkOperation("4 * i.get() + 5", 45);
+ checkOperation("3 + 4 * i.get() + 5", 48);
+ checkOperation("2 * 3 + 4 * i.get() + 5", 51);
+ checkOperation("1 + 2 * 3 + 4 * i.get() + 5", 52);
+ checkOperation("1 + 2 * 3 + 4 * i.get() * 5", 207);
+ checkOperation("i.get() + 1 + 2 * 3 + 4 * i.get()", 57);
+ }
+
+ private void checkOperation(String expression, int expectedResult) {
+ AtomicInteger i = new AtomicInteger( 10 );
+ VariableResolverFactory factory = new MapVariableResolverFactory(new HashMap<String, Object>());
+ factory.createVariable("i", i);
+
+ ParserConfiguration pconf = new ParserConfiguration();
+ ParserContext pctx = new ParserContext(pconf);
+ pctx.setStrictTypeEnforcement(true);
+ pctx.setStrongTyping(true);
+ pctx.addInput("i", AtomicInteger.class);
+
+ Serializable compiledExpr = MVEL.compileExpression(expression, pctx);
+ int result = (Integer)MVEL.executeExpression(compiledExpr, null, factory);
+ assertEquals(expectedResult, result);
+ }
}
\ No newline at end of file
=====================================
src/test/java/org/mvel2/tests/core/FunctionsTest.java
=====================================
@@ -10,13 +10,15 @@ import org.mvel2.compiler.ExpressionCompiler;
import org.mvel2.integration.VariableResolverFactory;
import org.mvel2.integration.impl.MapVariableResolverFactory;
import org.mvel2.optimizers.OptimizerFactory;
-import org.mvel2.util.CompilerTools;
-import org.mvel2.util.MVELClassLoader;
+import org.mvel2.tests.core.res.Member;
+import org.mvel2.tests.core.res.SharedFuncLib;
import static org.mvel2.util.CompilerTools.extractAllDeclaredFunctions;
import java.io.Serializable;
+import java.math.BigDecimal;
import java.util.*;
+import java.util.concurrent.*;
/**
* @author Dhanji R. Prasanna (dhanji at gmail com)
@@ -200,4 +202,37 @@ public class FunctionsTest extends AbstractTest {
assertEquals("foobar", MVEL.executeExpression(s, myVarFactory));
}
+
+
+ public void testFunctionReuseMultiThread(){
+ ExecutorService executor = Executors.newFixedThreadPool(4);
+ List<Callable<BigDecimal>> tasks = new ArrayList<Callable<BigDecimal>>();
+ for (int i=0;i<30;i++){
+ tasks.add(new Callable<BigDecimal>() {
+ @Override
+ public BigDecimal call() throws Exception {
+ List<Member> lst = new ArrayList<Member>();
+ lst.add(new Member("a", 18));
+ lst.add(new Member("b", 12));
+ lst.add(new Member("c", 40));
+ lst.add(new Member("d", 66));
+ lst.add(new Member("e", 72));
+ HashMap<String, Object> map = new HashMap<String,Object>();
+ map.put("members",lst);
+ return new SharedFuncLib().eval("round( sum(members,0B, def(p){ return 2B*p.age; }) ,2)", map, BigDecimal.class);
+ }
+ });
+ }
+
+ try {
+ List<Future<BigDecimal>> futures = executor.invokeAll(tasks);
+ for (Future<BigDecimal> future : futures){
+ System.out.println("res=" + future.get().toString());
+ }
+ } catch (InterruptedException ie){
+ throw new RuntimeException(ie);
+ } catch (ExecutionException ee) {
+ throw new RuntimeException(ee);
+ }
+ }
}
=====================================
src/test/java/org/mvel2/tests/core/MvelArrayTest.java
=====================================
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2005 JBoss Inc
+ *
+ * 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.tests.core;
+
+import java.io.Serializable;
+import java.util.HashMap;
+
+import junit.framework.TestCase;
+import org.mvel2.MVEL;
+import org.mvel2.integration.VariableResolverFactory;
+import org.mvel2.integration.impl.MapVariableResolverFactory;
+import org.mvel2.optimizers.OptimizerFactory;
+
+import static org.mvel2.MVEL.executeExpression;
+
+public class MvelArrayTest extends TestCase {
+
+ private final String biglistTestScript =
+ "list = [];\n" +
+ "list.add(1);\n" +
+ "list.add(2);\n" +
+ "list.add(3);\n" +
+ "list.add(null);\n" + // null!
+ "list.add(5);\n" +
+ "list.add(6);\n" +
+ "list.add(7);\n" +
+ "list.add(8);\n" +
+ "list.add(9);\n" +
+ "list.add(10);\n" +
+ "list.add(11);\n" +
+ "list.add(12);\n" +
+ "java.util.Collections.replaceAll( list, null, 25 );\n" + // replace nulls, with a big value
+ "java.util.Collections.max( list );\n"; // return
+
+ public void testAsmOptimizerDiesWithBigList() {
+
+ OptimizerFactory.setDefaultOptimizer("ASM");
+ Serializable compileExpression = MVEL.compileExpression( biglistTestScript );
+ VariableResolverFactory factory = new MapVariableResolverFactory(new HashMap());
+
+ int actual = (Integer) executeExpression(compileExpression, factory);
+ assertEquals( actual, 25);
+ }
+
+ public void testReflectiveOptimizerWorksFine() {
+
+ OptimizerFactory.setDefaultOptimizer("reflective");
+ Serializable compileExpression = MVEL.compileExpression( biglistTestScript );
+ VariableResolverFactory factory = new MapVariableResolverFactory(new HashMap());
+
+ int actual = (Integer) executeExpression(compileExpression, factory);
+ assertEquals( actual, 25);
+ }
+
+ public void testDynamicOptimizerWorksFine() {
+
+ OptimizerFactory.setDefaultOptimizer("dynamic");
+ Serializable compileExpression = MVEL.compileExpression( biglistTestScript );
+ VariableResolverFactory factory = new MapVariableResolverFactory(new HashMap());
+
+ int actual = (Integer) executeExpression(compileExpression, factory);
+ assertEquals( actual, 25);
+ }
+
+ private final String smallListTestScript =
+ "list = [];\n" +
+ "list.add(1);\n" +
+ "list.add(2);\n" +
+ "list.add(3);\n" +
+ "list.add(null);\n" + // null!
+ "list.add(5);\n" +
+ "list.add(6);\n" +
+ "java.util.Collections.replaceAll( list, null, 25 );\n" + // replace nulls, with a big value
+ "java.util.Collections.max( list );\n"; // return
+
+ public void testAsmOptimizerWithSmallListIsFine() {
+
+ OptimizerFactory.setDefaultOptimizer("ASM");
+ Serializable compileExpression = MVEL.compileExpression( smallListTestScript );
+ VariableResolverFactory factory = new MapVariableResolverFactory(new HashMap());
+
+ int actual = (Integer) executeExpression(compileExpression, factory);
+ assertEquals( actual, 25);
+ }
+}
\ No newline at end of file
=====================================
src/test/java/org/mvel2/tests/core/PrimitiveTypesTest.java
=====================================
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2005 JBoss Inc
+ *
+ * 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.tests.core;
+
+import org.mvel2.MVEL;
+import org.mvel2.ParserConfiguration;
+import org.mvel2.ParserContext;
+
+public class PrimitiveTypesTest extends AbstractTest {
+ public static class FactWithFloat {
+
+ private final float floatValue;
+ private final Float floatObjectValue;
+
+ public FactWithFloat(final float floatValue) {
+ this.floatValue = floatValue;
+ this.floatObjectValue = floatValue;
+ }
+
+ public float getFloatValue() {
+ return floatValue;
+ }
+
+ public Float getFloatObjectValue() {
+ return floatObjectValue;
+ }
+ }
+
+ public void testFloatPrimitive() {
+ ParserConfiguration conf = new ParserConfiguration();
+ conf.addImport( FactWithFloat.class );
+ ParserContext pctx = new ParserContext( conf );
+ pctx.setStrictTypeEnforcement(true);
+ pctx.setStrongTyping(true);
+ pctx.addInput("this", FactWithFloat.class);
+ boolean result = ( Boolean ) MVEL.executeExpression(MVEL.compileExpression("floatValue == 15.1", pctx), new FactWithFloat(15.1f));
+ assertTrue( result );
+ }
+
+ public void testFloat() {
+ ParserConfiguration conf = new ParserConfiguration();
+ conf.addImport( FactWithFloat.class );
+ ParserContext pctx = new ParserContext( conf );
+ pctx.setStrictTypeEnforcement(true);
+ pctx.setStrongTyping(true);
+ pctx.addInput("this", FactWithFloat.class);
+ boolean result = ( Boolean ) MVEL.executeExpression(MVEL.compileExpression("floatObjectValue == 15.1", pctx), new FactWithFloat(15.1f));
+ assertTrue( result );
+ }
+}
=====================================
src/test/java/org/mvel2/tests/core/PropertyAccessTests.java
=====================================
@@ -468,6 +468,41 @@ public class PropertyAccessTests extends AbstractTest {
}
}
+ public final class Data {
+
+ private final Collection<Object> list;
+
+ Data(List<Object> list) {
+ this.list = list;
+ }
+
+ public Collection<Object> getList() {
+ return list;
+ }
+ }
+
+ public void testStaleReflectiveCollectionIsEmptyAccessor() {
+ try
+ {
+ OptimizerFactory.setDefaultOptimizer(OptimizerFactory.SAFE_REFLECTIVE);
+ Serializable getFooExpression = MVEL.compileExpression("list.empty");
+ Map vars = new HashMap();
+
+ // ArrayList -> Colletions.EmptyList
+ assertEquals(true, MVEL.executeExpression(getFooExpression, new Data(new ArrayList<Object>())));
+ assertEquals(true, MVEL.executeExpression(getFooExpression, new Data(Collections.emptyList())));
+
+ // Colletions.EmptyList -> ArrayList
+ assertEquals(true, MVEL.executeExpression(getFooExpression, new Data(Collections.emptyList())));
+ assertEquals(true, MVEL.executeExpression(getFooExpression, new Data(new ArrayList<Object>())));
+ OptimizerFactory.setDefaultOptimizer(OptimizerFactory.DYNAMIC);
+ }
+ finally
+ {
+ OptimizerFactory.setDefaultOptimizer(OptimizerFactory.DYNAMIC);
+ }
+ }
+
public void testMVEL308() {
String expression = "foreach(field: updates.entrySet()) { ctx._target[field.key] = field.value; }";
Serializable compiled = MVEL.compileExpression(expression);
=====================================
src/test/java/org/mvel2/tests/core/res/Member.java
=====================================
@@ -0,0 +1,20 @@
+package org.mvel2.tests.core.res;
+
+public class Member {
+ private String name;
+ private Integer age;
+
+ public Member(String name, Integer age) {
+ super();
+ this.name = name;
+ this.age = age;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Integer getAge() {
+ return age;
+ }
+}
=====================================
src/test/java/org/mvel2/tests/core/res/SharedFuncLib.java
=====================================
@@ -0,0 +1,26 @@
+package org.mvel2.tests.core.res;
+
+import org.mvel2.MVEL;
+import org.mvel2.integration.VariableResolverFactory;
+import org.mvel2.integration.impl.MapVariableResolverFactory;
+
+import java.util.Map;
+
+public class SharedFuncLib {
+
+ final static VariableResolverFactory functionFactory = new MapVariableResolverFactory();
+
+ static {
+ MVEL.eval(
+ "def round(numValue, decPlaces) { return numValue.setScale(decPlaces,java.math.RoundingMode.HALF_UP) };"
+ + "\n"
+ + "def sum(lst, startValue, accFunc){ s = startValue; foreach (i : lst){ s = s + accFunc(i); } return s; };",
+ functionFactory);
+ }
+
+ public <T> T eval(String formula, Map<String, Object> context, Class<T> toType) {
+ VariableResolverFactory myVariableResolverFactory = new MapVariableResolverFactory();
+ myVariableResolverFactory.setNextFactory(functionFactory);
+ return MVEL.eval(formula, context, myVariableResolverFactory, toType);
+ }
+}
View it on GitLab: https://salsa.debian.org/java-team/mvel/compare/502131fe1313f21797f751233cbdf0f274d8c126...1c71b40994133d4a6b9ef94d24433d76357a186a
--
View it on GitLab: https://salsa.debian.org/java-team/mvel/compare/502131fe1313f21797f751233cbdf0f274d8c126...1c71b40994133d4a6b9ef94d24433d76357a186a
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-java-commits/attachments/20190826/f2d8be02/attachment.html>
More information about the pkg-java-commits
mailing list