package Ġcom . dit cho om . mqtt . topic Ċ Ċ import Ġcom . dit cho om . mqtt . control packet . Mqtt Utf 8 String Ċ Ċ /** Ċ Ġ* ĠRepresent Ġthe Ġtopics Ġin Ġa Ġtree Ġlike Ġstructure . ĠS aves Ġmemory Ġfor Ġmultiple Ġtopics Ġwith Ġa Ġsimilar Ġstructure Ġcompared Ċ Ġ* Ġto Ġusing Ġa Ġstring Ġand Ġspeed s Ġup Ġlook ups Ġto Ġsee Ġif Ġa Ġtopic Ġmatches Ġa Ġstructure Ċ Ġ*/ Ċ data Ġclass ĠTopic Level Node ( val Ġvalue : ĠTopic Level ) Ġ{ ĊĠĠĠ Ġval Ġchildren : ĠMutable Map < CharSequence , ĠTopic Level Node > Ġ= Ġmutable Map Of () ĊĠĠĠ Ġvar Ġparent : ĠTopic Level Node ? Ġ= Ġnull ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠIs Ġthis Ġtopic Ġlevel Ġa Ġwildcard ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġis Wildcard Ġ= Ġvalue Ġis ĠMulti Level Wildcard Ġ|| Ġvalue Ġis ĠSingle Level Wildcard ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCheck Ġif Ġthis Ġtopic Ġor Ġany Ġchildren Ġhas Ġa Ġwildcard ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġhas Wildcard In Topic (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( children . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġis Wildcard ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġchildren . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it . value . has Wildcard In Topic ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġis Wildcard ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġdetach From Parent () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġparent Ġ= Ġparent ĊĠĠĠĠĠĠĠ Ġparent ?. children ?. remove ( value . value ) ĊĠĠĠĠĠĠĠ Ġthis . parent Ġ= Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġfind Similar Child Node ( other Child Node : ĠTopic Level Node ): ĠTopic Level Node ? Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġcurrent Child Other Node : ĠTopic Level Node ? Ġ= Ġother Child Node . parent ĊĠĠĠĠĠĠĠ Ġval Ġkey Path Ġ= ĠArrayList < Topic Level >() ĊĠĠĠĠĠĠĠ Ġkey Path . add ( other Child Node . value ) ĊĠĠĠĠĠĠĠ Ġwhile Ġ( current Child Other Node Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġkey Path . add ( current Child Other Node . value ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Child Other Node Ġ= Ġcurrent Child Other Node . parent ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġkey Path . reverse () ĊĠĠĠĠĠĠĠ Ġvar Ġindex Ġ= Ġ 1 ĊĠĠĠĠĠĠĠ Ġval Ġkey Path Current Ġ= Ġkey Path . get OrNull ( index ++) ?. value ĊĠĠĠĠĠĠĠ Ġvar Ġcurrent Child This Node Ġ= Ġchildren [ key Path Current ] ĊĊĠĠĠĠĠĠĠ Ġwhile Ġ( index Ġ< Ġkey Path . size ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnext Key Ġ= Ġkey Path . get OrNull ( index ++) ?. value !! ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( current Child This Node Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Child This Node Ġ= Ġcurrent Child This Node . children [ next Key ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġcurrent Child This Node ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun ĠgetAll Bottom Level Children (): ĠSet < Topic Level Node > Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( children . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġset Of ( this ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġchildren s Children Ġ= Ġmutable Set Of < Topic Level Node >() ĊĠĠĠĠĠĠĠ Ġchildren . values . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġchildren s Children Ġ+= Ġit . getAll Bottom Level Children () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġchildren s Children ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun ĠgetCurrent Path (): ĠCharSequence Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġparent Ġ= Ġparent ĊĠĠĠĠĠĠĠ Ġval Ġparent Path Ġ= Ġparent ?. getCurrent Path () ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( parent Path Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvalue . value ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ"$ parent Path /${ value . value }" ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠtoString () Ġ= ĠgetCurrent Path (). toString () ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCheck Ġand Ġsee Ġif Ġthe Ġother Ġtopic Ġmatches Ġthis Ġtopic Ġstructure . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġmatches Topic ( other : ĠTopic Level Node ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġis Current Topic Multi Level Wildcard Ġ= Ġvalue Ġis ĠMulti Level Wildcard ĊĠĠĠĠĠĠĠ Ġval Ġis Other Topic Multi Level Wildcard Ġ= Ġother . value Ġis ĠMulti Level Wildcard ĊĠĠĠĠĠĠĠ Ġif Ġ( is Current Topic Multi Level Wildcard Ġ|| Ġis Other Topic Multi Level Wildcard ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġis Current Topic Single Level Wildcard Ġ= Ġvalue Ġis ĠSingle Level Wildcard ĊĠĠĠĠĠĠĠ Ġval Ġis Other Topic Single Level Wildcard Ġ= Ġother . value Ġis ĠSingle Level Wildcard ĊĠĠĠĠĠĠĠ Ġif Ġ( is Current Topic Single Level Wildcard Ġ|| Ġis Other Topic Single Level Wildcard ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( children . isEmpty () Ġ&& Ġother . children . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ(( is Current Topic Single Level Wildcard Ġ&& Ġchildren . isNotEmpty ()) Ġ|| ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ( is Other Topic Single Level Wildcard Ġ&& Ġother . children . isNotEmpty ()) ĊĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmissing Keys Ġ= Ġother . children . keys Ġ- Ġchildren . keys ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( missing Keys . contains ("+ ") Ġ|| Ġmissing Keys . contains ("# ")) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( missing Keys . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġother . children . forEach Ġ{ Ġother Child Pair Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġother Key Ġ= Ġother Child Pair . key ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġother Value Ġ= Ġother Child Pair . value ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmatching Child Ġ= Ġchildren [ other Key ] Ġ?: Ġreturn Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! matching Child . matches Topic ( other Value )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġis Either AW ildcard Ġ= Ġis Wildcard Ġ|| Ġother . is Wildcard ĊĠĠĠĠĠĠĠ Ġif Ġ(! is Either AW ildcard ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( value Ġ!= Ġother . value ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( children . size Ġ!= Ġother . children . size Ġ&& Ġchildren [" # "] Ġ== Ġnull Ġ&& Ġ! is Either AW ildcard ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġother . children . forEach Ġ{ Ġother Child Pair Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġother Key Ġ= Ġother Child Pair . key ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( other Key Ġ!= Ġ"+ ") Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġother Value Ġ= Ġother Child Pair . value ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġmatching Child Ġ= Ġchildren [ other Key ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( matching Child Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmatching Child Ġ= Ġchildren [" + "] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( matching Child Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmatching Child Ġ= Ġchildren [" # "] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġchild Ġ= Ġmatching Child ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġreturn Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! child . matches Topic ( other Value )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( other . children . isEmpty () Ġ&& Ġchildren . isNotEmpty () Ġ&& Ġ( other . value Ġ== ĠSingle Level Wildcard Ġ|| Ġvalue Ġ== ĠSingle Level Wildcard )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠTOP IC _ LEVEL _ SE PER ATOR Ġ= Ġ'/' ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠConvert Ġan ĠMQTT ĠUTF 8 ĠComp liant Ġstring Ġinto Ġa Ġtopic Ġlevel Ġnode Ġstructure ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġfun Ġfrom ( topic : ĠM qtt Utf 8 String ): ĠTopic Level Node Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtopic Validated Ġ= Ġtopic . getValue OrThrow () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( topic Validated . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠTopic Level Node ( Empty Value ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġparse ( topic Validated . toString ()) Ġ?: ĠTopic Level Node ( Empty Value ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠConvert Ġthe Ġstring Ġformat Ġof Ġa Ġsuspect ed Ġtopic Ġinto Ġa Ġtopic Ġlevel Ġtree Ġstructure Ġreturning Ġthe Ġroot Ġnode ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġfun Ġparse ( topic : ĠString , Ġparent : ĠTopic Level Node ? Ġ= Ġnull ): ĠTopic Level Node ? Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( parent Ġ== Ġnull Ġ&& Ġtopic . startsWith ('/ ')) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtop Topic Level Ġ= ĠEmpty Value ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġchild Ġ= Ġparse ( topic . substring ( 1 ), Ġparent ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnode Ġ= ĠTopic Level Node ( top Topic Level ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( child Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchild . parent Ġ= Ġnode ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnode . children [ child . value . value ] Ġ= Ġchild ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnode ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( topic . endsWith ("/ ")) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġparsed Without Suffix Ġ= Ġparse ( topic . substring Before Last ("/ "), Ġparent ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbottom Level Node Ġ= Ġparsed Without Suffix ?. getAll Bottom Level Children ()?. first () Ġ?: Ġreturn Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġempty Node Ġ= ĠTopic Level Node ( Empty Value ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġempty Node . parent Ġ= Ġbottom Level Node ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbottom Level Node . children [ "" ] Ġ= Ġempty Node ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġparsed Without Suffix ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtopics Ġ= Ġtopic . split ( TOPIC _ LEVEL _ SE PER ATOR , Ġlimit Ġ= Ġ 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( topics . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcurrent Topic Level Ġ= Ġtopics [ 0 ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( current Topic Level . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalArgumentException (" Invalid Ġsize Ġof Ġtopic Ġlevel ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( current Topic Level . length Ġ> Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmulti Level Wildcard Index Ġ= Ġcurrent Topic Level . indexOf ('# ') ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( multi Level Wildcard Index Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalArgumentException ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Error Ġbuilding Ġtopic Ġ($ current Topic Level ): ĠThe Ġmulti - level Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" wildcard Ġcharacter ĠMUST Ġbe Ġspecified Ġeither Ġon Ġits Ġown Ġor Ġfollowing Ġa Ġtopic Ġlevel Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" separator . ĠIn Ġeither Ġcase Ġit ĠMUST Ġbe Ġthe Ġlast Ġcharacter Ġspecified Ġin Ġthe ĠTopic ĠFilter " Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Ġ[ MQTT - 4 . 7 . 1 - 1 ]" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsingle Level Wildcard Index Ġ= Ġcurrent Topic Level . indexOf ('+ ') ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( single Level Wildcard Index Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalArgumentException ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Error Ġbuilding Ġtopic Ġ($ current Topic Level ): ĠThe Ġsingle - level Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" wildcard ĠMUST Ġocc upy Ġan Ġentire Ġlevel Ġof Ġthe Ġfilter Ġ[ MQTT - 4 . 7 . 1 - 2 ]. " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtopics . size Ġ== Ġ 1 Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( current Topic Level Ġ== Ġ"# ") Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠTopic Level Node ( Multi Level Wildcard ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( current Topic Level Ġ== Ġ"+ ") Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠTopic Level Node ( Single Level Wildcard ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( current Topic Level . isBlank ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnode Ġ= ĠTopic Level Node ( String Topic Level ( current Topic Level )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnode . parent Ġ= Ġparent ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnode ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtopics . size Ġ== Ġ 2 Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( current Topic Level Ġ== Ġ"# ") Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalArgumentException (" Invalid Ġmult ile vel Ġwildcard Ġfound Ġat Ġposition Ġ${ current Topic Level . length } Ġin Ġtopic : Ġ$ topic . ĠWas Ġnot Ġexpecting Ġany Ġmore Ġcharacters Ġafter Ġthat .") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrest Of Topic Ġ= Ġtopics [ 1 ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlevel Ġ= Ġwhen Ġ( current Topic Level ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"#" Ġ-> ĠMulti Level Wildcard ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" +" Ġ-> ĠSingle Level Wildcard ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> ĠString Topic Level ( current Topic Level ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( rest Of Topic . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠTopic Level Node ( level ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġchild Topic Level Ġ= Ġparse ( topics [ 1 ]) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresult Ġ= Ġif Ġ( child Topic Level Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPair ( child Topic Level . value . value , Ġchild Topic Level ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠcurrentNode Ġ= ĠTopic Level Node ( level ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( result Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠcurrentNode . children [ result . first ] Ġ= Ġresult . second ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchild Topic Level ?. parent Ġ= ĠcurrentNode ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠcurrentNode . parent Ġ= Ġparent ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠcurrentNode ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠRuntimeException ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Topic Ġsplit Ġoperation Ġfailing . ĠExpected Ġa Ġmax Ġof Ġtwo Ġstring Ġsplits , Ġgot Ġmore " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠAdd Ġthe Ġtopics Ġin Ġto Ġthe Ġtree Ġstructure Ġof Ġthe Ġorigin ial Ġ' self ' Ġtopic Ġlevel Ġnode Ċ Ġ*/ Ċ fun Ġadd Topic Level Node ( self : ĠTopic Level Node , Ġother : ĠTopic Level Node ) Ġ{ ĊĠĠĠ Ġif Ġ( self . value Ġ== Ġother . value ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġmissing Children Ġ= Ġother . children . keys Ġ- Ġself . children . keys ĊĠĠĠĠĠĠĠ Ġmissing Children . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmissing Child Ġ= Ġother . children [ it ] !! ĊĠĠĠĠĠĠĠĠĠĠĠ Ġself . children [ missing Child . value . value ] Ġ= Ġmissing Child ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmissing Child . parent Ġ= Ġself ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġduplicate Children Keys Ġ= Ġself . children . keys . intersect ( other . children . keys ) ĊĠĠĠĠĠĠĠ Ġduplicate Children Keys . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd Topic Level Node ( self . children [ it ] !! , Ġother . children [ it ] !! ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠMerge Ġthe Ġtwo Ġtopics Ġtogether Ġinto Ġone Ġstructure Ċ Ġ*/ Ċ operator Ġfun ĠTopic Level Node . plus Assign ( other : ĠTopic Level Node ) Ġ{ ĊĠĠĠ Ġadd Topic Level Node ( this , Ġother ) Ċ } ĊĊ Ċ operator Ġfun ĠTopic Level Node . minus Assign ( other : ĠTopic Level Node ) Ġ{ ĊĠĠĠ Ġremove Topic Level Node ( this , Ġother ) Ċ } Ċ Ċ fun Ġremove Topic Level Node ( self : ĠTopic Level Node , Ġother : ĠTopic Level Node ) Ġ{ ĊĠĠĠ Ġval Ġother Children Ġ= Ġother . getAll Bottom Level Children () ĊĠĠĠ Ġother Children . forEach Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġnode Ġ= Ġself . find Similar Child Node ( it ) ĊĠĠĠĠĠĠĠ Ġif Ġ( node Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnode . detach From Parent () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ