package tc.oc.commons.core.reflect;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Member;
import java.lang.reflect.Modifier;
import java.util.Map;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.stream.Stream;
import javax.annotation.Nullable;
import com.google.common.collect.Maps;
import tc.oc.commons.core.stream.BiStream;
public final class Members {
private Members() {}
private static final int ACCESS_MODIFIERS = Modifier.PRIVATE | Modifier.PROTECTED | Modifier.PUBLIC;
private static final int NON_INHERITABLE_MODIFIERS = Modifier.PRIVATE | Modifier.STATIC;
public static String qualifiedName(Class<?> decl, String name) {
return decl.getName() + "#" + name;
}
public static String qualifiedName(Member member) {
return qualifiedName(member.getDeclaringClass(), member.getName());
}
public static boolean isPrivate(Member member) {
return Modifier.isPrivate(member.getModifiers());
}
public static boolean isProtected(Member member) {
return Modifier.isProtected(member.getModifiers());
}
public static boolean isPublic(Member member) {
return Modifier.isPublic(member.getModifiers());
}
public static boolean isPackagePrivate(Member member) {
return (member.getModifiers() & ACCESS_MODIFIERS) == 0;
}
public static boolean isAbstract(Member member) {
return Modifier.isAbstract(member.getModifiers());
}
public static boolean isStatic(Member member) {
return Modifier.isStatic(member.getModifiers());
}
public static boolean isInheritable(Member member) {
return (member.getModifiers() & NON_INHERITABLE_MODIFIERS) == 0;
}
public static void error(Member member, String description) {
throw new IllegalArgumentException(member.getDeclaringClass().getName() + "#" + member.getName() + " " + description);
}
public static void assertPublic(Member member) {
if(!Modifier.isPublic(member.getModifiers())) {
error(member, "is not public");
}
}
public static Predicate<? super Member> withModifiers(final int modifiers, final int mask) {
return member -> (member.getModifiers() & mask) == modifiers;
}
public static Predicate<? super Member> withAllModifiers(int modifiers) {
return withModifiers(modifiers, modifiers);
}
public static Predicate<? super Member> withoutAnyModifiers(int modifiers) {
return withModifiers(0, modifiers);
}
public static Predicate<? super Member> staticMembers() {
return withAllModifiers(Modifier.STATIC);
}
public static Predicate<? super Member> instanceMembers() {
return withoutAnyModifiers(Modifier.STATIC);
}
public static @Nullable Member enclosingMember(Class<?> cls) {
final Member member = cls.getEnclosingMethod();
return member != null ? member : cls.getEnclosingConstructor();
}
public static <A extends Annotation> Optional<A> annotation(Class<A> type, AnnotatedElement element) {
return Optional.ofNullable(element.getAnnotation(type));
}
public static <E extends AnnotatedElement, A extends Annotation> BiStream<E, A> annotations(Class<A> type, Stream<E> elements) {
return BiStream.fromKeys(elements, element -> element.getAnnotation(type))
.filter((element, annotation) -> annotation != null);
}
}