1   /***************************************************************************************
2    * Copyright (c) Jonas BonŽr, Alexandre Vasseur. All rights reserved.                 *
3    * http://aspectwerkz.codehaus.org                                                    *
4    * ---------------------------------------------------------------------------------- *
5    * The software in this package is published under the terms of the LGPL license      *
6    * a copy of which has been included with this distribution in the license.txt file.  *
7    **************************************************************************************/
8   package test.expression;
9   
10  
11  import java.lang.reflect.Constructor;
12  import java.lang.reflect.Field;
13  import java.lang.reflect.Method;
14  
15  import junit.extensions.TestSetup;
16  import junit.framework.Test;
17  import junit.framework.TestCase;
18  import junit.framework.TestSuite;
19  
20  import org.codehaus.aspectwerkz.expression.ExpressionContext;
21  import org.codehaus.aspectwerkz.expression.ExpressionInfo;
22  import org.codehaus.aspectwerkz.expression.PointcutType;
23  import org.codehaus.aspectwerkz.reflect.ClassInfo;
24  import org.codehaus.aspectwerkz.reflect.ConstructorInfo;
25  import org.codehaus.aspectwerkz.reflect.FieldInfo;
26  import org.codehaus.aspectwerkz.reflect.MethodInfo;
27  import org.codehaus.aspectwerkz.reflect.ReflectHelper;
28  import org.codehaus.aspectwerkz.reflect.impl.java.JavaClassInfo;
29  
30  /***
31   * Unit test for annotation matching.
32   * 
33   * @author <a href="mailto:the_mindstorm@evolva.ro">Alex Popescu</a>
34   * @version $Revision: 1.3 $
35   */
36  public class AnnotationExpressionTest extends TestCase {
37  	protected static final String NAMESPACE = "TESTING";
38  
39  	protected static ClassInfo s_declaringType = JavaClassInfo.getClassInfo(AnnotationTarget.class);
40  	protected static ClassInfo s_innerType     = JavaClassInfo.getClassInfo(
41  			AnnotationTarget.ClassLevelAnnotation.class);
42  	
43  	protected static ConstructorInfo s_constructor;
44  	protected static ConstructorInfo s_innerConstructor;
45  	
46  	protected static MethodInfo s_method;
47  	protected static MethodInfo s_innerMethod;
48  	
49  	protected static FieldInfo s_field;
50  	protected static FieldInfo s_innerField;
51  
52      static {
53          try {
54              setMeUp();
55          } catch (Throwable t) {
56              throw new Error(t.toString());
57          }
58      }
59  
60  
61  	public void testConstructor() {
62  		assertTrue(
63  				new ExpressionInfo("call(@DefaultConstructor)", NAMESPACE).getExpression()
64  				.match(
65  						new ExpressionContext(PointcutType.CALL, s_constructor, null)
66  				)
67  		);
68  		
69  		assertTrue(
70  				new ExpressionInfo("call(@DefaultConstructor new())", NAMESPACE).getExpression()
71  						.match(
72  								new ExpressionContext(PointcutType.CALL, s_constructor, null)
73  								));
74  
75  		assertTrue(
76  				new ExpressionInfo("call(@DefaultConstructor new(..))", NAMESPACE).getExpression()
77  						.match(
78  								new ExpressionContext(PointcutType.CALL, s_constructor, null)
79  								));
80  
81  		assertTrue(
82  				new ExpressionInfo("call(@DefaultConstructor *.new())", NAMESPACE).getExpression()
83  				.match(
84  						new ExpressionContext(PointcutType.CALL, s_constructor, null)
85  				)
86  		);
87  		
88  		assertTrue(
89  				new ExpressionInfo("call(@DefaultConstructor test.*.AnnotationTarget.new())", NAMESPACE)
90  					.getExpression().match(
91  							new ExpressionContext(PointcutType.CALL, s_constructor, null)
92  							)
93  		);
94  
95  		assertTrue(
96  				new ExpressionInfo("call(@DefaultConstructor test.expression.AnnotationTarget.new())", NAMESPACE)
97  					.getExpression().match(
98  							new ExpressionContext(PointcutType.CALL, s_constructor, null)
99  							)
100 		);
101 
102 		assertFalse(
103 				new ExpressionInfo("call(@OtherConstructor)", NAMESPACE).getExpression().match(
104 						new ExpressionContext(PointcutType.CALL, s_constructor, null)));
105 		
106 		assertFalse(
107 				new ExpressionInfo("call(@DefaultConstructor new(*))", NAMESPACE).getExpression()
108 				.match(
109 						new ExpressionContext(PointcutType.CALL, s_constructor, null)));
110 		
111 		assertFalse(
112 				new ExpressionInfo("call(@DefaultConstructor test.expression.AnnotationTargetWRONG.new())", NAMESPACE)
113 					.getExpression().match(
114 							new ExpressionContext(PointcutType.CALL, s_constructor, null)
115 							)
116 		);
117 
118 		assertTrue(
119 				new ExpressionInfo(
120 						"within(test.expression.AnnotationTarget) && execution(@DefaultConstructor)",
121 						NAMESPACE).getExpression().match(
122 				new ExpressionContext(PointcutType.EXECUTION, s_constructor, s_declaringType))
123 				);
124 		
125 		assertTrue(
126 				new ExpressionInfo(
127 						"within(test.expression.*) && execution(@DefaultConstructor)",
128 						NAMESPACE).getExpression().match(
129 				new ExpressionContext(PointcutType.EXECUTION, s_constructor, s_declaringType))
130 				);
131 		
132 		assertTrue(
133 				new ExpressionInfo(
134 						"within(@Service) && execution(@DefaultConstructor)",
135 						NAMESPACE).getExpression().match(
136 				new ExpressionContext(PointcutType.EXECUTION, s_innerConstructor, s_innerType))
137 				);
138 
139 		// HINT: constructor on AnnotationTarget
140 		assertTrue(
141 				new ExpressionInfo(
142 						"!within(@Service) && execution(@DefaultConstructor)",
143 						NAMESPACE).getExpression().match(
144 				new ExpressionContext(PointcutType.EXECUTION, s_constructor, s_declaringType))
145 				);
146 		
147 		// HINT: constructor of inner (@Service)
148 		assertFalse(
149 				new ExpressionInfo(
150 						"!within(@Service) && execution(@DefaultConstructor)",
151 						NAMESPACE).getExpression().match(
152 				new ExpressionContext(PointcutType.EXECUTION, s_innerConstructor, s_innerType))
153 				);
154 				
155 		assertTrue(
156 				new ExpressionInfo(
157 						"withincode(@DefaultConstructor)",
158 						NAMESPACE).getExpression().match(
159 				new ExpressionContext(PointcutType.WITHIN, s_constructor, s_constructor))
160 				);
161 		
162 		assertTrue(
163 				new ExpressionInfo(
164 						"withincode(@DefaultConstructor test.expression.AnnotationTarget.new())",
165 						NAMESPACE).getExpression().match(
166 				new ExpressionContext(PointcutType.WITHIN, s_constructor, s_constructor))
167 				);
168 		
169 		assertTrue(
170 				new ExpressionInfo(
171 						"call(@Asynch) && withincode(@DefaultConstructor)",
172 						NAMESPACE).getExpression().match(
173 				new ExpressionContext(PointcutType.CALL, s_innerMethod, s_innerConstructor))
174 				);
175 						
176 	}
177 	
178 	public void testHasMethod() {
179         assertTrue(
180                 new ExpressionInfo(
181                         "hasmethod(@Asynch)",
182                         NAMESPACE
183                 ).getExpression().match(new ExpressionContext(PointcutType.EXECUTION, s_method, null))
184         );
185         
186         assertTrue(
187                 new ExpressionInfo(
188                         "hasmethod(@Asynch void methodOneAsynch())",
189                         NAMESPACE
190                 ).getExpression().match(new ExpressionContext(PointcutType.CALL, s_method, s_method))
191         );
192         
193         // HINT hasmethod on constructor
194         assertTrue(
195         		new ExpressionInfo(
196         				"hasmethod(@DefaultConstructor)",
197 						NAMESPACE).getExpression().match(
198 				new ExpressionContext(PointcutType.EXECUTION, s_constructor, null))
199 				);
200 
201         assertTrue(
202         		new ExpressionInfo(
203         				"hasmethod(@DefaultConstructor new())",
204 						NAMESPACE).getExpression().match(
205 				new ExpressionContext(PointcutType.CALL, s_constructor, s_constructor)
206 				)
207 		);
208 	}
209 
210     public void testHasField() throws Exception {
211         assertTrue(
212                 new ExpressionInfo(
213                         "hasfield(@Persistable)",
214                         NAMESPACE).getExpression().match(
215                 new ExpressionContext(PointcutType.EXECUTION, s_field, null))
216         );
217         
218         assertTrue(
219                 new ExpressionInfo(
220                         "hasfield(@Persistable)",
221                         NAMESPACE).getExpression().match(
222                 new ExpressionContext(PointcutType.CALL, s_field, s_field))
223         );
224         
225         assertTrue(
226                 new ExpressionInfo(
227                         "hasfield(@Persistable) && !within(@Service)",
228                         NAMESPACE).getExpression().match(
229                 new ExpressionContext(PointcutType.CALL, s_field, s_declaringType))
230         );
231         
232         assertFalse(
233                 new ExpressionInfo(
234                         "hasfield(@Persistable) && !within(@Service)",
235                         NAMESPACE).getExpression().match(
236                 new ExpressionContext(PointcutType.CALL, s_field, s_innerType))
237         );
238         
239         assertTrue(
240                 new ExpressionInfo(
241                         "hasfield(@Persistable) && within(@Service)",
242                         NAMESPACE).getExpression().match(
243                 new ExpressionContext(PointcutType.CALL, s_innerField, s_innerType))
244         );        
245     }
246     
247     public void testFieldAttributes() {
248     	assertTrue(
249                 new ExpressionInfo(
250                 		"set(@Persistable)", 
251 						NAMESPACE).getExpression().match(
252                 new ExpressionContext(PointcutType.SET, s_field, null))
253         );
254     	
255     	assertTrue(
256     			new ExpressionInfo(
257     					"get(@Persistable) && !within(@Service)",
258 						NAMESPACE).getExpression().match(
259 				new ExpressionContext(PointcutType.GET, s_field, s_declaringType))
260 				);
261     	
262     	assertTrue(
263     			new ExpressionInfo(
264     					"set(@Persistable) && within(@Service)",
265 						NAMESPACE).getExpression().match(
266 				new ExpressionContext(PointcutType.SET, s_innerField, s_innerType))
267 				);
268     	
269     	assertFalse(
270     			new ExpressionInfo(
271     					"get(@Persistable) && !within(@Service)",
272 						NAMESPACE).getExpression().match(
273 				new ExpressionContext(PointcutType.GET, s_field, s_innerType))
274 				);
275     	
276     	assertFalse(
277     			new ExpressionInfo(
278     					"get(@Persistable) && !within(@Service)",
279 						NAMESPACE).getExpression().match(
280 				new ExpressionContext(PointcutType.GET, s_innerField, s_innerType))
281 				);
282     }
283     
284 	
285 	public static void main(String[] args) {
286 		junit.textui.TestRunner.run(suite());
287 	}
288 
289 	public static junit.framework.Test suite() {
290         return new junit.framework.TestSuite(AnnotationExpressionTest.class);
291 	}
292 
293     protected static void setMeUp() throws Exception {
294         Class clazz = AnnotationTarget.class;
295         Class[] noParams = new Class[0];
296 
297         Method method = clazz.getMethod("methodOneAsynch", noParams);
298         s_method = s_declaringType.getMethod(ReflectHelper.calculateHash(method));
299 
300         Constructor constructor = clazz.getConstructor(noParams);
301         s_constructor = s_declaringType.getConstructor(
302                 ReflectHelper.calculateHash(constructor));
303 
304         Field field = clazz.getDeclaredField("m_annotatedField");
305         s_field = s_declaringType.getField(ReflectHelper.calculateHash(field));
306 
307         clazz = AnnotationTarget.ClassLevelAnnotation.class;
308         method = clazz.getMethod("innerMethodAsynch", noParams);
309         s_innerMethod = s_innerType.getMethod(ReflectHelper.calculateHash(method));
310 
311         constructor = clazz.getConstructor(noParams);
312         s_innerConstructor = s_innerType.getConstructor(ReflectHelper.calculateHash(constructor));
313 
314         field = clazz.getDeclaredField("m_innerField");
315         s_innerField = s_innerType.getField(ReflectHelper.calculateHash(field));
316     }
317 }