package Ġch oo ong g . box . log Ċ Ċ import Ġjava . util .* Ċ import Ġkotlin . math . min Ċ Ċ object ĠLog Act uator Ġ{ ĊĊĠĠĠ Ġfun Ġlog ( ĊĠĠĠĠĠĠĠ Ġconfig : ĠLog Config , ĊĠĠĠĠĠĠĠ Ġ@ Log Config . Level Ġlevel : ĠInt ?, ĊĠĠĠĠĠĠĠ Ġtag : ĠString ?, ĊĠĠĠĠĠĠĠ Ġchild Tag : ĠString ?, ĊĠĠĠĠĠĠĠ Ġvar arg Ġany : ĠAny ? ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! config . enable ) Ġreturn ĊĠĠĠĠĠĠĠ Ġval Ġlog Ġ= ĠStringBuilder () ĊĊĠĠĠĠĠĠĠ Ġ// ĠThread Info ĊĠĠĠĠĠĠĠ Ġval Ġthread Info Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( config . show Thread Info ) Ġ"[ Thread : Ġ${ Thread . currentThread (). name }] " Ġelse Ġnull ĊĊĠĠĠĠĠĠĠ Ġ// ĠStack Info ĊĠĠĠĠĠĠĠ Ġif Ġ( config . show Stack Info ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . append ( config . formatter . top ( thread Info , Ġchild Tag , Ġnull )) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstack Trace Ġ= ĠThrowable (). stack Trace ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstack Index Ġ= ĠLog Constant . DEFAULT _ STACK _ OFFSET Ġ+ Ġconfig . stack Offset ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( stack Index Ġ< Ġstack Trace . size ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġtarget Element Ġ= Ġstack Trace [ Log Constant . DEFAULT _ STACK _ OFFSET ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠfileName Ġ= Ġget FileName ( target Element ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġhead Ġ= ĠFormatter () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. format ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"% s .% s (% s :% d )", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtarget Element . className , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtarget Element . methodName , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠfileName , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtarget Element . line Number ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. toString () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( config . stack Deep Ġ<= Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . append ( config . formatter . separator ()). append ( config . formatter . middle ( head )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġconsole Head Ġ= ĠarrayOf Null s < String >( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmin ( config . stack Deep , Ġstack Trace . size Ġ- Ġstack Index ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġi Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlen Ġ= Ġconsole Head . size ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( i Ġ< Ġlen ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtarget Element Ġ= Ġstack Trace [ i Ġ+ Ġstack Index ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconsole Head [ i ] Ġ= ĠFormatter () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. format ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"% s .% s (% s :% d )", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtarget Element . className , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtarget Element . methodName , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġget FileName ( target Element ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtarget Element . line Number ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. toString () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ++ i ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconsole Head . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . append ( config . formatter . separator ()). append ( config . formatter . middle ( it )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠContent ĊĠĠĠĠĠĠĠ Ġany . forEach Indexed Ġ{ Ġindex , Ġitem Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcontent Tag : ĠString ? ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcontent : ĠAny ? ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġis Show Type : ĠBoolean ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( item Ġis ĠLog Entity ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontent Tag Ġ= Ġ"${ item . content Tag }" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontent Ġ= Ġitem . any ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Show Type Ġ= Ġitem . is Show Type ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontent Tag Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontent Ġ= Ġitem ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Show Type Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( content Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . append ( config . formatter . separator ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. append ( config . formatter . middle ( Log Constant . NONE )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġclass Type : ĠString ? Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcontent Split Ġ= ĠArrayList < String >(). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconfig . handlers . reversed (). forEach Ġ{ Ġhandler Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( handler . is Handler ( content )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġclass Type Ġ= Ġhandler . getType String ( content ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġadd All ( handler . handler ( config , Ġcontent , Ġ 0 )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ apply ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcontent ClassType Ġ= Ġif Ġ( is Show Type ) Ġclass Type Ġelse Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . append ( config . formatter . separator ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( index Ġ== Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( config . show Stack Info ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . append ( config . formatter . middle Primary ( content Tag , Ġcontent ClassType )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtemp Tag Ġ= Ġif Ġ( child Tag Ġ!= Ġnull Ġ&& Ġcontent Tag Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"$ child Tag /$ content Tag " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġchild Tag Ġ?: Ġcontent Tag ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . append ( config . formatter . top ( thread Info , Ġtemp Tag , Ġcontent ClassType )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . append ( config . formatter . middle Secondary ( content Tag , Ġcontent ClassType )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontent Split . forEach Ġ{ Ġtext Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . append ( config . formatter . separator ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. append ( config . formatter . middle ( text )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠEnd ĊĠĠĠĠĠĠĠ Ġlog . append ( config . formatter . separator ()). append ( config . formatter . bottom ()) ĊĊĠĠĠĠĠĠĠ Ġconfig . printer s . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit . print Log ( level Ġ?: Ġconfig . level , Ġtag Ġ?: Ġconfig . tag , Ġlog . toString ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġhandler Loop ( config : ĠLog Config , Ġany : ĠAny ?, Ġcolumns : ĠInt ): ĠList < String > Ġ= ĊĠĠĠĠĠĠĠ ĠArrayList < String >(). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( any Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġadd ( Log Constant . NONE ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ apply ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġconfig . handlers . reversed (). forEach Ġ{ Ġhandler Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( handler . is Handler ( any )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġadd All ( handler . handler ( config , Ġany , Ġcolumns )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ apply ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget FileName ( target Element : ĠStack Trace Element ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠfileName Ġ= Ġtarget Element . fileName ĊĠĠĠĠĠĠĠ Ġif Ġ( fileName Ġ!= Ġnull ) Ġreturn ĠfileName ĊĠĠĠĠĠĠĠ Ġ// ĠIf Ġname Ġof Ġfile Ġis Ġnull , Ġshould Ġadd ĊĠĠĠĠĠĠĠ Ġ// Ġ"- keep attributes ĠSource File , LineNumber Table " Ġin Ġpro guard Ġfile . ĊĠĠĠĠĠĠĠ Ġvar ĠclassName Ġ= Ġtarget Element . className ĊĠĠĠĠĠĠĠ Ġval ĠclassName Info Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ ĠclassName . split ("\\ .". to Regex ()). drop Last While Ġ{ Ġit . isEmpty () Ġ}. to Typed Array () ĊĠĠĠĠĠĠĠ Ġif Ġ( className Info . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠclassName Ġ= ĠclassName Info [ className Info . size Ġ- Ġ 1 ] ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġindex Ġ= ĠclassName . indexOf ('$ ') ĊĠĠĠĠĠĠĠ Ġif Ġ( index Ġ!= Ġ- 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠclassName Ġ= ĠclassName . substring ( 0 , Ġindex ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġ"$ className . java " ĊĠĠĠ Ġ} Ċ }