1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.juneau.annotation;
18
19 import static org.apache.juneau.TestUtils.*;
20 import static org.apache.juneau.junit.bct.BctAssertions.*;
21 import static org.junit.jupiter.api.Assertions.*;
22
23 import org.apache.juneau.*;
24 import org.apache.juneau.commons.reflect.ExecutableException;
25 import org.junit.jupiter.api.*;
26
27 class ParentPropertyAnnotation_Test extends TestBase {
28
29 private static final String CNAME = ParentPropertyAnnotation_Test.class.getName();
30
31
32
33
34
35 ParentProperty a1 = ParentPropertyAnnotation.create()
36 .description("a")
37 .on("b")
38 .build();
39
40 ParentProperty a2 = ParentPropertyAnnotation.create()
41 .description("a")
42 .on("b")
43 .build();
44
45 @Test void a01_basic() {
46 assertBean(a1, "description,on", "[a],[b]");
47 }
48
49 @Test void a02_testEquivalency() {
50 assertEquals(a2, a1);
51 assertNotEqualsAny(a1.hashCode(), 0, -1);
52 assertEquals(a1.hashCode(), a2.hashCode());
53 }
54
55
56
57
58
59 @Test void b01_testEquivalencyInPropertyStores() {
60 var bc1 = BeanContext.create().annotations(a1).build();
61 var bc2 = BeanContext.create().annotations(a2).build();
62 assertSame(bc1, bc2);
63 }
64
65
66
67
68
69 public static class C1 {
70 public int f1;
71 public void m1() {}
72 }
73 public static class C2 {
74 public int f2;
75 public void m2() {}
76 }
77
78 @Test void c01_otherMethods() throws Exception {
79 var c1 = ParentPropertyAnnotation.create("a").on("b").build();
80 var c2 = ParentPropertyAnnotation.create().on(C1.class.getField("f1")).on(C2.class.getField("f2")).build();
81 var c3 = ParentPropertyAnnotation.create().on(C1.class.getMethod("m1")).on(C2.class.getMethod("m2")).build();
82
83 assertBean(c1, "on", "[a,b]");
84 assertBean(c2, "on", "["+CNAME+"$C1.f1,"+CNAME+"$C2.f2]");
85 assertBean(c3, "on", "["+CNAME+"$C1.m1(),"+CNAME+"$C2.m2()]");
86 }
87
88
89
90
91
92 @ParentProperty(
93 description={ "a" },
94 on="b"
95 )
96 public static class D1 {}
97 ParentProperty d1 = D1.class.getAnnotationsByType(ParentProperty.class)[0];
98
99 @ParentProperty(
100 description={ "a" },
101 on="b"
102 )
103 public static class D2 {}
104 ParentProperty d2 = D2.class.getAnnotationsByType(ParentProperty.class)[0];
105
106 @Test void d01_comparisonWithDeclarativeAnnotations() {
107 assertEqualsAll(a1, d1, d2);
108 assertNotEqualsAny(a1.hashCode(), 0, -1);
109 assertEqualsAll(a1.hashCode(), d1.hashCode(), d2.hashCode());
110 }
111
112
113
114
115
116 public static class ParentBean {
117 public int value = 42;
118 }
119
120 public static class TestBeanWithParentPropertyField {
121 @ParentProperty
122 public ParentBean parent;
123 }
124
125 public static class TestBeanWithParentPropertyMethod {
126 private ParentBean parent;
127
128 @ParentProperty
129 protected void setParent(ParentBean parent) {
130 this.parent = parent;
131 }
132
133 public ParentBean getParent() {
134 return parent;
135 }
136 }
137
138 @Test void e01_parentPropertyField() throws Exception {
139 var bc = BeanContext.DEFAULT;
140 var cm = bc.getClassMeta(TestBeanWithParentPropertyField.class);
141 var prop = cm.getParentProperty();
142 assertNotNull(prop, "ParentProperty should be found");
143 assertTrue(prop.canWrite(), "Should have setter");
144 assertTrue(prop.canRead(), "Should have getter");
145
146 var bean = new TestBeanWithParentPropertyField();
147 var parent = new ParentBean();
148 prop.set(bean, parent);
149 assertSame(parent, prop.get(bean));
150 assertSame(parent, bean.parent);
151 }
152
153 @Test void e02_parentPropertyMethod() throws Exception {
154 var bc = BeanContext.DEFAULT;
155 var cm = bc.getClassMeta(TestBeanWithParentPropertyMethod.class);
156 var prop = cm.getParentProperty();
157 assertNotNull(prop, "ParentProperty should be found");
158 assertTrue(prop.canWrite(), "Should have setter");
159 assertTrue(prop.canRead(), "Should have getter");
160
161 var bean = new TestBeanWithParentPropertyMethod();
162 var parent = new ParentBean();
163 prop.set(bean, parent);
164 assertSame(parent, prop.get(bean));
165 assertSame(parent, bean.getParent());
166 }
167
168 @Test void e03_parentPropertyNotFound() {
169 var bc = BeanContext.DEFAULT;
170 var cm = bc.getClassMeta(String.class);
171 var prop = cm.getParentProperty();
172 assertNull(prop, "ParentProperty should not be found on String class");
173 }
174
175 public static class TestBeanWithReadOnlyParentProperty {
176 private ParentBean parent = new ParentBean();
177
178 @ParentProperty
179 public ParentBean getParent() {
180 return parent;
181 }
182 }
183
184 @Test void e04_readOnlyParentProperty() throws Exception {
185 var bc = BeanContext.DEFAULT;
186 var cm = bc.getClassMeta(TestBeanWithReadOnlyParentProperty.class);
187 var prop = cm.getParentProperty();
188 assertNotNull(prop, "ParentProperty should be found even if read-only");
189 assertFalse(prop.canWrite(), "Should not have setter");
190 assertTrue(prop.canRead(), "Should have getter");
191
192 var bean = new TestBeanWithReadOnlyParentProperty();
193 var parent = (ParentBean)prop.get(bean);
194 assertNotNull(parent, "Should be able to get parent");
195 assertEquals(42, parent.value);
196
197
198 var newParent = new ParentBean();
199 var ex = assertThrows(ExecutableException.class, () -> prop.set(bean, newParent));
200 assertTrue(ex.getMessage().contains("No setter defined"), "Should throw exception when trying to set read-only property");
201 }
202 }