package Ġorg . jetbrains . team city . rest . infrastructure Ċ Ċ import Ġokhttp 3 .* Ċ import Ġorg . slf 4 j . LoggerFactory Ċ import Ġjava . io . File Ċ import Ġjava . io . IOException Ċ import Ġjava . util . regex . Pattern Ċ Ċ open Ġclass ĠApi Client ( val Ġclient Config : ĠClient Config ) Ġ{ ĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġ@ Published Api Ġinternal Ġval ĠContentType Ġ= Ġ" Content - Type " ĊĠĠĠĠĠĠĠ Ġ@ Published Api Ġinternal Ġval ĠAccept Ġ= Ġ" Accept " ĊĠĠĠĠĠĠĠ Ġ@ Published Api Ġinternal Ġval ĠAuthorization Ġ= Ġ" Authorization " ĊĠĠĠĠĠĠĠ Ġ@ Published Api Ġinternal Ġval ĠJson MediaType Ġ= Ġ" application / json " ĊĠĠĠĠĠĠĠ Ġ@ Published Api Ġinternal Ġval ĠFormData MediaType Ġ= Ġ" multipart / form - data " ĊĠĠĠĠĠĠĠ Ġ@ Published Api Ġinternal Ġval ĠXml MediaType Ġ= Ġ" application / xml " ĊĊĠĠĠĠĠĠĠ Ġ@ Jvm Static ĊĠĠĠĠĠĠĠ Ġval Ġclient Ġby Ġlazy Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbuilder . build () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ@ Jvm Static ĊĠĠĠĠĠĠĠ Ġval Ġbuilder : ĠOk HttpClient . Builder Ġ= ĠOk HttpClient . Builder () ĊĊĠĠĠĠĠĠĠ Ġ@ Jvm Static ĊĠĠĠĠĠĠĠ Ġvar Ġdefault Headers : ĠMap < String , ĠString > Ġby ĠApplication Deleg ates . set Once ( map Of ( ContentType Ġto ĠJson MediaType , ĠAccept Ġto ĠJson MediaType )) ĊĊĠĠĠĠĠĠĠ Ġ@ Jvm Static ĊĠĠĠĠĠĠĠ Ġval Ġjson Headers : ĠMap < String , ĠString > Ġ= Ġmap Of ( ContentType Ġto ĠJson MediaType , ĠAccept Ġto ĠJson MediaType ) ĊĊĠĠĠĠĠĠĠ Ġinline Ġfun Ġ< re ified ĠT Ġ: ĠAny > Ġprocess Response ( response : ĠApi Infrastructure Response < T >): ĠT Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ( response . response Type ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠResponse Type . Success Ġ-> Ġ( response Ġas ĠSuccess < *> ). data Ġas ĠT ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠResponse Type . Information al Ġ-> ĠTODO () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠResponse Type . Red irection Ġ-> ĠTODO () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠResponse Type . Client Error Ġ-> Ġthrow ĠClient Exception (( response Ġas ĠClient Error < *> ). body Ġas ? ĠString Ġ?: Ġ" Client Ġerror ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠResponse Type . ServerError Ġ-> Ġthrow ĠServer Exception (( response Ġas ĠServer Error < *> ). body Ġas ? ĠString Ġ?: Ġ" Server Ġerror ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval ĠLOG Ġ= ĠLoggerFactory . getLogger ( this . java Class . name ) ĊĊĠĠĠ Ġ@ Published Api Ġinternal Ġinline Ġfun Ġ< re ified ĠT > Ġrequest Body ( content : ĠT , Ġmedia Type : ĠString Ġ= ĠJson MediaType ): ĠRequest Body Ġ{ ĊĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontent Ġis ĠFile Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠRequest Body . create ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMediaType . parse ( media Type ), Ġcontent ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontent Ġis ĠString Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠRequest Body . create ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMediaType . parse ( media Type ), Ġcontent ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmedia Type Ġ== ĠFormData MediaType Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrequest Body Builder Ġ= ĠMultip art Body . Builder (). setType ( Multipart Body . FORM ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġcontent 's Ġtype Ġ* must * Ġbe ĠMap < String , ĠAny > ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ@ Suppress (" UN CHECK ED _ CAST ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( content Ġas ĠMap < String , ĠAny >). forEach Ġ{ Ġkey , Ġvalue Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( value :: class Ġ== ĠFile :: class ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfile Ġ= Ġvalue Ġas ĠFile ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequest Body Builder . add FormData Part ( key , Ġfile . name , ĠRequest Body . create ( MediaType . parse (" application / octet - stream "), Ġfile )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstring Value Ġ= Ġvalue Ġas ĠString ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequest Body Builder . add FormData Part ( key , Ġstring Value ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTODO (" Handle Ġother Ġtypes Ġinside ĠFormData MediaType ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġrequest Body Builder . build () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmedia Type Ġ== ĠJson MediaType Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠRequest Body . create ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMediaType . parse ( media Type ), ĠSerializer . mos hi . adapter ( T :: class . java ). toJson ( content ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmedia Type Ġ== ĠXml MediaType Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTODO (" xml Ġnot Ġcurrently Ġsupported .") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠTODO : Ġthis Ġshould Ġbe Ġextended Ġwith Ġother Ġserializers ĊĠĠĠĠĠĠĠ ĠTODO (" request Body Ġcurrently Ġonly Ġsupports ĠJSON Ġbody Ġand ĠFile Ġbody .") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Published Api Ġinternal Ġinline Ġfun Ġ< re ified ĠT Ġ: ĠAny > Ġresponse Body ( response : ĠResponse , Ġmedia Type : ĠString Ġ= ĠJson MediaType ): ĠT Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( T :: class . java Ġ== Ġjava . io . File :: class . java ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġdownload File From Response ( response ) Ġas ĠT ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( T :: class Ġ== ĠUnit :: class ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠUnit Ġas ĠT ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġvar ĠcontentType Ġ= Ġresponse . headers (). get (" Content - Type ") ĊĊĠĠĠĠĠĠĠ Ġif Ġ( contentType Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠcontentType Ġ= ĠJson MediaType ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Json Mime ( contentType ) Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSerializer . mos hi . adapter ( T :: class . java ). fromJson ( response . body ()?. source ()) !! ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠcontentType . equals ( String . java Class ) Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresponse . body (). toString () Ġas ĠT ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTODO (" Fill Ġin Ġmore Ġtypes !") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġis Json Mime ( mime : ĠString ?): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġjson Mime Ġ= Ġ"( ? i )^ ( application / json |[ ^ ;/ Ġ\ t ]+ / [^ ;/ Ġ\ t ]+ [+ ] json )[ Ġ\ t ]* ( ; .* )? $" ĊĠĠĠĠĠĠĠ Ġreturn Ġmime Ġ!= Ġnull Ġ&& Ġ( mime . matches ( json Mime . to Regex ()) Ġ|| Ġmime Ġ== Ġ"* /* ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinline Ġfun Ġ< re ified ĠT Ġ: ĠAny > Ġrequest ( request Config : ĠRequest Config , Ġbody : ĠAny ? Ġ= Ġnull ): ĠApi Infrastructure Response < T > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġhttp Url Ġ= ĠHttp Url . parse ( client Config . baseUrl ) Ġ?: Ġthrow ĠIllegalStateException (" baseUrl Ġis Ġinvalid .") ĊĊĠĠĠĠĠĠĠ Ġvar Ġurl Builder Ġ= Ġhttp Url . newBuilder () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. add Path Segments ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequest Config . path . trim Start ('/') ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠ Ġrequest Config . query . forEach Ġ{ Ġquery Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġquery . value . forEach Ġ{ Ġquery Value Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġurl Builder Ġ= Ġurl Builder . add QueryParameter ( query . key , Ġquery Value ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( request Config . encoded Query Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġurl Builder . add Encoded Path Segment ( request Config . encoded Query ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġurl Ġ= Ġurl Builder . build () ĊĠĠĠĠĠĠĠ Ġval Ġheaders Ġ= Ġ( default Headers Ġ+ Ġrequest Config . headers ). to Mutable Map () ĊĠĠĠĠĠĠĠ ĠLOG . info ("[ {}] Ġ{} Ġ| Ġheaders : Ġ{}", Ġrequest Config . method , Ġurl , Ġheaders ) ĊĠĠĠĠĠĠĠ Ġif Ġ( body Ġ!= Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLOG . debug ("[ {}] Ġ{} Ġ| Ġbody : Ġ{}", Ġrequest Config . method , Ġurl , Ġbody . toString ()) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( client Config . auth Header Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġheaders [ Authorization ] Ġ= Ġclient Config . auth Header ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( headers [ ContentType ] Ġ?: Ġ"" Ġ== Ġ"") Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġkotlin . IllegalStateException (" Missing ĠContent - Type Ġheader . ĠThis Ġis Ġrequired .") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif ( headers [ Accept ] Ġ?: Ġ"" Ġ== Ġ"") Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġkotlin . IllegalStateException (" Missing ĠAccept Ġheader . ĠThis Ġis Ġrequired .") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( headers [ Accept ] Ġ?: Ġ"" Ġ== Ġ"") Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġkotlin . IllegalStateException (" Missing ĠAccept Ġheader . ĠThis Ġis Ġrequired .") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠTODO : Ġsupport Ġmultiple ĠcontentType , accept Ġoptions Ġhere . ĊĠĠĠĠĠĠĠ Ġval ĠcontentType Ġ= Ġ( headers [ ContentType ] Ġas ĠString ). substring Before ("; "). toLowerCase () ĊĠĠĠĠĠĠĠ Ġval Ġaccept Ġ= Ġ( headers [ Accept ] Ġas ĠString ). substring Before ("; "). toLowerCase () ĊĊĠĠĠĠĠĠĠ Ġvar Ġrequest : ĠRequest . Builder Ġ= ĠRequest . Builder (). url ( url ) ĊĠĠĠĠĠĠĠ Ġwhen Ġ( request Config . method ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠRequestMethod . DELETE Ġ-> Ġrequest . delete () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠRequestMethod . GET Ġ-> Ġrequest Ġ// Ġjust Ġto Ġillustr ate Ġwe Ġdo Ġnothing Ġspecial Ġabout ĠGET Ġrequests ĊĠĠĠĠĠĠĠĠĠĠĠ ĠRequestMethod . HEAD Ġ-> Ġrequest . head () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠRequestMethod . PATCH Ġ-> Ġrequest . patch ( request Body ( body , ĠcontentType )) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠRequestMethod . PUT Ġ-> Ġrequest . put ( request Body ( body , ĠcontentType )) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠRequestMethod . POST Ġ-> Ġrequest . post ( request Body ( body , ĠcontentType )) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠRequestMethod . OPTIONS Ġ-> Ġrequest . method (" OPTIONS ", Ġnull ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġheaders . forEach Ġ{ Ġheader Ġ-> Ġrequest Ġ= Ġrequest . add Header ( header . key , Ġheader . value ) Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġreal Request Ġ= Ġrequest . build () ĊĠĠĠĠĠĠĠ Ġval Ġresponse Ġ= Ġclient . new Call ( real Request ). execute () ĊĊĠĠĠĠĠĠĠ Ġ// ĠTODO : Ġhandle Ġspecific Ġmapping Ġtypes . Ġe . g . ĠMap < int , ĠClass <?>> ĊĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresponse . is Redirect Ġ-> Ġreturn ĠRed irection ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresponse . code (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresponse . headers (). to Multimap () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresponse . is Information al Ġ-> Ġreturn ĠInformation al ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresponse . message (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresponse . code (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresponse . headers (). to Multimap () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresponse . is Successful Ġ-> Ġreturn ĠSuccess ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresponse Body ( response , Ġaccept ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresponse . code (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresponse . headers (). to Multimap () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresponse . is Client Error Ġ-> Ġreturn ĠClient Error ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresponse . body ()?. string (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresponse . code (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresponse . headers (). to Multimap () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġreturn ĠServer Error ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnull , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresponse . body ()?. string (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresponse . code (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresponse . headers (). to Multimap () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( IOException :: class ) ĊĠĠĠ Ġfun Ġdownload File From Response ( response : ĠResponse ): ĠFile Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġfile Ġ= Ġprepare Download File ( response ) ĊĊĠĠĠĠĠĠĠ Ġresponse . body ()?. byte Stream (). use Ġ{ Ġinput Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ ĠFile ( file . path ). output Stream (). use Ġ{ Ġinput ?. copy To ( it ) Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġfile ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( IOException :: class ) ĊĠĠĠ Ġfun Ġprepare Download File ( response : ĠResponse ): ĠFile Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġfilename : ĠString ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġval Ġcontent Disposition Ġ= Ġresponse . headers (). get (" Content - Disposition ") ĊĊĠĠĠĠĠĠĠ Ġif Ġ( content Disposition Ġ!= Ġnull Ġ&& Ġcontent Disposition Ġ!= Ġ"") Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpattern Ġ= ĠPattern . compile (" filename =[' \"] ? ([^ ' \" \\ s ]+ )[' \"] ?") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmatcher Ġ= Ġpattern . matcher ( content Disposition ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( matcher . find ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfilename Ġ= Ġmatcher . group ( 1 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġvar Ġprefix : ĠString ĊĠĠĠĠĠĠĠ Ġvar Ġsuffix : ĠString ? Ġ= Ġnull ĊĊĠĠĠĠĠĠĠ Ġif Ġ( filename Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprefix Ġ= Ġ" download -" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsuffix Ġ= Ġ"" ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpos Ġ= Ġfilename . lastIndexOf ('.') ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( pos Ġ== Ġ- 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprefix Ġ= Ġ"$ filename - "; ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprefix Ġ= Ġfilename . substring ( 0 , Ġpos ) Ġ+ Ġ"-" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsuffix Ġ= Ġfilename . substring ( pos ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠFile . create TempFile Ġrequires Ġthe Ġprefix Ġto Ġbe Ġat Ġleast Ġthree Ġcharacters Ġlong ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( prefix . length Ġ< Ġ 3 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprefix Ġ= Ġ" download -" ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn ĠFile . create TempFile ( prefix , Ġsuffix ) ĊĠĠĠ Ġ} Ċ }