blob: 7fe631060991beb964625d5b541bf36dbdbdde4c [file] [log] [blame]
// ***************************************************************************************************************************
// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file *
// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file *
// * to you 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.apache.juneau.reflection;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
import static org.apache.juneau.reflect.ReflectFlags.*;
import static org.junit.Assert.*;
import java.io.*;
import java.lang.annotation.*;
import java.util.*;
import java.util.function.*;
import java.util.stream.*;
import org.apache.juneau.*;
import org.apache.juneau.internal.*;
import org.apache.juneau.reflect.*;
import org.junit.*;
public class ExecutableInfoTest {
private static void check(String expected, Object o) {
assertEquals(expected, TO_STRING.apply(o));
}
private static final Function<Object,String> TO_STRING = new Function<Object,String>() {
@Override
public String apply(Object t) {
if (t == null)
return null;
if (t instanceof List)
return ((List<?>)t).stream().map(this).collect(Collectors.joining(","));
if (t.getClass().isArray())
return StreamSupport.stream(ArrayUtils.toList(t, Object.class).spliterator(), false).map(this).collect(Collectors.joining(","));
if (t instanceof Annotation)
return t.toString().replaceAll("\\@[^\\$]*\\$(.*)", "@$1");
if (t instanceof Class)
return ((Class<?>)t).getSimpleName();
if (t instanceof ClassInfo)
return ((ClassInfo)t).getSimpleName();
if (t instanceof ConstructorInfo)
return ((ConstructorInfo)t).getShortName();
if (t instanceof ParamInfo)
return apply(((ParamInfo)t).toString());
return t.toString();
}
};
//-----------------------------------------------------------------------------------------------------------------
// Instantiation.
//-----------------------------------------------------------------------------------------------------------------
static class A {
public A() {}
public void foo() {}
}
static ClassInfo a = ClassInfo.of(A.class);
@Test
public void isConstructor() {
assertTrue(a.getPublicConstructor().isConstructor());
assertFalse(a.getPublicMethod("foo").isConstructor());
}
@Test
public void getDeclaringClass() {
check("A", a.getPublicConstructor().getDeclaringClass());
check("A", a.getPublicMethod("foo").getDeclaringClass());
}
//-----------------------------------------------------------------------------------------------------------------
// Parameters
//-----------------------------------------------------------------------------------------------------------------
static class B {
public B() {}
public B(String s) {}
public void m() {}
public int m(String s) { return 0; }
}
static ClassInfo b = ClassInfo.of(B.class);
static ExecutableInfo
b_c1=b.getPublicConstructor(),
b_c2=b.getPublicConstructor(String.class),
b_m1=b.getPublicMethod("m"),
b_m2=b.getPublicMethod("m", String.class)
;
@Test
public void getParamCount() {
assertEquals(0, b_c1.getParamCount());
assertEquals(1, b_c2.getParamCount());
assertEquals(0, b_m1.getParamCount());
assertEquals(1, b_m2.getParamCount());
}
@Test
public void hasParams() {
assertEquals(false, b_c1.hasParams());
assertEquals(true, b_c2.hasParams());
assertEquals(false, b_m1.hasParams());
assertEquals(true, b_m2.hasParams());
}
@Test
public void hasNoParams() {
assertEquals(true, b_c1.hasNoParams());
assertEquals(false, b_c2.hasNoParams());
assertEquals(true, b_m1.hasNoParams());
assertEquals(false, b_m2.hasNoParams());
}
@Test
public void hasNumParams() {
assertEquals(false, b_c1.hasNumParams(1));
assertEquals(true, b_c2.hasNumParams(1));
assertEquals(false, b_m1.hasNumParams(1));
assertEquals(true, b_m2.hasNumParams(1));
}
@Test
public void getParams() {
check("", b_c1.getParams());
check("B[0]", b_c2.getParams());
check("", b_m1.getParams());
check("m[0]", b_m2.getParams());
}
@Test
public void getParams_twice() {
check("", b_c1.getParams());
check("", b_c1.getParams());
}
@Test
public void getParam() {
check("B[0]", b_c2.getParam(0));
check("m[0]", b_m2.getParam(0));
}
@Test
public void getParam_nocache() {
ClassInfo b = ClassInfo.of(B.class);
check("B[0]", b.getPublicConstructor(String.class).getParam(0));
check("m[0]", b.getPublicMethod("m", String.class).getParam(0));
}
@Test
public void getParam_indexOutOfBounds() {
try {
b_c1.getParam(0);
} catch (IndexOutOfBoundsException e) {
assertEquals("Invalid index '0'. No parameters.", e.getLocalizedMessage());
}
try {
b_c2.getParam(-1);
} catch (IndexOutOfBoundsException e) {
assertEquals("Invalid index '-1'. Parameter count: 1", e.getLocalizedMessage());
}
try {
b_c2.getParam(1);
} catch (IndexOutOfBoundsException e) {
assertEquals("Invalid index '1'. Parameter count: 1", e.getLocalizedMessage());
}
}
@Test
public void getParam_indexOutOfBounds_noCache() {
ClassInfo b = ClassInfo.of(B.class);
try {
b.getPublicConstructor().getParam(0);
} catch (IndexOutOfBoundsException e) {
assertEquals("Invalid index '0'. No parameters.", e.getLocalizedMessage());
}
try {
b.getPublicConstructor(String.class).getParam(-1);
} catch (IndexOutOfBoundsException e) {
assertEquals("Invalid index '-1'. Parameter count: 1", e.getLocalizedMessage());
}
try {
b.getPublicConstructor(String.class).getParam(1);
} catch (IndexOutOfBoundsException e) {
assertEquals("Invalid index '1'. Parameter count: 1", e.getLocalizedMessage());
}
}
@Test
public void getParamTypes() {
check("", b_c1.getParamTypes());
check("String", b_c2.getParamTypes());
check("", b_m1.getParamTypes());
check("String", b_m2.getParamTypes());
}
@Test
public void getParamTypes_twice() {
check("", b_c1.getParamTypes());
check("", b_c1.getParamTypes());
}
static enum B1 {
FOO;
}
@Test
public void getParamTypes_enum() {
ClassInfo b1 = ClassInfo.of(B1.class);
check("B1(String,int)", b1.getDeclaredConstructors());
check("String,int", b1.getDeclaredConstructors().get(0).getParamTypes());
}
@Test
public void getParamType() {
check("String", b_c2.getParamType(0));
check("String", b_m2.getParamType(0));
}
@Test
public void getRawParamTypes() {
check("", b_c1.getRawParamTypes());
check("String", b_c2.getRawParamTypes());
check("", b_m1.getRawParamTypes());
check("String", b_m2.getRawParamTypes());
}
@Test
public void getRawParamType() {
check("String", b_c2.getRawParamType(0));
check("String", b_m2.getRawParamType(0));
}
@Test
public void getRawGenericParamType() {
check("String", b_c2.getRawGenericParamType(0));
check("String", b_m2.getRawGenericParamType(0));
}
@Test
public void getRawGenericParamTypes() {
check("", b_c1.getRawGenericParamTypes());
check("String", b_c2.getRawGenericParamTypes());
check("", b_m1.getRawGenericParamTypes());
check("String", b_m2.getRawGenericParamTypes());
}
@Test
public void getRawParameters() {
check("", b_c1.getRawParameters());
assertTrue(b_c2.getRawParameters()[0].toString().startsWith("java.lang.String "));
check("", b_m1.getRawParameters());
assertTrue(b_m2.getRawParameters()[0].toString().startsWith("java.lang.String "));
}
@Test
public void getRawParameter() {
assertTrue(b_c2.getRawParameter(0).toString().startsWith("java.lang.String "));
assertTrue(b_m2.getRawParameter(0).toString().startsWith("java.lang.String "));
}
//-----------------------------------------------------------------------------------------------------------------
// Annotations
//-----------------------------------------------------------------------------------------------------------------
@Documented
@Target({PARAMETER,METHOD,CONSTRUCTOR})
@Retention(RUNTIME)
@Inherited
public static @interface CA {}
static class C {
public C() {}
public C(@CA String foo) {}
public @CA C(int bar) {}
public void m() {}
public void m(@CA String foo) {}
public @CA void m(int bar) {}
}
static ClassInfo c = ClassInfo.of(C.class);
static ConstructorInfo
c_c1=c.getPublicConstructor(),
c_c2=c.getPublicConstructor(String.class),
c_c3=c.getPublicConstructor(int.class)
;
static MethodInfo
c_m1=c.getPublicMethod("m"),
c_m2=c.getPublicMethod("m", String.class),
c_m3=c.getPublicMethod("m", int.class)
;
@Test
public void getParameterAnnotations() {
check("", c_c1.getParameterAnnotations());
check("@CA()", c_c2.getParameterAnnotations());
check("", c_c3.getParameterAnnotations());
check("", c_m1.getParameterAnnotations());
check("@CA()", c_m2.getParameterAnnotations());
check("", c_m3.getParameterAnnotations());
}
@Test
public void getParameterAnnotations_atIndex() {
check("@CA()", c_c2.getParameterAnnotations(0));
check("@CA()", c_m2.getParameterAnnotations(0));
}
@Test
public void hasAnnotation() {
assertFalse(c_c1.hasAnnotation(CA.class));
assertFalse(c_c2.hasAnnotation(CA.class));
assertTrue(c_c3.hasAnnotation(CA.class));
assertFalse(c_m1.hasAnnotation(CA.class));
assertFalse(c_m2.hasAnnotation(CA.class));
assertTrue(c_m3.hasAnnotation(CA.class));
}
@Test
public void getAnnotation() {
check(null, c_c1.getAnnotation(CA.class));
check(null, c_c2.getAnnotation(CA.class));
check("@CA()", c_c3.getAnnotation(CA.class));
check(null, c_m1.getAnnotation(CA.class));
check(null, c_m2.getAnnotation(CA.class));
check("@CA()", c_m3.getAnnotation(CA.class));
}
@Test
public void getAnnotation_nullArg() {
check(null, c_c3.getAnnotation(null));
}
//-----------------------------------------------------------------------------------------------------------------
// Exceptions
//-----------------------------------------------------------------------------------------------------------------
static class D {
public D() throws IOException {}
public void m() throws IOException {}
}
static ClassInfo d = ClassInfo.of(D.class);
static ExecutableInfo
d_c=d.getPublicConstructor(),
d_m=d.getPublicMethod("m")
;
@Test
public void getExceptionTypes() {
check("IOException", d_c.getExceptionTypes());
check("IOException", d_m.getExceptionTypes());
}
@Test
public void getExceptionTypes_twice() {
check("IOException", d_c.getExceptionTypes());
check("IOException", d_c.getExceptionTypes());
}
@Test
public void getRawExceptionTypes() {
check("IOException", d_c.getRawExceptionTypes());
check("IOException", d_m.getRawExceptionTypes());
}
//-----------------------------------------------------------------------------------------------------------------
// Characteristics
//-----------------------------------------------------------------------------------------------------------------
static abstract class E {
@Deprecated public void deprecated() {}
public void notDeprecated() {}
public void hasParams(int foo) {}
public void hasStringParam(String foo) {}
public void hasNoParams() {}
public void isPublic() {}
protected void isNotPublic() {}
public static void isStatic() {}
public void isNotStatic() {}
public abstract void isAbstract();
public void isNotAbstract() {}
}
static ClassInfo e = ClassInfo.of(E.class);
static ExecutableInfo
e_deprecated = e.getPublicMethod("deprecated"),
e_notDeprecated = e.getPublicMethod("notDeprecated"),
e_hasParams = e.getPublicMethod("hasParams", int.class),
e_hasStringParam = e.getPublicMethod("hasStringParam", String.class),
e_hasNoParams = e.getPublicMethod("hasNoParams"),
e_isPublic = e.getPublicMethod("isPublic"),
e_isNotPublic = e.getMethod("isNotPublic"),
e_isStatic = e.getPublicMethod("isStatic"),
e_isNotStatic = e.getPublicMethod("isNotStatic"),
e_isAbstract = e.getPublicMethod("isAbstract"),
e_isNotAbstract = e.getPublicMethod("isNotAbstract")
;
@Test
public void isAll() {
assertTrue(e_deprecated.isAll(DEPRECATED));
assertTrue(e_notDeprecated.isAll(NOT_DEPRECATED));
assertTrue(e_hasParams.isAll(HAS_PARAMS));
assertTrue(e_hasNoParams.isAll(HAS_NO_PARAMS));
assertTrue(e_isPublic.isAll(PUBLIC));
assertTrue(e_isNotPublic.isAll(NOT_PUBLIC));
assertTrue(e_isStatic.isAll(STATIC));
assertTrue(e_isNotStatic.isAll(NOT_STATIC));
assertTrue(e_isAbstract.isAll(ABSTRACT));
assertTrue(e_isNotAbstract.isAll(NOT_ABSTRACT));
assertFalse(e_deprecated.isAll(NOT_DEPRECATED));
assertFalse(e_notDeprecated.isAll(DEPRECATED));
assertFalse(e_hasParams.isAll(HAS_NO_PARAMS));
assertFalse(e_hasNoParams.isAll(HAS_PARAMS));
assertFalse(e_isPublic.isAll(NOT_PUBLIC));
assertFalse(e_isNotPublic.isAll(PUBLIC));
assertFalse(e_isStatic.isAll(NOT_STATIC));
assertFalse(e_isNotStatic.isAll(STATIC));
assertFalse(e_isAbstract.isAll(NOT_ABSTRACT));
assertFalse(e_isNotAbstract.isAll(ABSTRACT));
}
@Test
public void isAll_invalidFlag() {
try {
e_deprecated.isAll(TRANSIENT);
} catch (RuntimeException e) {
assertEquals("Invalid flag for executable: TRANSIENT", e.getLocalizedMessage());
}
}
@Test
public void isAny() {
assertTrue(e_deprecated.isAny(DEPRECATED));
assertTrue(e_notDeprecated.isAny(NOT_DEPRECATED));
assertTrue(e_hasParams.isAny(HAS_PARAMS));
assertTrue(e_hasNoParams.isAny(HAS_NO_PARAMS));
assertTrue(e_isPublic.isAny(PUBLIC));
assertTrue(e_isNotPublic.isAny(NOT_PUBLIC));
assertTrue(e_isStatic.isAny(STATIC));
assertTrue(e_isNotStatic.isAny(NOT_STATIC));
assertTrue(e_isAbstract.isAny(ABSTRACT));
assertTrue(e_isNotAbstract.isAny(NOT_ABSTRACT));
assertFalse(e_deprecated.isAny(NOT_DEPRECATED));
assertFalse(e_notDeprecated.isAny(DEPRECATED));
assertFalse(e_hasParams.isAny(HAS_NO_PARAMS));
assertFalse(e_hasNoParams.isAny(HAS_PARAMS));
assertFalse(e_isPublic.isAny(NOT_PUBLIC));
assertFalse(e_isNotPublic.isAny(PUBLIC));
assertFalse(e_isStatic.isAny(NOT_STATIC));
assertFalse(e_isNotStatic.isAny(STATIC));
assertFalse(e_isAbstract.isAny(NOT_ABSTRACT));
assertFalse(e_isNotAbstract.isAny(ABSTRACT));
}
@Test
public void isAny_invalidFlag() {
try {
e_deprecated.isAny(TRANSIENT);
} catch (RuntimeException e) {
assertEquals("Invalid flag for executable: TRANSIENT", e.getLocalizedMessage());
}
}
@Test
public void hasArgs() {
assertTrue(e_hasParams.hasParamTypes(int.class));
assertFalse(e_hasParams.hasParamTypes(new Class[0]));
assertFalse(e_hasParams.hasParamTypes(long.class));
assertTrue(e_hasNoParams.hasParamTypes(new Class[0]));
assertFalse(e_hasNoParams.hasParamTypes(long.class));
}
@Test
public void hasArgParents() {
assertTrue(e_hasStringParam.hasParamTypeParents(String.class));
assertTrue(e_hasStringParam.hasParamTypeParents(CharSequence.class));
assertFalse(e_hasStringParam.hasParamTypeParents(StringBuilder.class));
assertFalse(e_hasStringParam.hasParamTypeParents(new Class[0]));
assertFalse(e_hasStringParam.hasParamTypeParents(String.class, String.class));
assertFalse(e_hasStringParam.hasParamTypeParents(long.class));
}
@Test
public void hasFuzzyArgs() {
assertTrue(e_hasParams.hasFuzzyParamTypes(int.class));
assertTrue(e_hasParams.hasFuzzyParamTypes(int.class, long.class));
assertFalse(e_hasParams.hasFuzzyParamTypes(long.class));
assertTrue(e_hasNoParams.hasFuzzyParamTypes(new Class[0]));
assertTrue(e_hasNoParams.hasFuzzyParamTypes(long.class));
}
@Test
public void isDeprecated() {
assertTrue(e_deprecated.isDeprecated());
assertFalse(e_notDeprecated.isDeprecated());
}
@Test
public void isNotDeprecated() {
assertFalse(e_deprecated.isNotDeprecated());
assertTrue(e_notDeprecated.isNotDeprecated());
}
@Test
public void isAbstract() {
assertTrue(e_isAbstract.isAbstract());
assertFalse(e_isNotAbstract.isAbstract());
}
@Test
public void isNotAbstract() {
assertFalse(e_isAbstract.isNotAbstract());
assertTrue(e_isNotAbstract.isNotAbstract());
}
@Test
public void isPublic() {
assertTrue(e_isPublic.isPublic());
assertFalse(e_isNotPublic.isPublic());
}
@Test
public void isNotPublic() {
assertFalse(e_isPublic.isNotPublic());
assertTrue(e_isNotPublic.isNotPublic());
}
@Test
public void isStatic() {
assertTrue(e_isStatic.isStatic());
assertFalse(e_isNotStatic.isStatic());
}
@Test
public void isNotStatic() {
assertFalse(e_isStatic.isNotStatic());
assertTrue(e_isNotStatic.isNotStatic());
}
//-----------------------------------------------------------------------------------------------------------------
// Visibility
//-----------------------------------------------------------------------------------------------------------------
static abstract class F {
public void isPublic() {}
protected void isProtected() {}
@SuppressWarnings("unused")
private void isPrivate() {}
void isDefault() {}
}
static ClassInfo f = ClassInfo.of(F.class);
static ExecutableInfo
f_isPublic = f.getPublicMethod("isPublic"),
f_isProtected = f.getMethod("isProtected"),
f_isPrivate = f.getMethod("isPrivate"),
f_isDefault = f.getMethod("isDefault");
@Test
public void setAccessible() {
f_isPublic.setAccessible();
f_isProtected.setAccessible();
f_isPrivate.setAccessible();
f_isDefault.setAccessible();
}
@Test
public void isVisible() {
assertTrue(f_isPublic.isVisible(Visibility.PUBLIC));
assertTrue(f_isPublic.isVisible(Visibility.PROTECTED));
assertTrue(f_isPublic.isVisible(Visibility.PRIVATE));
assertTrue(f_isPublic.isVisible(Visibility.DEFAULT));
assertFalse(f_isProtected.isVisible(Visibility.PUBLIC));
assertTrue(f_isProtected.isVisible(Visibility.PROTECTED));
assertTrue(f_isProtected.isVisible(Visibility.PRIVATE));
assertTrue(f_isProtected.isVisible(Visibility.DEFAULT));
assertFalse(f_isPrivate.isVisible(Visibility.PUBLIC));
assertFalse(f_isPrivate.isVisible(Visibility.PROTECTED));
assertTrue(f_isPrivate.isVisible(Visibility.PRIVATE));
assertFalse(f_isPrivate.isVisible(Visibility.DEFAULT));
assertFalse(f_isDefault.isVisible(Visibility.PUBLIC));
assertFalse(f_isDefault.isVisible(Visibility.PROTECTED));
assertTrue(f_isDefault.isVisible(Visibility.PRIVATE));
assertTrue(f_isDefault.isVisible(Visibility.DEFAULT));
}
//-----------------------------------------------------------------------------------------------------------------
// Labels
//-----------------------------------------------------------------------------------------------------------------
static class X {
public X() {}
public X(String foo) {}
public X(Map<String,Object> foo) {}
public void foo(){}
public void foo(String foo){}
public void foo(Map<String,Object> foo){}
}
static ClassInfo x = ClassInfo.of(X.class);
@Test
public void getFullName_method() {
assertEquals("org.apache.juneau.reflection.ExecutableInfoTest$X.foo()", x.getPublicMethod("foo").getFullName());
assertEquals("org.apache.juneau.reflection.ExecutableInfoTest$X.foo(java.lang.String)", x.getPublicMethod("foo", String.class).getFullName());
assertEquals("org.apache.juneau.reflection.ExecutableInfoTest$X.foo(java.util.Map<java.lang.String,java.lang.Object>)", x.getPublicMethod("foo", Map.class).getFullName());
}
@Test
public void getFullName_constructor() {
assertEquals("org.apache.juneau.reflection.ExecutableInfoTest$X()", x.getPublicConstructor().getFullName());
assertEquals("org.apache.juneau.reflection.ExecutableInfoTest$X(java.lang.String)", x.getPublicConstructor(String.class).getFullName());
assertEquals("org.apache.juneau.reflection.ExecutableInfoTest$X(java.util.Map<java.lang.String,java.lang.Object>)", x.getPublicConstructor(Map.class).getFullName());
}
@Test
public void getShortName_method() {
assertEquals("foo()", x.getPublicMethod("foo").getShortName());
assertEquals("foo(String)", x.getPublicMethod("foo", String.class).getShortName());
assertEquals("foo(Map)", x.getPublicMethod("foo", Map.class).getShortName());
}
@Test
public void getShortName_constructor() {
assertEquals("X()", x.getPublicConstructor().getShortName());
assertEquals("X(String)", x.getPublicConstructor(String.class).getShortName());
assertEquals("X(Map)", x.getPublicConstructor(Map.class).getShortName());
}
@Test
public void getSimpleName_method() {
assertEquals("foo", x.getPublicMethod("foo").getSimpleName());
assertEquals("foo", x.getPublicMethod("foo", String.class).getSimpleName());
assertEquals("foo", x.getPublicMethod("foo", Map.class).getSimpleName());
}
@Test
public void getSimpleName_constructor() {
assertEquals("X", x.getPublicConstructor().getSimpleName());
assertEquals("X", x.getPublicConstructor(String.class).getSimpleName());
assertEquals("X", x.getPublicConstructor(Map.class).getSimpleName());
}
}