blob: c44d9e74eb4528dd8ae11bb2dca70f97cbd1778d [file] [log] [blame]
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* 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.intellij.util.xml;
import com.intellij.util.ArrayUtil;
import com.intellij.util.xml.ui.DomUIFactory;
import junit.framework.TestCase;
import net.sf.cglib.proxy.AdvancedProxy;
import net.sf.cglib.proxy.InvocationHandler;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @author peter
*/
public class ProxyTest extends TestCase {
public void testExtendClass() throws Throwable {
final List<String> invocations = new ArrayList<String>();
Implementation implementation = AdvancedProxy.createProxy(Implementation.class, new Class[]{Interface3.class}, new InvocationHandler(){
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
invocations.add(method.getName());
if (Object.class.equals(method.getDeclaringClass())) {
return method.invoke(this, args);
}
return Implementation.class.getMethod("getField").invoke(proxy);
}
}, "239");
implementation.hashCode();
implementation.method();
assertEquals("239", implementation.getFoo());
implementation.setField("42");
assertEquals("42", implementation.getBar());
assertEquals("42", implementation.toString());
assertEquals(Arrays.asList("hashCode", "getFoo", "getFoo", "getBar"), invocations);
assertEquals("42", Interface1.class.getMethod("getFoo").invoke(implementation));
assertEquals("42", Interface3.class.getMethod("bar").invoke(implementation));
assertEquals("42", Interface1.class.getMethod("foo").invoke(implementation));
assertEquals("42", Interface2.class.getMethod("foo").invoke(implementation));
assertEquals("42", Interface2.class.getMethod("foo").invoke(implementation));
assertEquals("42", Implementation.class.getMethod("foo").invoke(implementation));
}
public interface Interface1 {
Object getFoo();
Object foo();
}
public interface Interface2 extends Interface1 {
@Override
CharSequence getFoo();
@Override
CharSequence foo();
}
public interface Interface3 extends Interface1 {
@Override
String foo();
String bar();
}
private abstract static class Implementation implements Interface2 {
private String myField;
protected Implementation(final String field) {
myField = field;
}
public String getField() {
return myField;
}
public void setField(final String field) {
myField = field;
}
public void method() {
getFoo();
}
public String toString() {
return myField;
}
@Override
public abstract String getFoo();
public abstract String getBar();
@Override
public abstract String foo();
}
public void testAddInterfaces() throws Throwable {
final BaseImpl proxy = AdvancedProxy.createProxy(BaseImpl.class, BaseIEx.class);
assertEquals(proxy.sayA(), "a");
assertEquals(((BaseI)proxy).sayA(), "a");
assertEquals(((BaseIEx)proxy).sayA(), "a");
}
public interface BaseI {
Object sayA();
}
public interface BaseIEx extends BaseI {
@Override
CharSequence sayA();
}
public static abstract class BaseImpl implements BaseI {
@Override
public String sayA() {
return "a";
}
}
public static abstract class AbstractBase implements BaseI {
@Override
public abstract String sayA();
public abstract static class AbstractBaseImpl extends AbstractBase {}
}
public void testCovariantFromInterface() throws Throwable {
final AbstractBase.AbstractBaseImpl proxy = AdvancedProxy.createProxy(AbstractBase.AbstractBaseImpl.class, ArrayUtil.EMPTY_CLASS_ARRAY,
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return "a";
}
}, false, new Object[0]);
assertEquals(proxy.sayA(), "a");
assertEquals(((AbstractBase)proxy).sayA(), "a");
assertEquals(((BaseI)proxy).sayA(), "a");
}
public static class CovariantFromBaseClassTest {
public static interface Intf {
String sayA();
}
public static class Base {
public Object sayA() {
return "beeee";
}
}
public abstract static class Impl extends Base implements Intf {
@Override
public abstract String sayA();
}
}
public void testCovariantFromBaseClass() throws Throwable {
final CovariantFromBaseClassTest.Impl proxy = AdvancedProxy.createProxy(CovariantFromBaseClassTest.Impl.class,
ArrayUtil.EMPTY_CLASS_ARRAY, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return "a";
}
}, false, new Object[0]);
assertEquals(proxy.sayA(), "a");
assertEquals(((CovariantFromBaseClassTest.Base)proxy).sayA(), "a");
assertEquals(((CovariantFromBaseClassTest.Intf)proxy).sayA(), "a");
}
public void testGenericMethodInvocationJava8() throws Throwable {
ConcreteInterface proxy = AdvancedProxy.createProxy(new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return 42;
}
}, null, ConcreteInterface.class);
Method foo = DomUIFactory.findMethod(GenericInterface.class, "foo");
assert foo != null;
assertEquals(42, proxy.foo("a"));
assertEquals(42, foo.invoke(proxy, "a"));
}
interface GenericInterface<T> {
Object foo(T t);
}
interface ConcreteInterface extends GenericInterface<String> {
@Override
Object foo(String t);
}
}