View Javadoc

1   /*
2    * $Id: SMDMethodInterfaceTest.java 799110 2009-07-29 22:44:26Z musachy $
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
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             // dummy implementation
178             public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
179                 return null;
180             }
181         };
182         // proxy is proxy to an impl of ClassA
183         InterfaceA proxy = (InterfaceA) Proxy.newProxyInstance(ClassA.class.getClassLoader(), new Class[] {
184                 InterfaceA.class, InterfaceB.class, InterfaceC.class }, handler);
185 
186         // first, without the recursion
187         Method[] smdMethodsA = JSONUtil.listSMDMethods(proxy.getClass(), true);
188         assertEquals(0, smdMethodsA.length);
189 
190         // now with the recursion
191         Method[] smdMethodsB = JSONUtil.listSMDMethods(proxy.getClass(), false);
192         assertEquals(1, smdMethodsB.length);
193         assertEquals("getB", smdMethodsB[0].getName());
194     }
195 }