public static List < Class < ? > > findAllImplementations ( Class < ? > c , boolean everything , boolean parameterizable ) { if ( c == null ) { return Collections . emptyList ( ) ; } // Default is served from the registry if ( ! everything && parameterizable ) { return findAllImplementations ( c ) ; } // This codepath is used by utility classes to also find buggy // implementations (e.g. non-instantiable, abstract) of the interfaces. List < Class < ? > > known = findAllImplementations ( c ) ; // For quickly skipping seen entries: HashSet < Class < ? > > dupes = new HashSet <> ( known ) ; for ( Iterator < Class < ? > > iter = ELKIServiceScanner . nonindexedClasses ( ) ; iter . hasNext ( ) ; ) { Class < ? > cls = iter . next ( ) ; if ( dupes . contains ( cls ) ) { continue ; } // skip abstract / private classes. if ( ! everything && ( Modifier . isInterface ( cls . getModifiers ( ) ) || Modifier . isAbstract ( cls . getModifiers ( ) ) || Modifier . isPrivate ( cls . getModifiers ( ) ) ) ) { continue ; } if ( ! c . isAssignableFrom ( cls ) ) { continue ; } if ( parameterizable ) { boolean instantiable = false ; try { instantiable = cls . getConstructor ( ) != null ; } catch ( Exception | Error e ) { // ignore } try { instantiable = instantiable || ClassGenericsUtil . getParameterizer ( cls ) != null ; } catch ( Exception | Error e ) { // ignore } if ( ! instantiable ) { continue ; } } known . add ( cls ) ; dupes . add ( cls ) ; } return known ; }
Find all implementations of a given class in the classpath .