1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.jexl3.examples;
18
19 import static java.lang.Boolean.TRUE;
20 import static org.apache.commons.jexl3.JexlTestCase.TEST_PERMS;
21 import static org.junit.jupiter.api.Assertions.assertEquals;
22 import static org.junit.jupiter.api.Assertions.assertInstanceOf;
23 import static org.junit.jupiter.api.Assertions.assertTrue;
24
25 import java.lang.reflect.Method;
26 import java.net.URI;
27 import java.util.Arrays;
28 import java.util.Collection;
29 import java.util.Collections;
30 import java.util.List;
31 import java.util.Objects;
32 import java.util.stream.Collectors;
33 import java.util.stream.Stream;
34
35 import org.apache.commons.jexl3.JexlBuilder;
36 import org.apache.commons.jexl3.JexlContext;
37 import org.apache.commons.jexl3.JexlEngine;
38 import org.apache.commons.jexl3.JexlFeatures;
39 import org.apache.commons.jexl3.JexlScript;
40 import org.apache.commons.jexl3.MapContext;
41 import org.apache.commons.jexl3.introspection.JexlPermissions;
42 import org.apache.commons.jexl3.introspection.JexlPermissions.ClassPermissions;
43 import org.junit.jupiter.api.Assertions;
44 import org.junit.jupiter.api.BeforeAll;
45 import org.junit.jupiter.api.Test;
46
47
48
49
50 public class StreamTest {
51 @BeforeAll
52 static void setUpClass() {
53 JexlBuilder.setDefaultPermissions(TEST_PERMS);
54 }
55
56
57
58
59 public static class CollectionContext extends MapContext {
60
61
62
63
64
65
66
67
68 public List<?> filter(final Collection<?> collection, final JexlScript filter) {
69 return collection.stream()
70 .filter(x -> x != null && TRUE.equals(filter.execute(this, x)))
71 .collect(Collectors.toList());
72 }
73
74
75
76
77
78
79
80
81 public List<?> map(final Collection<?> collection, final JexlScript mapper) {
82 return collection.stream()
83 .map(x -> mapper.execute(this, x))
84 .filter(Objects::nonNull)
85 .collect(Collectors.toList());
86 }
87 }
88
89
90
91
92 public static class StreamContext extends MapContext {
93
94
95
96
97
98
99
100
101 public Stream<?> filter(final Stream<?> stream, final JexlScript filter) {
102 return stream.filter(x -> x != null && TRUE.equals(filter.execute(this, x)));
103 }
104
105
106
107
108
109
110
111
112 public Stream<?> map(final Stream<?> stream, final JexlScript mapper) {
113 return stream.map(x -> mapper.execute(this, x));
114 }
115 }
116
117
118 private final JexlEngine jexl;
119 private final JexlPermissions jexlPermissions;
120
121 public StreamTest() throws Exception {
122
123 final JexlFeatures features = new JexlFeatures()
124 .loops(false)
125 .sideEffectGlobal(false)
126 .sideEffect(false);
127
128 jexlPermissions = new ClassPermissions(java.net.URI.class, StreamContext.class, CollectionContext.class);
129
130 jexl = new JexlBuilder()
131 .features(features)
132 .permissions(jexlPermissions)
133 .namespaces(Collections.singletonMap("URI", java.net.URI.class))
134 .create();
135 }
136
137 @Test
138 void testURICollection() throws Exception {
139 Assertions.assertTrue(jexlPermissions.allow(java.net.URI.class));
140 Assertions.assertTrue(jexlPermissions.allow(java.util.stream.Stream.class));
141 for (final Method m : Arrays.stream(Stream.class.getMethods()).filter(m -> m.getName().equals("filter")).collect(Collectors.toSet())) {
142 Assertions.assertTrue(jexlPermissions.allow(m));
143 }
144
145 final JexlContext sctxt = new CollectionContext();
146
147 final List<URI> uris = Arrays.asList(
148 URI.create("http://user@www.apache.org:8000?qry=true"),
149 URI.create("https://commons.apache.org/releases/prepare.html"),
150 URI.create("mailto:henrib@apache.org")
151 );
152
153
154 final JexlScript filter = jexl.createScript(
155 "list.filter(uri -> uri.scheme =^ 'http')",
156 "list");
157 final Object filtered = filter.execute(sctxt, uris);
158 assertInstanceOf(List.class, filtered);
159 List<URI> result = (List<URI>) filtered;
160 assertEquals(2, result.size());
161 for(final URI uri : result) {
162 assertTrue(uri.getScheme().startsWith("http"));
163 }
164
165
166 final JexlScript mapper = jexl.createScript(
167 "list.map(uri -> uri.scheme =^ 'http'? URI:create(`https://${uri.host}`) : null)",
168 "list");
169 final Object transformed = mapper.execute(sctxt, uris);
170 assertInstanceOf(List.class, transformed);
171 result = (List<URI>) transformed;
172 assertEquals(2, result.size());
173 for (final URI uri : result) {
174 assertEquals("https", uri.getScheme());
175 }
176 }
177
178 @Test
179 void testURIStream() throws Exception {
180 Assertions.assertTrue(jexlPermissions.allow(StreamContext.class.getMethod("filter", Stream.class, JexlScript.class)));
181
182
183
184 final List<URI> uris = Arrays.asList(
185 URI.create("http://user@www.apache.org:8000?qry=true"),
186 URI.create("https://commons.apache.org/releases/prepare.html"),
187 URI.create("mailto:henrib@apache.org")
188 );
189
190 final List<?> control = uris.stream()
191 .map(uri -> uri.getScheme().startsWith("http")? "https://" + uri.getHost() : null)
192 .filter(Objects::nonNull)
193 .collect(Collectors.toList());
194 assertEquals(2, control.size());
195
196
197
198
199 final JexlScript mapper = jexl.createScript("uri.scheme =^ 'http'? `https://${uri.host}` : null", "uri");
200
201 final JexlScript transform = jexl.createScript(
202 "list.stream().map(mapper).filter(x -> !!x).collect(Collectors.toList())", "list");
203
204
205 final JexlContext sctxt = new StreamContext();
206
207 sctxt.set("Collectors", Collectors.class);
208
209 sctxt.set("mapper", mapper);
210
211 final Object transformed = transform.execute(sctxt, uris);
212 assertInstanceOf(List.class, transformed);
213 assertEquals(control, transformed);
214 }
215 }