001: // Copyright 2006, 2007 The Apache Software Foundation
002: //
003: // Licensed under the Apache License, Version 2.0 (the "License");
004: // you may not use this file except in compliance with the License.
005: // You may obtain a copy of the License at
006: //
007: // http://www.apache.org/licenses/LICENSE-2.0
008: //
009: // Unless required by applicable law or agreed to in writing, software
010: // distributed under the License is distributed on an "AS IS" BASIS,
011: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: // See the License for the specific language governing permissions and
013: // limitations under the License.
014:
015: package org.apache.tapestry.ioc.internal.services;
016:
017: import java.lang.reflect.Constructor;
018: import java.lang.reflect.Method;
019: import java.lang.reflect.Modifier;
020:
021: import org.apache.tapestry.ioc.Location;
022: import org.apache.tapestry.ioc.internal.util.LocationImpl;
023: import org.apache.tapestry.ioc.services.ClassFab;
024: import org.apache.tapestry.ioc.services.ClassFabUtils;
025: import org.apache.tapestry.ioc.services.ClassFactory;
026: import org.apache.tapestry.ioc.services.MethodSignature;
027: import org.apache.tapestry.ioc.test.IOCTestCase;
028: import org.testng.annotations.Test;
029:
030: public class ClassFactoryImplTest extends IOCTestCase {
031: public static class BaseClass {
032: public void run() {
033: }
034: }
035:
036: @Test
037: public void new_class_with_name_and_base_class() throws Exception {
038: ClassFactory factory = new ClassFactoryImpl();
039: String name = ClassFabUtils.generateClassName(Runnable.class);
040:
041: ClassFab cf = factory.newClass(name, Object.class);
042: cf.addInterface(Runnable.class);
043:
044: addRunMethod(cf);
045:
046: Class newClass = cf.createClass();
047:
048: Runnable instance = (Runnable) newClass.newInstance();
049:
050: instance.run();
051: }
052:
053: @Test
054: public void new_class_with_non_object_base_class() throws Exception {
055: ClassFactory factory = new ClassFactoryImpl();
056: String name = ClassFabUtils.generateClassName(Runnable.class);
057:
058: ClassFab cf = factory.newClass(name, BaseClass.class);
059: cf.addInterface(Runnable.class);
060:
061: Class newClass = cf.createClass();
062:
063: Runnable instance = (Runnable) newClass.newInstance();
064:
065: instance.run();
066: }
067:
068: @Test
069: public void new_class_with_interface() throws Exception {
070: ClassFactory factory = new ClassFactoryImpl();
071:
072: ClassFab cf = factory.newClass(Runnable.class);
073:
074: addRunMethod(cf);
075:
076: Class newClass = cf.createClass();
077:
078: Runnable instance = (Runnable) newClass.newInstance();
079:
080: instance.run();
081: }
082:
083: @Test
084: public void get_method_location() throws Exception {
085: ClassFactory factory = new ClassFactoryImpl();
086:
087: Class target = LineNumberBean.class;
088:
089: Method m = target.getMethod("fred");
090:
091: // 21 is the line containing the close brace
092:
093: Location l = factory.getMethodLocation(m);
094: assertEquals(
095: l.toString(),
096: "org.apache.tapestry.ioc.internal.services.LineNumberBean.fred() (at LineNumberBean.java:25)");
097: assertEquals(l.getLine(), 25);
098:
099: m = target.getMethod("betty", String.class, int.class);
100:
101: // 25 is the line of the return statement
102:
103: assertEquals(
104: factory.getMethodLocation(m).toString(),
105: "org.apache.tapestry.ioc.internal.services.LineNumberBean.betty(String, int) (at LineNumberBean.java:29)");
106:
107: m = target.getDeclaredMethod("wilma", int[].class,
108: Double[][][].class);
109:
110: assertEquals(
111: factory.getMethodLocation(m).toString(),
112: "org.apache.tapestry.ioc.internal.services.LineNumberBean.wilma(int[], Double[][][]) (at LineNumberBean.java:34)");
113: }
114:
115: private void addRunMethod(ClassFab cf) {
116: cf.addMethod(Modifier.PUBLIC, new MethodSignature(void.class,
117: "run", null, null), " { } ");
118: }
119:
120: @Test
121: public void get_constructor_location() throws Exception {
122: Constructor cc = LineNumberBean.class.getConstructors()[0];
123:
124: ClassFactory factory = new ClassFactoryImpl();
125:
126: // Eclipse and Sun JDK don't agree on the line number, so we'll accept either.
127:
128: assertTrue(factory
129: .getConstructorLocation(cc)
130: .toString()
131: .matches(
132: "org.apache.tapestry.ioc.internal.services.LineNumberBean\\(String, int\\) \\(at LineNumberBean.java:(19|20)\\)"));
133: }
134:
135: /**
136: * Import a class (or two) where the class is from a known and available class loader.
137: */
138: @Test
139: public void import_ordinary_class() {
140: ClassFactory factory = new ClassFactoryImpl();
141:
142: assertSame(factory.importClass(Object.class), Object.class);
143: assertSame(factory.importClass(LocationImpl.class),
144: LocationImpl.class);
145: }
146:
147: /**
148: * Import a class where the bytecode is not available, to ensure that the super-class (from an
149: * available class loader) is returned.
150: */
151: @Test
152: public void import_proxy_class() throws Exception {
153: ClassFactory alienFactory = new ClassFactoryImpl();
154:
155: Class<TargetBean> clazz = TargetBean.class;
156:
157: ClassFab cf = alienFactory.newClass(
158: clazz.getName() + "$$Proxy", clazz);
159:
160: Class alienClass = cf.createClass();
161:
162: ClassFactory factory = new ClassFactoryImpl();
163:
164: assertSame(factory.importClass(alienClass), clazz);
165: }
166: }
|