/*
* Copyright (c) 2002-2012 Alibaba Group Holding Limited.
* All rights reserved.
*
* 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 com.alibaba.citrus.util.internal;
import static com.alibaba.citrus.test.TestUtil.*;
import static org.junit.Assert.*;
import java.io.IOException;
import java.io.Serializable;
import java.net.URL;
import java.net.URLClassLoader;
import javax.servlet.ServletContext;
import org.junit.Test;
public class InterfaceImplementorBuilderTests {
private InterfaceImplementorBuilder builder;
@Test
public void classLoader() {
ClassLoader cl;
// default class loader
cl = Thread.currentThread().getContextClassLoader();
builder = new InterfaceImplementorBuilder().addInterface(Serializable.class);
assertSame(cl, builder.getClassLoader());
assertSame(cl, builder.toObject().getClass().getClassLoader());
// specified class loader
cl = new URLClassLoader(new URL[0]);
builder = new InterfaceImplementorBuilder(cl).addInterface(Serializable.class);
assertSame(cl, builder.getClassLoader());
assertSame(cl, builder.toObject().getClass().getClassLoader());
}
@Test
public void interfaces() {
try {
new InterfaceImplementorBuilder().toObject();
fail();
} catch (IllegalArgumentException e) {
assertThat(e, exception("no interface specified"));
}
try {
new InterfaceImplementorBuilder().addInterface(null).toObject();
fail();
} catch (IllegalArgumentException e) {
assertThat(e, exception("no interface specified"));
}
}
@Test
public void baseObject() {
// no baseObject
ServletContext sc = (ServletContext) new InterfaceImplementorBuilder().addInterface(ServletContext.class).toObject();
try {
sc.getAttribute("key");
fail();
} catch (UnsupportedOperationException e) {
assertThat(e, exception("ServletContext.getAttribute(String)"));
}
// wrong type of baseObject
try {
new InterfaceImplementorBuilder().addInterface(Runnable.class).setBaseClass(String.class).toObject();
fail();
} catch (IllegalArgumentException e) {
assertThat(e, exception("Base class java.lang.String must implement interface java.lang.Runnable"));
}
try {
new InterfaceImplementorBuilder().addInterface(Runnable.class).addInterface(ServletContext.class).setBaseClass(Runnable.class).toObject();
fail();
} catch (IllegalArgumentException e) {
assertThat(e, exception("Base class java.lang.Runnable must implement interface javax.servlet.ServletContext"));
}
}
@Test
public void setOverriderSetProxyObjectMethodName() {
final Object[] holder = new Object[1];
// default method
ServletContext sc = (ServletContext) new InterfaceImplementorBuilder().addInterface(ServletContext.class).toObject(new Object() {
public void setThisProxy(ServletContext proxy) {
holder[0] = proxy;
}
});
assertSame(holder[0], sc);
// specified method name
sc = (ServletContext) new InterfaceImplementorBuilder().addInterface(ServletContext.class).setOverriderSetProxyObjectMethodName("setMyProxy").toObject(new Object() {
public void setMyProxy(ServletContext proxy) {
holder[0] = proxy;
}
});
assertSame(holder[0], sc);
// super param type
sc = (ServletContext) new InterfaceImplementorBuilder().addInterface(ServletContext.class).toObject(new Object() {
public void setThisProxy(Object proxy) {
holder[0] = proxy;
}
});
assertSame(holder[0], sc);
// wrong param type
holder[0] = null;
sc = (ServletContext) new InterfaceImplementorBuilder().addInterface(ServletContext.class).toObject(new Object() {
public void setThisProxy(String proxy) {
holder[0] = proxy;
}
});
assertSame(null, holder[0]);
// no param type
holder[0] = null;
sc = (ServletContext) new InterfaceImplementorBuilder().addInterface(ServletContext.class).toObject(new Object() {
public void setThisProxy() {
}
});
assertSame(null, holder[0]);
// call failed
try {
sc = (ServletContext) new InterfaceImplementorBuilder().addInterface(ServletContext.class).toObject(new Object() {
public void setThisProxy(Object proxy) {
throw new IllegalArgumentException();
}
});
} catch (Exception e) {
assertThat(e, exception(IllegalArgumentException.class, "Failed to call ", "setThisProxy(Object)"));
}
assertSame(null, holder[0]);
}
@Test
public void toObject() {
final Object[] holder = new Object[1];
Object overrider = new Object() {
public void setThisProxy(Object proxy) {
holder[0] = proxy;
}
};
builder = new InterfaceImplementorBuilder().addInterface(ServletContext.class).setOverriderClass(overrider.getClass());
ServletContext sc1 = (ServletContext) builder.toObject(overrider);
assertSame(sc1, holder[0]);
ServletContext sc2 = (ServletContext) builder.toObject(overrider);
assertSame(sc2, holder[0]);
assertNotSame(sc1, sc2);
assertSame(sc1.getClass(), sc2.getClass());
}
@Test
public void invokeSuper() {
Runnable newObject = (Runnable) new InterfaceImplementorBuilder().addInterface(Runnable.class).toObject(null, new Runnable() {
public void run() {
}
@Override
public int hashCode() {
return 123;
}
@Override
public boolean equals(Object obj) {
return true;
}
@Override
public String toString() {
return "haha";
}
});
assertFalse(newObject.equals(""));
assertFalse(123 == newObject.hashCode());
assertFalse("haha".equals(newObject.toString()));
}
public static interface MyInterface1 {
String getName();
void throwException(Throwable e) throws Throwable;
}
@Test
public void invokeBaseObject() {
MyInterface1 newObject = (MyInterface1) new InterfaceImplementorBuilder().addInterface(MyInterface1.class).toObject(null, new MyInterface1() {
public String getName() {
return "myname";
}
public void throwException(Throwable e) throws Throwable {
throw e;
}
});
assertEquals("myname", newObject.getName());
try {
newObject.throwException(new IllegalArgumentException());
fail();
} catch (Throwable e) {
assertTrue(e instanceof IllegalArgumentException);
}
try {
newObject.throwException(new IOException());
fail();
} catch (Throwable e) {
assertTrue(e instanceof IOException);
}
}
public static class MySuperClass {
public String sayHello() {
return "hello";
}
}
@Test
public void invokeBaseObject_withSuperclass() {
MyInterface1 newObject = (MyInterface1) new InterfaceImplementorBuilder().setSuperclass(MySuperClass.class).addInterface(MyInterface1.class).toObject(null, new MyInterface1() {
public String getName() {
return "myname";
}
public void throwException(Throwable e) throws Throwable {
throw e;
}
});
assertTrue(newObject instanceof MySuperClass);
assertEquals("hello", ((MySuperClass) newObject).sayHello());
assertEquals("myname", newObject.getName());
try {
newObject.throwException(new IllegalArgumentException());
fail();
} catch (Throwable e) {
assertTrue(e instanceof IllegalArgumentException);
}
try {
newObject.throwException(new IOException());
fail();
} catch (Throwable e) {
assertTrue(e instanceof IOException);
}
}
public static interface MyInterface2 {
String getName();
String getName(String s);
String getName(Object o, String s);
void throwException(Throwable e) throws Throwable;
}
@Test
public void invokeOverrider() {
MyInterface2 baseObject = new MyInterface2() {
public String getName() {
return "myname";
}
public String getName(String s) {
return null;
}
public String getName(Object o, String s) {
return null;
}
public void throwException(Throwable e) throws Throwable {
}
};
Object overrider1 = new Object() {
public String getName(String s) {
return "" + s;
}
public String getName(Integer o, Object s) {
return "" + o + s;
}
public String getName(Object o, Integer s) {
return "" + o + s;
}
public void throwException(Throwable e) throws Throwable {
throw e;
}
};
MyInterface2 newObject = (MyInterface2) new InterfaceImplementorBuilder().addInterface(MyInterface2.class).toObject(overrider1, baseObject);
assertEquals("myname", newObject.getName()); // from baseObject
assertEquals("another name", newObject.getName("another name")); // from overrider
assertEquals(null, newObject.getName("my", " name")); // no overrider method matched
try {
newObject.throwException(new IllegalArgumentException());
fail();
} catch (Throwable e) {
assertTrue(e instanceof IllegalArgumentException);
}
try {
newObject.throwException(new IOException());
fail();
} catch (Throwable e) {
assertTrue(e instanceof IOException);
}
Object overrider2 = new Object() {
public String getName(Object o, Object s) {
return "" + o + s;
}
};
newObject = (MyInterface2) new InterfaceImplementorBuilder().addInterface(MyInterface2.class).toObject(overrider2, baseObject);
assertEquals("myname", newObject.getName()); // from baseObject
assertEquals(null, newObject.getName("another name")); // no overrider method matched
assertEquals("my name", newObject.getName("my", " name")); // from overrider, string parameter as an object
}
}