package org.ximplementation.spring;

import java.lang.reflect.Method;
import java.util.Arrays;

import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.ximplementation.support.Implementation;
import org.ximplementation.support.ImplementationResolver;
import org.ximplementation.support.ImplementorBeanFactory;
import org.ximplementation.support.SimpleImplementorBeanFactory;

public class CglibImplementeeBeanInvocationHandlerTest
{
	private ImplementationResolver implementationResolver;

	private CglibImplementeeBeanBuilder cglibImplementeeBeanBuilder;

	@Before
	public void setUp() throws Exception
	{
		this.implementationResolver = new ImplementationResolver();
		this.cglibImplementeeBeanBuilder = new CglibImplementeeBeanBuilder();
	}

	@After
	public void tearDown() throws Exception
	{
	}

	@Test
	public void invokeTest()
	{
		Implementation<Implementee> implementation = this.implementationResolver
				.resolve(Implementee.class, Implementee.class,
						Implementor0.class, Implementor1.class);

		ImplementorBeanFactory implementorBeanFactory = SimpleImplementorBeanFactory
				.valueOf(new Implementee(), new Implementor0(),
						new Implementor1());

		Implementee implementee = this.cglibImplementeeBeanBuilder
				.build(implementation, implementorBeanFactory);

		Assert.assertFalse(implementee.equals(new Object()));
		Assert.assertNotNull(implementee.handle());
	}

	public static class Implementee
	{
		public static final String RE = Implementee.class.getName();

		public String handle()
		{
			return RE;
		}
	}

	public static class Implementor0 extends Implementee
	{
		public static final String RE = Implementor0.class.getName();

		@Override
		public String handle()
		{
			return RE;
		}
	}

	public static class Implementor1 extends Implementee
	{
		public static final String RE = Implementor1.class.getName();

		@Override
		public String handle()
		{
			return RE;
		}
	}

	public static Method getMethodByName(Class<?> clazz, String name)
	{
		for (Method method : clazz.getMethods())
		{
			if (method.getName().equals(name))
				return method;
		}

		for (Method method : clazz.getDeclaredMethods())
		{
			if (method.getName().equals(name))
				return method;
		}

		return null;
	}

	public static Method getMethodByName(Method[] methods, String name)
	{
		for (Method method : methods)
		{
			if (method.getName().equals(name))
				return method;
		}

		return null;
	}

	public static Method getMethodByNameAndType(Class<?> clazz, String name,
			Class<?>... paramTypes)
	{
		for (Method method : clazz.getMethods())
		{
			if (method.getName().equals(name)
					&& Arrays.equals(method.getParameterTypes(), paramTypes))
				return method;
		}

		for (Method method : clazz.getDeclaredMethods())
		{
			if (method.getName().equals(name)
					&& Arrays.equals(method.getParameterTypes(), paramTypes))
				return method;
		}

		return null;
	}

	public static Method getMethodByNameAndType(Method[] methods, String name,
			Class<?>... paramTypes)
	{
		for (Method method : methods)
		{
			if (method.getName().equals(name)
					&& Arrays.equals(method.getParameterTypes(), paramTypes))
				return method;
		}

		return null;
	}
}

@@ -1,8 +1,586 @@
+/**%0A  * Licensed under the Apache License, Version 2.0 (the %22License%22);%0A  * you may not use this file except in compliance with the License.%0A  * You may obtain a copy of the License at%0A  *  %0A  * %09http://www.apache.org/licenses/LICENSE-2.0%0A  *  %0A  * Unless required by applicable law or agreed to in writing, software%0A  * distributed under the License is distributed on an %22AS IS%22 BASIS,%0A  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.%0A  * See the License for the specific language governing permissions and%0A  * limitations under the License. %0A  */%0A%0A
 package 
@@ -999,16 +999,148 @@
 ctory;%0A%0A
+/**%0A * %7B@linkplain CglibImplementeeBeanInvocationHandler%7D unit tests.%0A * %0A * @author earthangry@gmail.com%0A * @date 2016-11-2%0A *%0A */%0A
 public c

Add class doc