@Test(expectedExceptions = { InvalidProxyDescriptionException.class }) public void testMissingInterfaceMethod() throws InvalidProxyDescriptionException { @ProxyFor(implementedInterfaces = { "java.io.Closeable" }) class Subject extends BasicSubject { // missing close() method } ProxyBuildPlanImpl.create(Subject.class, "myname", ProxyBuildPlanImplTest.class.getClassLoader()); }
ProxyBuildPlanImpl plan = new ProxyBuildPlanImpl(); plan.proxyClassName = proxyName; ProxyFor proxyInfo = proxySubjectType.getAnnotation(ProxyFor.class); Class<?> superClass = getType(superClassName, context); plan.superClass = superClass; Class<?> interfaceClass = getType(interfaceName, context); plan.implementedInterfaces.add(interfaceClass); Class<?> paramType = getType(paramTypeName, context); plan.constructorParameterTypes.add(paramType); plan.validate(); plan.computeTargetClassLoader(); return plan;
/** * Validates the constructor. * * @throws InvalidProxyDescriptionException * if something is wrong */ private void validateConstructor() throws InvalidProxyDescriptionException { Class<?>[] params = this.getConstructorParameterTypes().toArray(new Class<?>[getConstructorParameterTypes().size()]); try { Constructor<?> ctr = superClass.getDeclaredConstructor(params); if ((ctr.getModifiers() & (Modifier.PROTECTED | Modifier.PUBLIC)) == 0) { InvalidProxyDescriptionException.throwException("The constructor with parameter types %s found in class %s is neither public nor protected!", params, superClass); } } catch (NoSuchMethodException e) { InvalidProxyDescriptionException.throwException("No accessible constructor with parameter types %s found in class %s", params, superClass); } }
/** * Computes the target classloader to place the proxy in based on the used dependencies. * * @throws InvalidProxyDescriptionException * if no fitting classloader can be located */ private void computeTargetClassLoader() throws InvalidProxyDescriptionException { // Collect all dependencies of the proxy class HashSet<ClassLoader> dependencies = new HashSet<ClassLoader>(); dependencies.add(getSuperClass().getClassLoader()); for (Class<?> interf : getImplementedInterfaces()) { dependencies.add(interf.getClassLoader()); } for (MethodBuildPlanImpl meth : getMethods()) { dependencies.add(meth.getReturnType().getClassLoader()); for (Class<?> type : meth.getParameterTypes()) { dependencies.add(type.getClassLoader()); } } targetClassLoader = getLowestClassLoader(dependencies); }
validateConstructor(); for (Class<?> parent : getAllParentTypes()) { for (Method meth : parent.getMethods()) { if ((meth.getModifiers() & Modifier.ABSTRACT) != 0) {
/** * {@inheritDoc} */ @Override public List<Class<?>> getConstructorExceptions() { try { Constructor<?> constructor = getSuperClass().getDeclaredConstructor(constructorParameterTypes.toArray(new Class<?>[constructorParameterTypes.size()])); return Arrays.asList(constructor.getExceptionTypes()); } catch (Exception e) { throw new RuntimeException("Error fetching constructor exception types!", e); } }
@Test(expectedExceptions = InvalidProxyDescriptionException.class) public void testNonOptionalMethod() throws InvalidProxyDescriptionException { @ProxyFor class Subject extends BasicSubject { @ProxyMethod(parameterTypes = { "this.does.not.Exist" }) public void methodWithMissingParameterType(Object param) { } } ProxyBuildPlanImpl.create(Subject.class, "myname", ProxyBuildPlanImplTest.class.getClassLoader()); }
@Test(expectedExceptions = { InvalidProxyDescriptionException.class }) public void testMissingProxyFor() throws InvalidProxyDescriptionException { class Subject extends BasicSubject { @ProxyMethod(methodName = "write") public void thisActuallyIsWrite(int value) { } } ProxyBuildPlanImpl.create(Subject.class, "myname", ProxyBuildPlanImplTest.class.getClassLoader()); }
@Test(expectedExceptions = { InvalidProxyDescriptionException.class }) public void testSuperClassConstructorInvalidParameters() throws InvalidProxyDescriptionException { @ProxyFor(superClass = "java.io.FileOutputStream", constructorParameterTypes = { "java.io.Closeable" }) class Subject extends BasicSubject { } ProxyBuildPlanImpl.create(Subject.class, "myname", ProxyBuildPlanImplTest.class.getClassLoader()); }
@Test public void testReturnTypeInvalidCasting() throws InvalidProxyDescriptionException { @ProxyFor() class Subject extends BasicSubject { @ProxyMethod(returnType = "java.io.OutputStream") public java.io.File castMe() { return null; } } ProxyBuildPlanImpl.create(Subject.class, "myname", ProxyBuildPlanImplTest.class.getClassLoader()); }
@Test(expectedExceptions = { InvalidProxyDescriptionException.class }) public void testMissingAbstractSuperclassMethod() throws InvalidProxyDescriptionException { @ProxyFor(superClass = "java.io.OutputStream") class Subject extends BasicSubject { // missing write() method } ProxyBuildPlanImpl.create(Subject.class, "myname", ProxyBuildPlanImplTest.class.getClassLoader()); }
@Test(expectedExceptions = { InvalidProxyDescriptionException.class }) public void testParameterInvalidCasting() throws InvalidProxyDescriptionException { @ProxyFor() class Subject extends BasicSubject { @ProxyMethod(parameterTypes = { "java.lang.Object" }) public void castMe(java.io.File thisCouldBeNotAFile) { } } ProxyBuildPlanImpl.create(Subject.class, "myname", ProxyBuildPlanImplTest.class.getClassLoader()); }
@Test(expectedExceptions = { InvalidProxyDescriptionException.class }) public void testMethodRenamingDuplicateDetection() throws InvalidProxyDescriptionException { @ProxyFor(superClass = "java.io.OutputStream") class Subject extends BasicSubject { @ProxyMethod(methodName = "write") public void thisActuallyisWrite(int value) { } @ProxyMethod(methodName = "write") public void thisActuallyisWriteToo(int value) { } } ProxyBuildPlanImpl.create(Subject.class, "myname", ProxyBuildPlanImplTest.class.getClassLoader()); }
@Test public void testDefaultSuperClass() throws InvalidProxyDescriptionException { @ProxyFor(implementedInterfaces = { "java.io.Closeable" }) class Subject extends BasicSubject { @ProxyMethod public void close() { } } IProxyBuildPlan bp = ProxyBuildPlanImpl.create(Subject.class, "myname", ProxyBuildPlanImplTest.class.getClassLoader()); assertThat(bp.getSuperClass().getName(), equalTo(Object.class.getName())); }
@Test public void testOptionalMethod() throws InvalidProxyDescriptionException { @ProxyFor class Subject extends BasicSubject { @ProxyMethod(parameterTypes = { "this.does.not.Exist" }, isOptional = true) public void methodWithMissingParameterType(Object param) { } } IProxyBuildPlan bp = ProxyBuildPlanImpl.create(Subject.class, "myname", ProxyBuildPlanImplTest.class.getClassLoader()); assertThat(bp.getMethods().size(), equalTo(0)); } }
@Test public void testSuperClassConstructorParameters() throws InvalidProxyDescriptionException { @ProxyFor(superClass = "java.io.FileOutputStream", constructorParameterTypes = { "java.io.File" }) class Subject extends BasicSubject { } IProxyBuildPlan bp = ProxyBuildPlanImpl.create(Subject.class, "myname", ProxyBuildPlanImplTest.class.getClassLoader()); assertThat(bp.getConstructorParameterTypes().size(), equalTo(1)); assertThat(bp.getConstructorParameterTypes().get(0).getName(), equalTo("java.io.File")); }
try { String name = getProxyClassName(subjectType.getName()); IProxyBuildPlan plan = ProxyBuildPlanImpl.create(subjectType, name, context);
@Test public void testReturnTypeCorrectCasting() throws InvalidProxyDescriptionException { @ProxyFor() class Subject extends BasicSubject { @ProxyMethod(returnType = "java.io.File") public Object castMe() { return null; } } IProxyBuildPlan bp = ProxyBuildPlanImpl.create(Subject.class, "myname", ProxyBuildPlanImplTest.class.getClassLoader()); assertThat(bp.getMethods().size(), equalTo(1)); assertThat(bp.getMethods().get(0).getReturnType().getName(), equalTo("java.io.File")); }
@Test public void testMethodRenaming() throws InvalidProxyDescriptionException { @ProxyFor class Subject extends BasicSubject { @ProxyMethod(methodName = "equals") public boolean thisActuallyisEquals(Object other) { return false; } } IProxyBuildPlan bp = ProxyBuildPlanImpl.create(Subject.class, "myname", ProxyBuildPlanImplTest.class.getClassLoader()); assertThat(bp.getMethods().size(), equalTo(1)); assertThat(bp.getMethods().get(0).getMethodName(), equalTo("equals")); }
@Test public void testParameterCorrectCasting() throws InvalidProxyDescriptionException { @ProxyFor() class Subject extends BasicSubject { @ProxyMethod(parameterTypes = { "java.io.File" }) public void castMe(Object thisIsActuallyAFile) { } } IProxyBuildPlan bp = ProxyBuildPlanImpl.create(Subject.class, "myname", ProxyBuildPlanImplTest.class.getClassLoader()); assertThat(bp.getMethods().size(), equalTo(1)); assertThat(bp.getMethods().get(0).getParameterTypes().size(), equalTo(1)); assertThat(bp.getMethods().get(0).getParameterTypes().get(0).getName(), equalTo("java.io.File")); }