Ether Framework
Unified API docs for Ether modules
Loading...
Searching...
No Matches
JettyHttpExchange.java
Go to the documentation of this file.
1package dev.rafex.ether.http.jetty12.exchange;
2
3/*-
4 * #%L
5 * ether-http-jetty12
6 * %%
7 * Copyright (C) 2025 - 2026 Raúl Eduardo González Argote
8 * %%
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 * THE SOFTWARE.
26 * #L%
27 */
28
29import java.util.Collections;
30import java.util.List;
31import java.util.Map;
32import java.util.Set;
33import java.util.TreeSet;
34
35import org.eclipse.jetty.server.Request;
36import org.eclipse.jetty.server.Response;
37import org.eclipse.jetty.util.Callback;
38
39import dev.rafex.ether.http.core.HttpExchange;
40import dev.rafex.ether.http.jetty12.response.JettyApiResponses;
41import dev.rafex.ether.json.JsonCodec;
42
43public final class JettyHttpExchange implements HttpExchange {
44
45 private final Request request;
46 private final Response response;
47 private final Callback callback;
48 private final Map<String, String> pathParams;
49 private final Map<String, List<String>> queryParams;
50 private final Set<String> allowedMethods;
51 private final JettyApiResponses apiResponses;
52
53 public JettyHttpExchange(final Request request, final Response response, final Callback callback,
54 final Map<String, String> pathParams, final Map<String, List<String>> queryParams,
55 final Set<String> allowedMethods, final JsonCodec jsonCodec) {
56 this.request = request;
57 this.response = response;
58 this.callback = callback;
59 this.pathParams = pathParams;
60 this.queryParams = queryParams;
61 this.allowedMethods = normalizeMethods(allowedMethods);
62 this.apiResponses = new JettyApiResponses(jsonCodec);
63 }
64
65 public Request request() {
66 return request;
67 }
68
69 public Response response() {
70 return response;
71 }
72
73 public Callback callback() {
74 return callback;
75 }
76
77 @Override
78 public String method() {
79 return request.getMethod();
80 }
81
82 @Override
83 public String path() {
84 return request.getHttpURI().getPath();
85 }
86
87 @Override
88 public String pathParam(final String name) {
89 return pathParams.get(name);
90 }
91
92 @Override
93 public String queryFirst(final String name) {
94 final var values = queryParams.get(name);
95 if (values == null || values.isEmpty()) {
96 return null;
97 }
98 return values.get(0);
99 }
100
101 @Override
102 public List<String> queryAll(final String name) {
103 return queryParams.getOrDefault(name, List.of());
104 }
105
106 @Override
107 public Map<String, String> pathParams() {
108 return Collections.unmodifiableMap(pathParams);
109 }
110
111 @Override
112 public Map<String, List<String>> queryParams() {
113 return Collections.unmodifiableMap(queryParams);
114 }
115
116 @Override
117 public Set<String> allowedMethods() {
118 return Collections.unmodifiableSet(allowedMethods);
119 }
120
121 @Override
122 public void json(final int status, final Object body) {
123 apiResponses.json(response, callback, status, body);
124 }
125
126 @Override
127 public void text(final int status, final String body) {
128 apiResponses.text(response, callback, status, body);
129 }
130
131 @Override
132 public void noContent(final int status) {
133 apiResponses.noContent(response, callback, status);
134 }
135
136 @Override
137 public void methodNotAllowed() {
138 response.getHeaders().put("Allow", String.join(", ", allowedMethods));
140 }
141
142 @Override
143 public void options() {
144 response.getHeaders().put("Allow", String.join(", ", allowedMethods));
145 HttpExchange.super.options();
146 }
147
148 private static Set<String> normalizeMethods(final Set<String> methods) {
149 final var out = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
150 if (methods != null) {
151 for (final var method : methods) {
152 if (method != null && !method.isBlank()) {
153 out.add(method.trim().toUpperCase());
154 }
155 }
156 }
157 out.add("OPTIONS");
158 return out;
159 }
160}
JettyHttpExchange(final Request request, final Response response, final Callback callback, final Map< String, String > pathParams, final Map< String, List< String > > queryParams, final Set< String > allowedMethods, final JsonCodec jsonCodec)