KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > hivemind > service > impl > TestClassFab


1 // Copyright 2004, 2005 The Apache Software Foundation
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
// http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14

15 package org.apache.hivemind.service.impl;
16
17 import hivemind.test.services.AbstractIntWrapper;
18 import hivemind.test.services.FailService;
19 import hivemind.test.services.SimpleService;
20
21 import java.io.IOException JavaDoc;
22 import java.io.Serializable JavaDoc;
23 import java.lang.reflect.Constructor JavaDoc;
24 import java.lang.reflect.Modifier JavaDoc;
25 import java.util.List JavaDoc;
26 import java.util.Map JavaDoc;
27 import java.util.zip.DataFormatException JavaDoc;
28
29 import javassist.CtClass;
30 import junit.framework.AssertionFailedError;
31
32 import org.apache.hivemind.ApplicationRuntimeException;
33 import org.apache.hivemind.impl.BaseLocatable;
34 import org.apache.hivemind.service.ClassFab;
35 import org.apache.hivemind.service.MethodFab;
36 import org.apache.hivemind.service.MethodSignature;
37 import org.apache.hivemind.test.HiveMindTestCase;
38 import org.apache.hivemind.util.PropertyUtils;
39
40 /**
41  * Tests related to {@link org.apache.hivemind.service.impl.ClassFabImpl},
42  * {@link org.apache.hivemind.service.impl.CtClassSource}, etc.
43  *
44  * @author Howard Lewis Ship
45  */

46 public class TestClassFab extends HiveMindTestCase
47 {
48     private CtClassSource _source;
49
50     protected void setUp() throws Exception JavaDoc
51     {
52         super.setUp();
53
54         ClassLoader JavaDoc threadLoader = Thread.currentThread().getContextClassLoader();
55
56         HiveMindClassPool pool = new HiveMindClassPool();
57
58         pool.appendClassLoader(threadLoader);
59
60         _source = new CtClassSource(pool);
61     }
62
63     private ClassFab newClassFab(String JavaDoc className, Class JavaDoc superClass)
64     {
65         CtClass ctClass = _source.newClass(className, superClass);
66
67         return new ClassFabImpl(_source, ctClass);
68     }
69
70     public void testCreateBean() throws Exception JavaDoc
71     {
72         ClassFab cf = newClassFab("TargetBean", Object JavaDoc.class);
73
74         cf.addField("_stringValue", String JavaDoc.class);
75
76         MethodSignature setStringValue = new MethodSignature(void.class, "setStringValue",
77                 new Class JavaDoc[]
78                 { String JavaDoc.class }, null);
79
80         cf.addMethod(Modifier.PUBLIC, setStringValue, "_stringValue = $1;");
81
82         MethodSignature getStringValue = new MethodSignature(String JavaDoc.class, "getStringValue", null,
83                 null);
84
85         cf.addMethod(Modifier.PUBLIC, getStringValue, "return _stringValue;");
86
87         Class JavaDoc targetClass = cf.createClass();
88
89         Object JavaDoc targetBean = targetClass.newInstance();
90
91         PropertyUtils.write(targetBean, "stringValue", "Fred");
92
93         String JavaDoc actual = (String JavaDoc) PropertyUtils.read(targetBean, "stringValue");
94
95         assertEquals("Fred", actual);
96     }
97
98     public void testConstructor() throws Exception JavaDoc
99     {
100         ClassFab cf = newClassFab("ConstructableBean", Object JavaDoc.class);
101
102         cf.addField("_stringValue", String JavaDoc.class);
103         cf.addConstructor(new Class JavaDoc[]
104         { String JavaDoc.class }, null, "{ _stringValue = $1; }");
105
106         MethodSignature getStringValue = new MethodSignature(String JavaDoc.class, "getStringValue", null,
107                 null);
108
109         cf.addMethod(Modifier.PUBLIC, getStringValue, "return _stringValue;");
110
111         Class JavaDoc targetClass = cf.createClass();
112
113         try
114         {
115             targetClass.newInstance();
116             unreachable();
117         }
118         catch (InstantiationException JavaDoc ex)
119         {
120         }
121
122         Constructor JavaDoc c = targetClass.getConstructors()[0];
123
124         Object JavaDoc targetBean = c.newInstance(new Object JavaDoc[]
125         { "Buffy" });
126
127         String JavaDoc actual = (String JavaDoc) PropertyUtils.read(targetBean, "stringValue");
128
129         assertEquals("Buffy", actual);
130     }
131
132     public void testConstructorFromBaseClass() throws Exception JavaDoc
133     {
134         ClassFab cf = newClassFab("MyIntHolder", AbstractIntWrapper.class);
135
136         cf.addField("_intValue", int.class);
137         cf.addConstructor(new Class JavaDoc[]
138         { int.class }, null, "{ _intValue = $1; }");
139
140         cf.addMethod(
141                 Modifier.PUBLIC,
142                 new MethodSignature(int.class, "getIntValue", null, null),
143                 "return _intValue;");
144
145         Class JavaDoc targetClass = cf.createClass();
146         Constructor JavaDoc c = targetClass.getConstructors()[0];
147
148         AbstractIntWrapper targetBean = (AbstractIntWrapper) c.newInstance(new Object JavaDoc[]
149         { new Integer JavaDoc(137) });
150
151         assertEquals(137, targetBean.getIntValue());
152     }
153
154     public void testInvalidSuperClass() throws Exception JavaDoc
155     {
156         ClassFab cf = newClassFab("InvalidSuperClass", List JavaDoc.class);
157
158         try
159         {
160             cf.createClass();
161             unreachable();
162         }
163         catch (ApplicationRuntimeException ex)
164         {
165             assertExceptionSubstring(ex, "Unable to create class InvalidSuperClass");
166         }
167     }
168
169     public void testAddInterface() throws Exception JavaDoc
170     {
171         ClassFab cf = newClassFab("SimpleService", Object JavaDoc.class);
172
173         cf.addInterface(SimpleService.class);
174
175         cf.addMethod(Modifier.PUBLIC, new MethodSignature(int.class, "add", new Class JavaDoc[]
176         { int.class, int.class }, null), "return $1 + $2;");
177
178         Class JavaDoc targetClass = cf.createClass();
179
180         SimpleService s = (SimpleService) targetClass.newInstance();
181
182         assertEquals(207, s.add(99, 108));
183     }
184
185     public void testSubclassFromFinal() throws Exception JavaDoc
186     {
187         ClassFab cf = newClassFab("StringSubclass", String JavaDoc.class);
188
189         try
190         {
191             cf.createClass();
192         }
193         catch (ApplicationRuntimeException ex)
194         {
195             assertExceptionRegexp(
196                     ex,
197                     "Unable to create class StringSubclass\\:.*Cannot inherit from final class");
198         }
199     }
200
201     public void testInPackage() throws Exception JavaDoc
202     {
203         ClassFab cf = newClassFab("org.apache.hivemind.InPackage", Object JavaDoc.class);
204
205         Class JavaDoc c = cf.createClass();
206
207         Object JavaDoc o = c.newInstance();
208
209         assertEquals("org.apache.hivemind.InPackage", o.getClass().getName());
210     }
211
212     public void testBadMethodBody() throws Exception JavaDoc
213     {
214         ClassFab cf = newClassFab("BadMethodBody", Object JavaDoc.class);
215
216         cf.addInterface(Runnable JavaDoc.class);
217
218         try
219         {
220             cf.addMethod(
221                     Modifier.PUBLIC,
222                     new MethodSignature(void.class, "run", null, null),
223                     "fail;");
224         }
225         catch (ApplicationRuntimeException ex)
226         {
227             assertExceptionSubstring(ex, "Unable to add method void run() to class BadMethodBody:");
228         }
229     }
230
231     public void testGetMethodFab() throws Exception JavaDoc
232     {
233         ClassFab cf = newClassFab("GetMethodFab", Object JavaDoc.class);
234
235         MethodSignature s = new MethodSignature(void.class, "run", null, null);
236         MethodFab mf = cf.addMethod(Modifier.PUBLIC, s, null);
237
238         assertSame(mf, cf.getMethodFab(s));
239
240         assertNull(cf.getMethodFab(new MethodSignature(void.class, "skip", null, null)));
241     }
242
243     public void testExtendMethod() throws Exception JavaDoc
244     {
245         ClassFab cf = newClassFab("ExtendMethod", Object JavaDoc.class);
246
247         MethodFab mf = cf.addMethod(Modifier.PUBLIC, new MethodSignature(int.class, "getValue",
248                 null, null), "return 1;");
249
250         mf.extend("return 2 * $_;", false);
251
252         Object JavaDoc bean = cf.createClass().newInstance();
253
254         assertEquals(new Integer JavaDoc(2), PropertyUtils.read(bean, "value"));
255     }
256
257     public void testExtendMethodAlterReturn() throws Exception JavaDoc
258     {
259         ClassFab cf = newClassFab("ExtendMethodAlterReturn", Object JavaDoc.class);
260
261         MethodFab mf = cf.addMethod(Modifier.PUBLIC, new MethodSignature(int.class, "getValue",
262                 null, null), "return 2;");
263
264         mf.extend("$_ = 3 * $_;", false);
265
266         Object JavaDoc bean = cf.createClass().newInstance();
267
268         assertEquals(new Integer JavaDoc(6), PropertyUtils.read(bean, "value"));
269     }
270
271     public void testExtendMethodFailure() throws Exception JavaDoc
272     {
273         ClassFab cf = newClassFab("ExtendMethodFailure", Object JavaDoc.class);
274
275         MethodFab mf = cf.addMethod(Modifier.PUBLIC, new MethodSignature(int.class, "getValue",
276                 null, null), "return 1;");
277
278         try
279         {
280             mf.extend("$_ =", true);
281             unreachable();
282         }
283         catch (ApplicationRuntimeException ex)
284         {
285             assertExceptionSubstring(
286                     ex,
287                     "Unable to extend method int getValue() of class ExtendMethodFailure:");
288         }
289     }
290
291     public void testDupeMethodAdd() throws Exception JavaDoc
292     {
293         ClassFab cf = newClassFab("DupeMethodAdd", Object JavaDoc.class);
294
295         cf.addMethod(Modifier.PUBLIC, new MethodSignature(void.class, "foo", null, null), "{}");
296
297         try
298         {
299             cf.addMethod(Modifier.PUBLIC, new MethodSignature(void.class, "foo", null, null), "{}");
300             unreachable();
301         }
302         catch (ApplicationRuntimeException ex)
303         {
304             assertEquals("Attempt to redefine method void foo() of class DupeMethodAdd.", ex
305                     .getMessage());
306         }
307     }
308
309     public void testBadConstructor() throws Exception JavaDoc
310     {
311         ClassFab cf = newClassFab("BadConstructor", Object JavaDoc.class);
312
313         try
314         {
315             cf.addConstructor(null, null, " woops!");
316         }
317         catch (ApplicationRuntimeException ex)
318         {
319             assertExceptionSubstring(ex, "Unable to add constructor to class BadConstructor");
320         }
321
322     }
323
324     public void testCatchException() throws Exception JavaDoc
325     {
326         ClassFab cf = newClassFab("Fail", Object JavaDoc.class);
327
328         cf.addInterface(FailService.class);
329
330         MethodFab mf = cf.addMethod(Modifier.PUBLIC, new MethodSignature(void.class, "fail", null,
331                 null), "throw new java.lang.RuntimeException(\"Ouch!\");");
332
333         mf.addCatch(RuntimeException JavaDoc.class, "throw new java.io.IOException($e.getMessage());");
334
335         Class JavaDoc targetClass = cf.createClass();
336
337         FailService fs = (FailService) targetClass.newInstance();
338
339         try
340         {
341             fs.fail();
342             unreachable();
343         }
344         catch (IOException JavaDoc ex)
345         {
346             assertEquals("Ouch!", ex.getMessage());
347         }
348     }
349
350     public void testBadCatch() throws Exception JavaDoc
351     {
352         ClassFab cf = newClassFab("BadCatch", Object JavaDoc.class);
353
354         cf.addInterface(Runnable JavaDoc.class);
355
356         MethodFab mf = cf.addMethod(Modifier.PUBLIC, new MethodSignature(void.class, "run", null,
357                 null), "return;");
358
359         try
360         {
361             mf.addCatch(RuntimeException JavaDoc.class, "woops!");
362             unreachable();
363         }
364         catch (ApplicationRuntimeException ex)
365         {
366             assertExceptionSubstring(
367                     ex,
368                     "Unable to add catch block for exception java.lang.RuntimeException to class BadCatch");
369         }
370     }
371
372     public void testInvalidField() throws Exception JavaDoc
373     {
374         ClassFab cf = newClassFab("InvalidField", Object JavaDoc.class);
375
376         cf.addField(".", String JavaDoc.class);
377         cf.addField("buffy", int.class);
378         cf.addField("", int.class);
379
380         try
381         {
382             cf.createClass();
383             unreachable();
384         }
385         catch (ApplicationRuntimeException ex)
386         {
387             assertExceptionSubstring(ex, "Unable to create class InvalidField");
388         }
389
390         // Javassist lets us down here; I can't think of a way to get addField() to actually
391
// fail.
392
}
393
394     /** @since 1.1 */
395     public void testToString() throws Exception JavaDoc
396     {
397         ClassFab cf = newClassFab("FredRunnable", BaseLocatable.class);
398
399         cf.addInterface(Runnable JavaDoc.class);
400         cf.addInterface(Serializable JavaDoc.class);
401
402         cf.addField("_map", Map JavaDoc.class);
403
404         cf.addConstructor(new Class JavaDoc[]
405         { Map JavaDoc.class, Runnable JavaDoc.class }, new Class JavaDoc[]
406         { IllegalArgumentException JavaDoc.class, DataFormatException JavaDoc.class }, "{ _map = $1; }");
407
408         MethodSignature sig = new MethodSignature(Map JavaDoc.class, "doTheNasty", new Class JavaDoc[]
409         { int.class, String JavaDoc.class }, new Class JavaDoc[]
410         { InstantiationException JavaDoc.class, IllegalAccessException JavaDoc.class });
411
412         MethodFab mf = cf.addMethod(
413                 Modifier.PUBLIC + Modifier.FINAL + Modifier.SYNCHRONIZED,
414                 sig,
415                 "{ return _map; }");
416
417         mf.addCatch(NullPointerException JavaDoc.class, "return null;");
418         mf.extend("_map.clear();", true);
419
420         String JavaDoc toString = cf.toString();
421
422         contains(
423                 toString,
424                 "public class FredRunnable extends org.apache.hivemind.impl.BaseLocatable\n"
425                         + " implements java.lang.Runnable, java.io.Serializable");
426
427         contains(toString, "private java.util.Map _map;");
428
429         contains(
430                 toString,
431                 "public FredRunnable(java.util.Map $1, java.lang.Runnable $2)\n"
432                         + " throws java.lang.IllegalArgumentException, java.util.zip.DataFormatException\n"
433                         + "{ _map = $1; }");
434
435         contains(
436                 toString,
437                 "public final synchronized java.util.Map doTheNasty(int $1, java.lang.String $2)\n"
438                         + " throws java.lang.InstantiationException, java.lang.IllegalAccessException\n"
439                         + "{ return _map; }\n" + "catch(java.lang.NullPointerException $e)\n"
440                         + "return null;\n" + "finally\n" + "_map.clear();");
441
442     }
443
444     public void testCanConvert()
445     {
446         final ClassFab cf = newClassFab("BamBam", Object JavaDoc.class);
447         assertTrue( cf.canConvert( String JavaDoc.class ) );
448         assertFalse(cf.canConvert(CglibBeanInterfaceFactory.createCglibBean().getClass()));
449         assertFalse(cf.canConvert(JavassistBeanInterfaceFactory.createJavassistBean().getClass()));
450         assertFalse(cf.canConvert(JdkBeanInterfaceFactory.createJdkBean().getClass()));
451     }
452     
453     /** @since 1.1 */
454     private void contains(String JavaDoc actual, String JavaDoc expected)
455     {
456         if (actual.indexOf(expected) < 0)
457             throw new AssertionFailedError("Missing substring: " + expected);
458     }
459     
460     
461 }
Popular Tags