This is an automated email from the ASF dual-hosted git repository. henrib pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-jexl.git
commit 01eebc45824856d8ea313dd9252eb4df076f1713 Author: henrib <hen...@apache.org> AuthorDate: Wed Aug 15 10:50:40 2018 +0200 JEXL-266: added an example/prototype through forEach operator 'overload' --- .../org/apache/commons/jexl3/Issues200Test.java | 108 ++++++++++++++++++++- 1 file changed, 107 insertions(+), 1 deletion(-) diff --git a/src/test/java/org/apache/commons/jexl3/Issues200Test.java b/src/test/java/org/apache/commons/jexl3/Issues200Test.java index a18dd9c..9b09dd4 100644 --- a/src/test/java/org/apache/commons/jexl3/Issues200Test.java +++ b/src/test/java/org/apache/commons/jexl3/Issues200Test.java @@ -16,12 +16,16 @@ */ package org.apache.commons.jexl3; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; -import java.util.Collections; +import java.util.Deque; import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.NoSuchElementException; import java.util.Set; import java.util.TreeSet; @@ -507,4 +511,106 @@ public class Issues200Test extends JexlTestCase { result = script.execute(ctxt); Assert.assertEquals(42, result); } + + + /** + * An iterator that implements Closeable (at least implements a close method). + */ + public static class Iterator266 implements /*Closeable,*/ Iterator<Object> { + private Iterator<Object> iterator; + + Iterator266(Iterator<Object> ator) { + iterator = ator; + } + + @Override + protected void finalize() throws Throwable { + close(); + super.finalize(); + } + + //@Override + public void close() { + if (iterator != null) { + Arithmetic266.closeIterator(this); + iterator = null; + } + } + + @Override + public boolean hasNext() { + if (iterator == null) { + return false; + } + boolean n = iterator.hasNext(); + if (!n) { + close(); + } + return n; + } + + @Override + public Object next() { + if (iterator == null) { + throw new NoSuchElementException(); + } + return iterator.next(); + } + + @Override + public void remove() { + if (iterator != null) { + iterator.remove(); + } + } + } + public static class Arithmetic266 extends JexlArithmetic { + static final ThreadLocal<Deque<Iterator266>> TLS_FOREACH = new ThreadLocal<Deque<Iterator266>>() { + @Override + public Deque<Iterator266> initialValue() { + return new LinkedList<Iterator266>(); + } + }; + public Arithmetic266(boolean strict) { + super(strict); + } + + static void closeIterator(Iterator266 i266) { + Deque<Iterator266> queue = TLS_FOREACH.get(); + if (queue != null) { + queue.remove(i266); + } + } + + public Iterator<?> forEach(Iterable<?> collection) { + Iterator266 it266 = new Iterator266((Iterator<Object>) collection.iterator()); + Deque<Iterator266> queue = TLS_FOREACH.get(); + queue.addFirst(it266); + return it266; + } + + public void remove() { + Deque<Iterator266> queue = TLS_FOREACH.get(); + Iterator266 i266 = queue.getFirst(); + if (i266 != null) { + i266.remove(); + throw new JexlException.Continue(null); + } else { + throw new NoSuchElementException(); + } + } + } + + @Test + public void test266() throws Exception { + JexlEngine jexl = new JexlBuilder().arithmetic(new Arithmetic266(true)).create(); + JexlContext ctxt = new MapContext(); + List<Integer> li = new ArrayList<Integer>(Arrays.asList(1, 2, 3, 4, 5 ,6)); + ctxt.set("list", li); + Object result; + JexlScript script; + script = jexl.createScript("for (var item : list) { if (item <= 3) remove(); } return size(list)"); + result = script.execute(ctxt); + Assert.assertEquals(3, result); + } }