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  import junit.framework.TestCase;
11  
12  import org.codehaus.aspectwerkz.expression.ast.ExpressionParser;
13  import org.codehaus.aspectwerkz.expression.ast.ParseException;
14  import org.codehaus.aspectwerkz.expression.ast.TokenMgrError;
15  import org.codehaus.aspectwerkz.expression.ExpressionInfo;
16  
17  
18  /***
19   * Unit test for expression parser.
20   * 
21   * @author <a href="mailto:the_mindstorm@evolva.ro">Alex Popescu</a>
22   */
23  public class ExpressionParserTest extends TestCase {
24  	private static final ExpressionParser PARSER = ExpressionInfo.getParser();
25  	
26  	public void testMethodPatternJP() {
27  		for(int i = 0; i < s_methodLikeExpressions.length; i++) {
28  			parse("call(" + s_methodLikeExpressions[i] + ")");
29  			parse("!call(" + s_methodLikeExpressions[i] + ")");
30  			parse("execution(" + s_methodLikeExpressions[i] + ")");
31  			parse("!execution(" + s_methodLikeExpressions[i] + ")");
32  			parse("withincode(" + s_methodLikeExpressions[i] + ")");
33  			parse("! withincode(" + s_methodLikeExpressions[i] + ")");
34  		}
35  	}
36  	
37  	public void testHasmethodJP() {
38  		for(int i = 0; i < s_methodLikeExpressions.length; i++) {
39  			parse("! hasmethod(" + s_methodLikeExpressions[i] + ")");
40  		}
41  
42  		for(int i = 0; i < s_methodLikeExpressions.length; i++) {
43  			parse("hasmethod(" + s_methodLikeExpressions[i] + ")");
44  		}
45  
46  	}
47  
48  	public void testComplexMethodLevelJP() {
49  		for(int i = 0; i < s_methodLikeExpressions.length; i++) {
50  			for(int j = 0; j < METHOD_EXPRESSIONS.length; j++) {
51  				parse("call(" + s_methodLikeExpressions[i] + ") AND "
52  						+ "hasmethod(" + METHOD_EXPRESSIONS[j] + ")");
53  				
54  				parse("call(" + s_methodLikeExpressions[i] + ") AND "
55  						+ "!hasmethod(" + METHOD_EXPRESSIONS[j] + ")");
56  				
57  				parse("call(" + s_methodLikeExpressions[i] + ") && "
58  						+ "!hasmethod(" + METHOD_EXPRESSIONS[j] + ")");
59  				
60  				parse("call(" + s_methodLikeExpressions[i] + ") OR "
61  						+ "!hasmethod(" + METHOD_EXPRESSIONS[j] + ")");
62  				
63  				parse("call(" + s_methodLikeExpressions[i] + ") || "
64  						+ "!hasmethod(" + METHOD_EXPRESSIONS[j] + ")");
65  			}
66  		}
67  	}
68  	
69  	public void testFieldPatternJP() {
70  		for(int i = 0; i < FIELD_EXPRESSIONS.length; i++) {
71  			parse("set(" + FIELD_EXPRESSIONS[i] + ")");
72  			
73  			parse("get(" + FIELD_EXPRESSIONS[i] + ")");
74  			
75  			parse("hasfield(" + FIELD_EXPRESSIONS[i] + ")");
76  		}
77  	}
78  	
79  	public void testSpecial() {
80  		parse("(set(* foo.bar.*) || get(* foo.bar.*)) && withincode(* foo.bar.Buzz.*(..))");
81  		
82  		parse("execution(* foo.bar.Baz.*(..)) || call(* foo.bar.Baz.*(..))");
83  		
84  		parse("handler(java.lang.Exception+)");
85  		
86  		parse("!cflow(call(* foo.bar.Buzz.*(..)))");
87  		
88  		parse("handler(java.lang.Exception+) && !cflow(call(* foo.bar.Buzz.*(..)))");
89  		
90  		parse("call(!public !static * *..*.*(..))");
91  	}
92  	
93  	public void testClassPatternJP() {
94  		for(int i = 0; i < TYPE_EXPRESSIONS.length; i++) {
95  			parse("within(" + TYPE_EXPRESSIONS[i] + ")");
96  			
97  			parse("staticinitialization(" + TYPE_EXPRESSIONS[i] + ")");
98  		}
99  	}
100 
101 	/* FIXME ArgParameters()
102 	public void testArgsAndPointcutrefs() {
103 		assertNull("args()", parseString("args()"));
104 		
105 		assertNotNull("args(,, String)", parseString("args(,, String)"));
106 		
107 		assertNotNull("args(, , String, , int)", parseString("args(, , String, , int)"));
108 		
109 		assertNull("pointcutref()", parseString("pointcutref()"));
110 		
111 		assertNull("pointcutref(arg1)", parseString("pointcutref(arg1)"));
112 		
113 		assertNull("pointcutref(..)", parseString("pointcutref(..)"));
114 		
115 		assertNull("pointcutref(arg1, ..)", parseString("pointcutref(arg1, ..)"));
116 		
117 		assertNotNull("pointcutref(, arg2)", parseString("pointcutref(, arg2)"));
118 		
119 		assertNotNull("pointcutref(, arg2, , arg4)", parseString("pointcutref(, arg2, , arg4)"));
120 	}
121 	*/
122 	
123 	
124 	public void testWithincodeStaticinitialization() {
125 	    for(int i = 0; i < TYPE_EXPRESSIONS.length; i++) {
126 	        Throwable cause = parseString("withincode(staticinitialization(" 
127 	                + TYPE_EXPRESSIONS[i] + "))");
128 	        if(null != cause) {
129 	            cause.printStackTrace();
130 	        }
131 			assertNull(TYPE_EXPRESSIONS[i] + cause, 
132 			           cause);
133 		}
134 	}
135 	
136 	private void parse(String expression) {
137 		try {
138 			PARSER.parse(expression);
139 		} catch(ParseException e) {
140 			fail("parsing [" + expression +"] failed because:\n" + e.getMessage());
141 		}
142 	}
143 	
144 	private Throwable parseString(String expression) {
145 		try {
146 			PARSER.parse(expression);
147 		} catch(ParseException pe) {
148 			return pe;
149 		} catch(TokenMgrError tokenerr) {
150 			return tokenerr;
151 		} catch(Exception ex) {
152 			return ex;
153 		}
154 		
155 		return null;
156 	}
157 	
158 	private static final String[] METHOD_EXPRESSIONS = {
159 			"int foo.*.Bar.method()",
160 			"int *.method(*)",
161 			"* method(..)",
162 			"int foo.*.*.method(*,int)",
163 			"int foo.*.Bar.method(..)",
164 			"int foo.*.Bar.method(int,..)",
165 			"int foo.*.Bar.method(java.lang.*)",
166 			"int foo.*.Bar.me*o*()",
167 			"* foo.*.Bar.method()", 
168 			"java.lang.* foo.*.Bar.method()",
169 			"static int foo.*.Bar.method()",
170 			"synchronized static int foo.*.Bar.method()",
171 			"!synchronized !static int foo.*.Bar.method()",
172 			"@Transaction * foo.*.*.*(..)",
173 			"@Transaction static * foo.*.*.*(..)",
174 			"@Transaction",
175 			"! @Transaction",
176 			"@Transaction !static * foo.*.*.*(..)",
177 			"!@Transaction !static * foo.*.*.*(..)"
178 	};
179 			
180 	private static final String[] CONSTRUCTOR_EXPRESSIONS = {
181 			"foo.*.Bar.new()",
182 			"*.new(*)",
183 			"foo.*.*.new(*,int)",
184 			"foo.*.Bar.new(..)",
185 			"foo.*.Bar.new(int,..)",
186 			"foo.*.Bar.new(java.lang.*)",
187 			"foo.*.Bar.new()",
188 			"@Transaction foo.*.*.new(..)",
189 	};
190 
191 	private static final String[] FIELD_EXPRESSIONS = {
192 			"int foo.*.Bar.m_foo",
193 			"* m_field",
194 			"* foo.*.Bar.m_foo",
195 			"java.lang.* foo.*.Bar.m_foo",
196 			"int foo.*.Bar.m_*",
197 			"int foo.*.Bar.m_*oo*",
198 			"int foo.bar.Baz.*",
199 			"int foo.*.Bar+.m_foo",
200 			"* foo.*.Bar+.m_foo",
201 			"java.lang.* foo.*.Bar+.m_foo",
202 			"private static final String foo.*.bar....m_field",
203 			"private static final String foo.*.bar.*.m_field",
204 			"private static final String foo.*.bar.*.*",
205 			"@Persistent",
206 			"@Persistent * m_field",
207 			"@Persistent int foo.*.Bar.m_foo",
208 			"@Persistent * foo.*.Bar.m_foo",
209 			"@Persistent java.lang.* foo.*.Bar.m_foo",
210 			"@Persistent int foo.*.Bar.m_*",
211 			"@Persistent int foo.*.Bar.m_*oo*",
212 			"@Persistent int foo.bar.Baz.*",
213 			"@Persistent * foo.bar.Baz.*",
214 			"@Persistent private static final String foo.*.bar....m_field",
215 			"@Persistent private static final String foo.*.bar.*.m_field",
216 			"@Persistent private static final String foo.*.bar.*.*",
217 			"@Persistent @Instrumentable",
218 			"@Persistent @Instrumentable * m_field",
219 			"@Persistent @Instrumentable int foo.*.Bar.m_foo",
220 			"@Persistent @Instrumentable * foo.*.Bar.m_foo",
221 			"@Persistent @Instrumentable java.lang.* foo.*.Bar.m_foo",
222 			"@Persistent @Instrumentable int foo.*.Bar.m_*",
223 			"@Persistent @Instrumentable int foo.*.Bar.m_*oo*",
224 			"@Persistent @Instrumentable int foo.bar.Baz.*",
225 			"@Persistent @Instrumentable int foo.bar.Baz+.*",
226 			"@Persistent @Instrumentable * foo.bar.Baz.*",
227 			"@Persistent @Instrumentable private static final String foo.*.bar....m_field",
228 			"@Persistent @Instrumentable private static final String foo.*.bar.*.m_field",
229 			"@Persistent @Instrumentable private static final String foo.*.bar.*.*"
230 
231 	};
232 	
233 	private static final String[] TYPE_EXPRESSIONS = {
234 			"foo.bar.*",
235 			"foo.*.FooBar",
236 			"foo.*.FooB*",
237 			"foo..",
238 			"public foo.bar.*",
239 			"@Session foo.bar.*",
240 			"@Session",
241 			"@Session @Service foo....bar.*",
242 			"@Session @Service public abstract foo....bar.*"
243 			
244 	};
245 	
246 	private static String[] s_methodLikeExpressions;
247 	
248 	static {
249 		s_methodLikeExpressions = new String[METHOD_EXPRESSIONS.length 
250 														 + CONSTRUCTOR_EXPRESSIONS.length];
251 		for(int i = 0; i < METHOD_EXPRESSIONS.length; i++) {
252 			s_methodLikeExpressions[i] = METHOD_EXPRESSIONS[i];
253 		}
254 		for(int i = 0; i < CONSTRUCTOR_EXPRESSIONS.length; i++) {
255 			s_methodLikeExpressions[METHOD_EXPRESSIONS.length + i]
256 											= CONSTRUCTOR_EXPRESSIONS[i];
257 		}
258 	}
259 
260 
261     public static void main(String[] args) {
262         junit.textui.TestRunner.run(suite());
263     }
264 
265     public static junit.framework.Test suite() {
266         return new junit.framework.TestSuite(ExpressionParserTest.class);
267     }
268 
269 }