/*
* Copyright 2004-2015 the Seasar Foundation and the Others.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
package org.seasar.framework.aop.javassist;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Arrays;
import junit.framework.TestCase;
import org.aopalliance.intercept.MethodInvocation;
import org.seasar.framework.util.ClassPoolUtil;
/**
* @author koichik
*/
public class EnhancedClassGeneratorTest extends TestCase {
/**
* @throws Exception
*/
public void testNormalizeExceptionTypes() throws Exception {
assertTrue(
"1",
Arrays
.equals(
new Class[] { Throwable.class },
EnhancedClassGenerator
.normalizeExceptionTypes(new Class[] { Throwable.class })));
assertTrue("2", Arrays.equals(new Class[] { Throwable.class },
EnhancedClassGenerator.normalizeExceptionTypes(new Class[] {
Throwable.class, Exception.class })));
assertTrue("3", Arrays.equals(new Class[] { Throwable.class },
EnhancedClassGenerator.normalizeExceptionTypes(new Class[] {
Throwable.class, Exception.class, Error.class })));
assertTrue("4", Arrays.equals(new Class[] { Exception.class,
Error.class }, EnhancedClassGenerator
.normalizeExceptionTypes(new Class[] { Exception.class,
Error.class })));
assertTrue("5", Arrays.equals(new Class[] { Exception.class,
Error.class }, EnhancedClassGenerator
.normalizeExceptionTypes(new Class[] { RuntimeException.class,
Exception.class, Error.class })));
assertTrue("6", Arrays.equals(new Class[] { RuntimeException.class,
IOException.class, Error.class }, EnhancedClassGenerator
.normalizeExceptionTypes(new Class[] { RuntimeException.class,
IOException.class, Error.class })));
}
/**
* @throws Exception
*/
public void testAroundTryCatchBlock() throws Exception {
assertEquals(
"1",
"try {return;}"
+ "catch (java.lang.Exception e) {throw e;}"
+ "catch (java.lang.RuntimeException e) {throw e;}"
+ "catch (java.lang.Error e) {throw e;}"
+ "catch (java.lang.Throwable e) {throw new java.lang.reflect.UndeclaredThrowableException(e);}",
EnhancedClassGenerator.aroundTryCatchBlock(
new Class[] { Exception.class }, "return;"));
assertEquals(
"2",
"try {return;}"
+ "catch (java.lang.RuntimeException e) {throw e;}"
+ "catch (java.io.IOException e) {throw e;}"
+ "catch (java.lang.Error e) {throw e;}"
+ "catch (java.lang.Throwable e) {throw new java.lang.reflect.UndeclaredThrowableException(e);}",
EnhancedClassGenerator.aroundTryCatchBlock(new Class[] {
RuntimeException.class, IOException.class }, "return;"));
}
/**
* @throws Exception
*/
public void testCreateTargetMethodSource() throws Exception {
Method method1 = Object.class.getMethod("hashCode", null);
assertEquals(
"1",
"{"
+ "try {"
+ "Object result = new MethodInvocation(this, $args).proceed();"
+ "return ($r) ((result == null) ? 0 : ((java.lang.Number) result).intValue());"
+ "}"
+ "catch (java.lang.RuntimeException e) {throw e;}"
+ "catch (java.lang.Error e) {throw e;}"
+ "catch (java.lang.Throwable e) {throw new java.lang.reflect.UndeclaredThrowableException(e);}"
+ "}", EnhancedClassGenerator.createTargetMethodSource(
method1, "MethodInvocation"));
Method method2 = Object.class.getMethod("wait", null);
assertEquals(
"2",
"{"
+ "try {"
+ "Object result = new MethodInvocation(this, $args).proceed();"
+ "return;"
+ "}"
+ "catch (java.lang.InterruptedException e) {throw e;}"
+ "catch (java.lang.RuntimeException e) {throw e;}"
+ "catch (java.lang.Error e) {throw e;}"
+ "catch (java.lang.Throwable e) {throw new java.lang.reflect.UndeclaredThrowableException(e);}"
+ "}", EnhancedClassGenerator.createTargetMethodSource(
method2, "MethodInvocation"));
Method method3 = MethodInvocation.class.getMethod("proceed", null);
assertEquals(
"3",
"{"
+ "Object result = new MethodInvocation(this, $args).proceed();"
+ "return ($r) result;" + "}", EnhancedClassGenerator
.createTargetMethodSource(method3, "MethodInvocation"));
}
/**
* @throws Exception
*/
public void testCreateInvokeSuperMethodSource() throws Exception {
Method method = Object.class.getMethod("wait", null);
assertEquals("1", "{" + "return ($r) super.wait($$);" + "}",
EnhancedClassGenerator.createInvokeSuperMethodSource(method));
}
/**
* @throws Exception
*/
public void testGenerateFromInterface() throws Exception {
Method[] methods = TargetInterface.class.getDeclaredMethods();
for (int i = 0; i < methods.length; ++i) {
EnhancedClassGenerator generator = new EnhancedClassGenerator(
ClassPoolUtil.getClassPool(TargetInterface.class),
TargetInterface.class, TargetInterface.class.getName() + i);
generator
.createTargetMethod(
methods[i],
MethodInvocationClassGenerator.MethodInvocationTemplate.class
.getName());
Class clazz = generator.toClass(getClass().getClassLoader());
assertEquals("1", TargetInterface.class.getName() + i, clazz
.getName());
Method method = clazz.getDeclaredMethod(methods[i].getName(),
methods[i].getParameterTypes());
assertEquals("2", methods[i].getName(), method.getName());
}
}
/**
* @throws Exception
*/
public void testGenerateFromClass() throws Exception {
Method[] methods = TargetClass.class.getDeclaredMethods();
for (int i = 0; i < methods.length; ++i) {
EnhancedClassGenerator generator = new EnhancedClassGenerator(
ClassPoolUtil.getClassPool(TargetClass.class),
TargetClass.class, TargetClass.class.getName() + i);
generator.createInvokeSuperMethod(methods[i], methods[i].getName()
+ "__invokeSuper__");
generator
.createTargetMethod(
methods[i],
MethodInvocationClassGenerator.MethodInvocationTemplate.class
.getName());
Class clazz = generator.toClass(getClass().getClassLoader());
assertEquals("1", TargetClass.class.getName() + i, clazz.getName());
Method method = clazz.getDeclaredMethod(methods[i].getName(),
methods[i].getParameterTypes());
assertEquals("2", methods[i].getName(), method.getName());
Method invokeSuperMethod = clazz.getDeclaredMethod(methods[i]
.getName()
+ "__invokeSuper__", methods[i].getParameterTypes());
assertEquals("3", methods[i].getName() + "__invokeSuper__",
invokeSuperMethod.getName());
}
}
/**
*
*/
public static interface TargetInterface {
/**
*
*/
public void fVoid();
/**
* @return
*/
public boolean fBoolean();
/**
* @return
*/
public char fChar();
/**
* @return
*/
public byte fByte();
/**
* @return
*/
public short fShort();
/**
* @return
*/
public int fInt();
/**
* @return
*/
public long fLong();
/**
* @return
*/
public float fFloat();
/**
* @return
*/
public double fDouble();
/**
* @return
*/
public int[] fIntArray();
/**
* @return
*/
public int[][] fInt2DArray();
/**
* @return
*/
public Object fObject();
/**
* @return
*/
public Object[] fObjectArray();
/**
* @return
*/
public String fString();
/**
* @return
*/
public String[] fStringArray();
/**
* @param arg0
* @return
*/
public boolean f(boolean arg0);
/**
* @param arg0
* @return
*/
public char f(char arg0);
/**
* @param arg0
* @return
*/
public byte f(byte arg0);
/**
* @param arg0
* @return
*/
public short f(short arg0);
/**
* @param arg0
* @return
*/
public int f(int arg0);
/**
* @param arg0
* @return
*/
public long f(long arg0);
/**
* @param arg0
* @return
*/
public float f(float arg0);
/**
* @param arg0
* @return
*/
public double f(double arg0);
/**
* @param arg0
* @return
*/
public int[] f(int[] arg0);
/**
* @param arg0
* @return
*/
public int[][] f(int[][] arg0);
/**
* @param arg0
* @return
*/
public Object f(Object arg0);
/**
* @param arg0
* @return
*/
public Object[] f(Object[] arg0);
/**
* @param arg0
* @return
*/
public String f(String arg0);
/**
* @param arg0
* @return
*/
public String[] f(String[] arg0);
/**
* @param arg0
* @param arg1
* @param arg2
* @param arg3
* @param arg4
* @param arg5
* @param arg6
* @param arg7
* @param arg8
* @param arg9
* @param arg10
* @param arg11
* @param arg12
* @param arg13
*/
public void f(boolean arg0, char arg1, byte arg2, short arg3, int arg4,
long arg5, float arg6, double arg7, int[] arg8, int[][] arg9,
Object arg10, Object[] arg11, String arg12, String[] arg13);
}
/**
*
*/
public static class TargetClass {
/**
*
*/
public void fVoid() {
}
/**
* @return
*/
public boolean fBoolean() {
return false;
}
/**
* @return
*/
public char fChar() {
return 0;
}
/**
* @return
*/
public byte fByte() {
return 0;
}
/**
* @return
*/
public short fShort() {
return 0;
}
/**
* @return
*/
public int fInt() {
return 0;
}
/**
* @return
*/
public long fLong() {
return 0;
}
/**
* @return
*/
public float fFloat() {
return 0;
}
/**
* @return
*/
public double fDouble() {
return 0;
}
/**
* @return
*/
public int[] fIntArray() {
return new int[0];
}
/**
* @return
*/
public int[][] fInt2DArray() {
return new int[0][0];
}
/**
* @return
*/
public Object fObject() {
return null;
}
/**
* @return
*/
public Object[] fObjectArray() {
return new Object[0];
}
/**
* @return
*/
public String fString() {
return "";
}
/**
* @return
*/
public String[] fStringArray() {
return new String[0];
}
/**
* @param arg0
* @return
*/
public boolean f(boolean arg0) {
return arg0;
}
/**
* @param arg0
* @return
*/
public char f(char arg0) {
return arg0;
}
/**
* @param arg0
* @return
*/
public byte f(byte arg0) {
return arg0;
}
/**
* @param arg0
* @return
*/
public short f(short arg0) {
return arg0;
}
/**
* @param arg0
* @return
*/
public int f(int arg0) {
return arg0;
}
/**
* @param arg0
* @return
*/
public long f(long arg0) {
return arg0;
}
/**
* @param arg0
* @return
*/
public float f(float arg0) {
return arg0;
}
/**
* @param arg0
* @return
*/
public double f(double arg0) {
return arg0;
}
/**
* @param arg0
* @return
*/
public int[] f(int[] arg0) {
return arg0;
}
/**
* @param arg0
* @return
*/
public int[][] f(int[][] arg0) {
return arg0;
}
/**
* @param arg0
* @return
*/
public Object f(Object arg0) {
return arg0;
}
/**
* @param arg0
* @return
*/
public Object[] f(Object[] arg0) {
return arg0;
}
/**
* @param arg0
* @return
*/
public String f(String arg0) {
return arg0;
}
/**
* @param arg0
* @return
*/
public String[] f(String[] arg0) {
return arg0;
}
/**
* @param arg0
* @param arg1
* @param arg2
* @param arg3
* @param arg4
* @param arg5
* @param arg6
* @param arg7
* @param arg8
* @param arg9
* @param arg10
* @param arg11
* @param arg12
* @param arg13
*/
public void f(boolean arg0, char arg1, byte arg2, short arg3, int arg4,
long arg5, float arg6, double arg7, int[] arg8, int[][] arg9,
Object arg10, Object[] arg11, String arg12, String[] arg13) {
}
}
}