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.apache.juneau.junit.bct.BctAssertions.*;
23 import static org.junit.jupiter.api.Assertions.*;
24
25 import java.lang.annotation.*;
26 import java.util.*;
27 import java.util.function.*;
28
29 import org.apache.juneau.*;
30 import org.apache.juneau.annotation.*;
31 import org.apache.juneau.annotation.Named;
32 import org.apache.juneau.commons.reflect.*;
33 import org.apache.juneau.commons.utils.*;
34 import org.junit.jupiter.api.*;
35
36 class BeanStore_Test extends TestBase {
37
38 @Documented
39 @Target({PARAMETER})
40 @Retention(RUNTIME)
41 @Inherited
42 public @interface Name {
43 String value();
44 }
45
46
47
48
49
50 public static class A1 {}
51 public static class A2 {}
52
53 public static final String A1n = A1.class.getSimpleName();
54
55 public static class A3 extends BeanStore {
56 protected A3(Builder builder) {
57 super(builder);
58 }
59 }
60
61 private static A1 a1a = new A1(), a1b = new A1(), a1c = new A1(), a1d = new A1(), a1e = new A1();
62 private static A2 a2a = new A2();
63
64 @Test void a00_dummy() {
65 assertDoesNotThrow(BeanStore.Void::new);
66 }
67
68 @Test void a01_builderCopyConstructor() {
69 var b1p = BeanStore.create().readOnly().threadSafe().build();
70 var b1c = BeanStore.create().parent(b1p).build();
71 assertContains("readOnly=true", b1c.toString());
72 assertContains("threadSafe=true", b1c.toString());
73 }
74
75 @Test void a02_readOnly() {
76 var b1p = BeanStore.create().readOnly().build();
77 var b1c = BeanStore.create().parent(b1p).build();
78 var b2p = BeanStore.create().readOnly().threadSafe().build();
79 var b2c = BeanStore.create().parent(b1p).threadSafe().build();
80
81 for (var b : array(b1p, b2p)) {
82 assertThrowsWithMessage(IllegalStateException.class, "Method cannot be used because BeanStore is read-only.", ()->b.add(A1.class, a1a));
83 assertThrowsWithMessage(IllegalStateException.class, "Method cannot be used because BeanStore is read-only.", ()->b.add(A1.class, a1a, "foo"));
84 assertThrowsWithMessage(IllegalStateException.class, "Method cannot be used because BeanStore is read-only.", ()->b.addBean(A1.class, a1a));
85 assertThrowsWithMessage(IllegalStateException.class, "Method cannot be used because BeanStore is read-only.", ()->b.addBean(A1.class, a1a, "foo"));
86 assertThrowsWithMessage(IllegalStateException.class, "Method cannot be used because BeanStore is read-only.", ()->b.addSupplier(A1.class, ()->a1a));
87 assertThrowsWithMessage(IllegalStateException.class, "Method cannot be used because BeanStore is read-only.", ()->b.addSupplier(A1.class, ()->a1a, "foo"));
88 assertThrowsWithMessage(IllegalStateException.class, "Method cannot be used because BeanStore is read-only.", b::clear);
89 assertThrowsWithMessage(IllegalStateException.class, "Method cannot be used because BeanStore is read-only.", ()->b.removeBean(A1.class));
90 assertThrowsWithMessage(IllegalStateException.class, "Method cannot be used because BeanStore is read-only.", ()->b.removeBean(A1.class, "foo"));
91 }
92
93 for (var b : array(b1c, b2c)) {
94 b.add(A1.class, a1a);
95 b.add(A1.class, a1a, "foo");
96 b.addBean(A1.class, a1a);
97 b.addBean(A1.class, a1a, "foo");
98 b.addSupplier(A1.class, ()->a1a);
99 b.addSupplier(A1.class, ()->a1a, "foo");
100 b.clear();
101 b.removeBean(A1.class);
102 b.removeBean(A1.class, "foo");
103 }
104 }
105
106 @Test void a04_addBean() {
107 var b1p = BeanStore.create().build();
108 var b1c = BeanStore.of(b1p);
109 var b2p = BeanStore.create().threadSafe().build();
110 var b2c = BeanStore.create().threadSafe().parent(b2p).build();
111
112 for (var b : array(b1p, b1c, b2p, b2c)) {
113 assertFalse(b.hasBean(A1.class));
114 assertEmpty(b.getBean(A1.class));
115 }
116
117 b1p.addBean(A1.class, a1a);
118 b2p.addBean(A1.class, a1a);
119 for (var b : array(b1p, b1c, b2p, b2c)) {
120 assertTrue(b.hasBean(A1.class));
121 assertEquals(a1a, b.getBean(A1.class).get());
122 }
123
124 b1p.clear();
125 b2p.clear();
126 for (var b : array(b1p, b1c, b2p, b2c)) {
127 assertFalse(b.hasBean(A1.class));
128 assertEmpty(b.getBean(A1.class));
129 }
130
131 b1p.addBean(A1.class, null);
132 b2p.addBean(A1.class, null);
133 for (var b : array(b1p, b1c, b2p, b2c)) {
134 assertTrue(b.hasBean(A1.class));
135 assertEmpty(b.getBean(A1.class));
136 }
137
138 b1p.clear().addSupplier(A1.class, ()->a1a);
139 b2p.clear().addSupplier(A1.class, ()->a1a);
140 for (var b : array(b1p, b1c, b2p, b2c)) {
141 assertTrue(b.hasBean(A1.class));
142 assertEquals(a1a, b.getBean(A1.class).get());
143 }
144
145 b1p.add(A1.class, a1b);
146 b2p.add(A1.class, a1b);
147 for (var b : array(b1p, b1c, b2p, b2c)) {
148 assertTrue(b.hasBean(A1.class));
149 assertEquals(a1b, b.getBean(A1.class).get());
150 assertList(b.stream(A1.class).map(BeanStoreEntry::get), a1b, a1a);
151 }
152
153 b1c.add(A2.class, a2a);
154 b2c.add(A2.class, a2a);
155 for (var b : array(b1p, b2p)) {
156 assertFalse(b.hasBean(A2.class));
157 assertEmpty(b.getBean(A2.class));
158 assertEmpty(b.stream(A2.class));
159 }
160 for (var b : array(b1c, b2c)) {
161 assertTrue(b.hasBean(A2.class));
162 assertEquals(a2a, b.getBean(A2.class).get());
163 assertList(b.stream(A2.class).map(BeanStoreEntry::get), a2a);
164 }
165
166 assertMatchesGlob("{entries=[{type=A1,bean="+Utils.id(a1b)+"},{type=A1,bean="+Utils.id(a1a)+"}],identity=*}", b1p);
167 assertMatchesGlob("{entries=[{type=A2,bean="+Utils.id(a2a)+"}],identity=*,parent={entries=[{type=A1,bean="+Utils.id(a1b)+"},{type=A1,bean="+Utils.id(a1a)+"}],identity=*}}", b1c);
168 assertMatchesGlob("{entries=[{type=A1,bean="+Utils.id(a1b)+"},{type=A1,bean="+Utils.id(a1a)+"}],identity=*,threadSafe=true}", b2p);
169 assertMatchesGlob("{entries=[{type=A2,bean="+Utils.id(a2a)+"}],identity=*,parent={entries=[{type=A1,bean="+Utils.id(a1b)+"},{type=A1,bean="+Utils.id(a1a)+"}],identity=*,threadSafe=true},threadSafe=true}", b2c);
170
171 b1p.removeBean(A1.class);
172 b1c.clear().addBean(A1.class, a1a);
173 b2p.removeBean(A1.class);
174 b2c.clear().addBean(A1.class, a1a);
175
176 for (var b : array(b1p, b2p)) {
177 assertFalse(b.hasBean(A1.class));
178 assertEmpty(b.getBean(A1.class));
179 assertEmpty(b.stream(A1.class));
180 }
181 for (var b : array(b1c, b2c)) {
182 assertTrue(b.hasBean(A1.class));
183 assertEquals(a1a, b.getBean(A1.class).get());
184 assertList(b.stream(A1.class).map(BeanStoreEntry::get), a1a);
185 }
186
187 b1c.removeBean(A1.class);
188 b2c.removeBean(A1.class);
189 for (var b : array(b1p, b1c, b2p, b2c)) {
190 assertFalse(b.hasBean(A1.class));
191 assertEmpty(b.getBean(A1.class));
192 assertEmpty(b.stream(A1.class));
193 }
194 }
195
196 @Test void a05_addNamedBeans() {
197 var b1p = BeanStore.create().build();
198 var b1c = BeanStore.of(b1p);
199 var b2p = BeanStore.create().threadSafe().build();
200 var b2c = BeanStore.create().threadSafe().parent(b2p).build();
201
202 for (var b : array(b1p, b2p)) {
203 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");
204 }
205 for (var b : array(b1c, b2c)) {
206 b.addBean(A1.class, a1e);
207 }
208
209 for (var b : array(b1p, b2p)) {
210 assertList(b.stream(A1.class).map(BeanStoreEntry::get), a1d,a1c,a1b,a1a);
211 }
212 for (var b : array(b1c, b2c)) {
213 assertList(b.stream(A1.class).map(BeanStoreEntry::get), a1e,a1d,a1c,a1b,a1a);
214 }
215
216 for (var b : array(b1p, b1c, b2p, b2c)) {
217 assertEquals(a1b, b.getBean(A1.class, "foo").get());
218 assertEquals(a1d, b.getBean(A1.class, "bar").get());
219 assertEmpty(b.getBean(A1.class, "baz"));
220 }
221 for (var b : array(b1p, b2p)) {
222 assertEquals(a1a, b.getBean(A1.class, null).get());
223 }
224 for (var b : array(b1c, b2c)) {
225 assertEquals(a1e, b.getBean(A1.class, null).get());
226 }
227 }
228
229
230
231
232
233 public static class B1 {
234 A1 a1;
235 Optional<A2> a2;
236 BeanStore a3;
237
238 public B1(A1 a1, Optional<A2> a2, BeanStore a3) {
239 this.a1 = a1;
240 this.a2 = a2;
241 this.a3 = a3;
242 }
243
244 public B1(@Named("foo") A1 a1, @Named("bar") Optional<A2> a2) {
245 this.a1 = a1;
246 this.a2 = a2;
247 }
248
249 public void m1(A1 a1, Optional<A2> a2, BeanStore a3) {
250 this.a1 = a1;
251 this.a2 = a2;
252 this.a3 = a3;
253 }
254
255 public void m2(@Named("foo") A1 a1, @Named("bar") Optional<A2> a2) {
256 this.a1 = a1;
257 this.a2 = a2;
258 this.a3 = null;
259 }
260
261 public static B1 m3(A1 a1, Optional<A2> a2, BeanStore a3) {
262 return new B1(a1, a2, a3);
263 }
264 }
265
266 @Test void b01_getParams() {
267
268 Predicate<Object> pEmptyOptional = x -> !((Optional<?>)x).isPresent();
269 Predicate<Object> pIsBeanStore = BeanStore.class::isInstance;
270 Predicate<Object> pNull = x -> x == null;
271 Predicate<Object> pA1a = x -> x==a1a;
272 Predicate<Object> pA2a = x -> ((Optional<?>)x).get()==a2a;
273
274 var outer = new B1(null, null, null);
275
276 var b1p = BeanStore.create().outer(outer).build();
277 var b1c = BeanStore.create().outer(outer).parent(b1p).build();
278 var b2p = BeanStore.create().outer(outer).threadSafe().build();
279 var b2c = BeanStore.create().outer(outer).parent(b1p).threadSafe().build();
280
281 var ci = ClassInfo.of(B1.class);
282 var c1 = ci.getPublicConstructor(x -> x.hasParameterTypes(A1.class, Optional.class, BeanStore.class)).get();
283 var c2 = ci.getPublicConstructor(x -> x.hasParameterTypes(A1.class, Optional.class)).get();
284 var m1 = ci.getPublicMethod(x-> x.hasName("m1")).get();
285 var m2 = ci.getPublicMethod(x-> x.hasName("m2")).get();
286 var m3 = ci.getPublicMethod(x-> x.hasName("m3")).get();
287
288 for (var b : array(b1p, b1c, b2p, b2c)) {
289 for (var e : array(c1, m1, m3)) {
290 assertString(A1n, b.getMissingParams(e));
291 assertFalse(b.hasAllParams(e));
292 }
293 for (var e : array(c2, m2)) {
294 assertString(A1n+"@foo", b.getMissingParams(e));
295 assertFalse(b.hasAllParams(e));
296 }
297 }
298
299 for (var b : array(b1p, b1c, b2p, b2c)) {
300 assertList(b.getParams(c1), pNull, pEmptyOptional, pIsBeanStore);
301 assertList(b.getParams(c2), pNull, pEmptyOptional);
302 assertList(b.getParams(m1), pNull, pEmptyOptional, pIsBeanStore);
303 assertList(b.getParams(m2), pNull, pEmptyOptional);
304 assertList(b.getParams(m3), pNull, pEmptyOptional, pIsBeanStore);
305 }
306
307 b1p.add(A1.class, a1a);
308 b2p.add(A1.class, a1a);
309 for (var b : array(b1p, b1c, b2p, b2c)) {
310 assertNull(b.getMissingParams(c1));
311 assertString(A1n+"@foo", b.getMissingParams(c2));
312 assertNull(b.getMissingParams(m1));
313 assertString(A1n+"@foo", b.getMissingParams(m2));
314 assertNull(b.getMissingParams(m3));
315 assertTrue(b.hasAllParams(c1));
316 assertFalse(b.hasAllParams(c2));
317 assertTrue(b.hasAllParams(m1));
318 assertFalse(b.hasAllParams(m2));
319 assertTrue(b.hasAllParams(m3));
320 assertList(b.getParams(c1), pA1a, pEmptyOptional, pIsBeanStore);
321 assertList(b.getParams(c2), pNull, pEmptyOptional);
322 assertList(b.getParams(m1), pA1a, pEmptyOptional, pIsBeanStore);
323 assertList(b.getParams(m2), pNull, pEmptyOptional);
324 assertList(b.getParams(m3), pA1a, pEmptyOptional, pIsBeanStore);
325 }
326
327 b1p.add(A1.class, a1a, "foo");
328 b2p.add(A1.class, a1a, "foo");
329 for (var b : array(b1p, b1c, b2p, b2c)) {
330 for (var e : array(c1, c2, m1, m2, m3)) {
331 assertNull(b.getMissingParams(e));
332 assertTrue(b.hasAllParams(e));
333 }
334 assertList(b.getParams(c1), pA1a, pEmptyOptional, pIsBeanStore);
335 assertList(b.getParams(c2), pA1a, pEmptyOptional);
336 assertList(b.getParams(m1), pA1a, pEmptyOptional, pIsBeanStore);
337 assertList(b.getParams(m2), pA1a, pEmptyOptional);
338 assertList(b.getParams(m3), pA1a, pEmptyOptional, pIsBeanStore);
339 }
340
341 b1p.add(A1.class, a1b, "bar");
342 b2p.add(A1.class, a1b, "bar");
343 for (var b : array(b1p, b1c, b2p, b2c)) {
344 for (var e : array(c1, c2, m1, m2, m3)) {
345 assertNull(b.getMissingParams(e));
346 assertTrue(b.hasAllParams(e));
347 }
348 assertList(b.getParams(c1), pA1a, pEmptyOptional, pIsBeanStore);
349 assertList(b.getParams(c2), pA1a, pEmptyOptional);
350 assertList(b.getParams(m1), pA1a, pEmptyOptional, pIsBeanStore);
351 assertList(b.getParams(m2), pA1a, pEmptyOptional);
352 assertList(b.getParams(m3), pA1a, pEmptyOptional, pIsBeanStore);
353 }
354
355 b1p.add(A2.class, a2a, "bar");
356 b2p.add(A2.class, a2a, "bar");
357 for (var b : array(b1p, b1c, b2p, b2c)) {
358 for (var e : array(c1, c2, m1, m2, m3)) {
359 assertNull(b.getMissingParams(e));
360 assertTrue(b.hasAllParams(e));
361 }
362 assertList(b.getParams(c1), pA1a, pEmptyOptional, pIsBeanStore);
363 assertList(b.getParams(c2), pA1a, pA2a);
364 assertList(b.getParams(m1), pA1a, pEmptyOptional, pIsBeanStore);
365 assertList(b.getParams(m2), pA1a, pA2a);
366 assertList(b.getParams(m3), pA1a, pEmptyOptional, pIsBeanStore);
367 }
368
369 b1p.add(A2.class, a2a, null);
370 b2p.add(A2.class, a2a, null);
371 for (var b : array(b1p, b1c, b2p, b2c)) {
372 for (var e : array(c1, c2, m1, m2, m3)) {
373 assertNull(b.getMissingParams(e));
374 assertTrue(b.hasAllParams(e));
375 }
376 assertList(b.getParams(c1), pA1a, pA2a, pIsBeanStore);
377 assertList(b.getParams(c2), pA1a, pA2a);
378 assertList(b.getParams(m1), pA1a, pA2a, pIsBeanStore);
379 assertList(b.getParams(m2), pA1a, pA2a);
380 assertList(b.getParams(m3), pA1a, pA2a, pIsBeanStore);
381 }
382 }
383
384 public class B2 {
385 A1 a1;
386 Optional<A2> a2;
387 BeanStore a3;
388
389 public B2(A1 a1, Optional<A2> a2, BeanStore a3) {
390 this.a1 = a1;
391 this.a2 = a2;
392 this.a3 = a3;
393 }
394
395 public B2(@Named("foo") A1 a1, @Named("bar") Optional<A2> a2) {
396 this.a1 = a1;
397 this.a2 = a2;
398 }
399 }
400
401 @Test void b02_getParams_innerClass() {
402
403 Predicate<Object> pEmptyOptional = x -> !((Optional<?>)x).isPresent();
404 Predicate<Object> pIsBeanStore = BeanStore.class::isInstance;
405 Predicate<Object> pNull = x -> x == null;
406 Predicate<Object> pThis = x -> x == this;
407 Predicate<Object> pA1a = x -> x==a1a;
408 Predicate<Object> pA2a = x -> ((Optional<?>)x).get()==a2a;
409
410 var b1p = BeanStore.create().outer(this).build();
411 var b1c = BeanStore.create().outer(this).parent(b1p).build();
412 var b2p = BeanStore.create().outer(this).threadSafe().build();
413 var b2c = BeanStore.create().outer(this).parent(b1p).threadSafe().build();
414
415 var ci = ClassInfo.of(B2.class);
416 var c1 = ci.getPublicConstructor(x -> x.hasParameterTypes(BeanStore_Test.class, A1.class, Optional.class, BeanStore.class)).get();
417 var c2 = ci.getPublicConstructor(x -> x.hasParameterTypes(BeanStore_Test.class, A1.class, Optional.class)).get();
418
419 for (var b : array(b1p, b1c, b2p, b2c)) {
420 assertString(A1n, b.getMissingParams(c1));
421 assertString(A1n+"@foo", b.getMissingParams(c2));
422 assertFalse(b.hasAllParams(c1));
423 assertFalse(b.hasAllParams(c2));
424 }
425
426 for (var b : array(b1p, b1c, b2p, b2c)) {
427 assertList(b.getParams(c1), pThis, pNull, pEmptyOptional, pIsBeanStore);
428 assertList(b.getParams(c2), pThis, pNull, pEmptyOptional);
429 }
430
431 b1p.add(A1.class, a1a);
432 b2p.add(A1.class, a1a);
433 for (var b : array(b1p, b1c, b2p, b2c)) {
434 assertNull(b.getMissingParams(c1));
435 assertString(A1n+"@foo", b.getMissingParams(c2));
436 assertTrue(b.hasAllParams(c1));
437 assertFalse(b.hasAllParams(c2));
438 assertList(b.getParams(c1), pThis, pA1a, pEmptyOptional, pIsBeanStore);
439 assertList(b.getParams(c2), pThis, pNull, pEmptyOptional);
440 }
441
442 b1p.add(A1.class, a1a, "foo");
443 b2p.add(A1.class, a1a, "foo");
444 for (var b : array(b1p, b1c, b2p, b2c)) {
445 for (var e : array(c1, c2)) {
446 assertNull(b.getMissingParams(e));
447 assertTrue(b.hasAllParams(e));
448 }
449 assertList(b.getParams(c1), pThis, pA1a, pEmptyOptional, pIsBeanStore);
450 assertList(b.getParams(c2), pThis, pA1a, pEmptyOptional);
451 }
452
453 b1p.add(A1.class, a1b, "bar");
454 b2p.add(A1.class, a1b, "bar");
455 for (var b : array(b1p, b1c, b2p, b2c)) {
456 for (var e : array(c1, c2)) {
457 assertNull(b.getMissingParams(e));
458 assertTrue(b.hasAllParams(e));
459 }
460 assertList(b.getParams(c1), pThis, pA1a, pEmptyOptional, pIsBeanStore);
461 assertList(b.getParams(c2), pThis, pA1a, pEmptyOptional);
462 }
463
464 b1p.add(A2.class, a2a, "bar");
465 b2p.add(A2.class, a2a, "bar");
466 for (var b : array(b1p, b1c, b2p, b2c)) {
467 for (var e : array(c1, c2)) {
468 assertNull(b.getMissingParams(e));
469 assertTrue(b.hasAllParams(e));
470 }
471 assertList(b.getParams(c1), pThis, pA1a, pEmptyOptional, pIsBeanStore);
472 assertList(b.getParams(c2), pThis, pA1a, pA2a);
473 }
474
475 b1p.add(A2.class, a2a, null);
476 b2p.add(A2.class, a2a, null);
477 for (var b : array(b1p, b1c, b2p, b2c)) {
478 for (var e : array(c1, c2)) {
479 assertNull(b.getMissingParams(e));
480 assertTrue(b.hasAllParams(e));
481 }
482 assertList(b.getParams(c1), pThis, pA1a, pA2a, pIsBeanStore);
483 assertList(b.getParams(c2), pThis, pA1a, pA2a);
484 }
485 }
486
487
488
489
490
491 public static class C {
492 public A1 a;
493 }
494
495 @Test void c00_createMethodFinder_invalidArgs() {
496 var b = BeanStore.create().build();
497 assertThrowsWithMessage(IllegalArgumentException.class, "Method cannot be used without outer bean definition.", ()->b.createMethodFinder(null));
498 assertThrowsWithMessage(IllegalArgumentException.class, "Argument 'beanType' cannot be null.", ()->b.createMethodFinder((Class<?>)null,""));
499 assertThrowsWithMessage(IllegalArgumentException.class, "Argument 'resourceClass' cannot be null.", ()->b.createMethodFinder(String.class,null));
500 }
501
502
503 public static class C1 {
504 public C createA1() { return new C(); }
505 public A1 createA2() { return new A1(); }
506 protected C createA3() { return new C(); }
507 @Deprecated public C createA4() { return new C(); }
508 @BeanIgnore public C createA5() { return new C(); }
509 public C createA6() { return null; }
510 public C createA7() { throw new RuntimeException("foo"); }
511 }
512
513
514 public static class C2 {
515 public static C createB1() { return new C(); }
516 public static A1 createB2() { return new A1(); }
517 protected static C createB3() { return new C(); }
518 @Deprecated public static C createB4() { return new C(); }
519 @BeanIgnore public static C createB5() { return new C(); }
520 public static C createB6() { return null; }
521 public static C createB7() { throw new RuntimeException("foo"); }
522 }
523
524
525 public static class C3 {
526 public C createC1(A1 a) { return new C(); }
527 public static C createC2(A1 a) { return new C(); }
528 public static C createC3(Optional<A1> a) { C e = new C(); e.a = a.orElse(null); return e; }
529 public static C createC4(@Named("Foo") A1 a) { return new C(); }
530 public static C createC5(@Named("Foo") Optional<A1> a) { C e = new C(); e.a = a.orElse(null); return e; }
531 public static C createC6(BeanStore bs) { assertNotNull(bs); return new C(); }
532 }
533
534
535
536
537
538
539 public static class D1a {}
540 public class D1b {}
541
542 @Test void d01_createBean_basic() {
543 var bs = BeanStore.create().outer(new BeanStore_Test()).build();
544 assertNotNull(bs.createBean(D1a.class).run());
545 assertNotNull(bs.createBean(D1b.class).run());
546 assertThrows(IllegalArgumentException.class, () -> bs.createBean(null).run());
547 }
548
549 public static class D2 {
550 public static D2 create() { return d2; }
551 }
552 public static D2 d2 = new D2();
553
554 @Test void d02_createBean_staticCreator_create() {
555 var bs = BeanStore.INSTANCE;
556 assertEquals(d2, bs.createBean(D2.class).run());
557 }
558
559 public abstract static class D3 {
560 public static D3 getInstance() { return d3; }
561 }
562 public static D3 d3 = new D3() {};
563
564 @Test void d03_createBean_staticCreator_getInstance() {
565 var bs = BeanStore.INSTANCE;
566 assertEquals(d3, bs.createBean(D3.class).run());
567 }
568
569 public static class D4a {
570 public static D4a getFoo() { return d4a1; }
571 protected static D4a create() { return d4a2; }
572 public static D4a create(String foo) { return d4a3; }
573 @Deprecated protected static D4a getInstance() { return d4a4; }
574 protected D4a() {}
575 }
576 public static D4a d4a1 = new D4a(), d4a2 = new D4a(), d4a3 = new D4a(), d4a4 = new D4a();
577
578 public static class D4b {
579 public D4b create() { return d4b1; }
580 @BeanIgnore public static D4b getInstance() { return d4b2; }
581 protected D4b() {}
582 }
583 public static D4b d4b1 = new D4b(), d4b2 = new D4b();
584
585 public static class D4c {
586 public static String create() { return null; }
587 protected D4c() {}
588 }
589
590 @Test void d04_createBean_staticCreator_invalidSignatures() {
591 var bs = BeanStore.INSTANCE;
592 assertNotEqualsAny(bs.createBean(D4a.class).run(), d4a1, d4a2, d4a3, d4a4);
593 assertNotEqualsAny(bs.createBean(D4b.class).run(), d4b1, d4b2);
594 assertNotNull(bs.createBean(D4c.class).run());
595 }
596
597 public static class D5 {
598 public static D5 create() { return d5a; }
599 public static D5 create(Integer i, String s) { return d5b; }
600 public static D5 create(Integer i) { return d5c; }
601 protected D5() {}
602 }
603 public static D5 d5a = new D5(), d5b = new D5(), d5c = new D5();
604
605 @Test void d05_createBean_staticCreator_withBeans() {
606 var bs = BeanStore.create().build();
607 assertEquals(d5a, bs.createBean(D5.class).run());
608 bs.add(Integer.class, 1);
609 assertEquals(d5c, bs.createBean(D5.class).run());
610 bs.add(String.class, "x");
611 assertEquals(d5b, bs.createBean(D5.class).run());
612 bs.removeBean(Integer.class);
613 assertEquals(d5a, bs.createBean(D5.class).run());
614 }
615
616 public static class D6 {
617 public String s;
618 public static D6 create() { return new D6("0"); }
619 protected D6(String s) {
620 this.s = s;
621 }
622 }
623
624 @Test void d06_createBean_staticCreator_ignoredWithBuilder() {
625 var bs = BeanStore.INSTANCE;
626 assertString("1", bs.createBean(D6.class).builder(String.class, "1").run().s);
627 }
628
629 public static class D7 {
630 public String a;
631 public static D7 create(Optional<String> s) { return new D7(s.orElse("X")); }
632 protected D7(String s) { a = s; }
633 }
634
635 @Test void d07_createBean_staticCreator_withOptional() {
636 var bs = BeanStore.create().build();
637 assertString("X", bs.createBean(D7.class).run().a);
638 bs.add(String.class, "bar");
639 assertString("bar", bs.createBean(D7.class).run().a);
640 }
641
642 public static class D8 {
643 public String a = "foo";
644 public static D8 create(Optional<String> s, Integer i) { return new D8(s.orElse(null) + "," + i); }
645 private D8(String s) { a = s; }
646 }
647
648 @Test void d08_createBean_staticCreator_missingPrereqs() {
649 var bs = BeanStore.create().build();
650 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());
651 bs.add(Integer.class, 1);
652 assertString("null,1", bs.createBean(D8.class).run().a);
653 bs.add(String.class, "bar");
654 assertString("bar,1", bs.createBean(D8.class).run().a);
655 }
656
657 public abstract static class D9a {
658 public D9a() {}
659 }
660
661 public interface D9b {}
662
663 @Test void d09_createBean_staticCreator_withBeans() {
664 var bs = BeanStore.INSTANCE;
665 assertThrowsWithMessage(ExecutableException.class, "Could not instantiate class "+D9a.class.getName()+": Class is abstract.", ()->bs.createBean(D9a.class).run());
666 assertThrowsWithMessage(ExecutableException.class, "Could not instantiate class "+D9b.class.getName()+": Class is an interface.", ()->bs.createBean(D9b.class).run());
667 }
668
669 public static class D10 {
670 public String a;
671 public D10(String s) { a = "s="+s; }
672 public D10(Integer i) { a = "i="+i; }
673 public D10(String s, Integer i) { a = "s="+s+",i="+i; }
674 }
675
676 @Test void d10_createBean_constructors_public() {
677 var bs = BeanStore.create().build();
678 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());
679 bs.add(String.class, "foo");
680 assertString("s=foo", bs.createBean(D10.class).run().a);
681 bs.add(Integer.class, 1);
682 assertString("s=foo,i=1", bs.createBean(D10.class).run().a);
683 bs.removeBean(String.class);
684 assertString("i=1", bs.createBean(D10.class).run().a);
685 }
686
687 public static class D11 {
688 public String a;
689 protected D11(String s) { a = "s="+s; }
690 protected D11(Integer i) { a = "i="+i; }
691 protected D11(String s, Integer i) { a = "s="+s+",i="+i; }
692 }
693
694 @Test void d11_createBean_constructors_protected() {
695 var bs = BeanStore.create().build();
696 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());
697 bs.add(String.class, "foo");
698 assertString("s=foo", bs.createBean(D11.class).run().a);
699 bs.add(Integer.class, 1);
700 assertString("s=foo,i=1", bs.createBean(D11.class).run().a);
701 bs.removeBean(String.class);
702 assertString("i=1", bs.createBean(D11.class).run().a);
703 }
704
705 public static class D12 {
706 public String a;
707 public D12(String s) { a = "s="+s; }
708 protected D12(String s, Integer i) { a = "s="+s+",i="+i; }
709 }
710
711 @Test void d12_createBean_constructors_publicOverProtected() {
712 var bs = BeanStore.create().build();
713 assertThrowsWithMessage(ExecutableException.class, "Could not instantiate class "+D12.class.getName()+": Public constructor found but could not find prerequisites: String.", ()->bs.createBean(D12.class).run());
714 bs.add(String.class, "foo");
715 bs.add(Integer.class, 1);
716 assertString("s=foo", bs.createBean(D12.class).run().a);
717 }
718
719 public static class D13 {
720 private D13() {}
721 }
722
723 @Test void d13_createBean_constructors_private() {
724 var bs = BeanStore.INSTANCE;
725 assertThrowsWithMessage(ExecutableException.class, "Could not instantiate class "+D13.class.getName()+": No public/protected constructors found.", ()->bs.createBean(D13.class).run());
726 }
727
728 public static class D14 {
729 public String a;
730 public D14(@Named("foo") String o) { a = o; }
731 public D14(@Named("foo") String o, Integer i) { a = o + "," + i; }
732 }
733
734 @Test void d14_createBean_constructors_namedBean() {
735 var bs = BeanStore.create().build();
736 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());
737 bs.add(String.class, "bar", "foo");
738 assertString("bar", bs.createBean(D14.class).run().a);
739 }
740
741 public class D15 {
742 public String a;
743 public D15(@Named("foo") String o) { a = o; }
744 public D15(@Named("foo") String o, Integer i) { a = o + "," + i; }
745 }
746
747 @Test void d15_createBean_constructors_namedBean_withOuter() {
748 var bs = BeanStore.create().outer(new BeanStore_Test()).build();
749 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());
750 bs.add(String.class, "bar", "foo");
751 assertString("bar", bs.createBean(D15.class).run().a);
752 }
753
754 public static class D16 {
755 public String a;
756 public static Builder create() { return new Builder(); }
757 public static class Builder {
758 public String b;
759 }
760 protected D16(Builder b) { a = b.b; }
761 }
762
763 @Test void d16_createBean_builders() {
764 var bs = BeanStore.create().build();
765 var b = D16.create();
766 b.b = "foo";
767 assertString("foo", bs.createBean(D16.class).builder(D16.Builder.class, b).run().a);
768 }
769
770 public static class D17 {
771 public String a;
772 public static Builder create() { return new Builder(); }
773 public static class Builder {
774 public String b;
775 }
776 protected D17(Builder b, Integer i) { a = b.b; }
777 protected D17(Integer i) {}
778 D17(String s) {}
779 protected D17(Builder b) { a = b.b; }
780 }
781
782 @Test void d17_createBean_builders_inherent() {
783 var bs = BeanStore.create().build();
784 assertNull(bs.createBean(D17.class).run().a);
785 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());
786 }
787
788
789
790
791
792 @SafeVarargs
793 private static <T> T[] array(T...t) {
794 return t;
795 }
796 }