001: //$Id$
002: //=====================================================================
003: //
004: //(history at end)
005: //
006:
007: package ch.ethz.prose;
008:
009: // used packages
010: import junit.framework.*;
011:
012: import java.lang.reflect.*;
013:
014: import ch.ethz.inf.iks.jvmai.jvmdi.HotSwapClassWeaver;
015: import ch.ethz.inf.iks.jvmai.jvmdi.HotSwapFieldWeaver;
016: import ch.ethz.inf.iks.jvmai.jvmdi.HotSwapAspectInterfaceImpl;
017: import ch.ethz.jvmai.*;
018: import ch.ethz.prose.crosscut.*;
019: import ch.ethz.prose.filter.*;
020:
021: /**
022: * JUnit testcase for Constructor join points (HotSwap advice weaving).
023: *
024: * @version $Revision$
025: * @author Gerald Linhofer
026: * @author Angela Nicoara
027: */
028: public class HotSwapConstructorJoinPointTest extends TestCase {
029:
030: private HotSwapAspectInterfaceImpl aspectInterface;
031:
032: /**
033: * Construct test with given name.
034: * @param name test name
035: */
036: public HotSwapConstructorJoinPointTest(String name) {
037: super (name);
038: }
039:
040: /**
041: * Set up fixture.
042: */
043: protected void setUp() {
044: aspectInterface = HotSwapAspectInterfaceImpl.getInstance();
045: aspectInterface.startup(new String[0], true);
046: }
047:
048: /**
049: * Clean up.
050: */
051: protected void tearDown() {
052: aspectInterface.teardown();
053: }
054:
055: class MyClass1 {
056: MyClass1() {
057: super ();
058: }
059: }
060:
061: class MyClass2 {
062: String str;
063:
064: MyClass2(String s) {
065: str = s;
066: }
067: }
068:
069: static class TestHook extends JoinPointHook {
070: public int count;
071:
072: public void reset() {
073: count = 0;
074: }
075:
076: public void onFieldAccess(FieldAccessJoinPoint joinPoint) {
077: }
078:
079: public void onFieldModification(
080: FieldModificationJoinPoint joinPoint) {
081: }
082:
083: public void onMethodEntry(MethodEntryJoinPoint joinPoint) {
084: }
085:
086: public void onMethodExit(MethodExitJoinPoint joinPoint) {
087: }
088:
089: public void onExceptionThrow(ExceptionJoinPoint joinPoint) {
090: }
091:
092: public void onExceptionCatch(ExceptionCatchJoinPoint joinPoint) {
093: }
094:
095: public void onClassLoad(Class cls) {
096: }
097:
098: public void onConstructor(ConstructorJoinPoint joinPoint) {
099: count++;
100: }
101: }
102:
103: static class TestHook2 extends JoinPointHook {
104: public int count;
105:
106: public void reset() {
107: count = 0;
108: }
109:
110: public void onFieldAccess(FieldAccessJoinPoint joinPoint) {
111: }
112:
113: public void onFieldModification(
114: FieldModificationJoinPoint joinPoint) {
115: }
116:
117: public void onMethodEntry(MethodEntryJoinPoint joinPoint) {
118: }
119:
120: public void onMethodExit(MethodExitJoinPoint joinPoint) {
121: }
122:
123: public void onExceptionThrow(ExceptionJoinPoint joinPoint) {
124: }
125:
126: public void onExceptionCatch(ExceptionCatchJoinPoint joinPoint) {
127: }
128:
129: public void onClassLoad(Class cls) {
130: }
131:
132: public void onConstructor(ConstructorJoinPoint joinPoint) {
133: joinPoint.setArg(0, "testHook2 was here");
134: }
135: }
136:
137: public void test_040_aspectInterface() {
138: Object aopTag = new Object();
139: Constructor c = MyClass1.class.getDeclaredConstructors()[0];
140:
141: TestHook testHook = new TestHook();
142: testHook.reset();
143: aspectInterface.setJoinPointHook(testHook);
144:
145: aspectInterface.suspendNotification(Thread.currentThread());
146: aspectInterface.setConstructorWatch(c, aopTag);
147: aspectInterface.resumeNotification(Thread.currentThread());
148:
149: // normal notification
150: new MyClass1();
151: assertEquals("onConstructor notification", 1, testHook.count);
152:
153: // setWatch exceptions
154: int exceptionCount = 0;
155: try {
156: aspectInterface.setConstructorWatch(null, aopTag);
157: } catch (NullPointerException e) {
158: exceptionCount++;
159: }
160: try {
161: aspectInterface.setConstructorWatch(c, null);
162: } catch (IllegalArgumentException e) {
163: exceptionCount++;
164: }
165: try {
166: aspectInterface.setConstructorWatch(c, aopTag);
167: } catch (WatchAlreadySetException e) {
168: exceptionCount++;
169: }
170: assertEquals("number of exceptions ", 3, exceptionCount);
171:
172: // suspended notification
173: aspectInterface.suspendNotification(Thread.currentThread());
174: new MyClass1();
175: assertEquals("onConstructor suspended notification", 1,
176: testHook.count);
177:
178: // clear watch
179: aspectInterface.clearConstructorWatch(c);
180: aspectInterface.resumeNotification(Thread.currentThread());
181: new MyClass1();
182: assertEquals("clear constructor", 1, testHook.count);
183:
184: // change argument
185: TestHook2 th2 = new TestHook2();
186: aspectInterface.suspendNotification(Thread.currentThread());
187: aspectInterface.setConstructorWatch(MyClass2.class
188: .getDeclaredConstructors()[0], aopTag);
189: aspectInterface.setJoinPointHook(th2);
190: aspectInterface.resumeNotification(Thread.currentThread());
191: MyClass2 mc2 = new MyClass2("unmodified");
192: assertEquals("modify argument", "testHook2 was here", mc2.str);
193: }
194:
195: public class MyAspect1 extends DefaultAspect {
196:
197: int invokationCounter = 0;
198:
199: public Crosscut c1 = new ConstructorCut() {
200: public void METHOD_ARGS(MyClass1 x, REST y) {
201: invokationCounter++;
202: }
203:
204: protected PointCutter pointCutter() {
205: return Within.type("MyClass1.*");
206: }
207: };
208: }
209:
210: public class MyAspect2 extends DefaultAspect {
211:
212: int invokationCounter = 0;
213: String lastArg;
214:
215: public Crosscut c1 = new ConstructorCut() {
216: public void METHOD_ARGS(MyClass2 x, String i, REST y) {
217: lastArg = i;
218: invokationCounter++;
219: }
220:
221: protected PointCutter pointCutter() {
222: return Within.type("MyClass2.*");
223: }
224: };
225: }
226:
227: private String stackframes2string(Exception e) {
228: StringBuffer sb = new StringBuffer();
229: StackTraceElement sf[] = e.getStackTrace();
230: for (int i = 0; i < sf.length; i++) {
231: sb.append("\n " + sf[i].toString());
232: }
233: return sb.toString();
234: }
235:
236: public void test_050_aspectManager() {
237: MyClass1 mc1 = null;
238: MyClass2 mc2 = null;
239: try {
240: ProseSystem.startup();
241:
242: // Constructor without arguments
243: MyAspect1 asp1 = new MyAspect1();
244: ProseSystem.getAspectManager().insert(asp1);
245: for (int i = 0; i < 100; i++) {
246: mc1 = new MyClass1();
247: }
248: assertEquals("num of constructor invokations", 100,
249: asp1.invokationCounter);
250: ProseSystem.getAspectManager().withdraw(asp1);
251:
252: // Constructor with an argument
253: MyAspect2 asp2 = new MyAspect2();
254: ProseSystem.getAspectManager().insert(asp2);
255: for (int i = 0; i < 100; i++) {
256: mc2 = new MyClass2(String.valueOf(i));
257: assertEquals("constructor arg modified", i, Integer
258: .parseInt(asp2.lastArg));
259: }
260: assertEquals("num of constructor invokations with arg",
261: 100, asp2.invokationCounter);
262: ProseSystem.getAspectManager().withdraw(asp2);
263:
264: } catch (Exception e) {
265: fail(e.getClass().getName()
266: + ": "
267: + e.getMessage()
268: + /*" ->" + e.getStackTrace()[0].toString() */" trace: "
269: + stackframes2string(e));
270: }
271: try {
272: ProseSystem.teardown();
273: } catch (SystemTeardownException e) {
274: }
275: }
276:
277: /**
278: * Test suite.
279: * @return test instance
280: */
281: public static Test suite() {
282: return new TestSuite(HotSwapConstructorJoinPointTest.class);
283: }
284: }
285:
286: //======================================================================
287: //
288: // $Log$
289: //
|