package Ġcom . i wh ys . sdk editor . plugin Ċ Ċ import Ġcom . android . Sdk Constants Ċ import Ġcom . android . build . api . transform . Directory Input Ċ import Ġcom . android . build . api . transform . Jar Input Ċ import Ġcom . android . build . api . transform . Status Ċ import Ġcom . android . build . api . transform . Transform Invocation Ċ import Ġcom . android . ide . common . workers . ExecutorService Adapter Ċ import Ġcom . android . ide . common . workers . Worker Executor Facade Ċ import Ġcom . i wh ys . sdk editor . domain . Replace Class Ċ import Ġjav assist . Class Pool Ċ import Ġjav assist . Ct Class Ċ import Ġorg . apache . commons . io . FileUtils Ċ import Ġjava . io . File Ċ import Ġjava . util . concurrent . Fork Join Pool Ċ import Ġjava . util . jar . Jar File ĊĊ Ċ /** Ċ Ġ* ĠCreated Ġon Ġ 2 0 1 8 / 1 1 / 8 Ġ 1 4 : 2 2 Ċ Ġ* ĠDescription : Ġtransform æĵįä½ľ å¤ĦçĲĨ åĻ¨ Ċ Ġ* Ċ Ġ* Ġ@ author Ġ çİĭ æ´ ª èĥ ľ Ċ Ġ*/ Ċ class ĠTransform Handler ( ĊĠĠĠ Ġprivate Ġval Ġclass Pool : ĠClass Pool , ĊĠĠĠ Ġprivate Ġval Ġsdk Editor Config : ĠS dk Editor Config , ĊĠĠĠ Ġtransform Invocation : ĠTransform Invocation Ċ ) Ġ{ ĊĊĠĠĠ Ġprivate Ġval Ġis Parallel Ġ= Ġsdk Editor Config . parallel ĊĊĠĠĠ Ġprivate Ġval Ġoutput Provider Ġ= Ġtransform Invocation . output Provider ĊĊĠĠĠ Ġprivate Ġval Ġdir Inputs Ġ= Ġmutable Set Of < Directory Input >() ĊĊĠĠĠ Ġprivate Ġval Ġjar Inputs Ġ= Ġmutable Map Of < String , ĠJar Input >() ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ æĶ¶éĽĨ åĪ°çļĦ è¦ģ ä¿® å¤į çļĦ Jar æĸĩä»¶ åĲį ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġval Ġtarget Jar Names Ġ= Ġmutable Set Of < String >() ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ æĶ¶éĽĨ åĪ°çļĦ Fix ç±» ä¿¡æģ¯ ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġval Ġreplace Classes Ġ= Ġmutable Set Of < String >() ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġæĺ¯åĲ¦ å¢ŀ éĩı ç¼ĸè¯ĳ ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġval Ġis Incremental Ġ= Ġtransform Invocation . is Incremental ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġlog (" is Incremental Mode Ġ= Ġ$ is Incremental ") ĊĠĠĠĠĠĠĠ Ġif Ġ(! is Incremental ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoutput Provider . delete All () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġtransform Invocation . inputs . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdir Inputs Ġ+= Ġit . directory Inputs ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( jar Input Ġin Ġit . jar Inputs ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġclass Pool . add Path Jar Input ( jar Input ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġjar Inputs [ jar Input . file . name Without Extension ] Ġ= Ġjar Input ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġæī§è¡Į ä¿¡æģ¯ çļĦ æĶ¶éĽĨ åĴĮ sdk ä¿® å¤į æĵįä½ľ ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġhandle () Ġ{ ĊĠĠĠĠĠĠĠ Ġgather Info () ĊĠĠĠĠĠĠĠ Ġfix Sdk () ĊĠĠĠĠĠĠĠ Ġclear () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġæł¹æį® æĶ¶éĽĨ åĪ°çļĦ ä¿¡æģ¯ ä¿® å¤į sdk ä¸ŃçļĦ bug ç±» ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġfix Sdk () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( is Parallel ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfix Sdk Parallel () ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfix Sdk Serial () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġlog (" All Ġbug Ġclasses Ġhave Ġbeen Ġfixed .") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġfix Sdk Serial () Ġ{ ĊĠĠĠĠĠĠĠ Ġlog (" Begin Ġto Ġfix Ġthe Ġbug Ġclasses Ġin Ġserial .") ĊĠĠĠĠĠĠĠ Ġfor Ġ( jar Input Ġin Ġjar Inputs . values ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdest Ġ= Ġoutput Provider . jar Output ( jar Input ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! is Incremental Ġ|| Ġ( jar Input . status Ġ== ĠStatus . AD DED Ġ|| Ġjar Input . status Ġ== ĠStatus . CHANGED )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġjar File Ġ= Ġjar Input . file ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġjar Name Ġ= Ġjar File . name ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! is Target Jar ( jar Name )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog (" Not Ġthe Ġtarget Ġjar Ġpackage , Ġoutput Ġdirectly :${ jar Name }") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsafe Ġ{ ĠFileUtils . copy File ( jar File , Ġdest ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog (" Found Ġthe Ġtarget Ġjar Ġpackage ï¼ļ ${ jar Name }, Ġprepare Ġto Ġfix .") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġjar Input . handle Class Ġ{ Ġname Ġ! in Ġreplace Classes Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( is Incremental Ġ&& Ġjar Input . status Ġ== ĠStatus . RE MOVED ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdest . delete () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġfix Sdk Parallel () Ġ{ ĊĠĠĠĠĠĠĠ Ġlog (" Begin Ġto Ġfix Ġthe Ġbug Ġclasses Ġin Ġparallel .") ĊĠĠĠĠĠĠĠ Ġval Ġexecutor Ġ= ĠExecutor Service Adapter ( Fork Join Pool . common Pool ()) ĊĠĠĠĠĠĠĠ Ġfor Ġ( jar Input Ġin Ġjar Inputs . values ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdest Ġ= Ġoutput Provider . jar Output ( jar Input ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! is Incremental Ġ|| Ġ( jar Input . status Ġ== ĠStatus . AD DED Ġ|| Ġjar Input . status Ġ== ĠStatus . CHANGED )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġjar File Ġ= Ġjar Input . file ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġjar Name Ġ= Ġjar File . name ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! is Target Jar ( jar Name )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog (" Not Ġthe Ġtarget Ġjar Ġpackage , Ġoutput Ġdirectly :${ jar Name }") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġexecutor . submit ( object Ġ: ĠWorker Executor Facade . Work Action Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġrun () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsafe Ġ{ ĠFileUtils . copy File ( jar File , Ġdest ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog (" Found Ġthe Ġtarget Ġjar Ġpackage ï¼ļ ${ jar Name }, Ġprepare Ġto Ġfix .") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġexecutor . submit ( object Ġ: ĠWorker Executor Facade . Work Action Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġrun () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġjar Input . handle Class Ġ{ Ġname Ġ! in Ġreplace Classes Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( is Incremental Ġ&& Ġjar Input . status Ġ== ĠStatus . RE MOVED ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdest . delete () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġsafe Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġexecutor . await () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġexecutor . close () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġæ¸ ħ çĲĨ å¯¼åħ¥ çļĦ ç±» ä¿¡æģ¯ ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġclear () Ġ{ ĊĠĠĠĠĠĠĠ Ġclass Pool . clear () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠåĪ¤æĸŃ æĺ¯åĲ¦ çĽ®æłĩ Jar åĮħ ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġis Target Jar ( jar Name : ĠString ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġtarget Jar Names . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( jar Name . contains ( it )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ æĶ¶éĽĨ è¦ģ å¤ĦçĲĨ çļĦä¿¡æģ¯ ĊĠĠĠĠ Ġ* Ġé»ĺè®¤ åıª æĶ¶éĽĨ dir Inputs ä¸ŃçļĦ ä¿¡æģ¯ ï¼Į å¦Ĥæŀľ éħįç½® ä¸Ń æłĩè®° äºĨ çī¹ å®ļçļĦ jar Inputs ï¼Į åĪĻ ä¼ļ åĲĮæĹ¶ éģįåİĨ æĮĩå®ļçļĦ jar Inputs ĊĠĠĠĠ Ġ* Ġ æĶ¶éĽĨ ä¿¡æģ¯ ä¹ĭåĲİ çļĦ dir Inputs æĪĸèĢħ jar Inputs ä¼ļ è¢« çĽ´æİ¥ è¾ĵåħ¥ ï¼Į åĽłä¸º ä»ĸä»¬ å®ŀéĻħ ä¸Ĭ åºĶè¯¥ éĥ½æĺ¯ å¼Ģåıĳ èĢħ åı¯ æİ§ æºĲ æĸĩä»¶çļĦ ç¼ĸè¯ĳ äº§ çī© ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġgather Info () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( is Parallel ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġgather Info Parallel () ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġgather Info Serial () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġlog (" The Ġclasses Ġinformation Ġcollection :$ replace Classes ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġgather Info Serial () Ġ{ ĊĠĠĠĠĠĠĠ Ġlog (" Begin Ġto Ġgather Ġthe Ġclasses Ġinformation Ġin Ġserial .") ĊĠĠĠĠĠĠĠ Ġdir Inputs . forEach ( info From Dir Input ) ĊĠĠĠĠĠĠĠ Ġval Ġjar Input Names Ġ= Ġjar Inputs . keys ĊĠĠĠĠĠĠĠ Ġsdk Editor Config . fixed Jar Names Set ()?. map NotNull Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfind Info Jar Input ( it , Ġjar Input Names ) ĊĠĠĠĠĠĠĠ Ġ} ?. forEach ( info From Jar Input ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġgather Info Parallel () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġexecutor Ġ= ĠExecutor Service Adapter ( Fork Join Pool . common Pool ()) ĊĠĠĠĠĠĠĠ Ġlog (" Begin Ġto Ġgather Ġthe Ġclasses Ġinformation Ġin Ġparallel .") ĊĠĠĠĠĠĠĠ Ġfor Ġ( dir Input Ġin Ġdir Inputs ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġexecutor . submit ( object Ġ: ĠWorker Executor Facade . Work Action Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġrun () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinfo From Dir Input ( dir Input ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġjar Input Names Ġ= Ġjar Inputs . keys ĊĠĠĠĠĠĠĠ Ġsdk Editor Config . fixed Jar Names Set ()?. map NotNull Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfind Info Jar Input ( it , Ġjar Input Names ) ĊĠĠĠĠĠĠĠ Ġ} ?. forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġexecutor . submit ( object Ġ: ĠWorker Executor Facade . Work Action Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġrun () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinfo From Jar Input ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġsafe Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġexecutor . await () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġexecutor . close () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġæĺ¯åĲ¦ éľĢè¦ģ çĶ¨æĿ¥ æĶ¶éĽĨ ä¿¡æģ¯ çļĦ jar åĮħ ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġfind Info Jar Input ( jar Name : ĠString , Ġjar Input Names : ĠSet < String >): ĠJar Input ? Ġ{ ĊĠĠĠĠĠĠĠ Ġjar Input Names . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it . contains ( jar Name )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġjar Inputs . remove ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġä»İ çĽ®å½ķ æĸĩä»¶ ä¸Ń æĶ¶éĽĨ ä¿¡æģ¯ ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġval Ġinfo From Dir Input Ġ= Ġ{ Ġdir Input : ĠDirectory Input Ġ-> ĊĠĠĠĠĠĠĠ Ġclass Pool . add Path Dir Input ( dir Input ) ĊĠĠĠĠĠĠĠ Ġval Ġdest Ġ= Ġoutput Provider . dir Output ( dir Input ) ĊĠĠĠĠĠĠĠ Ġval Ġhandle File : Ġ( File ) Ġ-> ĠUnit Ġ= Ġ{ Ġfile : ĠFile Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( file . extension Ġ== ĠS dk Constants . EXT _ CLASS ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsafe Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġclass Pool . make Class ( file . inputStream ()) ?. apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġgather Info () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwrite File ( dest . absolute Path ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdetach () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog (" The Ġfile 's Ġextension Ġis Ġnot Ġclass , Ġoutput Ġdirectly :${ file . name }") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfile . copy To Dir ( dest ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( is Incremental ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdir Input . changed Files . forEach Ġ{ Ġfile , Ġstatus Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrelative File Ġ= Ġfile . relative To ( dir Input . file ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠoutputFile Ġ= Ġdest . resolve ( relative File ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( status ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠStatus . AD DED , ĠStatus . CHANGED Ġ-> Ġhandle File ( file ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠStatus . RE MOVED Ġ-> ĠoutputFile . delete () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠFileUtils . list Files ( dir Input . file , Ġnull , Ġtrue ). forEach ( handle File ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġä»İ jar æĸĩä»¶ ä¸Ń æĶ¶éĽĨ ä¿¡æģ¯ ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġval Ġinfo From Jar Input : Ġ( Jar Input ) Ġ-> ĠUnit Ġ= Ġ{ Ġjar Input Ġ-> ĊĠĠĠĠĠĠĠ Ġlog (" Gather ing Ġclasses Ġinformation Ġfrom Ġjar :${ jar Input . name }") ĊĠĠĠĠĠĠĠ Ġjar Input . handle Class Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġgather Info () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtrue ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ å¤ĦçĲĨ Jar Input ä¸ŃçļĦ ç±» ĊĠĠĠĠ Ġ* Ġ@ param Ġblock Ġä»İ Jar Input ä¸Ń æĪĲåĬŁ åıĸ åĩº Ct Class ç±» æĹ¶çļĦ åĽŀè°ĥ ï¼Į åħ¶ è¿ĶåĽŀ åĢ¼ è¡¨ç¤º å¤ĦçĲĨ ä¹ĭåĲİ çļĦ Ct Class æĸĩä»¶ æĺ¯åĲ¦ éľĢè¦ģ è¾ĵåĩº ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun ĠJar Input . handle Class ( block : ĠC t Class . () Ġ-> ĠBoolean ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġdest Ġ= Ġoutput Provider . jar Output ( this ) ĊĠĠĠĠĠĠĠ Ġval Ġjar File Tmp Dir Ġ= ĠJar Util . get Jar File Tmp Dir ( dest ) ĊĠĠĠĠĠĠĠ Ġval Ġjar File Ġ= ĠJar File ( this . file ) ĊĠĠĠĠĠĠĠ Ġjar File . stream (). forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it . name . endsWith ( Sdk Constants . DOT _ CLASS )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠinputStream Ġ= Ġjar File . getInputStream ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsafe Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġclass Pool . make Class ( inputStream )?. apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġneed Output Ġ= Ġblock () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( need Output ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwrite File ( jar File Tmp Dir ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog (" Re placed Ġthe Ġbug Ġclass :$ name ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdetach () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġout File Ġ= ĠFile ( jar File Tmp Dir , Ġit . name ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it . isDirectory Ġ&& Ġ! out File . exists ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog (" The Ġfile Ġis Ġdirectory Ġ${ it . name } Ġin Ġthe Ġtarget Ġjar Ġpackage :${ jar File . name }") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġout File . mkdir s () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog (" The Ġfile Ġnot Ġend Ġwith Ġ' class ' Ġin Ġthe Ġtarget Ġjar Ġpackage :${ jar File . name }") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠinputStream Ġ= Ġjar File . getInputStream ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠFileUtils . write ( out File , ĠinputStream . reader (). read Text ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġtmp Dir File Ġ= ĠFile ( jar File Tmp Dir ) ĊĠĠĠĠĠĠĠ Ġlog (" Re package Ġand Ġoutput Ġthe Ġtarget Ġjar Ġpackage :$ dest ") ĊĠĠĠĠĠĠĠ ĠJar Util . jar File ( tmp Dir File , Ġdest ) ĊĠĠĠĠĠĠĠ Ġsafe Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠFileUtils . delete Directory ( tmp Dir File ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġä»İ Ct Class ä¸Ń æĶ¶éĽĨ å¿ħè¦ģ çļĦä¿¡æģ¯ ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun ĠC t Class . gather Info () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( has Annotation ( Replace Class :: class . java )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġjar Name Ġ= Ġ( getAnnotation ( Replace Class :: class . java ) Ġas ĠReplace Class ). value ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( jar Name . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog (" Note : the Ġannotation Ġin Ġthe ĠFix Ġclass Ġis Ġmissing Ġthe Ġvalue Ġof Ġthe Ġjar Ġpackage Ġname :$ name ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhandle Replace Class ( jar Name ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ å¤ĦçĲĨ æĽ¿æį¢ ç±» ä¿¡æģ¯ ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun ĠC t Class . handle Replace Class ( jar Name : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġfinal Jar Name Ġ= Ġjar Name . replace (' :', Ġ'-') ĊĠĠĠĠĠĠĠ Ġ// Ġ éĢĴ å½Ĵ å¤ĦçĲĨ åĨħéĥ¨ ç±» ĊĠĠĠĠĠĠĠ Ġnested Classes ?. forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit . handle Replace Class ( final Jar Name ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġtarget Jar Names Ġ+= Ġjar Name ĊĠĠĠĠĠĠĠ Ġtarget Jar Names Ġ+= Ġfinal Jar Name ĊĠĠĠĠĠĠĠ Ġreplace Classes Ġ+= Ġname ĊĠĠĠĠĠĠĠ Ġlog (" Found Ġthe ĠFix Ġclass Ġnamed :$ name Ġthe Ġjar Ġpackage Ġname :$ final Jar Name ") ĊĠĠĠ Ġ} Ċ Ċ }