package Ġorg . tty . di oc . reflect Ċ Ċ import Ġjava . io . File Ċ import Ġjava . io . IOException Ċ import Ġjava . net . Jar URLConnection Ċ import Ġjava . net . URL Ċ import Ġjava . net . URL Decoder Ċ import Ġkotlin . jvm . Throws Ċ import Ġkotlin . reflect . K Class Ċ Ċ /** Ċ Ġ* ĠInstanti ates Ġa Ġnew ĠClass Ġscanner . Ċ Ġ* Ġ@ param Ġbase PackageName Ġthe Ġroot Ġpackage Ġto Ġscan Ċ Ġ* Ġ@ param Ġrecursive Ġwhether Ġscan Ġrecursively Ċ Ġ* Ġ@ param ĠpackageName Predicate Ġthe Ġpackage Ġpredicate Ċ Ġ* Ġ@ param Ġk Class Predicate Ġthe Ġclass Ġpredicate Ċ Ġ*/ Ċ class ĠK Class Scanner Ċ ( ĊĠĠĠ Ġprivate Ġval Ġbase PackageName : ĠString , ĊĠĠĠ Ġprivate Ġval Ġrecursive : ĠBoolean , ĊĠĠĠ Ġprivate Ġval ĠpackageName Predicate : Ġ(( String ) Ġ-> ĠBoolean )? , ĊĠĠĠ Ġprivate Ġval Ġk Class Predicate : Ġ(( K Class <* >) Ġ-> ĠBoolean )? Ċ ) Ġ{ ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠDo Ġscan Ġall Ġclasses Ġset . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ return Ġthe Ġset ĊĠĠĠĠ Ġ* Ġ@ throws ĠIOException ĠĠĠĠĠ Ġthe Ġio Ġexception ĊĠĠĠĠ Ġ* Ġ@ throws ĠClass NotFoundException Ġthe Ġclass Ġnot Ġfound Ġexception ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Throws ( IOException :: class , ĠClass NotFoundException :: class ) ĊĠĠĠ Ġfun Ġdo Scan All Classes (): ĠSet < K Class <* >> Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġk Class Container : ĠMutable Set < K Class <* >> Ġ= ĠLinked HashSet () ĊĠĠĠĠĠĠĠ Ġvar ĠpackageName Ġ= Ġbase PackageName ĊĊĠĠĠĠĠĠĠ Ġ// Ġif Ġthe Ġlast Ġcharacter Ġis Ġ'.' Ġthen Ġdelete Ġit ĊĠĠĠĠĠĠĠ Ġif Ġ( packageName . endsWith (". ")) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// packageName Ġ= ĠpackageName . substring ( 0 , ĠpackageName . lastIndexOf ('. ')) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠpackageName Ġ= ĠpackageName . slice ( 0 Ġuntil ĠpackageName . lastIndexOf ('. ')) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// Ġreplace Ġthe Ġ'.' Ġto Ġ'/', Ġmean Ġto Ġscan Ġby Ġfile . ĊĠĠĠĠĠĠĠ Ġval Ġpackage FilePath Ġ= ĠpackageName . replace ('.', Ġ'/') ĊĠĠĠĠĠĠĠ Ġval Ġresource URLs Ġ= ĠThread . currentThread (). context ClassLoader . getResources ( package FilePath ) ĊĠĠĠĠĠĠĠ Ġwhile Ġ( resource URLs . hasMore Elements ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresource URL Ġ= Ġresource URLs . nextElement () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprotocol Ġ= Ġresource URL . protocol ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(" file " Ġ== Ġprotocol ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠfilePath Ġ= ĠURL Decoder . decode ( resource URL . file , Ġ" UTF - 8 ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdo Scan Package Classes By File ( packageName , ĠfilePath , Ġk Class Container ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ(" jar " Ġ== Ġprotocol ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdo Scan Package Classes By Jar ( packageName , Ġresource URL , Ġk Class Container ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġk Class Container ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( IOException :: class , ĠClass NotFoundException :: class ) ĊĠĠĠ Ġprivate Ġfun Ġdo Scan Package Classes By Jar ( packageName : ĠString , Ġurl : ĠURL , Ġk Class Container : ĠMutable Set < K Class <* >>) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġthe Ġfile Ġpath Ġof Ġthe Ġpackage ĊĠĠĠĠĠĠĠ Ġval Ġpackage FilePath Ġ= ĠpackageName . replace ('.', Ġ'/') ĊĠĠĠĠĠĠĠ Ġ// Ġload Ġthe Ġjar File ĊĠĠĠĠĠĠĠ Ġval Ġjar Ġ= Ġ( url . open Connection () Ġas ĠJar URLConnection ). jar File ĊĠĠĠĠĠĠĠ Ġ// Ġenumerate Ġthe Ġentries ĊĠĠĠĠĠĠĠ Ġval Ġentries Ġ= Ġjar . entries () ĊĠĠĠĠĠĠĠ Ġwhile Ġ( entries . hasMore Elements ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġentry Ġ= Ġentries . nextElement () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġname Ġ= Ġentry . name ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġå¦Ĥæŀľ è·¯å¾Ħ ä¸į ä¸Ģèĩ´ ï¼Į æĪĸèĢħ æĺ¯ çĽ®å½ķ ï¼Į åĪĻ ç»§ç»Ń ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! name . startsWith ( package FilePath ) Ġ|| Ġentry . isDirectory ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠåĪ¤æĸŃ æĺ¯åĲ¦ éĢĴ å½Ĵ æĲľç´¢ åŃĲ åĮħ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! recursive Ġ&& Ġname . lastIndexOf ('/') Ġ!= Ġpackage FilePath . length ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( packageName Predicate Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġjar PackageName Ġ= Ġname . substring ( 0 , Ġname . lastIndexOf ('/ ')). replace ("/", Ġ". ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! packageName Predicate . invoke ( jar PackageName )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġ åĪ¤ å®ļ æĺ¯åĲ¦ ç¬¦åĲĪ è¿ĩæ»¤ æĿ¡ä»¶ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar ĠclassName Ġ= Ġname . replace ('/', Ġ'.') ĊĠĠĠĠĠĠĠĠĠĠĠ ĠclassName Ġ= ĠclassName . substring ( 0 , ĠclassName . length Ġ- Ġ 6 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠçĶ¨ å½ĵåīį çº¿ç¨ĭ çļĦ ç±» åĬłè½½ åĻ¨ åĬłè½½ ç±» ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġload Class Ġ= ĠThread . currentThread (). context ClassLoader . load Class ( className ). kotlin ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( k Class Predicate Ġ== Ġnull Ġ|| Ġk Class Predicate . invoke ( load Class )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġk Class Container . add ( load Class ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġåľ¨ æĸĩä»¶å¤¹ ä¸Ń æī«æıı åĮħ åĴĮ ç±» ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Throws ( Class NotFoundException :: class ) ĊĠĠĠ Ġprivate Ġfun Ġdo Scan Package Classes By File ( packageName : ĠString , Ġpackage Path : ĠString , Ġk Class Container : ĠMutable Set < K Class <* >>) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġ è½¬ ä¸º æĸĩä»¶ ĊĠĠĠĠĠĠĠ Ġval Ġdir Ġ= ĠFile ( package Path ) ĊĠĠĠĠĠĠĠ Ġif Ġ(! dir . exists () Ġ|| Ġ! dir . isDirectory ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ// Ġ åĪĹ åĩº æĸĩä»¶ ï¼Į è¿Ľè¡Į è¿ĩæ»¤ ĊĠĠĠĠĠĠĠ Ġ// Ġ èĩªå®ļä¹ī æĸĩä»¶ è¿ĩæ»¤ è§ĦåĪĻ ĊĠĠĠĠĠĠĠ Ġval Ġdir Files Ġ= Ġdir . list Files Ġ{ Ġfile : ĠFile Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfilename Ġ= Ġfile . name ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( file . isDirectory ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! recursive ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ list Files Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( packageName Predicate Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ list Files ĠpackageName Predicate . invoke ("$ packageName .$ filename ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ list Files Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfilename . endsWith (". class ") ĊĠĠĠĠĠĠĠ Ġ} Ġ?: Ġreturn ĊĠĠĠĠĠĠĠ Ġfor Ġ( file Ġin Ġdir Files ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( file . isDirectory ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġå¦Ĥæŀľ æĺ¯ çĽ®å½ķ ï¼Į åĪĻ éĢĴ å½Ĵ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdo Scan Package Classes By File ( packageName Ġ+ Ġ"." Ġ+ Ġfile . name , Ġfile . absolute Path , Ġk Class Container ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠçĶ¨ å½ĵåīį ç±» åĬłè½½ åĻ¨ åĬłè½½ Ġ åİ» éĻ¤ ĠfileName ĠçļĦ Ġ. class Ġ 6 Ġ ä½į ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠclassName Ġ= Ġfile . name . substring ( 0 , Ġfile . name . length Ġ- Ġ 6 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġload Class Ġ= ĠThread . currentThread (). context ClassLoader . load Class ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"$ packageName .$ className " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ). kotlin ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( k Class Predicate Ġ== Ġnull Ġ|| Ġk Class Predicate . invoke ( load Class )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġk Class Container . add ( load Class ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ