From ef3b7260ea806892a1c55d12b3e8076af6ec76f2 Mon Sep 17 00:00:00 2001
From: Tomek Kopycki <39048175+tomekfab@users.noreply.github.com>
Date: Mon, 25 Oct 2021 14:57:03 +0200
Subject: [PATCH] Changes from apache/commons-jexl (#2)
* Adjusted the name of the binary and source archives on the download page
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1720781 13f79535-47bb-0310-9956-ffa450edef68
* Downgrade again the findbugs plugin (3.0.0) to work around an encoding issue with the latest release
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1720784 13f79535-47bb-0310-9956-ffa450edef68
* Fixed the links to the previous API documentations
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1721833 13f79535-47bb-0310-9956-ffa450edef68
* Set the release date for JEXL 3.0
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1721953 13f79535-47bb-0310-9956-ffa450edef68
* Changed the version to 3.1-SNAPSHOT
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1721954 13f79535-47bb-0310-9956-ffa450edef68
* Update copyright for 2016 in NOTICE.txt
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1725436 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-186: correcting arithmetic operator overloading caching / discovery
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1726257 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
JEXL-187: added 'continue' and 'break' to syntax reference
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1727856 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Updated changes.xml to reflect JEXL-18{6,7}
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1727858 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Fix typos in doc wrt to {start,end}sWith operators (=^,=$)
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1729855 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Fixing JEXL-188 using more information from regexp (groups)
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1731915 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Fixing JEXL-189 using logical or (and avoiding masking the interruption status)
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1731917 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Updated changes.xml
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1731918 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Updated changes.xml
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1731919 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
FindBugs warning
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1731934 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
FindBugs warning
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1731935 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
FindBugs warning
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1731936 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-191:
When introspecting an object which is a class, also check for fields in the class itself (ie seek static members) rather than in its class.
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1735550 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Get at least line/column info from jexlInfo()
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1735590 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-190:
Modified logic to solve function calls, seeking variables then context, null namespace or arithmetic methods
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1735607 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Checkstyle
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1735971 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-186:
Cleaner arithmetic * operators handling
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1735973 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-192:
Fix antish variable * method evaluation logic
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1736210 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Preparing for 3.0.1 release
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1736215 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Preparing for 3.0.1 release
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1736235 13f79535-47bb-0310-9956-ffa450edef68
* Standard Maven location for assemblies
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1739830 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Forgot to mention side-effect operators (+=, etc...)
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1741404 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Javadoc typo
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1741405 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Fixing JEXL-193, refined handling of interruption (InterruptedException handling & interrupted()), more checks around cancellation (blocks,set/map/array literals), refactored internal Callable, more tests
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1741426 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Fixing JEXL-193 take 2; added a cancellable flag that controls whether JexlException.Cancel are throw when evaluation is interrupted/cancelled.
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1743249 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-195: added AtomicBoolean handling where relevant in JexlArithmetic.
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1743627 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-196: break out of method resolution loop when already failed to resolve through context method
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1745646 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-194:
added overload handling of forEach operator in arithmetic to allow customized iterator, added examples of synchronized arithmetic & context
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1747591 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-198:
added the submitted code & test (thanks Terefang) to trunk
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1747593 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
updated changes.xml & release-notes.txt
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1747630 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Initial code for annotations JEXL-197 - @syntax
The @default part of the specification is not implemented (and probably wont) to avoid incurring a prohibitive evaluation cost);
The JexStatement/Interceptor parts have been simplified with Callable and JexlContext.AnnotationProcessor.
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1751163 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Fixing JEXL-202 by extending parsing check on l-value for all assignment operators
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1751647 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Fixing JEXL-202 typo in error msg
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1751777 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Partial fix for JEXL-201 / JEXL-203 - moved silent/strict/cancellable flags out of interpreter (thus overridable by contextual options)
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1752310 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Blind fix for JEXL-205
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1752311 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Blind fix for JEXL-205 / JEXL-206 - added latches in tests
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1752318 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
JEXL-205; check interruption status within loop to detect cancellation
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1752420 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
JEXL-205; check interruption status within loop to detect cancellation
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1752424 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
JEXL-205 / JEXL-206 - dont interpret cancelled scripts
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1752426 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
JEXL-205 / JEXL-206 - clean up tests
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1752595 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Updated changes and release notes to reflect last fixes
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1752674 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
JEXL-207: split Interpreter in 2 (class was too big), reworked error/exception handling to be more coherent, added tests
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1754746 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
JEXL-207: update changes & release notes
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1754750 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
JEXL-207: update changes & release notes
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1754751 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
JEXL-208: typos in doc
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1754844 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-197: modified grammar to allow '@annotation var...'
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1755110 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-209; added test, updated changes & release notes
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1755186 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-201: added setting options from engine
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1755188 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-201: added setting options from context
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1755189 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Bulk fix for JEXL-210, JEXL-207 and JEXL-197; reverted to a sane version of error handling, exceptions stop script execution, annotation may create a new arithmetic if needed
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1755195 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Javadoc fixes
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1755315 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Typo
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1755433 13f79535-47bb-0310-9956-ffa450edef68
* Restored a constructor in JexlException$Property to preserve the compatibility
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1755545 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Preparing for release
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1756139 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-208: documentation typos
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1758189 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-217: protect tryInvoke in the same try/catch as invoke
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1758541 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-214: remove useless call to fillInStackTrace
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1758577 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-213: add charset(Charset arg) to JexlBuilder, deprecated loader(Charset...) which is a mistake
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1758578 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-215: create default jexlinfo in parse() rather than in multiple places
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1758579 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Restore ThreadLocal as specialization of JexlContext
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1764403 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-219:
Adding explicit white/black listing flag for default behavior of sandbox
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1764408 13f79535-47bb-0310-9956-ffa450edef68
* Add missing license header.
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1770440 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-211:
Protect various executors from null properties in tryInvoke
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1786350 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-216:
Use r/w lock on cache, busy-flag logic on parser (parser is not reentrant, create a temp one if busy)
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1786352 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-211:
Add callable method to JexlExpression interface - breaks compatibility but it is not expected than any codeimplements this interface besides Jexl
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1786353 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Various updates & improvements related to last fixes
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1786354 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Avoiding clirr error
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1786382 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Added clear statement about compatibility break
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1786387 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Removed (wrong) statement about Java7
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1786389 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Reworded compatibility break warning
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1786564 13f79535-47bb-0310-9956-ffa450edef68
* Use the same signature as the overridden method
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1786664 13f79535-47bb-0310-9956-ffa450edef68
* Update dependencies
Allow Clirr to be run from command line
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1786665 13f79535-47bb-0310-9956-ffa450edef68
* Add @since markers
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1786671 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Javadoc typo
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1786897 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Javadoc typo
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1786898 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Removed unused imports
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1786899 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-222:
Improved IndexedType, allow caching of last set/get, expose container class & name
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1786904 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Updated changes & release notes
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1786909 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Updated doc on the risks of implementing JEXL interfaces in user classes
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1786940 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Checkstyle & javadoc
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1786990 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Removed misleading/too broad warning
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1787168 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Add implementation warning
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1787206 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Add implementation warning
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1787207 13f79535-47bb-0310-9956-ffa450edef68
* Removed an unused local variable
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1788574 13f79535-47bb-0310-9956-ffa450edef68
* Removed an unnecessary type cast
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1788575 13f79535-47bb-0310-9956-ffa450edef68
* Inner enums are implicitly static
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1788576 13f79535-47bb-0310-9956-ffa450edef68
* foreach loop
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1788577 13f79535-47bb-0310-9956-ffa450edef68
* Inner enums are implicitly static (more)
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1788578 13f79535-47bb-0310-9956-ffa450edef68
* Minor simplification, the cache is guaranteed to be never null
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1788579 13f79535-47bb-0310-9956-ffa450edef68
* Update copyright to 2017
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1788581 13f79535-47bb-0310-9956-ffa450edef68
* Added the missing @Test annotations in the JUnit 4 tests
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1788590 13f79535-47bb-0310-9956-ffa450edef68
* Moved the @Test annotations to a separate line
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1788591 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Fix & re-added a few commented out tests
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1788925 13f79535-47bb-0310-9956-ffa450edef68
* Fixed a typo in the syntax guide
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1790129 13f79535-47bb-0310-9956-ffa450edef68
* Improved the release notes
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1790528 13f79535-47bb-0310-9956-ffa450edef68
* Replaced 'canceled' with 'cancelled' for consistency
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1790529 13f79535-47bb-0310-9956-ffa450edef68
* Updated the commons.release.version property to 3.1
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1790531 13f79535-47bb-0310-9956-ffa450edef68
* Updated download page in preparation for 3.1 release
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1790532 13f79535-47bb-0310-9956-ffa450edef68
* Refreshed CONTRIBUTING.md and README.md
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1790533 13f79535-47bb-0310-9956-ffa450edef68
* Fortunately CVS is no longer used
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1790540 13f79535-47bb-0310-9956-ffa450edef68
* Updated some version numbers in the site pages
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1790543 13f79535-47bb-0310-9956-ffa450edef68
* Removed unnecessary null checks (reported by Findbugs)
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1790548 13f79535-47bb-0310-9956-ffa450edef68
* Short circuit evaluation in ArrayBuilder.add() (reported by Findbugs)
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1790550 13f79535-47bb-0310-9956-ffa450edef68
* Removed the @inheritDoc tags with no extra information
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1790553 13f79535-47bb-0310-9956-ffa450edef68
* Removed unnecessary fully qualified names
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1790560 13f79535-47bb-0310-9956-ffa450edef68
* Add oraclejdk7 to Travis CI.
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1790595 13f79535-47bb-0310-9956-ffa450edef68
* Set the release date for JEXL 3.1
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1791328 13f79535-47bb-0310-9956-ffa450edef68
* Move to the next version
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1791358 13f79535-47bb-0310-9956-ffa450edef68
* Fix up URL so relative URLs such as Security work
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1792641 13f79535-47bb-0310-9956-ffa450edef68
* (chore) adding commons.module.name to pom
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1797214 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-230: documentation
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1800055 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-226: add ?? operator
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1800127 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-226: add ?? operator
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1800128 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-231: Syntax for accessing List elements is not mentioned in docs
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1800134 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-234: updated JexlArithmetic.start,ends}With to use CharSequence as first param
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1800482 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-227: JexlScriptEngineFactory.getEngineVersion() should return actual version
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1800511 13f79535-47bb-0310-9956-ffa450edef68
* JEXL: added empty and nested set tests
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1800843 13f79535-47bb-0310-9956-ffa450edef68
* JEXL: added null coalescing operator script test
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1800855 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-236: modified arguments class checks & casts, added tests
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1800856 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-224: ObjectContext rewrite based on lower level calls
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1801955 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-224: added logic to allow detecting an overloaded call(...) method in JexlArithmetic usable to perform a function call
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1801956 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-224:
JEXL-225:
new tests, split non-regression test class (IssuesTest) in 3
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1801957 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-224:
JEXL-225:
changes, release notes
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1801958 13f79535-47bb-0310-9956-ffa450edef68
* .travis.yml: remove oraclejdk7 (no longer available)
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1804605 13f79535-47bb-0310-9956-ffa450edef68
* .travis.yml: build pull requests (not only trunk)
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1804606 13f79535-47bb-0310-9956-ffa450edef68
* README.md: add build status badge and remove now redundant license badge
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1804607 13f79535-47bb-0310-9956-ffa450edef68
* README.md: fix travis badge
(side effect: close #4)
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1804623 13f79535-47bb-0310-9956-ffa450edef68
* try to fix build on travis by increasing max memory for tests
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1804627 13f79535-47bb-0310-9956-ffa450edef68
* Fix typos in Javadoc
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1807436 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-240:
Expose the Jexl engine evaluating a script/expression as a thread local;
Make classes functors, ie class(arg) will attempt to call a ctor, a simpler version of new(class, arg);
Fix antish variable used as method/function call;
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1811336 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-240:
Javadoc
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1811338 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-238:
Changed signatures & variable types
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1811339 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Updating changes & release notes for last issues fixes
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1811341 13f79535-47bb-0310-9956-ffa450edef68
* fix java 6 build on travis by using precise distribution
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1811465 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-241:
bad implementation of a double-check lazy initialization, aka item 71
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1812625 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-241:
Updating changes & release notes
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1812627 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Javadoc
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1812991 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-240:
Reverting to not considering class objects as functor (by default).
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1813542 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-243:
First drop of feature control code
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1813544 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-244:
Blind fix, removing static anonymous inner classes
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1814413 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Made permissions an explicit instance in preparation for future / further sandboxing capabilities
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1815813 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-243:
Features, refined version. Allow fine grain on what is syntactically available for both scripts and expressions (and make expressions a subset of script features).
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1816640 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-245:
Better handling of null properties during de-referencing
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1817082 13f79535-47bb-0310-9956-ffa450edef68
* Update commons-parent from 42 to 43.
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1820492 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Reducing FindBugs complaints
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1820566 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-246:
Better error handling or operator overload error, added specific test, changes & release notes updated
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1820568 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-246:
Refined AmbiguousException with severity flag to consider null arguments as being often benign; when benign (aka not severe), AmbiguousException no longer trigger logging
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1820883 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-246:
Javadoc
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1820884 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Javadoc
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1821294 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-246:
3rd times a charm... relaxing ambiguity rules wrt null / object; properly detect JexlArithmetic operator methods
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1821295 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Removing references to junit.framework, replaced by org.junit
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1821466 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Missing @Test
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1821738 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Protect against potential NPE
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1821740 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Log signature collision in debug
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1821777 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Protect against potential NPE
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1821779 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-246:
Improved detection of operator methods that arent overrides
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1821780 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Coverage, added a test on empty array assignment
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1821781 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Coverage, added a test on method overloads / object parameters / null arguments
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1821782 13f79535-47bb-0310-9956-ffa450edef68
* JEXL:
Coverage, added a test / call debug method
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1821783 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-248:
Fixed left-value check during assignment parsing, added test
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1821784 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-248:
Fixed left-value check during assignment parsing, added test
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1821785 13f79535-47bb-0310-9956-ffa450edef68
* JEXL-246:
Quiesced down logging, was missing check on actual signature diff
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jexl/trunk@1821853 13f79535-47bb-0310-9956-ffa450edef68
Co-authored-by: Emmanuel Bourg
Co-authored-by: Gary D. Gregory
Co-authored-by: Henri Biestro
Co-authored-by: Sebastian Bazley
Co-authored-by: henrib
Co-authored-by: Rob Tompkins
Co-authored-by: Pascal Schumacher
Co-authored-by: Bruno P. Kinoshita
---
.travis.yml | 22 +-
CONTRIBUTING.md | 40 +-
NOTICE.txt | 2 +-
README.md | 201 +--
RELEASE-NOTES.txt | 110 +-
pom.xml | 52 +-
src/{main => }/assembly/bin.xml | 0
src/{main => }/assembly/src.xml | 0
.../apache/commons/jexl3/JexlArithmetic.java | 233 ++-
.../org/apache/commons/jexl3/JexlBuilder.java | 91 +-
.../org/apache/commons/jexl3/JexlContext.java | 65 +-
.../org/apache/commons/jexl3/JexlEngine.java | 186 +-
.../apache/commons/jexl3/JexlException.java | 163 +-
.../apache/commons/jexl3/JexlExpression.java | 24 +-
.../apache/commons/jexl3/JexlFeatures.java | 474 +++++
.../apache/commons/jexl3/JexlOperator.java | 124 +-
.../org/apache/commons/jexl3/JexlScript.java | 2 +
.../org/apache/commons/jexl3/JxltEngine.java | 113 +-
.../apache/commons/jexl3/ObjectContext.java | 55 +-
.../commons/jexl3/internal/ArrayBuilder.java | 2 +-
.../commons/jexl3/internal/Closure.java | 18 +-
.../commons/jexl3/internal/Debugger.java | 82 +-
.../apache/commons/jexl3/internal/Engine.java | 317 ++--
.../commons/jexl3/internal/Interpreter.java | 928 +++++-----
.../jexl3/internal/InterpreterBase.java | 301 ++++
.../commons/jexl3/internal/Operators.java | 64 +-
.../apache/commons/jexl3/internal/Script.java | 115 +-
.../commons/jexl3/internal/ScriptVisitor.java | 496 ++++++
.../commons/jexl3/internal/SoftCache.java | 211 +++
.../apache/commons/jexl3/internal/Source.java | 94 +
.../jexl3/internal/TemplateEngine.java | 32 +-
.../jexl3/internal/TemplateScript.java | 10 +-
.../introspection/AbstractExecutor.java | 3 -
.../introspection/ArrayListWrapper.java | 3 -
.../introspection/BooleanGetExecutor.java | 11 +-
.../internal/introspection/ClassMap.java | 63 +-
.../introspection/DuckGetExecutor.java | 12 +-
.../introspection/DuckSetExecutor.java | 11 +-
.../internal/introspection/IndexedType.java | 123 +-
.../internal/introspection/Introspector.java | 26 +-
.../introspection/ListGetExecutor.java | 4 +-
.../introspection/ListSetExecutor.java | 2 +-
.../introspection/MapGetExecutor.java | 9 +-
.../introspection/MapSetExecutor.java | 6 +-
.../internal/introspection/MethodKey.java | 346 ++--
.../internal/introspection/Permissions.java | 48 +-
.../introspection/SandboxUberspect.java | 33 -
.../internal/introspection/Uberspect.java | 86 +-
.../jexl3/introspection/JexlSandbox.java | 113 +-
.../org/apache/commons/jexl3/package.html | 2 +
.../commons/jexl3/parser/ASTAnnotation.java | 54 +
.../commons/jexl3/parser/ASTArrayLiteral.java | 2 -
.../commons/jexl3/parser/ASTJexlScript.java | 46 +-
.../commons/jexl3/parser/ASTJxltLiteral.java | 1 -
.../commons/jexl3/parser/ASTMapLiteral.java | 2 -
.../jexl3/parser/ASTNumberLiteral.java | 2 +-
.../commons/jexl3/parser/ASTSetLiteral.java | 2 -
.../jexl3/parser/ASTStringLiteral.java | 4 -
.../jexl3/parser/FeatureController.java | 229 +++
.../apache/commons/jexl3/parser/JexlNode.java | 60 +-
.../commons/jexl3/parser/JexlParser.java | 260 ++-
.../commons/jexl3/parser/NumberParser.java | 32 +-
.../apache/commons/jexl3/parser/Parser.jjt | 62 +-
.../commons/jexl3/parser/ParserVisitor.java | 8 +-
.../scripting/JexlScriptEngineFactory.java | 6 +-
src/site/site.xml | 6 +-
src/site/xdoc/changes.xml | 158 +-
src/site/xdoc/download_jexl.xml | 30 +-
src/site/xdoc/reference/examples.xml | 2 +-
src/site/xdoc/reference/jsr223.xml | 2 +-
src/site/xdoc/reference/syntax.xml | 1542 ++++++++++-------
.../apache/commons/jexl3/AnnotationTest.java | 275 +++
.../apache/commons/jexl3/AntishCallTest.java | 174 ++
.../commons/jexl3/ArithmeticOperatorTest.java | 78 +
.../apache/commons/jexl3/ArithmeticTest.java | 110 +-
.../apache/commons/jexl3/ArrayAccessTest.java | 25 +
.../org/apache/commons/jexl3/AssignTest.java | 1 +
.../org/apache/commons/jexl3/CaptureLog.java | 137 ++
.../commons/jexl3/ContextNamespaceTest.java | 48 +
.../apache/commons/jexl3/ExceptionTest.java | 121 +-
.../apache/commons/jexl3/FeaturesTest.java | 290 ++++
.../java/org/apache/commons/jexl3/Foo.java | 9 +-
.../java/org/apache/commons/jexl3/IfTest.java | 96 +-
.../org/apache/commons/jexl3/IssuesTest.java | 784 +--------
.../apache/commons/jexl3/IssuesTest100.java | 814 +++++++++
.../apache/commons/jexl3/IssuesTest200.java | 350 ++++
.../org/apache/commons/jexl3/JXLTTest.java | 13 +-
.../apache/commons/jexl3/JexlEvalContext.java | 38 +-
.../org/apache/commons/jexl3/JexlTest.java | 47 +-
.../org/apache/commons/jexl3/LambdaTest.java | 1 +
.../org/apache/commons/jexl3/MethodTest.java | 117 +-
.../org/apache/commons/jexl3/PragmaTest.java | 29 +-
.../commons/jexl3/PropertyAccessTest.java | 123 +-
.../commons/jexl3/PublicFieldsTest.java | 40 +-
.../apache/commons/jexl3/ReadonlyContext.java | 6 +-
.../commons/jexl3/ScriptCallableTest.java | 357 +++-
.../org/apache/commons/jexl3/ScriptTest.java | 37 +-
.../apache/commons/jexl3/SetLiteralTest.java | 13 +
.../apache/commons/jexl3/SideEffectTest.java | 227 +++
.../commons/jexl3/SynchronizedArithmetic.java | 256 +++
.../commons/jexl3/SynchronizedContext.java | 74 +
.../jexl3/SynchronizedOverloadsTest.java | 84 +
.../commons/jexl3/examples/ArrayTest.java | 3 +-
.../jexl3/examples/MethodPropertyTest.java | 5 +-
.../apache/commons/jexl3/examples/Output.java | 5 +-
.../apache/commons/jexl3/internal/Util.java | 14 +-
.../internal/introspection/MethodKeyTest.java | 73 +-
.../jexl3/introspection/SandboxTest.java | 36 +-
.../apache/commons/jexl3/junit/Asserter.java | 28 +-
.../commons/jexl3/junit/AsserterTest.java | 8 +-
.../commons/jexl3/parser/ParserTest.java | 50 +-
.../JexlScriptEngineOptionalTest.java | 20 +-
.../jexl3/scripting/JexlScriptEngineTest.java | 104 +-
src/test/resources/log4j.xml | 34 -
src/test/scripts/testAdd.jexl | 18 +
115 files changed, 9737 insertions(+), 3473 deletions(-)
rename src/{main => }/assembly/bin.xml (100%)
rename src/{main => }/assembly/src.xml (100%)
create mode 100644 src/main/java/org/apache/commons/jexl3/JexlFeatures.java
create mode 100644 src/main/java/org/apache/commons/jexl3/internal/InterpreterBase.java
create mode 100644 src/main/java/org/apache/commons/jexl3/internal/ScriptVisitor.java
create mode 100644 src/main/java/org/apache/commons/jexl3/internal/SoftCache.java
create mode 100644 src/main/java/org/apache/commons/jexl3/internal/Source.java
create mode 100644 src/main/java/org/apache/commons/jexl3/parser/ASTAnnotation.java
create mode 100644 src/main/java/org/apache/commons/jexl3/parser/FeatureController.java
create mode 100644 src/test/java/org/apache/commons/jexl3/AnnotationTest.java
create mode 100644 src/test/java/org/apache/commons/jexl3/AntishCallTest.java
create mode 100644 src/test/java/org/apache/commons/jexl3/CaptureLog.java
create mode 100644 src/test/java/org/apache/commons/jexl3/FeaturesTest.java
create mode 100644 src/test/java/org/apache/commons/jexl3/IssuesTest100.java
create mode 100644 src/test/java/org/apache/commons/jexl3/IssuesTest200.java
create mode 100644 src/test/java/org/apache/commons/jexl3/SynchronizedArithmetic.java
create mode 100644 src/test/java/org/apache/commons/jexl3/SynchronizedContext.java
create mode 100644 src/test/java/org/apache/commons/jexl3/SynchronizedOverloadsTest.java
delete mode 100644 src/test/resources/log4j.xml
create mode 100644 src/test/scripts/testAdd.jexl
diff --git a/.travis.yml b/.travis.yml
index 0a0f062a8..f48251075 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,15 +1,27 @@
+# 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.
+
language: java
sudo: false
+dist: precise
+
jdk:
- openjdk6
- openjdk7
- oraclejdk8
-# only build trunk
-branches:
- only:
- - trunk
-
after_success:
- mvn clean test jacoco:report coveralls:report
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index e3ba801ea..8485c81c5 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -51,47 +51,65 @@ Getting Started
+ Make sure you have a [JIRA account](https://issues.apache.org/jira/).
+ Make sure you have a [GitHub account](https://github.com/signup/free).
+ If you're planning to implement a new feature it makes sense to discuss you're changes on the [dev list](https://commons.apache.org/mail-lists.html) first. This way you can make sure you're not wasting your time on something that isn't considered to be in Apache Commons JEXL's scope.
-+ Submit a ticket for your issue, assuming one does not already exist.
++ Submit a [Jira Ticket][jira] for your issue, assuming one does not already exist.
+ Clearly describe the issue including steps to reproduce when it is a bug.
+ Make sure you fill in the earliest version that you know has the issue.
-+ Fork the repository on GitHub.
++ Find the corresponding [repository on GitHub](https://github.com/apache/?query=commons-),
+[fork](https://help.github.com/articles/fork-a-repo/) and check out your forked repository.
Making Changes
--------------
-+ Create a topic branch from where you want to base your work (this is usually the master/trunk branch).
++ Create a _topic branch_ for your isolated work.
+ * Usually you should base your branch on the `master` or `trunk` branch.
+ * A good topic branch name can be the JIRA bug id plus a keyword, e.g. `JEXL-123-InputStream`.
+ * If you have submitted multiple JIRA issues, try to maintain separate branches and pull requests.
+ Make commits of logical units.
+ * Make sure your commit messages are meaningful and in the proper format. Your commit message should contain the key of the JIRA issue.
+ * e.g. `JEXL-123: Close input stream earlier`
+ Respect the original code style:
+ Only use spaces for indentation.
- + Create minimal diffs - disable on save actions like reformat source code or organize imports. If you feel the source code should be reformatted create a separate PR for this change.
- + Check for unnecessary whitespace with git diff --check before committing.
-+ Make sure your commit messages are in the proper format. Your commit message should contain the key of the JIRA issue.
-+ Make sure you have added the necessary tests for your changes.
+ + Create minimal diffs - disable _On Save_ actions like _Reformat Source Code_ or _Organize Imports_. If you feel the source code should be reformatted create a separate PR for this change first.
+ + Check for unnecessary whitespace with `git diff` -- check before committing.
++ Make sure you have added the necessary tests for your changes, typically in `src/test/java`.
+ Run all the tests with `mvn clean verify` to assure nothing else was accidentally broken.
Making Trivial Changes
----------------------
+The JIRA tickets are used to generate the changelog for the next release.
+
For changes of a trivial nature to comments and documentation, it is not always necessary to create a new ticket in JIRA.
In this case, it is appropriate to start the first line of a commit with '(doc)' instead of a ticket number.
+
Submitting Changes
------------------
-+ Sign the [Contributor License Agreement][cla] if you haven't already.
++ Sign and submit the Apache [Contributor License Agreement][cla] if you haven't already.
+ * Note that small patches & typical bug fixes do not require a CLA as
+ clause 5 of the [Apache License](https://www.apache.org/licenses/LICENSE-2.0.html#contributions)
+ covers them.
+ Push your changes to a topic branch in your fork of the repository.
-+ Submit a pull request to the repository in the apache organization.
++ Submit a _Pull Request_ to the corresponding repository in the `apache` organization.
+ * Verify _Files Changed_ shows only your intended changes and does not
+ include additional files like `target/*.class`
+ Update your JIRA ticket and include a link to the pull request in the ticket.
+If you prefer to not use GitHub, then you can instead use
+`git format-patch` (or `svn diff`) and attach the patch file to the JIRA issue.
+
+
Additional Resources
--------------------
+ [Contributing patches](https://commons.apache.org/patches.html)
-+ [Apache Commons JEXL JIRA project page](https://issues.apache.org/jira/browse/JEXL)
++ [Apache Commons JEXL JIRA project page][jira]
+ [Contributor License Agreement][cla]
+ [General GitHub documentation](https://help.github.com/)
+ [GitHub pull request documentation](https://help.github.com/send-pull-requests/)
+ [Apache Commons Twitter Account](https://twitter.com/ApacheCommons)
-+ #apachecommons IRC channel on freenode.org
++ `#apache-commons` IRC channel on `irc.freenode.net`
[cla]:https://www.apache.org/licenses/#clas
+[jira]:https://issues.apache.org/jira/browse/JEXL
diff --git a/NOTICE.txt b/NOTICE.txt
index f80f9dd2a..388baaab9 100644
--- a/NOTICE.txt
+++ b/NOTICE.txt
@@ -1,5 +1,5 @@
Apache Commons JEXL
-Copyright 2001-2015 The Apache Software Foundation
+Copyright 2001-2017 The Apache Software Foundation
This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).
diff --git a/README.md b/README.md
index 3c5bac0cc..f30cd0d04 100644
--- a/README.md
+++ b/README.md
@@ -1,98 +1,103 @@
-
-
-Apache Commons JEXL
-===================
-
-The Apache Commons JEXL library is an implementation of the JSTL Expression Language with extensions.
-
-Documentation
--------------
-
-More information can be found on the [homepage](https://commons.apache.org/proper/commons-jexl).
-The [JavaDoc](https://commons.apache.org/proper/commons-jexl/javadocs/api-release) can be browsed.
-Questions related to the usage of Apache Commons JEXL should be posted to the [user mailing list][ml].
-
-Where can I get the latest release?
------------------------------------
-You can download source and binaries from our [download page](https://commons.apache.org/proper/commons-jexl/download_jexl.cgi).
-
-Alternatively you can pull it from the central Maven repositories:
-
-```xml
-
- org.apache.commons
- commons-jexl3
- 3.0
-
-```
-
-Contributing
-------------
-
-We accept PRs via github. The [developer mailing list][ml] is the main channel of communication for contributors.
-There are some guidelines which will make applying PRs easier for us:
-+ No tabs! Please use spaces for indentation.
-+ Respect the code style.
-+ Create minimal diffs - disable on save actions like reformat source code or organize imports. If you feel the source code should be reformatted create a separate PR for this change.
-+ Provide JUnit tests for your changes and make sure your changes don't break any existing tests by running ```mvn clean test```.
-
-If you plan to contribute on a regular basis, please consider filing a [contributor license agreement](https://www.apache.org/licenses/#clas).
-You can learn more about contributing via GitHub in our [contribution guidelines](CONTRIBUTING.md).
-
-License
--------
-Code is under the [Apache Licence v2](https://www.apache.org/licenses/LICENSE-2.0.txt).
-
-Donations
----------
-You like Apache Commons JEXL? Then [donate back to the ASF](https://www.apache.org/foundation/contributing.html) to support the development.
-
-Additional Resources
---------------------
-
-+ [Apache Commons Homepage](https://commons.apache.org/)
-+ [Apache Bugtracker (JIRA)](https://issues.apache.org/jira/)
-+ [Apache Commons Twitter Account](https://twitter.com/ApacheCommons)
-+ #apachecommons IRC channel on freenode.org
-
-[ml]:https://commons.apache.org/mail-lists.html
+
+
+Apache Commons JEXL
+===================
+
+[![Build Status](https://travis-ci.org/apache/commons-jexl.svg?branch=trunk)](https://travis-ci.org/apache/commons-jexl)
+[![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.apache.commons/commons-jexl3/badge.svg)](https://maven-badges.herokuapp.com/maven-central/org.apache.commons/commons-jexl3/)
+
+The Apache Commons JEXL library is an implementation of the JSTL Expression Language with extensions.
+
+Documentation
+-------------
+
+More information can be found on the [Apache Commons JEXL homepage](https://commons.apache.org/proper/commons-jexl).
+The [JavaDoc](https://commons.apache.org/proper/commons-jexl/javadocs/api-release) can be browsed.
+Questions related to the usage of Apache Commons JEXL should be posted to the [user mailing list][ml].
+
+Where can I get the latest release?
+-----------------------------------
+You can download source and binaries from our [download page](https://commons.apache.org/proper/commons-jexl/download_jexl.cgi).
+
+Alternatively you can pull it from the central Maven repositories:
+
+```xml
+
+ org.apache.commons
+ commons-jexl3
+ 3.1
+
+```
+
+Contributing
+------------
+
+We accept Pull Requests via GitHub. The [developer mailing list][ml] is the main channel of communication for contributors.
+There are some guidelines which will make applying PRs easier for us:
++ No tabs! Please use spaces for indentation.
++ Respect the code style.
++ Create minimal diffs - disable on save actions like reformat source code or organize imports. If you feel the source code should be reformatted create a separate PR for this change.
++ Provide JUnit tests for your changes and make sure your changes don't break any existing tests by running ```mvn clean test```.
+
+If you plan to contribute on a regular basis, please consider filing a [contributor license agreement](https://www.apache.org/licenses/#clas).
+You can learn more about contributing via GitHub in our [contribution guidelines](CONTRIBUTING.md).
+
+License
+-------
+This code is under the [Apache Licence v2](https://www.apache.org/licenses/LICENSE-2.0).
+
+See the `NOTICE.txt` file for required notices and attributions.
+
+Donations
+---------
+You like Apache Commons JEXL? Then [donate back to the ASF](https://www.apache.org/foundation/contributing.html) to support the development.
+
+Additional Resources
+--------------------
+
++ [Apache Commons Homepage](https://commons.apache.org/)
++ [Apache Issue Tracker (JIRA)](https://issues.apache.org/jira/browse/JEXL)
++ [Apache Commons Twitter Account](https://twitter.com/ApacheCommons)
++ `#apache-commons` IRC channel on `irc.freenode.org`
+
+[ml]:https://commons.apache.org/mail-lists.html
diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt
index 229360ba6..5dd65e994 100644
--- a/RELEASE-NOTES.txt
+++ b/RELEASE-NOTES.txt
@@ -1,6 +1,6 @@
Apache Commons JEXL
- Version 3.0
+ Version 3.2
Release Notes
@@ -19,6 +19,114 @@ Its goal is to expose scripting features usable by technical operatives or consu
http://commons.apache.org/jexl/
+========================================================================================================================
+Release 3.2
+========================================================================================================================
+
+Version 3.2 is a minor release.
+
+New Features in 3.2:
+====================
+
+* JEXL-248: Allow range subexpression as an array property assignment identifier
+* JEXL-243: Allow restricting available features in Script/Expressions
+* JEXL-238: Restrict getLiteralClass to a Number for NumberLiterals
+* JEXL-237: Ability to restrict usage of certain names when declaring local variables
+* JEXL-236: Support CharSequence in size(), empty() and contains() operators
+* JEXL-234: Extend application of operators startsWith and endsWith from String to CharSequence types
+* JEXL-226: add ?? operator support
+* JEXL-224: The ability to overload call() operator in customized JexlArithmetic implementation
+* JEXL-212: Restrict usage of assignment statements in JexlExpression
+
+Bugs Fixed in 3.2:
+==================
+
+* JEXL-246: Intermittent ambiguous method invocation when processing assignOverload
+* JEXL-245: Engine in strict mode fails to fail on unsolvable variables or properties
+* JEXL-244: Webapp classloader memory leaks
+* JEXL-241: NPE when script containing string interpolation executed in multiple threads
+* JEXL-240: Unable to invoke a call operator using antish style variable resolution
+* JEXL-231: Syntax for accessing List elements is not mentioned in docs
+* JEXL-230: List literal is not mentioned in docs
+* JEXL-227: JexlScriptEngineFactory.getEngineVersion() should return actual version
+* JEXL-225: Incorrect invoking methods with ObjectContext
+
+There are no other changes.
+
+
+========================================================================================================================
+Release 3.1
+========================================================================================================================
+
+Version 3.1 is a minor release.
+
+Compatibility with previous releases
+====================================
+Version 3.1 is binary compatible with 3.0.
+
+However it is not source compatible, this release does break source compatibility by adding methods to existing
+interfaces; these interfaces are however not expected to be implemented by code external to the JEXL project.
+This compatibility break should remain hypothetical. It is nevertheless possible and we are sorry if it causes problems
+to any of you.
+If you encounter this issue, besides continuing using JEXL 3.0, your code likely delegates method calls to JEXL3 objects
+and you shall be able to continue doing so with these new methods.
+
+The three interfaces and methods are:
+
+1 - 'isCancellable()' in interface org.apache.commons.jexl3.JexlEngine$Options
+2 - 'callable(JexlContext)' in interface org.apache.commons.jexl3.JexlExpression
+3 - 'getPragmas()' in interface org.apache.commons.jexl3.JxltEngine$Template
+
+What's new in 3.1:
+==================
+* Annotations syntax (@annotation) and processing capabilities.
+ Annotations in JEXL are 'meta-statements'; they allow to wrap the execution of the JEXL statement in a user provided
+ caller; a typical example would be: ""@synchronized(x) x.someMethod();". Annotations may be declared with zero or more
+ parameters. Annotation processing is implemented by providing a JexlContext.AnnotationProcessor; its processAnnotation
+ method will call the annotated statement encapsulated in a Callable. Annotation arguments are evaluated and passed
+ as arguments to processAnnotation.
+* Better support for script execution options, error handling and cancelling.
+* All operators can be overloaded.
+
+New Features in 3.1:
+====================
+* JEXL-222: The ability to declare indexed property getter/setter in customized JexlArithmetic implementation
+* JEXL-219: Blacklist by default in sandbox
+* JEXL-216: Improve parsing concurrency in multithreaded environment
+* JEXL-211: Add callable method to JexlExpression interface
+* JEXL-201: Allow Interpreter to use live values from JexlEngine.Option interface implemented by JexlContext
+* JEXL-198: JxltEngine Template does not expose pragmas
+* JEXL-197: Add annotations
+* JEXL-194: Allow synchronization on iterableValue in foreach statement
+
+Bugs Fixed in 3.1:
+==================
+* JEXL-221: Sporadic undefined property error caused by NPE at MapGetExecutor.tryInvoke()
+* JEXL-217: Interpreter.getAttribute() raises exception in non-strict mode when cached property resolver is used
+* JEXL-215: JexlEngine.createInfo() is redundantly called when debug and caching is enabled leading to sub-optimal performance
+* JEXL-214: Redundant call of fillInStackTrace() in JexlEngine.createInfo() ?
+* JEXL-213: rename JexlBuilder.loader(Charset arg) to JexlBuilder.charset(Charset arg)
+* JEXL-210: The way to cancel script execution with an error
+* JEXL-209: Unsolvable function/method '>.(...)'
+* JEXL-208: Documentation typos/inconsistencies
+* JEXL-207: Inconsistent error handling
+* JEXL-206: testCallableCancel() test hangs sporadically
+* JEXL-205: testCancelForever() is not terminated properly as 'Fixed'
+* JEXL-204: Script is not interrupted by a method call throwing Exception
+* JEXL-203: JexlArithmetic.options() diverts Interpreter to use default implementation of JexlArithmetic instead of custom one
+* JEXL-202: Detect invalid assignment operator usage with non-assignable l-value during script parsing
+* JEXL-196: Script execution hangs while calling method with one argument without parameter
+* JEXL-195: Support for AtomicBoolean in logical expressions
+* JEXL-193: InterruptedException is swallowed in function call in silent and non-strict mode
+* JEXL-192: Invalid return type when expected result is null
+* JEXL-191: Jexl3 unsolvable property exception when using enum
+* JEXL-190: local function within context is not resolved if function resolver class without namespace is specified
+* JEXL-189: Possible bug in Interpreter.isCancelled()
+* JEXL-188: Possible bug in JexlArithmetic.isFloatingPointNumber()
+* JEXL-187: Jexl Syntax doc does not mention 'continue' and 'break' operators
+* JEXL-186: Performance regression in arithmetic operations compared to JEXL 2.1
+
+
========================================================================================================================
Release 3.0
========================================================================================================================
diff --git a/pom.xml b/pom.xml
index 2579be8fd..eb5910531 100644
--- a/pom.xml
+++ b/pom.xml
@@ -19,16 +19,16 @@
org.apache.commonscommons-parent
- 39
+ 434.0.0org.apache.commonscommons-jexl3
- 3.0-SNAPSHOT
+ 3.2-SNAPSHOTApache Commons JEXL2001The Apache Commons JEXL library is an implementation of the JSTL Expression Language with extensions.
- http://commons.apache.org/jexl/
+ http://commons.apache.org/proper/commons-jexl/jira
@@ -42,11 +42,11 @@
-
- people.apache.org
- Apache Commons JEXL
- scp://people.apache.org/www/commons.apache.org/jexl
-
+
+ apache.website
+ Apache Commons Site
+ scm:svn:https://svn.apache.org/repos/infra/websites/production/commons/content/proper/commons-net/
+
@@ -115,8 +115,9 @@
1.61.6
- jexl
- 3.0
+ jexl3
+ org.apache.commons.jexl3
+ 3.1jexlhttps://svn.apache.org/repos/infra/websites/production/commons/content/proper/commons-jexlsite-content
@@ -124,6 +125,7 @@
RC12.1.1
+ commons-jexl-${commons.release.version}commons-jexl-${commons.release.2.version}commons-jexl-${commons.release.3.version}Legacy
@@ -131,7 +133,7 @@
JEXL12310479
- 2.16
+ 2.176.13
@@ -148,14 +150,16 @@
**/*Test.java
+
+ -Xmx64mmaven-assembly-plugin
- src/main/assembly/bin.xml
- src/main/assembly/src.xml
+ src/assembly/bin.xml
+ src/assembly/src.xmlgnucommons-jexl-${project.version}
@@ -244,6 +248,18 @@
+
+
+ org.codehaus.mojo
+ clirr-maven-plugin
+ 2.8
+
+
+ org/apache/commons/jexl3/parser/**
+ org/apache/commons/jexl3/internal/**
+
+
+ org.apache.rat
@@ -270,7 +286,7 @@
org.apache.maven.pluginsmaven-changes-plugin
- 2.11
+ 2.12.1${basedir}/src/site/xdoc/changes.xml
@@ -297,7 +313,7 @@
org.codehaus.mojofindbugs-maven-plugin
- 3.0.2
+ 3.0.4${basedir}/src/main/config/findbugs-exclude-filter.xmltrue
@@ -308,7 +324,7 @@
org.apache.maven.pluginsmaven-pmd-plugin
- 3.5
+ 3.7${maven.compiler.target}
@@ -327,7 +343,7 @@
org.codehaus.mojoclirr-maven-plugin
-
+ 2.8org/apache/commons/jexl3/parser/**
@@ -346,4 +362,4 @@
-
\ No newline at end of file
+
diff --git a/src/main/assembly/bin.xml b/src/assembly/bin.xml
similarity index 100%
rename from src/main/assembly/bin.xml
rename to src/assembly/bin.xml
diff --git a/src/main/assembly/src.xml b/src/assembly/src.xml
similarity index 100%
rename from src/main/assembly/src.xml
rename to src/assembly/src.xml
diff --git a/src/main/java/org/apache/commons/jexl3/JexlArithmetic.java b/src/main/java/org/apache/commons/jexl3/JexlArithmetic.java
index 638349b80..2e6114eaa 100644
--- a/src/main/java/org/apache/commons/jexl3/JexlArithmetic.java
+++ b/src/main/java/org/apache/commons/jexl3/JexlArithmetic.java
@@ -25,13 +25,15 @@
import java.math.MathContext;
import java.util.Collection;
import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Perform arithmetic, implements JexlOperator methods.
- *
+ *
*
This is the class to derive to implement new operator behaviors.
- *
+ *
*
The 5 base arithmetic operators (+, - , *, /, %) follow the same evaluation rules regarding their arguments.
*
*
If both are null, result is 0
@@ -45,9 +47,9 @@
*
*
*
- *
+ *
* Note that the only exception thrown by JexlArithmetic is and must be ArithmeticException.
- *
+ *
* @see JexlOperator
* @since 2.0
*/
@@ -82,7 +84,7 @@ public static class NullOperand extends ArithmeticException {}
/**
* Creates a JexlArithmetic.
- *
+ *
* @param astrict whether this arithmetic is strict or lenient
*/
public JexlArithmetic(boolean astrict) {
@@ -91,7 +93,7 @@ public JexlArithmetic(boolean astrict) {
/**
* Creates a JexlArithmetic.
- *
+ *
* @param astrict whether this arithmetic is lenient or strict
* @param bigdContext the math context instance to use for +,-,/,*,% operations on big decimals.
* @param bigdScale the scale used for big decimals.
@@ -104,29 +106,59 @@ public JexlArithmetic(boolean astrict, MathContext bigdContext, int bigdScale) {
/**
* Apply options to this arithmetic which eventually may create another instance.
- *
+ * @see #createWithOptions(boolean, java.math.MathContext, int)
+ *
* @param options the {@link JexlEngine.Options} to use
* @return an arithmetic with those options set
*/
public JexlArithmetic options(JexlEngine.Options options) {
- boolean ostrict = options.isStrictArithmetic() == null
- ? this.strict
- : options.isStrictArithmetic();
+ Boolean ostrict = options.isStrictArithmetic();
+ if (ostrict == null) {
+ ostrict = isStrict();
+ }
MathContext bigdContext = options.getArithmeticMathContext();
if (bigdContext == null) {
- bigdContext = mathContext;
+ bigdContext = getMathContext();
}
int bigdScale = options.getArithmeticMathScale();
if (bigdScale == Integer.MIN_VALUE) {
- bigdScale = mathScale;
+ bigdScale = getMathScale();
}
- if ((ostrict != this.strict)
- || bigdScale != this.mathScale
- || bigdContext != this.mathContext) {
- return new JexlArithmetic(ostrict, bigdContext, bigdScale);
- } else {
- return this;
+ if (ostrict != isStrict()
+ || bigdScale != getMathScale()
+ || bigdContext != getMathContext()) {
+ return createWithOptions(ostrict, bigdContext, bigdScale);
}
+ return this;
+ }
+
+ /**
+ * Apply options to this arithmetic which eventually may create another instance.
+ * @see #createWithOptions(boolean, java.math.MathContext, int)
+ *
+ * @param context the context that may extend {@link JexlEngine.Options} to use
+ * @return a new arithmetic instance or this
+ * @since 3.1
+ */
+ public JexlArithmetic options(JexlContext context) {
+ return context instanceof JexlEngine.Options
+ ? options((JexlEngine.Options) context)
+ : this;
+ }
+
+ /**
+ * Creates a JexlArithmetic instance.
+ * Called by options(...) method when another instance of the same class of arithmetic is required.
+ * @see #options(org.apache.commons.jexl3.JexlEngine.Options)
+ *
+ * @param astrict whether this arithmetic is lenient or strict
+ * @param bigdContext the math context instance to use for +,-,/,*,% operations on big decimals.
+ * @param bigdScale the scale used for big decimals.
+ * @return default is a new JexlArithmetic instance
+ * @since 3.1
+ */
+ protected JexlArithmetic createWithOptions(boolean astrict, MathContext bigdContext, int bigdScale) {
+ return new JexlArithmetic(astrict, bigdContext, bigdScale);
}
/**
@@ -136,7 +168,7 @@ public JexlArithmetic options(JexlEngine.Options options) {
public interface Uberspect {
/**
* Checks whether this uberspect has overloads for a given operator.
- *
+ *
* @param operator the operator to check
* @return true if an overload exists, false otherwise
*/
@@ -144,7 +176,7 @@ public interface Uberspect {
/**
* Gets the most specific method for an operator.
- *
+ *
* @param operator the operator
* @param arg the arguments
* @return the most specific method or null if no specific override could be found
@@ -154,9 +186,9 @@ public interface Uberspect {
/**
* Helper interface used when creating an array literal.
- *
+ *
*
The default implementation creates an array and attempts to type it strictly.
- *
+ *
*
*
If all objects are of the same type, the array returned will be an array of that same type
*
If all objects are Numbers, the array returned will be an array of Numbers
@@ -168,14 +200,14 @@ public interface ArrayBuilder {
/**
* Adds a literal to the array.
- *
+ *
* @param value the item to add
*/
void add(Object value);
/**
* Creates the actual "array" instance.
- *
+ *
* @param extended true when the last argument is ', ...'
* @return the array
*/
@@ -184,7 +216,7 @@ public interface ArrayBuilder {
/**
* Called by the interpreter when evaluating a literal array.
- *
+ *
* @param size the number of elements in the array
* @return the array builder
*/
@@ -199,14 +231,14 @@ public ArrayBuilder arrayBuilder(int size) {
public interface SetBuilder {
/**
* Adds a literal to the set.
- *
+ *
* @param value the item to add
*/
void add(Object value);
/**
* Creates the actual "set" instance.
- *
+ *
* @return the set
*/
Object create();
@@ -214,7 +246,7 @@ public interface SetBuilder {
/**
* Called by the interpreter when evaluating a literal set.
- *
+ *
* @param size the number of elements in the set
* @return the array builder
*/
@@ -229,7 +261,7 @@ public SetBuilder setBuilder(int size) {
public interface MapBuilder {
/**
* Adds a new entry to the map.
- *
+ *
* @param key the map entry key
* @param value the map entry value
*/
@@ -237,7 +269,7 @@ public interface MapBuilder {
/**
* Creates the actual "map" instance.
- *
+ *
* @return the map
*/
Object create();
@@ -245,7 +277,7 @@ public interface MapBuilder {
/**
* Called by the interpreter when evaluating a literal map.
- *
+ *
* @param size the number of elements in the map
* @return the map builder
*/
@@ -256,7 +288,7 @@ public MapBuilder mapBuilder(int size) {
/**
* Creates a literal range.
*
The default implementation only accepts integers and longs.
- *
+ *
* @param from the included lower bound value (null if none)
* @param to the included upper bound value (null if none)
* @return the range as an iterable
@@ -276,7 +308,7 @@ public Iterable> createRange(Object from, Object to) throws ArithmeticExceptio
/**
* Checks whether this JexlArithmetic instance
* strictly considers null as an error when used as operand unexpectedly.
- *
+ *
* @return true if strict, false if lenient
*/
public boolean isStrict() {
@@ -285,7 +317,7 @@ public boolean isStrict() {
/**
* The MathContext instance used for +,-,/,*,% operations on big decimals.
- *
+ *
* @return the math context
*/
public MathContext getMathContext() {
@@ -294,7 +326,7 @@ public MathContext getMathContext() {
/**
* The BigDecimal scale used for comparison and coericion operations.
- *
+ *
* @return the scale
*/
public int getMathScale() {
@@ -303,7 +335,7 @@ public int getMathScale() {
/**
* Ensure a big decimal is rounded by this arithmetic scale and rounding mode.
- *
+ *
* @param number the big decimal to round
* @return the rounded big decimal
*/
@@ -318,7 +350,7 @@ protected BigDecimal roundBigDecimal(final BigDecimal number) {
/**
* The result of +,/,-,*,% when both operands are null.
- *
+ *
* @return Integer(0) if lenient
* @throws ArithmeticException if strict
*/
@@ -331,7 +363,7 @@ protected Object controlNullNullOperands() {
/**
* Throw a NPE if arithmetic is strict.
- *
+ *
* @throws ArithmeticException if strict
*/
protected void controlNullOperand() {
@@ -342,8 +374,11 @@ protected void controlNullOperand() {
/**
* The float regular expression pattern.
+ *
+ * The decimal and exponent parts are optional and captured allowing to determine if the number is a real
+ * by checking whether one of these 2 capturing groups is not empty.
*/
- public static final Pattern FLOAT_PATTERN = Pattern.compile("^[+-]?\\d*(\\.\\d*)?([eE]?[+-]?\\d*)?$");
+ public static final Pattern FLOAT_PATTERN = Pattern.compile("^[+-]?\\d*(\\.\\d*)?([eE][+-]?\\d+)?$");
/**
* Test if the passed value is a floating point number, i.e. a float, double
@@ -356,19 +391,11 @@ protected boolean isFloatingPointNumber(Object val) {
if (val instanceof Float || val instanceof Double) {
return true;
}
- if (val instanceof String) {
- String str = (String) val;
- for(int c = 0; c < str.length(); ++c) {
- char ch = str.charAt(c);
- // we need at least a marker that says it is a float
- if (ch == '.' || ch == 'E' || ch == 'e') {
- return FLOAT_PATTERN.matcher(str).matches();
- }
- // and it must be a number
- if (ch != '+' && ch != '-' && ch < '0' && ch > '9') {
- break;
- }
- }
+ if (val instanceof CharSequence) {
+ final Matcher m = FLOAT_PATTERN.matcher((CharSequence) val);
+ // first group is decimal, second is exponent;
+ // one of them must exist hence start({1,2}) >= 0
+ return m.matches() && (m.start(1) >= 0 || m.start(2) >= 0);
}
return false;
}
@@ -414,7 +441,7 @@ public Number narrow(Number original) {
/**
* Whether we consider the narrow class as a potential candidate for narrowing the source.
- *
+ *
* @param narrow the target narrow class
* @param source the orginal source class
* @return true if attempt to narrow source to target is accepted
@@ -425,7 +452,7 @@ protected boolean narrowAccept(Class> narrow, Class> source) {
/**
* Given a Number, return back the value attempting to narrow it to a target class.
- *
+ *
* @param original the original number
* @param narrow the attempted target class
* @return the narrowed number or the source if no narrowing was possible
@@ -502,7 +529,7 @@ public Number narrowNumber(Number original, Class> narrow) {
* if either arguments is a BigInteger, no narrowing will occur
* if either arguments is a Long, no narrowing to Integer will occur
*
- *
+ *
* @param lhs the left hand side operand that lead to the bigi result
* @param rhs the right hand side operand that lead to the bigi result
* @param bigi the BigInteger to narrow
@@ -554,21 +581,23 @@ protected Number narrowBigDecimal(Object lhs, Object rhs, BigDecimal bigd) {
/**
* Replace all numbers in an arguments array with the smallest type that will fit.
- *
+ *
* @param args the argument array
* @return true if some arguments were narrowed and args array is modified,
* false if no narrowing occurred and args array has not been modified
*/
public boolean narrowArguments(Object[] args) {
boolean narrowed = false;
- for (int a = 0; a < args.length; ++a) {
- Object arg = args[a];
- if (arg instanceof Number) {
- Number narg = (Number) arg;
- Number narrow = narrow(narg);
- if (!narg.equals(narrow)) {
- args[a] = narrow;
- narrowed = true;
+ if (args != null) {
+ for (int a = 0; a < args.length; ++a) {
+ Object arg = args[a];
+ if (arg instanceof Number) {
+ Number narg = (Number) arg;
+ Number narrow = narrow(narg);
+ if (!narg.equals(narrow)) {
+ args[a] = narrow;
+ narrowed = true;
+ }
}
}
}
@@ -581,7 +610,7 @@ public boolean narrowArguments(Object[] args) {
* If any numeric add fails on coercion to the appropriate type,
* treat as Strings and do concatenation.
*
- *
+ *
* @param left left argument
* @param right right argument
* @return left + right.
@@ -624,7 +653,7 @@ public Object add(Object left, Object right) {
/**
* Divide the left value by the right.
- *
+ *
* @param left left argument
* @param right right argument
* @return left / right
@@ -665,7 +694,7 @@ public Object divide(Object left, Object right) {
/**
* left value modulo right.
- *
+ *
* @param left left argument
* @param right right argument
* @return left % right
@@ -697,16 +726,16 @@ public Object mod(Object left, Object right) {
// otherwise treat as integers
BigInteger l = toBigInteger(left);
BigInteger r = toBigInteger(right);
- BigInteger result = l.mod(r);
if (BigInteger.ZERO.equals(r)) {
throw new ArithmeticException("%");
}
+ BigInteger result = l.mod(r);
return narrowBigInteger(left, right, result);
}
/**
* Multiply the left value by the right.
- *
+ *
* @param left left argument
* @param right right argument
* @return left * right.
@@ -737,7 +766,7 @@ public Object multiply(Object left, Object right) {
/**
* Subtract the right value from the left.
- *
+ *
* @param left left argument
* @param right right argument
* @return left - right.
@@ -768,7 +797,7 @@ public Object subtract(Object left, Object right) {
/**
* Negates a value (unary minus for numbers).
- *
+ *
* @param val the value to negate
* @return the negated value
*/
@@ -791,6 +820,8 @@ public Object negate(Object val) {
return (byte) -((Byte) val);
} else if (val instanceof Boolean) {
return ((Boolean) val) ? Boolean.FALSE : Boolean.TRUE;
+ } else if (val instanceof AtomicBoolean) {
+ return ((AtomicBoolean) val).get() ? Boolean.FALSE : Boolean.TRUE;
}
throw new ArithmeticException("Object negation:(" + val + ")");
}
@@ -799,7 +830,7 @@ public Object negate(Object val) {
* Test if left contains right (right matches/in left).
*
Beware that this method arguments are the opposite of the operator arguments.
* 'x in y' means 'y contains x'.
- *
+ *
* @param container the container
* @param value the value
* @return test result or null if there is no arithmetic solution
@@ -817,7 +848,7 @@ public Boolean contains(Object container, Object value) {
if (container instanceof java.util.regex.Pattern) {
return ((java.util.regex.Pattern) container).matcher(value.toString()).matches();
}
- if (container instanceof String) {
+ if (container instanceof CharSequence) {
return value.toString().matches(container.toString());
}
// try contains on map key
@@ -854,8 +885,8 @@ public Boolean endsWith(Object left, Object right) {
// we know both aren't null, therefore L != R
return false;
}
- if (left instanceof String) {
- return ((String) left).endsWith(toString(right));
+ if (left instanceof CharSequence) {
+ return (toString(left)).endsWith(toString(right));
}
return null;
}
@@ -876,25 +907,25 @@ public Boolean startsWith(Object left, Object right) {
// we know both aren't null, therefore L != R
return false;
}
- if (left instanceof String) {
- return ((String) left).startsWith(toString(right));
+ if (left instanceof CharSequence) {
+ return (toString(left)).startsWith(toString(right));
}
return null;
}
/**
- * Check for emptyness of various types: Number, Collection, Array, Map, String.
+ * Check for emptiness of various types: Number, Collection, Array, Map, String.
*
- * @param object the object to check the emptyness of
- * @return the boolean or null of there is no arithmetic solution
+ * @param object the object to check the emptiness of
+ * @return the boolean or null if there is no arithmetic solution
*/
public Boolean isEmpty(Object object) {
if (object instanceof Number) {
double d = ((Number) object).doubleValue();
return Double.isNaN(d) || d == 0.d ? Boolean.TRUE : Boolean.FALSE;
}
- if (object instanceof String) {
- return "".equals(object) ? Boolean.TRUE : Boolean.FALSE;
+ if (object instanceof CharSequence) {
+ return ((CharSequence) object).length() == 0 ? Boolean.TRUE : Boolean.FALSE;
}
if (object.getClass().isArray()) {
return Array.getLength(object) == 0 ? Boolean.TRUE : Boolean.FALSE;
@@ -916,8 +947,8 @@ public Boolean isEmpty(Object object) {
* @return the size of object or null if there is no arithmetic solution
*/
public Integer size(Object object) {
- if (object instanceof String) {
- return ((String) object).length();
+ if (object instanceof CharSequence) {
+ return ((CharSequence) object).length();
}
if (object.getClass().isArray()) {
return Array.getLength(object);
@@ -933,7 +964,7 @@ public Integer size(Object object) {
/**
* Performs a bitwise and.
- *
+ *
* @param left the left operand
* @param right the right operator
* @return left & right
@@ -946,7 +977,7 @@ public Object and(Object left, Object right) {
/**
* Performs a bitwise or.
- *
+ *
* @param left the left operand
* @param right the right operator
* @return left | right
@@ -959,7 +990,7 @@ public Object or(Object left, Object right) {
/**
* Performs a bitwise xor.
- *
+ *
* @param left the left operand
* @param right the right operator
* @return left ^ right
@@ -972,7 +1003,7 @@ public Object xor(Object left, Object right) {
/**
* Performs a bitwise complement.
- *
+ *
* @param val the operand
* @return ~val
*/
@@ -983,7 +1014,7 @@ public Object complement(Object val) {
/**
* Performs a logical not.
- *
+ *
* @param val the operand
* @return !val
*/
@@ -993,7 +1024,7 @@ public Object not(Object val) {
/**
* Performs a comparison.
- *
+ *
* @param left the left operand
* @param right the right operator
* @param operator the operator
@@ -1156,6 +1187,8 @@ public boolean toBoolean(Object val) {
} else if (val instanceof Number) {
double number = toDouble(val);
return !Double.isNaN(number) && number != 0.d;
+ } else if (val instanceof AtomicBoolean) {
+ return ((AtomicBoolean) val).get();
} else if (val instanceof String) {
String strval = val.toString();
return strval.length() > 0 && !"false".equals(strval);
@@ -1194,6 +1227,8 @@ public int toInteger(Object val) {
return Integer.parseInt((String) val);
} else if (val instanceof Boolean) {
return ((Boolean) val) ? 1 : 0;
+ } else if (val instanceof AtomicBoolean) {
+ return ((AtomicBoolean) val).get() ? 1 : 0;
} else if (val instanceof Character) {
return ((Character) val);
}
@@ -1232,6 +1267,8 @@ public long toLong(Object val) {
}
} else if (val instanceof Boolean) {
return ((Boolean) val) ? 1L : 0L;
+ } else if (val instanceof AtomicBoolean) {
+ return ((AtomicBoolean) val).get() ? 1L : 0L;
} else if (val instanceof Character) {
return ((Character) val);
}
@@ -1268,6 +1305,8 @@ public BigInteger toBigInteger(Object val) {
return BigInteger.valueOf(((Number) val).longValue());
} else if (val instanceof Boolean) {
return BigInteger.valueOf(((Boolean) val) ? 1L : 0L);
+ } else if (val instanceof AtomicBoolean) {
+ return BigInteger.valueOf(((AtomicBoolean) val).get() ? 1L : 0L);
} else if (val instanceof String) {
String string = (String) val;
if ("".equals(string)) {
@@ -1309,6 +1348,8 @@ public BigDecimal toBigDecimal(Object val) {
return roundBigDecimal(new BigDecimal(val.toString(), getMathContext()));
} else if (val instanceof Boolean) {
return BigDecimal.valueOf(((Boolean) val) ? 1. : 0.);
+ } else if (val instanceof AtomicBoolean) {
+ return BigDecimal.valueOf(((AtomicBoolean) val).get() ? 1L : 0L);
} else if (val instanceof String) {
String string = (String) val;
if ("".equals(string)) {
@@ -1327,7 +1368,7 @@ public BigDecimal toBigDecimal(Object val) {
* Coerce to a primitive double.
*
Double.NaN, null and empty string coerce to zero.
*
Boolean false is 0, true is 1.
- *
+ *
* @param val value to coerce.
* @return The double coerced value.
* @throws ArithmeticException if val is null and mode is strict or if coercion is not possible
@@ -1344,6 +1385,8 @@ public double toDouble(Object val) {
return Double.parseDouble(String.valueOf(val));
} else if (val instanceof Boolean) {
return ((Boolean) val) ? 1. : 0.;
+ } else if (val instanceof AtomicBoolean) {
+ return ((AtomicBoolean) val).get() ? 1. : 0.;
} else if (val instanceof String) {
String string = (String) val;
if ("".equals(string)) {
@@ -1399,7 +1442,7 @@ public final Object bitwiseAnd(Object lhs, Object rhs) {
/**
* Use or overload or() instead.
- *
+ *
* @param lhs left hand side
* @param rhs right hand side
* @return lhs | rhs
@@ -1413,7 +1456,7 @@ public final Object bitwiseOr(Object lhs, Object rhs) {
/**
* Use or overload xor() instead.
- *
+ *
* @param lhs left hand side
* @param rhs right hand side
* @return lhs ^ rhs
@@ -1427,7 +1470,7 @@ public final Object bitwiseXor(Object lhs, Object rhs) {
/**
* Use or overload not() instead.
- *
+ *
* @param arg argument
* @return !arg
* @see JexlArithmetic#not
@@ -1440,7 +1483,7 @@ public final Object logicalNot(Object arg) {
/**
* Use or overload contains() instead.
- *
+ *
* @param lhs left hand side
* @param rhs right hand side
* @return contains(rhs, lhs)
diff --git a/src/main/java/org/apache/commons/jexl3/JexlBuilder.java b/src/main/java/org/apache/commons/jexl3/JexlBuilder.java
index 16914c772..7332f576b 100644
--- a/src/main/java/org/apache/commons/jexl3/JexlBuilder.java
+++ b/src/main/java/org/apache/commons/jexl3/JexlBuilder.java
@@ -27,16 +27,16 @@
/**
* Configure and builds a JexlEngine.
- *
+ *
*
The setSilent and setStrict methods allow to fine-tune an engine instance behavior
* according to various error control needs. The strict flag tells the engine when and if null as operand is
* considered an error, the silent flag tells the engine what to do with the error
* (log as warning or throw exception).
- *
+ *
*
*
When "silent" & "not-strict":
*
0 & null should be indicators of "default" values so that even in an case of error,
- * something meaningfull can still be inferred; may be convenient for configurations.
+ * something meaningful can still be inferred; may be convenient for configurations.
*
*
*
When "silent" & "strict":
@@ -46,7 +46,7 @@
* Use case could be configuration with no implicit values or defaults.
*
*
- *
When "not-silent" & "not-stict":
+ *
When "not-silent" & "not-strict":
*
The error control grain is roughly on par with JEXL 1.0
*
*
When "not-silent" & "strict":
@@ -85,6 +85,9 @@ public class JexlBuilder {
/** Whether error messages will carry debugging information. */
private Boolean debug = null;
+ /** Whether interrupt throws JexlException.Cancel. */
+ private Boolean cancellable = null;
+
/** The map of 'prefix:function' to object implementing the namespaces. */
private Map namespaces = null;
@@ -103,9 +106,12 @@ public class JexlBuilder {
/** The class loader. */
private ClassLoader loader = null;
+ /** The features. */
+ private JexlFeatures features = null;
+
/**
* Sets the JexlUberspect instance the engine will use.
- *
+ *
* @param u the uberspect
* @return this builder
*/
@@ -122,7 +128,7 @@ public JexlUberspect uberspect() {
/**
* Sets the JexlUberspect strategy strategy the engine will use.
*
This is ignored if the uberspect has been set.
- *
+ *
* @param rs the strategy
* @return this builder
*/
@@ -138,7 +144,7 @@ public JexlUberspect.ResolverStrategy strategy() {
/**
* Sets the JexlArithmetic instance the engine will use.
- *
+ *
* @param a the arithmetic
* @return this builder
*/
@@ -154,7 +160,7 @@ public JexlArithmetic arithmetic() {
/**
* Sets the sandbox the engine will use.
- *
+ *
* @param box the sandbox
* @return this builder
*/
@@ -168,9 +174,26 @@ public JexlSandbox sandbox() {
return this.sandbox;
}
+ /**
+ * Sets the features the engine will use as a base by default.
+ *
Note that the script flag will be ignored; the engine will be able to parse expressions and scripts.
+ *
Note also that these will apply to template expressions and scripts.
+ * @param f the features
+ * @return this builder
+ */
+ public JexlBuilder features(JexlFeatures f) {
+ this.features = f;
+ return this;
+ }
+
+ /** @return the features */
+ public JexlFeatures features() {
+ return this.features;
+ }
+
/**
* Sets the o.a.c.Log instance to use.
- *
+ *
* @param l the logger
* @return this builder
*/
@@ -186,7 +209,7 @@ public Log logger() {
/**
* Sets the class loader to use.
- *
+ *
* @param l the class loader
* @return this builder
*/
@@ -202,11 +225,24 @@ public ClassLoader loader() {
/**
* Sets the charset to use.
- *
+ *
* @param arg the charset
* @return this builder
+ * @deprecated since 3.1 use {@link #charset(Charset)} instead
*/
+ @Deprecated
public JexlBuilder loader(Charset arg) {
+ return charset(arg);
+ }
+
+ /**
+ * Sets the charset to use.
+ *
+ * @param arg the charset
+ * @return this builder
+ * @since 3.1
+ */
+ public JexlBuilder charset(Charset arg) {
this.charset = arg;
return this;
}
@@ -218,7 +254,7 @@ public Charset charset() {
/**
* Sets whether the engine will throw JexlException during evaluation when an error is triggered.
- *
+ *
* @param flag true means no JexlException will occur, false allows them
* @return this builder
*/
@@ -235,7 +271,7 @@ public Boolean silent() {
/**
* Sets whether the engine considers unknown variables, methods, functions and constructors as errors or
* evaluates them as null.
- *
+ *
* @param flag true means strict error reporting, false allows them to be evaluated as null
* @return this builder
*/
@@ -251,7 +287,7 @@ public Boolean strict() {
/**
* Sets whether the engine will report debugging information when error occurs.
- *
+ *
* @param flag true implies debug is on, false implies debug is off.
* @return this builder
*/
@@ -265,6 +301,27 @@ public Boolean debug() {
return this.debug;
}
+ /**
+ * Sets the engine behavior upon interruption: throw an JexlException.Cancel or terminates the current evaluation
+ * and return null.
+ *
+ * @param flag true implies the engine throws the exception, false makes the engine return null.
+ * @return this builder
+ * @since 3.1
+ */
+ public JexlBuilder cancellable(boolean flag) {
+ this.cancellable = flag;
+ return this;
+ }
+
+ /**
+ * @return the cancellable information flag
+ * @since 3.1
+ */
+ public Boolean cancellable() {
+ return this.cancellable;
+ }
+
/**
* Sets the default namespaces map the engine will use.
*
@@ -286,7 +343,7 @@ public Boolean debug() {
*
*
Note that the JexlContext is also used to try to solve top-level namespaces. This allows ObjectContext
* derived instances to call methods on the wrapped object.
- *
+ *
* @param ns the map of namespaces
* @return this builder
*/
@@ -306,7 +363,7 @@ public Map namespaces() {
* Sets the expression cache size the engine will use.
*
The cache will contain at most size expressions of at most cacheThreshold length.
* Note that all JEXL caches are held through SoftReferences and may be garbage-collected.
- *
+ *
* @param size if not strictly positive, no cache is used.
* @return this builder
*/
@@ -328,7 +385,7 @@ public int cache() {
* bypass the cache.
*
It is expected that a "long" script will be parsed once and its reference kept
* around in user-space structures; the jexl expression cache has no added-value in this case.
- *
+ *
* @param length if not strictly positive, the value is silently replaced by the default value (64).
* @return this builder
*/
diff --git a/src/main/java/org/apache/commons/jexl3/JexlContext.java b/src/main/java/org/apache/commons/jexl3/JexlContext.java
index d47fe2fd3..0ab91944e 100644
--- a/src/main/java/org/apache/commons/jexl3/JexlContext.java
+++ b/src/main/java/org/apache/commons/jexl3/JexlContext.java
@@ -17,28 +17,30 @@
package org.apache.commons.jexl3;
+import java.util.concurrent.Callable;
+
/**
* Manages variables which can be referenced in a JEXL expression.
- *
+ *
*
JEXL variable names in their simplest form are 'java-like' identifiers.
* JEXL also considers 'ant' inspired variables expressions as valid.
* For instance, the expression 'x.y.z' is an 'antish' variable and will be resolved as a whole by the context,
* i.e. using the key "x.y.z". This proves to be useful to solve "fully qualified class names".
- *
+ *
*
The interpreter variable resolution algorithm will try the different sequences of identifiers till it finds
* one that exists in the context; if "x" is an object known in the context (JexlContext.has("x") returns true),
* "x.y" will not be looked up in the context but will most likely refer to "x.getY()".
- *
+ *
*
Note that JEXL may use '$jexl' and '$ujexl' variables for internal purpose; setting or getting those
* variables may lead to unexpected results unless specified otherwise.
- *
+ *
* @since 1.0
*/
public interface JexlContext {
/**
* Gets the value of a variable.
- *
+ *
* @param name the variable's name
* @return the value
*/
@@ -46,7 +48,7 @@ public interface JexlContext {
/**
* Sets the value of a variable.
- *
+ *
* @param name the variable's name
* @param value the variable's value
*/
@@ -54,27 +56,27 @@ public interface JexlContext {
/**
* Checks whether a variable is defined in this context.
- *
+ *
*
A variable may be defined with a null value; this method checks whether the
* value is null or if the variable is undefined.
- *
+ *
* @param name the variable's name
* @return true if it exists, false otherwise
*/
boolean has(String name);
/**
- * This interface declares how to resolve a namespace from its name; it is used by the interpreter during
- * evalutation.
- *
+ * A marker interface of the JexlContext that declares how to resolve a namespace from its name;
+ * it is used by the interpreter during evaluation.
+ *
*
In JEXL, a namespace is an object that serves the purpose of encapsulating functions; for instance,
* the "math" namespace would be the proper object to expose functions like "log(...)", "sinus(...)", etc.
- *
+ *
* In expressions like "ns:function(...)", the resolver is called with resolveNamespace("ns").
- *
+ *
*
JEXL itself reserves 'jexl' and 'ujexl' as namespaces for internal purpose; resolving those may lead to
* unexpected results.
- *
+ *
* @since 3.0
*/
interface NamespaceResolver {
@@ -88,8 +90,9 @@ interface NamespaceResolver {
}
/**
- * Namespace type that allows creating an instance to delegate namespace methods calls to.
- *
+ * A marker interface of the JexlContext, NamespaceFunctor allows creating an instance
+ * to delegate namespace methods calls to.
+ *
*
The functor is created once during the lifetime of a script evaluation.
*/
interface NamespaceFunctor {
@@ -102,14 +105,14 @@ interface NamespaceFunctor {
}
/**
- * A marker interface that indicates the interpreter to put this context in the JexlEngine thread local context
- * instance during evaluation.
+ * A marker interface of the JexlContext that indicates the interpreter to put this context
+ * in the JexlEngine thread local context instance during evaluation.
* This allows user functions or methods to access the context during a call.
* Note that the usual caveats wrt using thread local apply (caching/leaking references, etc.); in particular,
* keeping a reference to such a context is to be considered with great care and caution.
* It should also be noted that sharing such a context between threads should implicate synchronizing variable
* accessing the implementation class.
- *
+ *
* @see JexlEngine#setThreadContext(JexlContext.ThreadLocal)
* @see JexlEngine#getThreadContext()
*/
@@ -117,4 +120,28 @@ interface ThreadLocal extends JexlContext {
// no specific method
}
+ /**
+ * A marker interface of the JexlContext that allows to process annotations.
+ * It is used by the interpreter during evaluation to execute annotation evaluations.
+ *
If the JexlContext is not an instance of an AnnotationProcessor, encountering an annotation will generate
+ * an error or a warning depending on the engine strictness.
+ * @since 3.1
+ */
+ interface AnnotationProcessor {
+ /**
+ * Processes an annotation.
+ *
All annotations are processed through this method; the statement 'call' is to be performed within
+ * the processAnnotation method. The implementation must perform the call explicitly.
+ *
The arguments and the statement must not be referenced or cached for longer than the duration
+ * of the processAnnotation call.
+ *
+ * @param name the annotation name
+ * @param args the arguments of the annotation, evaluated as arguments of this call
+ * @param statement the statement that was annotated; the processor should invoke this statement 'call' method
+ * @return the result of statement.call()
+ * @throws Exception if annotation processing fails
+ */
+ Object processAnnotation(String name, Object[] args, Callable
- *
+ *
*
Note that methods that evaluate expressions may throw unchecked exceptions;
* The {@link JexlException} are thrown in "non-silent" mode but since these are
* RuntimeException, user-code should catch them wherever most appropriate.
- *
+ *
* @since 2.0
*/
public abstract class JexlEngine {
- /** A marker for invocation failures in tryInvoke. */
- public static final Object TRY_FAILED = new Object() {
+ /** A marker singleton for invocation failures in tryInvoke. */
+ public static final Object TRY_FAILED = new FailObject();
+
+ /** The failure marker class. */
+ private static final class FailObject {
+ /**
+ * Default ctor.
+ */
+ private FailObject() {}
+
@Override
public String toString() {
return "tryExecute failed";
@@ -58,27 +66,38 @@ public String toString() {
* The thread local context.
*/
protected static final java.lang.ThreadLocal CONTEXT =
- new java.lang.ThreadLocal() {
- @Override
- protected JexlContext.ThreadLocal initialValue() {
- return null;
- }
- };
+ new java.lang.ThreadLocal();
/**
* Accesses the current thread local context.
- *
+ *
* @return the context or null
*/
public static JexlContext.ThreadLocal getThreadContext() {
return CONTEXT.get();
}
+ /**
+ * The thread local engine.
+ */
+ protected static final java.lang.ThreadLocal ENGINE =
+ new java.lang.ThreadLocal();
+
+ /**
+ * Accesses the current thread local engine.
+ *
Advanced: you should only use this to retrieve the engine within a method/ctor called through the evaluation
+ * of a script/expression.
+ * @return the engine or null
+ */
+ public static JexlEngine getThreadEngine() {
+ return ENGINE.get();
+ }
+
/**
* Sets the current thread local context.
*
This should only be used carefully, for instance when re-evaluating a "stored" script that requires a
* given Namespace resolver. Remember to synchronize access if context is shared between threads.
- *
+ *
* @param tls the thread local context to set
*/
public static void setThreadContext(JexlContext.ThreadLocal tls) {
@@ -93,13 +112,13 @@ public interface Options {
/**
* The charset used for parsing.
- *
+ *
* @return the charset
*/
Charset getCharset();
/**
* Sets whether the engine will throw a {@link JexlException} when an error is encountered during evaluation.
- *
+ *
* @return true if silent, false otherwise
*/
Boolean isSilent();
@@ -107,37 +126,57 @@ public interface Options {
/**
* Checks whether the engine considers unknown variables, methods, functions and constructors as errors or
* evaluates them as null.
- *
+ *
* @return true if strict, false otherwise
*/
Boolean isStrict();
/**
* Checks whether the arithmetic triggers errors during evaluation when null is used as an operand.
- *
+ *
* @return true if strict, false otherwise
*/
Boolean isStrictArithmetic();
+ /**
+ * Whether evaluation will throw JexlException.Cancel (true) or return null (false) when interrupted.
+ * @return true when cancellable, false otherwise
+ * @since 3.1
+ */
+ Boolean isCancellable();
+
/**
* The MathContext instance used for +,-,/,*,% operations on big decimals.
- *
+ *
* @return the math context
*/
MathContext getArithmeticMathContext();
/**
* The BigDecimal scale used for comparison and coercion operations.
- *
+ *
* @return the scale
*/
int getArithmeticMathScale();
}
+ /** Default features. */
+ public static final JexlFeatures DEFAULT_FEATURES = new JexlFeatures();
+
/**
- * An empty/static/non-mutable JexlContext used instead of null context.
+ * An empty/static/non-mutable JexlContext singleton used instead of null context.
*/
- public static final JexlContext EMPTY_CONTEXT = new JexlContext() {
+ public static final JexlContext EMPTY_CONTEXT = new EmptyContext();
+
+ /**
+ * The empty context class, public for instrospection.
+ */
+ public static final class EmptyContext implements JexlContext {
+ /**
+ * Default ctor.
+ */
+ private EmptyContext() {}
+
@Override
public Object get(String name) {
return null;
@@ -155,9 +194,19 @@ public void set(String name, Object value) {
};
/**
- * An empty/static/non-mutable JexlNamesapce used instead of null namespace.
+ * An empty/static/non-mutable JexlNamespace singleton used instead of null namespace.
*/
- public static final JexlContext.NamespaceResolver EMPTY_NS = new JexlContext.NamespaceResolver() {
+ public static final JexlContext.NamespaceResolver EMPTY_NS = new EmptyNamespaceResolver();
+
+ /**
+ * The empty/static/non-mutable JexlNamespace class, public for instrospection.
+ */
+ public static final class EmptyNamespaceResolver implements JexlContext.NamespaceResolver {
+ /**
+ * Default ctor.
+ */
+ private EmptyNamespaceResolver() {}
+
@Override
public Object resolveNamespace(String name) {
return null;
@@ -169,58 +218,66 @@ public Object resolveNamespace(String name) {
/**
* Gets the charset used for parsing.
- *
+ *
* @return the charset
*/
public abstract Charset getCharset();
/**
* Gets this engine underlying {@link JexlUberspect}.
- *
+ *
* @return the uberspect
*/
public abstract JexlUberspect getUberspect();
/**
* Gets this engine underlying {@link JexlArithmetic}.
- *
+ *
* @return the arithmetic
*/
public abstract JexlArithmetic getArithmetic();
/**
* Checks whether this engine is in debug mode.
- *
+ *
* @return true if debug is on, false otherwise
*/
public abstract boolean isDebug();
/**
* Checks whether this engine throws JexlException during evaluation.
- *
+ *
* @return true if silent, false (default) otherwise
*/
public abstract boolean isSilent();
/**
- * Checks whether the engine considers unknown variables, methods, functions and constructors as errors.
- *
+ * Checks whether this engine considers unknown variables, methods, functions and constructors as errors.
+ *
* @return true if strict, false otherwise
*/
public abstract boolean isStrict();
+ /**
+ * Checks whether this engine will throw JexlException.Cancel (true) or return null (false) when interrupted
+ * during an execution.
+ *
+ * @return true if cancellable, false otherwise
+ */
+ public abstract boolean isCancellable();
+
/**
* Sets the class loader used to discover classes in 'new' expressions.
*
This method is not thread safe; it should be called as an optional step of the JexlEngine
* initialization code before expression creation & evaluation.
- *
+ *
* @param loader the class loader to use
*/
public abstract void setClassLoader(ClassLoader loader);
/**
* Creates a new {@link JxltEngine} instance using this engine.
- *
+ *
* @return a JEXL Template engine
*/
public JxltEngine createJxltEngine() {
@@ -229,7 +286,7 @@ public JxltEngine createJxltEngine() {
/**
* Creates a new {@link JxltEngine} instance using this engine.
- *
+ *
* @param noScript whether the JxltEngine only allows Jexl expressions or scripts
* @return a JEXL Template engine
*/
@@ -239,7 +296,7 @@ public JxltEngine createJxltEngine(boolean noScript) {
/**
* Creates a new instance of {@link JxltEngine} using this engine.
- *
+ *
* @param noScript whether the JxltEngine only allows JEXL expressions or scripts
* @param cacheSize the number of expressions in this cache, default is 256
* @param immediate the immediate template expression character, default is '$'
@@ -264,10 +321,22 @@ public JxltEngine createJxltEngine(boolean noScript) {
*/
public abstract JexlExpression createExpression(JexlInfo info, String expression);
+ /**
+ * Creates a JexlExpression from a String containing valid JEXL syntax.
+ * This method parses the expression which must contain either a reference or an expression.
+ *
+ * @param expression A String containing valid JEXL syntax
+ * @return An {@link JexlExpression} which can be evaluated using a {@link JexlContext}
+ * @throws JexlException if there is a problem parsing the script
+ */
+ public final JexlExpression createExpression(String expression) {
+ return createExpression(null, expression);
+ }
/**
* Creates a JexlScript from a String containing valid JEXL syntax.
* This method parses the script and validates the syntax.
*
+ * @param features A set of features that will be enforced during parsing
* @param info An info structure to carry debugging information if needed
* @param source A string containing valid JEXL syntax
* @param names The script parameter names used during parsing; a corresponding array of arguments containing
@@ -275,18 +344,21 @@ public JxltEngine createJxltEngine(boolean noScript) {
* @return A {@link JexlScript} which can be executed using a {@link JexlContext}
* @throws JexlException if there is a problem parsing the script
*/
- public abstract JexlScript createScript(JexlInfo info, String source, String[] names);
+ public abstract JexlScript createScript(JexlFeatures features, JexlInfo info, String source, String[] names);
/**
- * Creates a JexlExpression from a String containing valid JEXL syntax.
- * This method parses the expression which must contain either a reference or an expression.
+ * Creates a JexlScript from a String containing valid JEXL syntax.
+ * This method parses the script and validates the syntax.
*
- * @param expression A String containing valid JEXL syntax
- * @return An {@link JexlExpression} which can be evaluated using a {@link JexlContext}
+ * @param info An info structure to carry debugging information if needed
+ * @param source A string containing valid JEXL syntax
+ * @param names The script parameter names used during parsing; a corresponding array of arguments containing
+ * values should be used during evaluation
+ * @return A {@link JexlScript} which can be executed using a {@link JexlContext}
* @throws JexlException if there is a problem parsing the script
*/
- public final JexlExpression createExpression(String expression) {
- return createExpression(null, expression);
+ public final JexlScript createScript(JexlInfo info, String source, String[] names) {
+ return createScript(null, null, source, names);
}
/**
@@ -298,7 +370,7 @@ public final JexlExpression createExpression(String expression) {
* @throws JexlException if there is a problem parsing the script.
*/
public final JexlScript createScript(String scriptText) {
- return createScript(null, scriptText, null);
+ return createScript(null, null, scriptText, null);
}
/**
@@ -312,7 +384,7 @@ public final JexlScript createScript(String scriptText) {
* @throws JexlException if there is a problem parsing the script
*/
public final JexlScript createScript(String scriptText, String... names) {
- return createScript(null, scriptText, names);
+ return createScript(null, null, scriptText, names);
}
/**
@@ -324,7 +396,7 @@ public final JexlScript createScript(String scriptText, String... names) {
* @throws JexlException if there is a problem reading or parsing the script.
*/
public final JexlScript createScript(File scriptFile) {
- return createScript(null, readSource(scriptFile), null);
+ return createScript(null, null, readSource(scriptFile), null);
}
/**
@@ -338,7 +410,7 @@ public final JexlScript createScript(File scriptFile) {
* @throws JexlException if there is a problem reading or parsing the script.
*/
public final JexlScript createScript(File scriptFile, String... names) {
- return createScript(null, readSource(scriptFile), names);
+ return createScript(null, null, readSource(scriptFile), names);
}
/**
@@ -353,7 +425,7 @@ public final JexlScript createScript(File scriptFile, String... names) {
* @throws JexlException if there is a problem reading or parsing the script.
*/
public final JexlScript createScript(JexlInfo info, File scriptFile, String[] names) {
- return createScript(info, readSource(scriptFile), names);
+ return createScript(null, info, readSource(scriptFile), names);
}
/**
@@ -379,7 +451,7 @@ public final JexlScript createScript(URL scriptUrl) {
* @throws JexlException if there is a problem reading or parsing the script.
*/
public final JexlScript createScript(URL scriptUrl, String[] names) {
- return createScript(null, readSource(scriptUrl), names);
+ return createScript(null, null, readSource(scriptUrl), names);
}
/**
@@ -394,7 +466,7 @@ public final JexlScript createScript(URL scriptUrl, String[] names) {
* @throws JexlException if there is a problem reading or parsing the script.
*/
public final JexlScript createScript(JexlInfo info, URL scriptUrl, String[] names) {
- return createScript(info, readSource(scriptUrl), names);
+ return createScript(null, info, readSource(scriptUrl), names);
}
/**
@@ -459,7 +531,7 @@ public final JexlScript createScript(JexlInfo info, URL scriptUrl, String[] name
/**
* Invokes an object's method by name and arguments.
- *
+ *
* @param obj the method's invoker object
* @param meth the method's name
* @param args the method's arguments
@@ -470,7 +542,7 @@ public final JexlScript createScript(JexlInfo info, URL scriptUrl, String[] name
/**
* Creates a new instance of an object using the most appropriate constructor based on the arguments.
- *
+ *
* @param the type of object
* @param clazz the class to instantiate
* @param args the constructor arguments
@@ -480,7 +552,7 @@ public final JexlScript createScript(JexlInfo info, URL scriptUrl, String[] name
/**
* Creates a new instance of an object using the most appropriate constructor based on the arguments.
- *
+ *
* @param clazz the name of the class to instantiate resolved through this engine's class loader
* @param args the constructor arguments
* @return the created object instance or null on failure when silent
@@ -489,7 +561,7 @@ public final JexlScript createScript(JexlInfo info, URL scriptUrl, String[] name
/**
* Creates a JexlInfo instance.
- *
+ *
* @param fn url/file/template/script user given name
* @param l line number
* @param c column number
@@ -503,14 +575,12 @@ public JexlInfo createInfo(String fn, int l, int c) {
* Create an information structure for dynamic set/get/invoke/new.
*
This gathers the class, method and line number of the first calling method
* outside of o.a.c.jexl3.
- *
+ *
* @return a JexlInfo instance
*/
public JexlInfo createInfo() {
JexlInfo info = null;
- Throwable xinfo = new Throwable();
- xinfo.fillInStackTrace();
- StackTraceElement[] stack = xinfo.getStackTrace();
+ StackTraceElement[] stack = new Throwable().getStackTrace();
StackTraceElement se = null;
String name = getClass().getName();
for (int s = 1; s < stack.length; ++s) {
@@ -534,7 +604,7 @@ public JexlInfo createInfo() {
/**
* Creates a string from a reader.
- *
+ *
* @param reader to be read.
* @return the contents of the reader as a String.
* @throws IOException on any error reading the reader.
@@ -550,7 +620,7 @@ protected static String toString(BufferedReader reader) throws IOException {
/**
* Reads a JEXL source from a File.
- *
+ *
* @param file the script file
* @return the source
*/
@@ -577,7 +647,7 @@ protected String readSource(final File file) {
/**
* Reads a JEXL source from an URL.
- *
+ *
* @param url the script url
* @return the source
*/
diff --git a/src/main/java/org/apache/commons/jexl3/JexlException.java b/src/main/java/org/apache/commons/jexl3/JexlException.java
index 9b0706106..d23ecc090 100644
--- a/src/main/java/org/apache/commons/jexl3/JexlException.java
+++ b/src/main/java/org/apache/commons/jexl3/JexlException.java
@@ -31,7 +31,7 @@
/**
* Wraps any error that might occur during interpretation of a script or expression.
- *
+ *
* @since 2.0
*/
public class JexlException extends RuntimeException {
@@ -47,7 +47,7 @@ public class JexlException extends RuntimeException {
/**
* Creates a new JexlException.
- *
+ *
* @param node the node causing the error
* @param msg the error message
*/
@@ -57,7 +57,7 @@ public JexlException(JexlNode node, String msg) {
/**
* Creates a new JexlException.
- *
+ *
* @param node the node causing the error
* @param msg the error message
* @param cause the exception causing the error
@@ -75,7 +75,7 @@ public JexlException(JexlNode node, String msg, Throwable cause) {
/**
* Creates a new JexlException.
- *
+ *
* @param jinfo the debugging information associated
* @param msg the error message
* @param cause the exception causing the error
@@ -88,7 +88,7 @@ public JexlException(JexlInfo jinfo, String msg, Throwable cause) {
/**
* Gets the specific information for this exception.
- *
+ *
* @return the information
*/
public JexlInfo getInfo() {
@@ -97,7 +97,7 @@ public JexlInfo getInfo() {
/**
* Creates a string builder pre-filled with common error information (if possible).
- *
+ *
* @param node the node
* @return a string builder
*/
@@ -115,7 +115,7 @@ private static StringBuilder errorAt(JexlNode node) {
/**
* Gets the most specific information attached to a node.
- *
+ *
* @param node the node
* @param info the information
* @return the information or null
@@ -137,7 +137,7 @@ public JexlInfo.Detail getDetail() {
/**
* Cleans a JexlException from any org.apache.commons.jexl3.internal stack trace element.
- *
+ *
* @return this exception
*/
public JexlException clean() {
@@ -146,7 +146,7 @@ public JexlException clean() {
/**
* Cleans a Throwable from any org.apache.commons.jexl3.internal stack trace element.
- *
+ *
* @param the throwable type
* @param xthrow the thowable
* @return the throwable
@@ -168,7 +168,7 @@ private static X clean(X xthrow) {
/**
* Unwraps the cause of a throwable due to reflection.
- *
+ *
* @param xthrow the throwable
* @return the cause
*/
@@ -184,7 +184,7 @@ private static Throwable unwrap(Throwable xthrow) {
/**
* Merge the node info and the cause info to obtain best possible location.
- *
+ *
* @param info the node
* @param cause the cause
* @return the info to use
@@ -202,7 +202,7 @@ private static JexlInfo merge(JexlInfo info, JavaccError cause) {
/**
* Accesses detailed message.
- *
+ *
* @return the message
*/
protected String detailedMessage() {
@@ -211,7 +211,7 @@ protected String detailedMessage() {
/**
* Formats an error message from the parser.
- *
+ *
* @param prefix the prefix to the message
* @param expr the expression in error
* @return the formatted message
@@ -235,7 +235,7 @@ protected String parserError(String prefix, String expr) {
/**
* Thrown when tokenization fails.
- *
+ *
* @since 3.0
*/
public static class Tokenization extends JexlException {
@@ -263,13 +263,13 @@ protected String detailedMessage() {
/**
* Thrown when parsing fails.
- *
+ *
* @since 3.0
*/
public static class Parsing extends JexlException {
/**
* Creates a new Parsing exception instance.
- *
+ *
* @param info the location information
* @param cause the javacc cause
*/
@@ -279,7 +279,7 @@ public Parsing(JexlInfo info, ParseException cause) {
/**
* Creates a new Parsing exception instance.
- *
+ *
* @param info the location information
* @param msg the message
*/
@@ -302,7 +302,7 @@ protected String detailedMessage() {
/**
* Thrown when parsing fails due to an ambiguous statement.
- *
+ *
* @since 3.0
*/
public static class Ambiguous extends Parsing {
@@ -323,13 +323,13 @@ protected String detailedMessage() {
/**
* Thrown when parsing fails due to an invalid assigment.
- *
+ *
* @since 3.0
*/
public static class Assignment extends Parsing {
/**
* Creates a new Assignment statement exception instance.
- *
+ *
* @param info the location information
* @param expr the source expression line
*/
@@ -339,13 +339,38 @@ public Assignment(JexlInfo info, String expr) {
@Override
protected String detailedMessage() {
- return parserError("assignement", getDetail());
+ return parserError("assignment", getDetail());
+ }
+ }
+
+ /**
+ * Thrown when parsing fails due to a disallowed feature.
+ *
+ * @since 3.2
+ */
+ public static class Feature extends Parsing {
+ /** The feature code. */
+ private final int code;
+ /**
+ * Creates a new Ambiguous statement exception instance.
+ * @param info the location information
+ * @param feature the feature code
+ * @param expr the source expression line
+ */
+ public Feature(JexlInfo info, int feature, String expr) {
+ super(info, expr);
+ this.code = feature;
+ }
+
+ @Override
+ protected String detailedMessage() {
+ return parserError(JexlFeatures.stringify(code), getDetail());
}
}
/**
* Thrown when a variable is unknown.
- *
+ *
* @since 3.0
*/
public static class Variable extends JexlException {
@@ -355,7 +380,7 @@ public static class Variable extends JexlException {
private final boolean undefined;
/**
* Creates a new Variable exception instance.
- *
+ *
* @param node the offending ASTnode
* @param var the unknown variable
* @param undef whether the variable is undefined or evaluated as null
@@ -367,7 +392,7 @@ public Variable(JexlNode node, String var, boolean undef) {
/**
* Whether the variable causing an error is undefined or evaluated as null.
- *
+ *
* @return true if undefined, false otherwise
*/
public boolean isUndefined() {
@@ -389,7 +414,7 @@ protected String detailedMessage() {
/**
* Generates a message for a variable error.
- *
+ *
* @param node the node where the error occurred
* @param variable the variable
* @param undef whether the variable is null or undefined
@@ -409,13 +434,13 @@ public static String variableError(JexlNode node, String variable, boolean undef
/**
* Thrown when a property is unknown.
- *
+ *
* @since 3.0
*/
public static class Property extends JexlException {
/**
* Creates a new Property exception instance.
- *
+ *
* @param node the offending ASTnode
* @param var the unknown variable
*/
@@ -425,7 +450,7 @@ public Property(JexlNode node, String var) {
/**
* Creates a new Property exception instance.
- *
+ *
* @param node the offending ASTnode
* @param var the unknown variable
* @param cause the exception causing the error
@@ -449,7 +474,7 @@ protected String detailedMessage() {
/**
* Generates a message for an unsolvable property error.
- *
+ *
* @param node the node where the error occurred
* @param var the variable
* @return the error message
@@ -464,13 +489,13 @@ public static String propertyError(JexlNode node, String var) {
/**
* Thrown when a method or ctor is unknown, ambiguous or inaccessible.
- *
+ *
* @since 3.0
*/
public static class Method extends JexlException {
/**
* Creates a new Method exception instance.
- *
+ *
* @param node the offending ASTnode
* @param name the method name
*/
@@ -480,7 +505,7 @@ public Method(JexlNode node, String name) {
/**
* Creates a new Method exception instance.
- *
+ *
* @param info the location information
* @param name the unknown method
* @param cause the exception causing the error
@@ -504,7 +529,7 @@ protected String detailedMessage() {
/**
* Generates a message for a unsolvable method error.
- *
+ *
* @param node the node where the error occurred
* @param method the method name
* @return the error message
@@ -519,13 +544,13 @@ public static String methodError(JexlNode node, String method) {
/**
* Thrown when an operator fails.
- *
+ *
* @since 3.0
*/
public static class Operator extends JexlException {
/**
* Creates a new Operator exception instance.
- *
+ *
* @param node the location information
* @param symbol the operator name
* @param cause the exception causing the error
@@ -549,7 +574,7 @@ protected String detailedMessage() {
/**
* Generates a message for an operator error.
- *
+ *
* @param node the node where the error occurred
* @param symbol the operator name
* @return the error message
@@ -562,9 +587,55 @@ public static String operatorError(JexlNode node, String symbol) {
return msg.toString();
}
+ /**
+ * Thrown when an annotation handler throws an exception.
+ *
+ * @since 3.1
+ */
+ public static class Annotation extends JexlException {
+ /**
+ * Creates a new Annotation exception instance.
+ *
+ * @param node the annotated statement node
+ * @param name the annotation name
+ * @param cause the exception causing the error
+ */
+ public Annotation(JexlNode node, String name, Throwable cause) {
+ super(node, name, cause);
+ }
+
+ /**
+ * @return the annotation name
+ */
+ public String getAnnotation() {
+ return super.detailedMessage();
+ }
+
+ @Override
+ protected String detailedMessage() {
+ return "error processing annotation '" + getAnnotation() + "'";
+ }
+ }
+
+ /**
+ * Generates a message for an annotation error.
+ *
+ * @param node the node where the error occurred
+ * @param annotation the annotation name
+ * @return the error message
+ * @since 3.1
+ */
+ public static String annotationError(JexlNode node, String annotation) {
+ StringBuilder msg = errorAt(node);
+ msg.append("error processing annotation '");
+ msg.append(annotation);
+ msg.append('\'');
+ return msg.toString();
+ }
+
/**
* Thrown to return a value.
- *
+ *
* @since 3.0
*/
public static class Return extends JexlException {
@@ -574,7 +645,7 @@ public static class Return extends JexlException {
/**
* Creates a new instance of Return.
- *
+ *
* @param node the return node
* @param msg the message
* @param value the returned value
@@ -594,13 +665,13 @@ public Object getValue() {
/**
* Thrown to cancel a script execution.
- *
+ *
* @since 3.0
*/
public static class Cancel extends JexlException {
/**
* Creates a new instance of Cancel.
- *
+ *
* @param node the node where the interruption was detected
*/
public Cancel(JexlNode node) {
@@ -610,13 +681,13 @@ public Cancel(JexlNode node) {
/**
* Thrown to break a loop.
- *
+ *
* @since 3.0
*/
public static class Break extends JexlException {
/**
* Creates a new instance of Break.
- *
+ *
* @param node the break
*/
public Break(JexlNode node) {
@@ -626,13 +697,13 @@ public Break(JexlNode node) {
/**
* Thrown to continue a loop.
- *
+ *
* @since 3.0
*/
public static class Continue extends JexlException {
/**
* Creates a new instance of Continue.
- *
+ *
* @param node the continue
*/
public Continue(JexlNode node) {
@@ -643,12 +714,12 @@ public Continue(JexlNode node) {
/**
* Detailed info message about this error.
* Format is "debug![begin,end]: string \n msg" where:
- *
+ *
* - debug is the debugging information if it exists (@link JexlEngine.setDebug)
* - begin, end are character offsets in the string for the precise location of the error
* - string is the string representation of the offending expression
* - msg is the actual explanation message for this error
- *
+ *
* @return this error as a string
*/
@Override
diff --git a/src/main/java/org/apache/commons/jexl3/JexlExpression.java b/src/main/java/org/apache/commons/jexl3/JexlExpression.java
index 7bdc29b64..7f88c5b2a 100644
--- a/src/main/java/org/apache/commons/jexl3/JexlExpression.java
+++ b/src/main/java/org/apache/commons/jexl3/JexlExpression.java
@@ -17,6 +17,8 @@
package org.apache.commons.jexl3;
+import java.util.concurrent.Callable;
+
/**
* Represents a single JEXL expression.
*
@@ -27,13 +29,13 @@
*
* An expression is different than a script - it is simply a reference to
* a single expression, not to multiple statements.
- * This implies 'if','for','while','var' and blocks '{'... '}'are NOT allowed in expressions.
+ * This implies 'if','for','while','var' and blocks '{'... '}'are not allowed in expressions.
*
+ *
Do not create classes that implement this interface; delegate or compose instead.
*
* @since 1.0
*/
public interface JexlExpression {
-
/**
* Evaluates the expression with the variables contained in the
* supplied {@link JexlContext}.
@@ -46,15 +48,27 @@ public interface JexlExpression {
/**
* Returns the source text of this expression.
- *
+ *
* @return the source text
*/
String getSourceText();
/**
- * Recreates the source text of this expression from the internal synactic tree.
- *
+ * Recreates the source text of this expression from the internal syntactic tree.
+ *
* @return the source text
*/
String getParsedText();
+
+ /**
+ * Creates a Callable from this expression.
+ *
+ *
This allows to submit it to an executor pool and provides support for asynchronous calls.
+ *
The interpreter will handle interruption/cancellation gracefully if needed.