1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.juneau.cp;
18
19 import static java.lang.annotation.ElementType.*;
20 import static java.lang.annotation.RetentionPolicy.*;
21 import static org.apache.juneau.TestUtils.*;
22 import static org.junit.jupiter.api.Assertions.*;
23
24 import java.lang.annotation.*;
25 import java.util.*;
26 import java.util.function.*;
27
28 import org.apache.juneau.*;
29 import org.apache.juneau.annotation.*;
30 import org.apache.juneau.reflect.*;
31 import org.junit.jupiter.api.*;
32
33 class BeanStore_Test extends TestBase {
34
35 @Documented
36 @Target({PARAMETER})
37 @Retention(RUNTIME)
38 @Inherited
39 public @interface Named {
40 String value();
41 }
42
43
44
45
46
47 public static class A1 {}
48 public static class A2 {}
49
50 public static final String A1n = A1.class.getSimpleName();
51
52 public static class A3 extends BeanStore {
53 protected A3(Builder builder) {
54 super(builder);
55 }
56 }
57
58 private static A1 a1a = new A1(), a1b = new A1(), a1c = new A1(), a1d = new A1(), a1e = new A1();
59 private static A2 a2a = new A2();
60
61 @Test void a00_dummy() {
62 assertDoesNotThrow(BeanStore.Void::new);
63 }
64
65 @Test void a01_builderCopyConstructor() {
66 var b1p = BeanStore.create().readOnly().threadSafe().build();
67 var b1c = BeanStore.create().parent(b1p).build();
68 assertContains("readOnly:true", b1c.toString());
69 assertContains("threadSafe:true", b1c.toString());
70 }
71
72 @Test void a02_readOnly() {
73 var b1p = BeanStore.create().readOnly().build();
74 var b1c = BeanStore.create().parent(b1p).build();
75 var b2p = BeanStore.create().readOnly().threadSafe().build();
76 var b2c = BeanStore.create().parent(b1p).threadSafe().build();
77
78 for (BeanStore b : array(b1p, b2p)) {
79 assertThrowsWithMessage(IllegalStateException.class, "Method cannot be used because BeanStore is read-only.", ()->b.add(A1.class, a1a));
80 assertThrowsWithMessage(IllegalStateException.class, "Method cannot be used because BeanStore is read-only.", ()->b.add(A1.class, a1a, "foo"));
81 assertThrowsWithMessage(IllegalStateException.class, "Method cannot be used because BeanStore is read-only.", ()->b.addBean(A1.class, a1a));
82 assertThrowsWithMessage(IllegalStateException.class, "Method cannot be used because BeanStore is read-only.", ()->b.addBean(A1.class, a1a, "foo"));
83 assertThrowsWithMessage(IllegalStateException.class, "Method cannot be used because BeanStore is read-only.", ()->b.addSupplier(A1.class, ()->a1a));
84 assertThrowsWithMessage(IllegalStateException.class, "Method cannot be used because BeanStore is read-only.", ()->b.addSupplier(A1.class, ()->a1a, "foo"));
85 assertThrowsWithMessage(IllegalStateException.class, "Method cannot be used because BeanStore is read-only.", b::clear);
86 assertThrowsWithMessage(IllegalStateException.class, "Method cannot be used because BeanStore is read-only.", ()->b.removeBean(A1.class));
87 assertThrowsWithMessage(IllegalStateException.class, "Method cannot be used because BeanStore is read-only.", ()->b.removeBean(A1.class, "foo"));
88 }
89
90 for (var b : array(b1c, b2c)) {
91 b.add(A1.class, a1a);
92 b.add(A1.class, a1a, "foo");
93 b.addBean(A1.class, a1a);
94 b.addBean(A1.class, a1a, "foo");
95 b.addSupplier(A1.class, ()->a1a);
96 b.addSupplier(A1.class, ()->a1a, "foo");
97 b.clear();
98 b.removeBean(A1.class);
99 b.removeBean(A1.class, "foo");
100 }
101 }
102
103 @Test void a04_addBean() {
104 var b1p = BeanStore.create().build();
105 var b1c = BeanStore.of(b1p);
106 var b2p = BeanStore.create().threadSafe().build();
107 var b2c = BeanStore.create().threadSafe().parent(b2p).build();
108
109 for (var b : array(b1p, b1c, b2p, b2c)) {
110 assertFalse(b.hasBean(A1.class));
111 assertEmpty(b.getBean(A1.class));
112 }
113
114 b1p.addBean(A1.class, a1a);
115 b2p.addBean(A1.class, a1a);
116 for (var b : array(b1p, b1c, b2p, b2c)) {
117 assertTrue(b.hasBean(A1.class));
118 assertEquals(a1a, b.getBean(A1.class).get());
119 }
120
121 b1p.clear();
122 b2p.clear();
123 for (var b : array(b1p, b1c, b2p, b2c)) {
124 assertFalse(b.hasBean(A1.class));
125 assertEmpty(b.getBean(A1.class));
126 }
127
128 b1p.addBean(A1.class, null);
129 b2p.addBean(A1.class, null);
130 for (var b : array(b1p, b1c, b2p, b2c)) {
131 assertTrue(b.hasBean(A1.class));
132 assertEmpty(b.getBean(A1.class));
133 }
134
135 b1p.clear().addSupplier(A1.class, ()->a1a);
136 b2p.clear().addSupplier(A1.class, ()->a1a);
137 for (var b : array(b1p, b1c, b2p, b2c)) {
138 assertTrue(b.hasBean(A1.class));
139 assertEquals(a1a, b.getBean(A1.class).get());
140 }
141
142 b1p.add(A1.class, a1b);
143 b2p.add(A1.class, a1b);
144 for (var b : array(b1p, b1c, b2p, b2c)) {
145 assertTrue(b.hasBean(A1.class));
146 assertEquals(a1b, b.getBean(A1.class).get());
147 assertList(b.stream(A1.class).map(BeanStoreEntry::get), a1b, a1a);
148 }
149
150 b1c.add(A2.class, a2a);
151 b2c.add(A2.class, a2a);
152 for (var b : array(b1p, b2p)) {
153 assertFalse(b.hasBean(A2.class));
154 assertEmpty(b.getBean(A2.class));
155 assertEmpty(b.stream(A2.class));
156 }
157 for (var b : array(b1c, b2c)) {
158 assertTrue(b.hasBean(A2.class));
159 assertEquals(a2a, b.getBean(A2.class).get());
160 assertList(b.stream(A2.class).map(BeanStoreEntry::get), a2a);
161 }
162
163 assertMatchesGlob("{*,entries:[{type:'A1',bean:'"+identity(a1b)+"'},{type:'A1',bean:'"+identity(a1a)+"'}]}", b1p);
164 assertMatchesGlob("{*,entries:[{type:'A2',bean:'"+identity(a2a)+"'}],parent:{*,entries:[{type:'A1',bean:'"+identity(a1b)+"'},{type:'A1',bean:'"+identity(a1a)+"'}]}}", b1c);
165 assertMatchesGlob("{*,entries:[{type:'A1',bean:'"+identity(a1b)+"'},{type:'A1',bean:'"+identity(a1a)+"'}],threadSafe:true}", b2p);
166 assertMatchesGlob("{*,entries:[{type:'A2',bean:'"+identity(a2a)+"'}],parent:{*,entries:[{type:'A1',bean:'"+identity(a1b)+"'},{type:'A1',bean:'"+identity(a1a)+"'}],threadSafe:true},threadSafe:true}", b2c);
167
168 b1p.removeBean(A1.class);
169 b1c.clear().addBean(A1.class, a1a);
170 b2p.removeBean(A1.class);
171 b2c.clear().addBean(A1.class, a1a);
172
173 for (var b : array(b1p, b2p)) {
174 assertFalse(b.hasBean(A1.class));
175 assertEmpty(b.getBean(A1.class));
176 assertEmpty(b.stream(A1.class));
177 }
178 for (var b : array(b1c, b2c)) {
179 assertTrue(b.hasBean(A1.class));
180 assertEquals(a1a, b.getBean(A1.class).get());
181 assertList(b.stream(A1.class).map(BeanStoreEntry::get), a1a);
182 }
183
184 b1c.removeBean(A1.class);
185 b2c.removeBean(A1.class);
186 for (var b : array(b1p, b1c, b2p, b2c)) {
187 assertFalse(b.hasBean(A1.class));
188 assertEmpty(b.getBean(A1.class));
189 assertEmpty(b.stream(A1.class));
190 }
191 }
192
193 @Test void a05_addNamedBeans() {
194 var b1p = BeanStore.create().build();
195 var b1c = BeanStore.of(b1p);
196 var b2p = BeanStore.create().threadSafe().build();
197 var b2c = BeanStore.create().threadSafe().parent(b2p).build();
198
199 for (var b : array(b1p, b2p)) {
200 b.addBean(A1.class, a1a).addBean(A1.class, a1b, "foo").addBean(A1.class, a1c, "bar").addBean(A1.class, a1d, "bar").addBean(A2.class, a2a, "foo");
201 }
202 for (var b : array(b1c, b2c)) {
203 b.addBean(A1.class, a1e);
204 }
205
206 for (var b : array(b1p, b2p)) {
207 assertList(b.stream(A1.class).map(BeanStoreEntry::get), a1d,a1c,a1b,a1a);
208 }
209 for (var b : array(b1c, b2c)) {
210 assertList(b.stream(A1.class).map(BeanStoreEntry::get), a1e,a1d,a1c,a1b,a1a);
211 }
212
213 for (var b : array(b1p, b1c, b2p, b2c)) {
214 assertEquals(a1b, b.getBean(A1.class, "foo").get());
215 assertEquals(a1d, b.getBean(A1.class, "bar").get());
216 assertEmpty(b.getBean(A1.class, "baz"));
217 }
218 for (var b : array(b1p, b2p)) {
219 assertEquals(a1a, b.getBean(A1.class, null).get());
220 }
221 for (var b : array(b1c, b2c)) {
222 assertEquals(a1e, b.getBean(A1.class, null).get());
223 }
224 }
225
226
227
228
229
230 public static class B1 {
231 A1 a1;
232 Optional<A2> a2;
233 BeanStore a3;
234
235 public B1(A1 a1, Optional<A2> a2, BeanStore a3) {
236 this.a1 = a1;
237 this.a2 = a2;
238 this.a3 = a3;
239 }
240
241 public B1(@Named("foo") A1 a1, @Named("bar") Optional<A2> a2) {
242 this.a1 = a1;
243 this.a2 = a2;
244 }
245
246 public void m1(A1 a1, Optional<A2> a2, BeanStore a3) {
247 this.a1 = a1;
248 this.a2 = a2;
249 this.a3 = a3;
250 }
251
252 public void m2(@Named("foo") A1 a1, @Named("bar") Optional<A2> a2) {
253 this.a1 = a1;
254 this.a2 = a2;
255 this.a3 = null;
256 }
257
258 public static B1 m3(A1 a1, Optional<A2> a2, BeanStore a3) {
259 return new B1(a1, a2, a3);
260 }
261 }
262
263 @Test void b01_getParams() {
264
265 Predicate<Object> pEmptyOptional = x -> !((Optional<?>)x).isPresent();
266 Predicate<Object> pIsBeanStore = BeanStore.class::isInstance;
267 Predicate<Object> pNull = x -> x == null;
268 Predicate<Object> pA1a = x -> x==a1a;
269 Predicate<Object> pA2a = x -> ((Optional<?>)x).get()==a2a;
270
271 var outer = new B1(null, null, null);
272
273 var b1p = BeanStore.create().outer(outer).build();
274 var b1c = BeanStore.create().outer(outer).parent(b1p).build();
275 var b2p = BeanStore.create().outer(outer).threadSafe().build();
276 var b2c = BeanStore.create().outer(outer).parent(b1p).threadSafe().build();
277
278 var ci = ClassInfo.of(B1.class);
279 var c1 = ci.getPublicConstructor(x -> x.hasParamTypes(A1.class, Optional.class, BeanStore.class));
280 var c2 = ci.getPublicConstructor(x -> x.hasParamTypes(A1.class, Optional.class));
281 var m1 = ci.getPublicMethod(x-> x.hasName("m1"));
282 var m2 = ci.getPublicMethod(x-> x.hasName("m2"));
283 var m3 = ci.getPublicMethod(x-> x.hasName("m3"));
284
285 for (var b : array(b1p, b1c, b2p, b2c)) {
286 for (var e : array(c1, m1, m3)) {
287 assertString(A1n, b.getMissingParams(e));
288 assertFalse(b.hasAllParams(e));
289 }
290 for (var e : array(c2, m2)) {
291 assertString(A1n+"@foo", b.getMissingParams(e));
292 assertFalse(b.hasAllParams(e));
293 }
294 }
295
296 for (var b : array(b1p, b1c, b2p, b2c)) {
297 assertList(b.getParams(c1), pNull, pEmptyOptional, pIsBeanStore);
298 assertList(b.getParams(c2), pNull, pEmptyOptional);
299 assertList(b.getParams(m1), pNull, pEmptyOptional, pIsBeanStore);
300 assertList(b.getParams(m2), pNull, pEmptyOptional);
301 assertList(b.getParams(m3), pNull, pEmptyOptional, pIsBeanStore);
302 }
303
304 b1p.add(A1.class, a1a);
305 b2p.add(A1.class, a1a);
306 for (var b : array(b1p, b1c, b2p, b2c)) {
307 assertNull(b.getMissingParams(c1));
308 assertString(A1n+"@foo", b.getMissingParams(c2));
309 assertNull(b.getMissingParams(m1));
310 assertString(A1n+"@foo", b.getMissingParams(m2));
311 assertNull(b.getMissingParams(m3));
312 assertTrue(b.hasAllParams(c1));
313 assertFalse(b.hasAllParams(c2));
314 assertTrue(b.hasAllParams(m1));
315 assertFalse(b.hasAllParams(m2));
316 assertTrue(b.hasAllParams(m3));
317 assertList(b.getParams(c1), pA1a, pEmptyOptional, pIsBeanStore);
318 assertList(b.getParams(c2), pNull, pEmptyOptional);
319 assertList(b.getParams(m1), pA1a, pEmptyOptional, pIsBeanStore);
320 assertList(b.getParams(m2), pNull, pEmptyOptional);
321 assertList(b.getParams(m3), pA1a, pEmptyOptional, pIsBeanStore);
322 }
323
324 b1p.add(A1.class, a1a, "foo");
325 b2p.add(A1.class, a1a, "foo");
326 for (var b : array(b1p, b1c, b2p, b2c)) {
327 for (var e : array(c1, c2, m1, m2, m3)) {
328 assertNull(b.getMissingParams(e));
329 assertTrue(b.hasAllParams(e));
330 }
331 assertList(b.getParams(c1), pA1a, pEmptyOptional, pIsBeanStore);
332 assertList(b.getParams(c2), pA1a, pEmptyOptional);
333 assertList(b.getParams(m1), pA1a, pEmptyOptional, pIsBeanStore);
334 assertList(b.getParams(m2), pA1a, pEmptyOptional);
335 assertList(b.getParams(m3), pA1a, pEmptyOptional, pIsBeanStore);
336 }
337
338 b1p.add(A1.class, a1b, "bar");
339 b2p.add(A1.class, a1b, "bar");
340 for (var b : array(b1p, b1c, b2p, b2c)) {
341 for (var e : array(c1, c2, m1, m2, m3)) {
342 assertNull(b.getMissingParams(e));
343 assertTrue(b.hasAllParams(e));
344 }
345 assertList(b.getParams(c1), pA1a, pEmptyOptional, pIsBeanStore);
346 assertList(b.getParams(c2), pA1a, pEmptyOptional);
347 assertList(b.getParams(m1), pA1a, pEmptyOptional, pIsBeanStore);
348 assertList(b.getParams(m2), pA1a, pEmptyOptional);
349 assertList(b.getParams(m3), pA1a, pEmptyOptional, pIsBeanStore);
350 }
351
352 b1p.add(A2.class, a2a, "bar");
353 b2p.add(A2.class, a2a, "bar");
354 for (var b : array(b1p, b1c, b2p, b2c)) {
355 for (var e : array(c1, c2, m1, m2, m3)) {
356 assertNull(b.getMissingParams(e));
357 assertTrue(b.hasAllParams(e));
358 }
359 assertList(b.getParams(c1), pA1a, pEmptyOptional, pIsBeanStore);
360 assertList(b.getParams(c2), pA1a, pA2a);
361 assertList(b.getParams(m1), pA1a, pEmptyOptional, pIsBeanStore);
362 assertList(b.getParams(m2), pA1a, pA2a);
363 assertList(b.getParams(m3), pA1a, pEmptyOptional, pIsBeanStore);
364 }
365
366 b1p.add(A2.class, a2a, null);
367 b2p.add(A2.class, a2a, null);
368 for (var b : array(b1p, b1c, b2p, b2c)) {
369 for (var e : array(c1, c2, m1, m2, m3)) {
370 assertNull(b.getMissingParams(e));
371 assertTrue(b.hasAllParams(e));
372 }
373 assertList(b.getParams(c1), pA1a, pA2a, pIsBeanStore);
374 assertList(b.getParams(c2), pA1a, pA2a);
375 assertList(b.getParams(m1), pA1a, pA2a, pIsBeanStore);
376 assertList(b.getParams(m2), pA1a, pA2a);
377 assertList(b.getParams(m3), pA1a, pA2a, pIsBeanStore);
378 }
379 }
380
381 public class B2 {
382 A1 a1;
383 Optional<A2> a2;
384 BeanStore a3;
385
386 public B2(A1 a1, Optional<A2> a2, BeanStore a3) {
387 this.a1 = a1;
388 this.a2 = a2;
389 this.a3 = a3;
390 }
391
392 public B2(@Named("foo") A1 a1, @Named("bar") Optional<A2> a2) {
393 this.a1 = a1;
394 this.a2 = a2;
395 }
396 }
397
398 @Test void b02_getParams_innerClass() {
399
400 Predicate<Object> pEmptyOptional = x -> !((Optional<?>)x).isPresent();
401 Predicate<Object> pIsBeanStore = BeanStore.class::isInstance;
402 Predicate<Object> pNull = x -> x == null;
403 Predicate<Object> pThis = x -> x == this;
404 Predicate<Object> pA1a = x -> x==a1a;
405 Predicate<Object> pA2a = x -> ((Optional<?>)x).get()==a2a;
406
407 var b1p = BeanStore.create().outer(this).build();
408 var b1c = BeanStore.create().outer(this).parent(b1p).build();
409 var b2p = BeanStore.create().outer(this).threadSafe().build();
410 var b2c = BeanStore.create().outer(this).parent(b1p).threadSafe().build();
411
412 var ci = ClassInfo.of(B2.class);
413 var c1 = ci.getPublicConstructor(x -> x.hasParamTypes(BeanStore_Test.class, A1.class, Optional.class, BeanStore.class));
414 var c2 = ci.getPublicConstructor(x -> x.hasParamTypes(BeanStore_Test.class, A1.class, Optional.class));
415
416 for (var b : array(b1p, b1c, b2p, b2c)) {
417 assertString(A1n, b.getMissingParams(c1));
418 assertString(A1n+"@foo", b.getMissingParams(c2));
419 assertFalse(b.hasAllParams(c1));
420 assertFalse(b.hasAllParams(c2));
421 }
422
423 for (var b : array(b1p, b1c, b2p, b2c)) {
424 assertList(b.getParams(c1), pThis, pNull, pEmptyOptional, pIsBeanStore);
425 assertList(b.getParams(c2), pThis, pNull, pEmptyOptional);
426 }
427
428 b1p.add(A1.class, a1a);
429 b2p.add(A1.class, a1a);
430 for (var b : array(b1p, b1c, b2p, b2c)) {
431 assertNull(b.getMissingParams(c1));
432 assertString(A1n+"@foo", b.getMissingParams(c2));
433 assertTrue(b.hasAllParams(c1));
434 assertFalse(b.hasAllParams(c2));
435 assertList(b.getParams(c1), pThis, pA1a, pEmptyOptional, pIsBeanStore);
436 assertList(b.getParams(c2), pThis, pNull, pEmptyOptional);
437 }
438
439 b1p.add(A1.class, a1a, "foo");
440 b2p.add(A1.class, a1a, "foo");
441 for (var b : array(b1p, b1c, b2p, b2c)) {
442 for (var e : array(c1, c2)) {
443 assertNull(b.getMissingParams(e));
444 assertTrue(b.hasAllParams(e));
445 }
446 assertList(b.getParams(c1), pThis, pA1a, pEmptyOptional, pIsBeanStore);
447 assertList(b.getParams(c2), pThis, pA1a, pEmptyOptional);
448 }
449
450 b1p.add(A1.class, a1b, "bar");
451 b2p.add(A1.class, a1b, "bar");
452 for (var b : array(b1p, b1c, b2p, b2c)) {
453 for (var e : array(c1, c2)) {
454 assertNull(b.getMissingParams(e));
455 assertTrue(b.hasAllParams(e));
456 }
457 assertList(b.getParams(c1), pThis, pA1a, pEmptyOptional, pIsBeanStore);
458 assertList(b.getParams(c2), pThis, pA1a, pEmptyOptional);
459 }
460
461 b1p.add(A2.class, a2a, "bar");
462 b2p.add(A2.class, a2a, "bar");
463 for (var b : array(b1p, b1c, b2p, b2c)) {
464 for (var e : array(c1, c2)) {
465 assertNull(b.getMissingParams(e));
466 assertTrue(b.hasAllParams(e));
467 }
468 assertList(b.getParams(c1), pThis, pA1a, pEmptyOptional, pIsBeanStore);
469 assertList(b.getParams(c2), pThis, pA1a, pA2a);
470 }
471
472 b1p.add(A2.class, a2a, null);
473 b2p.add(A2.class, a2a, null);
474 for (var b : array(b1p, b1c, b2p, b2c)) {
475 for (var e : array(c1, c2)) {
476 assertNull(b.getMissingParams(e));
477 assertTrue(b.hasAllParams(e));
478 }
479 assertList(b.getParams(c1), pThis, pA1a, pA2a, pIsBeanStore);
480 assertList(b.getParams(c2), pThis, pA1a, pA2a);
481 }
482 }
483
484
485
486
487
488 public static class C {
489 public A1 a;
490 }
491
492 @Test void c00_createMethodFinder_invalidArgs() {
493 var b = BeanStore.create().build();
494 assertThrowsWithMessage(IllegalArgumentException.class, "Method cannot be used without outer bean definition.", ()->b.createMethodFinder(null));
495 assertThrowsWithMessage(IllegalArgumentException.class, "Argument 'beanType' cannot be null.", ()->b.createMethodFinder((Class<?>)null,""));
496 assertThrowsWithMessage(IllegalArgumentException.class, "Argument 'resourceClass' cannot be null.", ()->b.createMethodFinder(String.class,null));
497 }
498
499
500 public static class C1 {
501 public C createA1() { return new C(); }
502 public A1 createA2() { return new A1(); }
503 protected C createA3() { return new C(); }
504 @Deprecated public C createA4() { return new C(); }
505 @BeanIgnore public C createA5() { return new C(); }
506 public C createA6() { return null; }
507 public C createA7() { throw new RuntimeException("foo"); }
508 }
509
510 @Test void c01_createMethodFinder_instanceMethods() throws Exception {
511 var x = new C1();
512 var b1p = BeanStore.create().build();
513 var b1c = BeanStore.create().parent(b1p).build();
514 var b2p = BeanStore.create().build();
515 var b2c = BeanStore.create().outer(x).parent(b2p).build();
516 var b3p = BeanStore.create().build();
517 var b3c = BeanStore.create().outer(this).parent(b3p).build();
518
519 for (var m : array("createA0", "createA2", "createA3", "createA4", "createA5", "createA6")) {
520 for (var b : array(b1c, b2c, b3c)) {
521 assertNull(b.createMethodFinder(C.class, x).find(m).run());
522 assertNull(b.createMethodFinder(C.class, C1.class).find(m).run());
523 }
524 for (var b : array(b2c, b3c)) {
525 assertNull(b.createMethodFinder(C.class).find(m).run());
526 }
527 }
528 assertNotNull(b1c.createMethodFinder(C.class, x).find("createA1").run());
529 assertNull(b1c.createMethodFinder(C.class, C1.class).find("createA1").run());
530 assertNotNull(b2c.createMethodFinder(C.class).find("createA1").run());
531 assertNull(b3c.createMethodFinder(C.class).find("createA1").run());
532 assertThrowsWithMessage(Exception.class, "foo", ()->b1c.createMethodFinder(C.class, x).find("createA7").run());
533 assertNull(b1c.createMethodFinder(C.class, C1.class).find("createA7").run());
534 assertThrowsWithMessage(Exception.class, "foo", ()->b2c.createMethodFinder(C.class).find("createA7").run());
535 assertNull(b3c.createMethodFinder(C.class).find("createA7").run());
536 }
537
538
539 public static class C2 {
540 public static C createB1() { return new C(); }
541 public static A1 createB2() { return new A1(); }
542 protected static C createB3() { return new C(); }
543 @Deprecated public static C createB4() { return new C(); }
544 @BeanIgnore public static C createB5() { return new C(); }
545 public static C createB6() { return null; }
546 public static C createB7() { throw new RuntimeException("foo"); }
547 }
548
549 @Test void c02_createMethodFinder_staticMethods() throws Exception {
550 var x = new C2();
551 var b1p = BeanStore.create().build();
552 var b1c = BeanStore.create().parent(b1p).build();
553 var b2p = BeanStore.create().build();
554 var b2c = BeanStore.create().outer(x).parent(b2p).build();
555 var b3p = BeanStore.create().build();
556 var b3c = BeanStore.create().outer(this).parent(b3p).build();
557
558 for (var m : array("createB0", "createB2", "createB3", "createB4", "createB5", "createB6")) {
559 for (var b : array(b1c, b2c, b3c)) {
560 assertNull(b.createMethodFinder(C.class, x).find(m).run());
561 assertNull(b.createMethodFinder(C.class, C2.class).find(m).run());
562 }
563 for (var b : array(b2c, b3c)) {
564 assertNull(b.createMethodFinder(C.class).find(m).run());
565 }
566 }
567 assertNotNull(b1c.createMethodFinder(C.class, x).find("createB1").run());
568 assertNotNull(b1c.createMethodFinder(C.class, C2.class).find("createB1").run());
569 assertNotNull(b2c.createMethodFinder(C.class).find("createB1").run());
570 assertNull(b3c.createMethodFinder(C.class).find("createB1").run());
571 assertThrowsWithMessage(Exception.class, "foo", ()->b1c.createMethodFinder(C.class, x).find("createB7").run());
572 assertThrowsWithMessage(Exception.class, "foo", ()->b1c.createMethodFinder(C.class, C2.class).find("createB7").run());
573 assertThrowsWithMessage(Exception.class, "foo", ()->b2c.createMethodFinder(C.class).find("createB7").run());
574 assertNull(b3c.createMethodFinder(C.class).find("createB7").run());
575 }
576
577
578 public static class C3 {
579 public C createC1(A1 a) { return new C(); }
580 public static C createC2(A1 a) { return new C(); }
581 public static C createC3(Optional<A1> a) { C e = new C(); e.a = a.orElse(null); return e; }
582 public static C createC4(@Named("Foo") A1 a) { return new C(); }
583 public static C createC5(@Named("Foo") Optional<A1> a) { C e = new C(); e.a = a.orElse(null); return e; }
584 public static C createC6(BeanStore bs) { assertNotNull(bs); return new C(); }
585 }
586
587 @Test void c03_createMethodFinder_beanMatching() throws Exception {
588 var x = new C3();
589 var b1p = BeanStore.create().build();
590 var b1c = BeanStore.create().parent(b1p).build();
591 var b2p = BeanStore.create().build();
592 var b2c = BeanStore.create().outer(x).parent(b2p).build();
593 var b3p = BeanStore.create().build();
594 var b3c = BeanStore.create().outer(this).parent(b3p).build();
595
596 for (var b : array(b1c, b2c, b3c)) {
597 assertNull(b.createMethodFinder(C.class, x).find("createC1").run());
598 assertNull(b.createMethodFinder(C.class, x).find("createC2").run());
599 assertNull(b.createMethodFinder(C.class, x).find("createC3").run().a);
600 assertNull(b.createMethodFinder(C.class, x).find("createC4").run());
601 assertNull(b.createMethodFinder(C.class, x).find("createC5").run().a);
602 assertNotNull(b.createMethodFinder(C.class, x).find("createC6").run());
603 }
604
605 b1p.addBean(A1.class, new A1());
606 b2p.addBean(A1.class, new A1());
607 b3p.addBean(A1.class, new A1());
608 for (var b : array(b1c, b2c)) {
609 assertNotNull(b.createMethodFinder(C.class, x).find("createC1").run());
610 assertNotNull(b.createMethodFinder(C.class, x).find("createC2").run());
611 assertNotNull(b.createMethodFinder(C.class, x).find("createC3").run().a);
612 assertNull(b.createMethodFinder(C.class, x).find("createC4").run());
613 assertNull(b.createMethodFinder(C.class, x).find("createC5").run().a);
614 assertNotNull(b.createMethodFinder(C.class, x).find("createC6").run());
615 assertNull(b.createMethodFinder(C.class, C3.class).find("createC1").run());
616 assertNotNull(b.createMethodFinder(C.class, C3.class).find("createC2").run());
617 assertNotNull(b.createMethodFinder(C.class, C3.class).find("createC3").run().a);
618 assertNull(b.createMethodFinder(C.class, C3.class).find("createC4").run());
619 assertNull(b.createMethodFinder(C.class, C3.class).find("createC5").run().a);
620 assertNotNull(b.createMethodFinder(C.class, C3.class).find("createC6").run());
621 }
622 assertNotNull(b2c.createMethodFinder(C.class).find("createC1").run());
623 assertNotNull(b2c.createMethodFinder(C.class).find("createC2").run());
624 assertNotNull(b2c.createMethodFinder(C.class).find("createC3").run().a);
625 assertNull(b2c.createMethodFinder(C.class).find("createC4").run());
626 assertNull(b2c.createMethodFinder(C.class).find("createC5").run().a);
627 assertNotNull(b2c.createMethodFinder(C.class).find("createC6").run());
628 for (var m : array("createC1","createC2","createC3","createC4","createC5","createC6")) {
629 assertNull(b3c.createMethodFinder(C.class).find(m).run());
630 }
631
632 b1p.clear().addSupplier(A1.class, A1::new);
633 b2p.clear().addSupplier(A1.class, A1::new);
634 for (var b : array(b1c, b2c)) {
635 assertNotNull(b.createMethodFinder(C.class, x).find("createC1").run());
636 assertNotNull(b.createMethodFinder(C.class, x).find("createC2").run());
637 assertNotNull(b.createMethodFinder(C.class, x).find("createC3").run().a);
638 assertNull(b.createMethodFinder(C.class, x).find("createC4").run());
639 assertNull(b.createMethodFinder(C.class, x).find("createC5").run().a);
640 assertNotNull(b.createMethodFinder(C.class, x).find("createC6").run());
641 assertNull(b.createMethodFinder(C.class, C3.class).find("createC1").run());
642 assertNotNull(b.createMethodFinder(C.class, C3.class).find("createC2").run());
643 assertNotNull(b.createMethodFinder(C.class, C3.class).find("createC3").run().a);
644 assertNull(b.createMethodFinder(C.class, C3.class).find("createC4").run());
645 assertNull(b.createMethodFinder(C.class, C3.class).find("createC5").run().a);
646 assertNotNull(b.createMethodFinder(C.class, C3.class).find("createC6").run());
647 }
648 assertNotNull(b2c.createMethodFinder(C.class).find("createC1").run());
649 assertNotNull(b2c.createMethodFinder(C.class).find("createC2").run());
650 assertInstanceOf(A1.class, b2c.createMethodFinder(C.class).find("createC3").run().a);
651 assertNull(b2c.createMethodFinder(C.class).find("createC4").run());
652 assertNull(b2c.createMethodFinder(C.class).find("createC5").run().a);
653 assertNotNull(b2c.createMethodFinder(C.class).find("createC6").run());
654 for (var m : array("createC1","createC2","createC3","createC4","createC5","createC6")) {
655 assertNull(b3c.createMethodFinder(C.class).find(m).run());
656 }
657
658 b1p.clear().add(A1.class, null);
659 b2p.clear().add(A1.class, null);
660 for (var b : array(b1c, b2c)) {
661 assertNotNull(b.createMethodFinder(C.class, x).find("createC1").run());
662 assertNotNull(b.createMethodFinder(C.class, x).find("createC2").run());
663 assertNull(b.createMethodFinder(C.class, x).find("createC3").run().a);
664 assertNull(b.createMethodFinder(C.class, x).find("createC4").run());
665 assertNull(b.createMethodFinder(C.class, x).find("createC5").run().a);
666 assertNotNull(b.createMethodFinder(C.class, x).find("createC6").run());
667 assertNull(b.createMethodFinder(C.class, C3.class).find("createC1").run());
668 assertNotNull(b.createMethodFinder(C.class, C3.class).find("createC2").run());
669 assertNull(b.createMethodFinder(C.class, C3.class).find("createC3").run().a);
670 assertNull(b.createMethodFinder(C.class, C3.class).find("createC4").run());
671 assertNull(b.createMethodFinder(C.class, C3.class).find("createC5").run().a);
672 assertNotNull(b.createMethodFinder(C.class, C3.class).find("createC6").run());
673 }
674 assertNotNull(b2c.createMethodFinder(C.class).find("createC1").run());
675 assertNotNull(b2c.createMethodFinder(C.class).find("createC2").run());
676 assertNull(b2c.createMethodFinder(C.class).find("createC3").run().a);
677 assertNull(b2c.createMethodFinder(C.class).find("createC4").run());
678 assertNull(b2c.createMethodFinder(C.class).find("createC5").run().a);
679 assertNotNull(b2c.createMethodFinder(C.class).find("createC6").run());
680 for (var m : array("createC1","createC2","createC3","createC4","createC5","createC6")) {
681 assertNull(b3c.createMethodFinder(C.class).find(m).run());
682 }
683
684 b1p.clear().addBean(A1.class, new A1()).add(A1.class, new A1(), "Foo");
685 b2p.clear().addBean(A1.class, new A1()).add(A1.class, new A1(), "Foo");
686 for (var b : array(b1c, b2c)) {
687 assertNotNull(b.createMethodFinder(C.class, x).find("createC1").run());
688 assertNotNull(b.createMethodFinder(C.class, x).find("createC2").run());
689 assertNotNull(b.createMethodFinder(C.class, x).find("createC3").run().a);
690 assertNotNull(b.createMethodFinder(C.class, x).find("createC4").run());
691 assertNotNull(b.createMethodFinder(C.class, x).find("createC5").run().a);
692 assertNotNull(b.createMethodFinder(C.class, x).find("createC6").run());
693 assertNull(b.createMethodFinder(C.class, C3.class).find("createC1").run());
694 assertNotNull(b.createMethodFinder(C.class, C3.class).find("createC2").run());
695 assertNotNull(b.createMethodFinder(C.class, C3.class).find("createC3").run().a);
696 assertNotNull(b.createMethodFinder(C.class, C3.class).find("createC4").run());
697 assertNotNull(b.createMethodFinder(C.class, C3.class).find("createC5").run().a);
698 assertNotNull(b.createMethodFinder(C.class, C3.class).find("createC6").run());
699 }
700 assertNotNull(b2c.createMethodFinder(C.class).find("createC1").run());
701 assertNotNull(b2c.createMethodFinder(C.class).find("createC2").run());
702 assertNotNull(b2c.createMethodFinder(C.class).find("createC3").run().a);
703 assertNotNull(b2c.createMethodFinder(C.class).find("createC4").run());
704 assertNotNull(b2c.createMethodFinder(C.class).find("createC5").run().a);
705 assertNotNull(b2c.createMethodFinder(C.class).find("createC6").run());
706 for (var m : array("createC1","createC2","createC3","createC4","createC5","createC6")) {
707 assertNull(b3c.createMethodFinder(C.class).find(m).run());
708 }
709 }
710
711
712 public static class C4 {
713 public static String createC1(A1 a) { return "createC1"; }
714 public static String createC2() { return "createC2"; }
715 }
716
717 @Test void c04_createMethodFinder_beanMatching_requiredArgs() throws Exception {
718 var x = new C4();
719 var b1p = BeanStore.create().build();
720 var b1c = BeanStore.create().outer(x).parent(b1p).build();
721
722 assertString("createC2", b1c.createMethodFinder(String.class).find("createC1").thenFind("createC2").run());
723 assertString("createC2", b1c.createMethodFinder(String.class).find("createC2").thenFind("createC1").run());
724
725 b1p.add(A1.class, null);
726 assertString("createC1", b1c.createMethodFinder(String.class).find("createC1").thenFind("createC2").run());
727 assertString("createC2", b1c.createMethodFinder(String.class).find("createC2").thenFind("createC1").run());
728 assertString("createC1", b1c.createMethodFinder(String.class).find(x2->x2.hasName("createC1") && x2.hasAllArgs(A1.class)).thenFind(x2->x2.hasName("createC2") && x2.hasAllArgs(A1.class)).run());
729 assertString("createC1", b1c.createMethodFinder(String.class).find(x2->x2.hasName("createC2") && x2.hasAllArgs(A1.class)).thenFind(x2->x2.hasName("createC1") && x2.hasAllArgs(A1.class)).run());
730
731 b1p.clear();
732 assertString("createC1", b1c.createMethodFinder(String.class).addBean(A1.class, null).find("createC1").thenFind("createC2").run());
733 assertString("createC2", b1c.createMethodFinder(String.class).addBean(A1.class, null).find("createC2").thenFind("createC1").run());
734 assertString("createC1", b1c.createMethodFinder(String.class).addBean(A1.class, null).find(x2->x2.hasName("createC1") && x2.hasAllArgs(A1.class)).thenFind(x2->x2.hasName("createC2") && x2.hasAllArgs(A1.class)).run());
735 assertString("createC1", b1c.createMethodFinder(String.class).addBean(A1.class, null).find(x2->x2.hasName("createC2") && x2.hasAllArgs(A1.class)).thenFind(x2->x2.hasName("createC1") && x2.hasAllArgs(A1.class)).run());
736
737 assertString("X", b1c.createMethodFinder(String.class).withDefault("X").run());
738 assertString("X", b1c.createMethodFinder(String.class).withDefault(()->"X").run());
739
740 b1c.createMethodFinder(String.class).withDefault("X").run(y -> assertString("X", y));
741 }
742
743
744 public class C5 {
745 public String createC1(A1 a) { return "createC1"; }
746 public String createC2() { return "createC2"; }
747 }
748
749 @Test void c05_createMethodFinder_beanMatching_requiredArgs_innerClass() throws Exception {
750 var x = new C5();
751 var b1p = BeanStore.create().build();
752 var b1c = BeanStore.create().outer(x).parent(b1p).build();
753
754 assertString("createC2", b1c.createMethodFinder(String.class).find("createC1").thenFind("createC2").run());
755 assertString("createC2", b1c.createMethodFinder(String.class).find("createC2").thenFind("createC1").run());
756
757 b1p.add(A1.class, null);
758 assertString("createC1", b1c.createMethodFinder(String.class).find("createC1").thenFind("createC2").run());
759 assertString("createC2", b1c.createMethodFinder(String.class).find("createC2").thenFind("createC1").run());
760 assertString("createC1", b1c.createMethodFinder(String.class).find(x2->x2.hasName("createC1") && x2.hasAllArgs(A1.class)).thenFind(x2->x2.hasName("createC2") && x2.hasAllArgs(A1.class)).run());
761 assertString("createC1", b1c.createMethodFinder(String.class).find(x2->x2.hasName("createC2") && x2.hasAllArgs(A1.class)).thenFind(x2->x2.hasName("createC1") && x2.hasAllArgs(A1.class)).run());
762
763 b1p.clear();
764 assertString("createC1", b1c.createMethodFinder(String.class).addBean(A1.class, null).find("createC1").thenFind("createC2").run());
765 assertString("createC2", b1c.createMethodFinder(String.class).addBean(A1.class, null).find("createC2").thenFind("createC1").run());
766 assertString("createC1", b1c.createMethodFinder(String.class).addBean(A1.class, null).find(x2->x2.hasName("createC1") && x2.hasAllArgs(A1.class)).thenFind(x2->x2.hasName("createC2") && x2.hasAllArgs(A1.class)).run());
767 assertString("createC1", b1c.createMethodFinder(String.class).addBean(A1.class, null).find(x2->x2.hasName("createC2") && x2.hasAllArgs(A1.class)).thenFind(x2->x2.hasName("createC1") && x2.hasAllArgs(A1.class)).run());
768
769 assertString("X", b1c.createMethodFinder(String.class).withDefault("X").run());
770 assertString("X", b1c.createMethodFinder(String.class).withDefault(()->"X").run());
771
772 b1c.createMethodFinder(String.class).withDefault("X").run(y -> assertString("X", y));
773 }
774
775
776
777
778
779 public static class D1a {}
780 public class D1b {}
781
782 @Test void d01_createBean_basic() {
783 var bs = BeanStore.create().outer(new BeanStore_Test()).build();
784 assertNotNull(bs.createBean(D1a.class).run());
785 assertNotNull(bs.createBean(D1b.class).run());
786 assertNull(bs.createBean(null).run());
787 }
788
789 public static class D2 {
790 public static D2 create() { return d2; }
791 }
792 public static D2 d2 = new D2();
793
794 @Test void d02_createBean_staticCreator_create() {
795 var bs = BeanStore.INSTANCE;
796 assertEquals(d2, bs.createBean(D2.class).run());
797 }
798
799 public abstract static class D3 {
800 public static D3 getInstance() { return d3; }
801 }
802 public static D3 d3 = new D3() {};
803
804 @Test void d03_createBean_staticCreator_getInstance() {
805 var bs = BeanStore.INSTANCE;
806 assertEquals(d3, bs.createBean(D3.class).run());
807 }
808
809 public static class D4a {
810 public static D4a getFoo() { return d4a1; }
811 protected static D4a create() { return d4a2; }
812 public static D4a create(String foo) { return d4a3; }
813 @Deprecated protected static D4a getInstance() { return d4a4; }
814 protected D4a() {}
815 }
816 public static D4a d4a1 = new D4a(), d4a2 = new D4a(), d4a3 = new D4a(), d4a4 = new D4a();
817
818 public static class D4b {
819 public D4b create() { return d4b1; }
820 @BeanIgnore public static D4b getInstance() { return d4b2; }
821 protected D4b() {}
822 }
823 public static D4b d4b1 = new D4b(), d4b2 = new D4b();
824
825 public static class D4c {
826 public static String create() { return null; }
827 protected D4c() {}
828 }
829
830 @Test void d04_createBean_staticCreator_invalidSignatures() {
831 var bs = BeanStore.INSTANCE;
832 assertNotEqualsAny(bs.createBean(D4a.class).run(), d4a1, d4a2, d4a3, d4a4);
833 assertNotEqualsAny(bs.createBean(D4b.class).run(), d4b1, d4b2);
834 assertNotNull(bs.createBean(D4c.class).run());
835 }
836
837 public static class D5 {
838 public static D5 create() { return d5a; }
839 public static D5 create(Integer i, String s) { return d5b; }
840 public static D5 create(Integer i) { return d5c; }
841 protected D5() {}
842 }
843 public static D5 d5a = new D5(), d5b = new D5(), d5c = new D5();
844
845 @Test void d05_createBean_staticCreator_withBeans() {
846 var bs = BeanStore.create().build();
847 assertEquals(d5a, bs.createBean(D5.class).run());
848 bs.add(Integer.class, 1);
849 assertEquals(d5c, bs.createBean(D5.class).run());
850 bs.add(String.class, "x");
851 assertEquals(d5b, bs.createBean(D5.class).run());
852 bs.removeBean(Integer.class);
853 assertEquals(d5a, bs.createBean(D5.class).run());
854 }
855
856 public static class D6 {
857 public String s;
858 public static D6 create() { return new D6("0"); }
859 protected D6(String s) {
860 this.s = s;
861 }
862 }
863
864 @Test void d06_createBean_staticCreator_ignoredWithBuilder() {
865 var bs = BeanStore.INSTANCE;
866 assertString("1", bs.createBean(D6.class).builder(String.class, "1").run().s);
867 }
868
869 public static class D7 {
870 public String a;
871 public static D7 create(Optional<String> s) { return new D7(s.orElse("X")); }
872 protected D7(String s) { a = s; }
873 }
874
875 @Test void d07_createBean_staticCreator_withOptional() {
876 var bs = BeanStore.create().build();
877 assertString("X", bs.createBean(D7.class).run().a);
878 bs.add(String.class, "bar");
879 assertString("bar", bs.createBean(D7.class).run().a);
880 }
881
882 public static class D8 {
883 public String a = "foo";
884 public static D8 create(Optional<String> s, Integer i) { return new D8(s.orElse(null) + "," + i); }
885 private D8(String s) { a = s; }
886 }
887
888 @Test void d08_createBean_staticCreator_missingPrereqs() {
889 var bs = BeanStore.create().build();
890 assertThrowsWithMessage(ExecutableException.class, "Could not instantiate class org.apache.juneau.cp.BeanStore_Test$D8: Static creator found but could not find prerequisites: Integer.", ()->bs.createBean(D8.class).run());
891 bs.add(Integer.class, 1);
892 assertString("null,1", bs.createBean(D8.class).run().a);
893 bs.add(String.class, "bar");
894 assertString("bar,1", bs.createBean(D8.class).run().a);
895 }
896
897 public abstract static class D9a {
898 public D9a() {}
899 }
900
901 public interface D9b {}
902
903 @Test void d09_createBean_staticCreator_withBeans() {
904 var bs = BeanStore.INSTANCE;
905 assertThrowsWithMessage(ExecutableException.class, "Could not instantiate class "+D9a.class.getName()+": Class is abstract.", ()->bs.createBean(D9a.class).run());
906 assertThrowsWithMessage(ExecutableException.class, "Could not instantiate class "+D9b.class.getName()+": Class is an interface.", ()->bs.createBean(D9b.class).run());
907 }
908
909 public static class D10 {
910 public String a;
911 public D10(String s) { a = "s="+s; }
912 public D10(Integer i) { a = "i="+i; }
913 public D10(String s, Integer i) { a = "s="+s+",i="+i; }
914 }
915
916 @Test void d10_createBean_constructors_public() {
917 var bs = BeanStore.create().build();
918 assertThrowsWithMessage(ExecutableException.class, "Could not instantiate class "+D10.class.getName()+": Public constructor found but could not find prerequisites: Integer or Integer,String or String.", ()->bs.createBean(D10.class).run());
919 bs.add(String.class, "foo");
920 assertString("s=foo", bs.createBean(D10.class).run().a);
921 bs.add(Integer.class, 1);
922 assertString("s=foo,i=1", bs.createBean(D10.class).run().a);
923 bs.removeBean(String.class);
924 assertString("i=1", bs.createBean(D10.class).run().a);
925 }
926
927 public static class D11 {
928 public String a;
929 protected D11(String s) { a = "s="+s; }
930 protected D11(Integer i) { a = "i="+i; }
931 protected D11(String s, Integer i) { a = "s="+s+",i="+i; }
932 }
933
934 @Test void d11_createBean_constructors_protected() {
935 var bs = BeanStore.create().build();
936 assertThrowsWithMessage(ExecutableException.class, "Could not instantiate class "+D11.class.getName()+": Protected constructor found but could not find prerequisites: Integer or Integer,String or String.", ()->bs.createBean(D11.class).run());
937 bs.add(String.class, "foo");
938 assertString("s=foo", bs.createBean(D11.class).run().a);
939 bs.add(Integer.class, 1);
940 assertString("s=foo,i=1", bs.createBean(D11.class).run().a);
941 bs.removeBean(String.class);
942 assertString("i=1", bs.createBean(D11.class).run().a);
943 }
944
945 public static class D12 {
946 public String a;
947 public D12(String s) { a = "s="+s; }
948 protected D12(String s, Integer i) { a = "s="+s+",i="+i; }
949 }
950
951 @Test void d12_createBean_constructors_publicOverProtected() {
952 var bs = BeanStore.create().build();
953 assertThrowsWithMessage(ExecutableException.class, "Could not instantiate class "+D12.class.getName()+": Public constructor found but could not find prerequisites: String.", ()->bs.createBean(D12.class).run());
954 bs.add(String.class, "foo");
955 bs.add(Integer.class, 1);
956 assertString("s=foo", bs.createBean(D12.class).run().a);
957 }
958
959 public static class D13 {
960 private D13() {}
961 }
962
963 @Test void d13_createBean_constructors_private() {
964 var bs = BeanStore.INSTANCE;
965 assertThrowsWithMessage(ExecutableException.class, "Could not instantiate class "+D13.class.getName()+": No public/protected constructors found.", ()->bs.createBean(D13.class).run());
966 }
967
968 public static class D14 {
969 public String a;
970 public D14(@Named("foo") String o) { a = o; }
971 public D14(@Named("foo") String o, Integer i) { a = o + "," + i; }
972 }
973
974 @Test void d14_createBean_constructors_namedBean() {
975 var bs = BeanStore.create().build();
976 assertThrowsWithMessage(ExecutableException.class, "Could not instantiate class "+D14.class.getName()+": Public constructor found but could not find prerequisites: Integer,String@foo or String@foo.", ()->bs.createBean(D14.class).run());
977 bs.add(String.class, "bar", "foo");
978 assertString("bar", bs.createBean(D14.class).run().a);
979 }
980
981 public class D15 {
982 public String a;
983 public D15(@Named("foo") String o) { a = o; }
984 public D15(@Named("foo") String o, Integer i) { a = o + "," + i; }
985 }
986
987 @Test void d15_createBean_constructors_namedBean_withOuter() {
988 var bs = BeanStore.create().outer(new BeanStore_Test()).build();
989 assertThrowsWithMessage(ExecutableException.class, "Could not instantiate class "+D15.class.getName()+": Public constructor found but could not find prerequisites: Integer,String@foo or String@foo.", ()->bs.createBean(D15.class).run());
990 bs.add(String.class, "bar", "foo");
991 assertString("bar", bs.createBean(D15.class).run().a);
992 }
993
994 public static class D16 {
995 public String a;
996 public static Builder create() { return new Builder(); }
997 public static class Builder {
998 public String b;
999 }
1000 protected D16(Builder b) { a = b.b; }
1001 }
1002
1003 @Test void d16_createBean_builders() {
1004 var bs = BeanStore.create().build();
1005 var b = D16.create();
1006 b.b = "foo";
1007 assertString("foo", bs.createBean(D16.class).builder(D16.Builder.class, b).run().a);
1008 }
1009
1010 public static class D17 {
1011 public String a;
1012 public static Builder create() { return new Builder(); }
1013 public static class Builder {
1014 public String b;
1015 }
1016 protected D17(Builder b, Integer i) { a = b.b; }
1017 protected D17(Integer i) {}
1018 D17(String s) {}
1019 protected D17(Builder b) { a = b.b; }
1020 }
1021
1022 @Test void d17_createBean_builders_inherent() {
1023 var bs = BeanStore.create().build();
1024 assertNull(bs.createBean(D17.class).run().a);
1025 assertThrowsWithMessage(ExecutableException.class, "Could not instantiate class "+D17.class.getName()+": Protected constructor found but could not find prerequisites: Builder or Builder,Integer or Integer.", ()->bs.createBean(D17.class).builder(Boolean.class, true).run());
1026 }
1027
1028
1029
1030
1031
1032 @SafeVarargs
1033 private static <T> T[] array(T...t) {
1034 return t;
1035 }
1036 }