1   /*
2    * Jour - java profiler and monitoring library
3    *
4    * Copyright (C) 2004 Jour team
5    *
6    * This library is free software; you can redistribute it and/or
7    * modify it under the terms of the GNU Library General Public
8    * License as published by the Free Software Foundation; either
9    * version 2 of the License, or (at your option) any later version.
10   *
11   * This library is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   * Library General Public License for more details.
15   *
16   * You should have received a copy of the GNU Library General Public
17   * License along with this library; if not, write to the
18   * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19   * Boston, MA  02111-1307, USA.
20   */
21  package net.sf.jour.filter;
22  
23  import java.util.StringTokenizer;
24  import java.lang.reflect.Modifier;
25  
26  import javassist.ClassPool;
27  import javassist.CtClass;
28  import javassist.CtMethod;
29  
30  import junit.framework.TestCase;
31  
32  /***
33   * TODO Add docs
34   * Created on 03.12.2004
35   *
36   * Contributing Author(s):
37   *
38   *   Misha Lifschitz <mishalifschitz at users.sourceforge.net> (Inital implementation)
39   *   Vlad Skarzhevskyy <vlads at users.sourceforge.net> (Inital implementation)
40   *
41   * @author vlads
42   * @version $Revision: 1.8 $ ($Author: vlads $) $Date: 2004/12/08 19:37:26 $
43   */
44  public class PointcutTest extends TestCase {
45  	
46  	public void verifyMod(String patterns, int mod, boolean expect) {
47  	    PointcutModifierListFiler pm = new PointcutModifierListFiler();
48  	    pm.addPatterns(patterns);
49  	    if (MatchFilter.debug) {
50  	        pm.debug();
51  	    }
52  	    assertEquals(patterns + " for:" + Modifier.toString(mod), expect, pm.match(mod));
53  	}
54  	
55  	public void testPointcutModifierFilter() {
56  	    verifyMod("", Modifier.SYNCHRONIZED, true);
57  	    verifyMod("public", Modifier.PUBLIC, true);
58  	    verifyMod("public;", Modifier.PUBLIC, true);
59  	    verifyMod("public;", Modifier.PRIVATE, false);
60  	    verifyMod("public;private", Modifier.PUBLIC, true);
61  	    verifyMod("public;private", Modifier.PRIVATE, true);
62  	    verifyMod("public;private", Modifier.PRIVATE | Modifier.STATIC, true);
63  	    verifyMod("public;private", Modifier.SYNCHRONIZED | Modifier.STATIC, false);
64  	    
65  	    verifyMod("public;!private", Modifier.PRIVATE, false);
66  	    verifyMod("!public;private", Modifier.PRIVATE, true);
67  	    verifyMod("private", Modifier.PRIVATE | Modifier.STATIC, true);
68  	    verifyMod("private;static", Modifier.PRIVATE | Modifier.STATIC, true);
69  	    
70  	    verifyMod("public,synchronized", Modifier.PUBLIC, false);
71  	    verifyMod("public,synchronized", Modifier.SYNCHRONIZED, false);
72  	    verifyMod("public,synchronized", Modifier.PUBLIC | Modifier.SYNCHRONIZED, true);
73  	    verifyMod("public,synchronized", Modifier.PUBLIC | Modifier.SYNCHRONIZED | Modifier.STATIC, true);
74  	    verifyMod("synchronized,!private", Modifier.SYNCHRONIZED | Modifier.PRIVATE, false);
75  	    
76  	    verifyMod("public,synchronized;!static", Modifier.PUBLIC | Modifier.SYNCHRONIZED, true);
77  	    verifyMod("public,synchronized;!static", Modifier.PUBLIC, false);
78  	    verifyMod("public,synchronized;!static", Modifier.PUBLIC | Modifier.SYNCHRONIZED | Modifier.STATIC, false);
79  	    
80  	    verifyMod("public,!final;static", Modifier.PUBLIC, true);
81  	    verifyMod("public,!final;static", Modifier.STATIC, true);
82  	    verifyMod("public,!final;static", Modifier.STATIC | Modifier.FINAL, true);
83  	    
84  	    verifyMod("public,static;final,synchronized", Modifier.PUBLIC | Modifier.FINAL, false);
85  	    verifyMod("public,static;final,synchronized", Modifier.PUBLIC | Modifier.STATIC, true);
86  	    verifyMod("public,static;final,synchronized", Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL, true);
87  	    verifyMod("public,static;final,synchronized", Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL | Modifier.SYNCHRONIZED , true);
88  	    verifyMod("public,static;final,synchronized", Modifier.PUBLIC | Modifier.SYNCHRONIZED , false);
89  	    
90  	    verifyMod("public,static;!final,synchronized", Modifier.PUBLIC | Modifier.FINAL, false);
91  	    verifyMod("public,static;!final,synchronized", Modifier.PUBLIC | Modifier.STATIC, true);
92  	    verifyMod("public,static;!final,synchronized", Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL, true);
93  	    verifyMod("public,static;!final,synchronized", Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL | Modifier.SYNCHRONIZED, true);
94  	    verifyMod("public,static;synchronized,!final", Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL | Modifier.SYNCHRONIZED, true);
95  	    verifyMod("public,static;!final,synchronized", Modifier.PUBLIC | Modifier.FINAL | Modifier.SYNCHRONIZED, false);
96  	    verifyMod("public,static;!final,synchronized", Modifier.FINAL | Modifier.SYNCHRONIZED, false);
97  	    verifyMod("public,static;!final,synchronized", Modifier.SYNCHRONIZED, true);
98  	}
99  	
100 	private void verify(String pattern, String methodName, boolean expect) { 
101 		Pointcut pc = new Pointcut(pattern);
102 		assertEquals(pattern + " for:" + methodName, expect, pc.acceptMethod(methodName, new String[0], "int"));
103 	}
104 	
105 	public void testPointcut() {
106 		Pointcut pc = new Pointcut("* *(..)");
107 		assertEquals("*", pc.getMethodName());
108 		assertEquals("*", pc.getRetType());
109 		assertTrue(pc.acceptMethod("bob", new String[0], "int"));
110 		
111 		verify("* *(..)", "bob", true);
112 		verify("* !*(..)", "bob", false);
113 		
114 		verify("* bob*(..)", "bobY", true);
115 		
116 		verify("* bob(..)", "bob", true);
117 		
118 		verify("* !bob*(..)", "bobY", false);
119 		
120 		verify("* foo*(..)", "bob", false);
121 
122 	}
123 	
124 	private void verifyList(String patterns, String methodName, boolean expect) throws Exception {
125 	    PointcutListFilter pointcuts = new PointcutListFilter();
126 	    
127 	    StringTokenizer tokenizer = new StringTokenizer(patterns, "|");
128 		while (tokenizer.hasMoreTokens()) {
129 			String str = tokenizer.nextToken().trim();
130 			pointcuts.addPointcut(str);
131 		}
132 	    ClassPool pool = ClassPool.getDefault();
133 	    CtClass clazz = pool.get("uut.PointcutCase");
134 	    CtMethod method = clazz.getDeclaredMethod(methodName);
135 	    
136 	    assertEquals(patterns + " for:" + methodName, expect, pointcuts.match(method));
137 	}
138 	
139 	public void testPointcutList() throws Exception {
140 	    verifyList("* *(..)", "getFoo", true);
141 	    verifyList("* *(..)|!* set*(..)", "getFoo", true);
142 	    verifyList("* *(..)|!* get*(..)", "getFoo", false);
143 	    verifyList("* *(..)|!* set*(..)", "doFoo", true);
144 	}
145 	
146 	public void xtestPointcutRetType() throws Exception {
147 	    // Test retType filter
148 	    verifyList("int *(..)", "getint", true);
149 	    verifyList("void *(..)", "setint", true);
150 	    verifyList("java.lang.String *(..)", "getint", false);
151 	    verifyList("int *(..)", "getString", false);
152 	    verifyList("java.lang.String *(..)", "getString", true);
153 	    verifyList("java.lang.* *(..)", "getString", true);
154 	    verifyList("java.lang.*;int *(..)", "getString", true);
155 	    verifyList("java.lang.*;int *(..)", "getint", true);
156 	    verifyList("java.lang.*;int *(..)", "getBar", false);
157 	    verifyList("java.lang.*;int get*(..)", "getBar", false);
158 	    verifyList("java.util.*;int get*(..)", "getBar", true);
159 	    verifyList("java.lang.String getStringArray()", "getStringArray", false);
160 	    verifyList("java.lang.String[] getStringArray()", "getStringArray", true);
161 	}
162 	
163 	public void testPointcutParamType() throws Exception {
164 	    verifyList("* *(int)", "getint", false);
165 	    verifyList("* *()", "getint", true);
166 	    verifyList("* *(int)", "getFooBar", true);
167 
168 	    // public int doFoo(String foo, List bar)
169 	    verifyList("* *(java.lang.String,..)", "doFoo", true);
170 	    verifyList("* *(java.lang.String,*)", "doFoo", true);
171 	    verifyList("* *(java.lang.String,int)", "doFoo", false);
172 	    verifyList("* *(java.lang.String,java.util.List)", "doFoo", true);
173 	    verifyList("* *(java.*,java.*)", "doFoo", true);
174 	    verifyList("* * ( java.* , java.* ) ", "doFoo", true);
175 	    verifyList("* * ( .. ) ", "doFoo", true);
176 	}
177 	
178 	public void testPointcutModifier() throws Exception {
179 	    verifyList("public;!static;!final * *()", "getint", true);
180 	    verifyList("!public;!static;!final * *()", "getint", false);
181 	    
182 	    verifyList("private * *()", "getintprivate", true);
183 	    verifyList("!private * *()", "getintprivate", false);
184 	    
185 	    verifyList("!static,!final * *()", "getintprivate", false);
186 	    verifyList("synchronized,private * *()", "getintprivatesyn", true);
187 	    verifyList("synchronized,!private * *()", "getintprivatesyn", false);
188 	    verifyList("synchronized,static,private * *()", "getintprivatesynstat", true);
189 	    verifyList("synchronized;static;private * *()", "getintprivatesynstat", true);
190 	    verifyList("synchronized;!static;private * *()", "getintprivatesynstat", false);
191 	    
192 	    verifyList("private * *(..)", "setint", false);
193 	}
194 	
195 	public void testInterfacesImplements() throws Exception {
196 	    verifyList("* uut.PointcutCaseInterface->*(..)", "getFooBar", true);
197 	    verifyList("* uut.PointcutCaseInterface->get*(..)", "getFooBar", true);
198 	    verifyList("* uut.PointcutCaseInterface->*(..)", "getFoo", false);
199 	    verifyList("* uut.PointcutCaseInterface->get*(..)", "getFoo", false);
200 	}
201 
202 	public void testClassAsFilter() throws Exception {
203 	    verifyList("* uut.PointcutCaseClassAsFilter=>*(..)", "getBar", true);
204 	    verifyList("* uut.PointcutCaseClassAsFilter=>get*(..)", "getBarList", false);
205 	    verifyList("* uut.PointcutCaseClassAsFilter=>*(..)", "getFoo", false);
206 	    verifyList("* uut.PointcutCaseClassAsFilter=>get*(..)", "getFoo", false);
207 	}
208 
209 }