001 package org.junit.runners.model; 002 003 import java.lang.reflect.Modifier; 004 import java.util.List; 005 006 /** 007 * Parent class for {@link FrameworkField} and {@link FrameworkMethod} 008 * 009 * @since 4.7 010 */ 011 public abstract class FrameworkMember<T extends FrameworkMember<T>> implements 012 Annotatable { 013 abstract boolean isShadowedBy(T otherMember); 014 015 /** 016 * Check if this member is shadowed by any of the given members. If it 017 * is, the other member is removed. 018 * 019 * @return member that should be used, or {@code null} if no member should be used. 020 */ 021 final T handlePossibleShadowedMember(List<T> members) { 022 for (int i = members.size() - 1; i >=0; i--) { 023 T otherMember = members.get(i); 024 if (isShadowedBy(otherMember)) { 025 if (otherMember.isBridgeMethod()) { 026 /* 027 * We need to return the previously-encountered bridge method 028 * because JUnit won't be able to call the parent method, 029 * because the parent class isn't public. 030 */ 031 members.remove(i); 032 return otherMember; 033 } 034 // We found a shadowed member that isn't a bridge method. Ignore it. 035 return null; 036 } 037 } 038 // No shadow or bridge method found. The caller should add *this* member. 039 return self(); 040 } 041 042 @SuppressWarnings("unchecked") 043 private T self() { 044 return (T) this; 045 } 046 047 abstract boolean isBridgeMethod(); 048 049 protected abstract int getModifiers(); 050 051 /** 052 * Returns true if this member is static, false if not. 053 */ 054 public boolean isStatic() { 055 return Modifier.isStatic(getModifiers()); 056 } 057 058 /** 059 * Returns true if this member is public, false if not. 060 */ 061 public boolean isPublic() { 062 return Modifier.isPublic(getModifiers()); 063 } 064 065 public abstract String getName(); 066 067 public abstract Class<?> getType(); 068 069 public abstract Class<?> getDeclaringClass(); 070 }