1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.apache.struts2.json;
22
23 import java.lang.reflect.InvocationHandler;
24 import java.lang.reflect.Method;
25 import java.lang.reflect.Proxy;
26
27 import junit.framework.TestCase;
28
29 import org.apache.struts2.json.annotations.SMDMethod;
30
31 /***
32 * Tests that the SMDMethod annotation can be found in interfaces when
33 * ignoreSMDMethodInterface is false
34 */
35 public class SMDMethodInterfaceTest extends TestCase {
36
37 public interface InterfaceA {
38 String getA();
39 }
40
41 public interface InterfaceB {
42 @SMDMethod
43 String getB();
44 }
45
46 public interface InterfaceC {
47 String getC();
48 }
49
50 public interface InterfaceD {
51 String getD();
52 }
53
54 public interface InterfaceE {
55 String getE();
56 }
57
58 public static class ClassA extends ClassB implements InterfaceA {
59
60 private String a;
61 private String z;
62
63 public ClassA(String a, String b, String c, String d, String e, String x, String y, String z) {
64 super(b, c, d, e, x, y);
65 this.a = a;
66 this.z = z;
67 }
68
69 public String getA() {
70 return a;
71 }
72
73 @SMDMethod
74 public String getZ() {
75 return z;
76 }
77 }
78
79 public static class ClassB extends ClassC implements InterfaceB, InterfaceC {
80
81 private String b;
82 private String c;
83 private String y;
84
85 public ClassB(String b, String c, String d, String e, String x, String y) {
86 super(d, e, x);
87 this.b = b;
88 this.c = c;
89 this.y = y;
90 }
91
92 public String getC() {
93 return c;
94 }
95
96 public String getB() {
97 return b;
98 }
99
100 public String getY() {
101 return y;
102 }
103 }
104
105 public static class ClassC implements InterfaceD, InterfaceE {
106
107 private String d;
108 private String e;
109 private String x;
110
111 public ClassC(String d, String e, String x) {
112 this.d = d;
113 this.e = e;
114 this.x = x;
115 }
116
117 public String getD() {
118 return d;
119 }
120
121 public String getE() {
122 return e;
123 }
124
125 @SMDMethod
126 public String getX() {
127 return x;
128 }
129 }
130
131 /***
132 * Asserts that the SMDMethod annotation is only detected on the classes
133 * when ignoreSMDMethodInterfaces is true
134 */
135 public void testBaseClassOnly() {
136 Method[] smdMethodsA = JSONUtil.listSMDMethods(ClassA.class, true);
137 assertEquals(2, smdMethodsA.length);
138 assertEquals("getZ", smdMethodsA[0].getName());
139 assertEquals("getX", smdMethodsA[1].getName());
140
141 Method[] smdMethodsB = JSONUtil.listSMDMethods(ClassB.class, true);
142 assertEquals(1, smdMethodsB.length);
143 assertEquals("getX", smdMethodsB[0].getName());
144
145 Method[] smdMethodsC = JSONUtil.listSMDMethods(ClassC.class, true);
146 assertEquals(1, smdMethodsC.length);
147 assertEquals("getX", smdMethodsC[0].getName());
148 }
149
150 /***
151 * Asserts that the SMDMethod annotation is also detected on the interfaces
152 * and superclasses when ignoreSMDMethodInterfaces is false
153 */
154 public void testInterfaces() {
155 Method[] smdMethodsA = JSONUtil.listSMDMethods(ClassA.class, false);
156 assertEquals(3, smdMethodsA.length);
157 assertEquals("getZ", smdMethodsA[0].getName());
158 assertEquals("getX", smdMethodsA[1].getName());
159 assertEquals("getB", smdMethodsA[2].getName());
160
161 Method[] smdMethodsB = JSONUtil.listSMDMethods(ClassB.class, false);
162 assertEquals(2, smdMethodsB.length);
163 assertEquals("getX", smdMethodsB[0].getName());
164 assertEquals("getB", smdMethodsB[1].getName());
165
166 Method[] smdMethodsC = JSONUtil.listSMDMethods(ClassC.class, false);
167 assertEquals(1, smdMethodsC.length);
168 assertEquals("getX", smdMethodsC[0].getName());
169 }
170
171 /***
172 * This is the important case: detects the SMDMethod annotation on a proxy
173 */
174 public void testWithProxy() {
175
176 InvocationHandler handler = new InvocationHandler() {
177
178 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
179 return null;
180 }
181 };
182
183 InterfaceA proxy = (InterfaceA) Proxy.newProxyInstance(ClassA.class.getClassLoader(), new Class[] {
184 InterfaceA.class, InterfaceB.class, InterfaceC.class }, handler);
185
186
187 Method[] smdMethodsA = JSONUtil.listSMDMethods(proxy.getClass(), true);
188 assertEquals(0, smdMethodsA.length);
189
190
191 Method[] smdMethodsB = JSONUtil.listSMDMethods(proxy.getClass(), false);
192 assertEquals(1, smdMethodsB.length);
193 assertEquals("getB", smdMethodsB[0].getName());
194 }
195 }