11package com .retailsvc .http .internal ;
22
3+ import com .retailsvc .http .AfterResponseHook ;
4+ import com .retailsvc .http .ExceptionHandler ;
35import com .retailsvc .http .MethodNotAllowedException ;
46import com .retailsvc .http .NotFoundException ;
57import com .retailsvc .http .Request ;
1719import com .sun .net .httpserver .HttpExchange ;
1820import java .io .IOException ;
1921import java .util .HashMap ;
22+ import java .util .List ;
2023import java .util .Locale ;
2124import java .util .Map ;
2225import java .util .Optional ;
26+ import org .slf4j .Logger ;
27+ import org .slf4j .LoggerFactory ;
2328
2429public final class RequestPreparationFilter extends Filter {
2530
31+ private static final Logger LOG = LoggerFactory .getLogger (RequestPreparationFilter .class );
2632 private static final String BODY_POINTER = "/body" ;
2733
2834 private final Spec spec ;
2935 private final Router router ;
3036 private final Validator validator ;
3137 private final Map <String , TypeMapper > bodyMappers ;
38+ private final ExceptionHandler exceptionHandler ;
39+ private final List <AfterResponseHook > afterHooks ;
3240
3341 public RequestPreparationFilter (
34- Spec spec , Router router , Validator validator , Map <String , TypeMapper > bodyMappers ) {
42+ Spec spec ,
43+ Router router ,
44+ Validator validator ,
45+ Map <String , TypeMapper > bodyMappers ,
46+ ExceptionHandler exceptionHandler ,
47+ List <AfterResponseHook > afterHooks ) {
3548 this .spec = spec ;
3649 this .router = router ;
3750 this .validator = validator ;
3851 this .bodyMappers = Map .copyOf (bodyMappers );
52+ this .exceptionHandler = exceptionHandler ;
53+ this .afterHooks = List .copyOf (afterHooks );
3954 }
4055
4156 @ Override
@@ -45,6 +60,30 @@ public String description() {
4560
4661 @ Override
4762 public void doFilter (HttpExchange exchange , Chain chain ) throws IOException {
63+ Request request ;
64+ try {
65+ request = buildRequest (exchange );
66+ } catch (RuntimeException | IOException t ) {
67+ exceptionHandler .handle (exchange , t );
68+ return ;
69+ }
70+
71+ try {
72+ ScopedValue .where (DispatchHandler .CURRENT , request )
73+ .call (
74+ () -> {
75+ runInnerChain (exchange , chain );
76+ fireAfterHooks (exchange , request );
77+ return null ;
78+ });
79+ } catch (IOException | RuntimeException e ) {
80+ throw e ;
81+ } catch (Exception e ) {
82+ throw new IOException (e );
83+ }
84+ }
85+
86+ private Request buildRequest (HttpExchange exchange ) throws IOException {
4887 byte [] body = exchange .getRequestBody ().readAllBytes ();
4988
5089 HttpMethod method = HttpMethod .parse (exchange .getRequestMethod ());
@@ -65,30 +104,28 @@ public void doFilter(HttpExchange exchange, Chain chain) throws IOException {
65104 ParsedBody parsedBody = validateAndParseBody (exchange , op , body );
66105
67106 var headers = exchange .getRequestHeaders ();
68- Request request =
69- new Request (
70- body ,
71- parsedBody .value (),
72- parsedBody . mapper (),
73- op . operationId (),
74- match . pathParameters (),
75- exchange . getRequestURI (). getRawQuery (),
76- headers :: getFirst );
107+ return new Request (
108+ body ,
109+ parsedBody . value () ,
110+ parsedBody .mapper (),
111+ op . operationId (),
112+ match . pathParameters (),
113+ exchange . getRequestURI (). getRawQuery (),
114+ headers :: getFirst );
115+ }
77116
117+ private void runInnerChain (HttpExchange exchange , Chain chain ) throws IOException {
78118 try {
79- ScopedValue .where (DispatchHandler .CURRENT , request )
80- .call (
81- () -> {
82- chain .doFilter (exchange );
83- return null ;
84- });
85- } catch (IOException | RuntimeException e ) {
86- throw e ;
87- } catch (Exception e ) {
88- throw new IOException (e );
119+ chain .doFilter (exchange );
120+ } catch (RuntimeException | IOException t ) {
121+ exceptionHandler .handle (exchange , t );
89122 }
90123 }
91124
125+ private void fireAfterHooks (HttpExchange exchange , Request request ) {
126+ // implemented in Task 5
127+ }
128+
92129 private String stripBasePath (String path ) {
93130 String base = spec .basePath ();
94131 if (base == null || base .isEmpty () || base .equals ("/" )) {
0 commit comments