Ether Framework
Unified API docs for Ether modules
Loading...
Searching...
No Matches
EnhancedHelloHandler.java
Go to the documentation of this file.
1package dev.rafex.ether.http.jetty12.health;
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.time.Instant;
30import java.util.LinkedHashMap;
31import java.util.List;
32import java.util.Map;
33import java.util.Set;
34
35import dev.rafex.ether.http.core.HttpExchange;
36import dev.rafex.ether.http.core.Route;
37import dev.rafex.ether.http.jetty12.exchange.JettyHttpExchange;
38import dev.rafex.ether.http.jetty12.handler.NonBlockingResourceHandler;
39import dev.rafex.ether.http.jetty12.response.JettyApiResponses;
40import dev.rafex.ether.json.JsonCodec;
41import dev.rafex.ether.json.JsonUtils;
42
44
45 private static final JsonCodec JSON_CODEC = JsonUtils.codec();
46 private static final JettyApiResponses RESPONSES = new JettyApiResponses(JSON_CODEC);
47
48 private static final Set<String> ALL_METHODS = Set.of("GET", "POST", "PUT", "DELETE", "PATCH");
49
50 // Top 10 most spoken languages by number of speakers
51 // Format: "greeting" / "greeting, {name}!"
52 private static final Map<String, String[]> GREETINGS = Map.of(
53 "en", new String[] { "Hello", "Hello, %s!" }, // English
54 "zh", new String[] { "你好", "%s,你好!" }, // Mandarin Chinese
55 "hi", new String[] { "नमस्ते", "नमस्ते, %s!" }, // Hindi
56 "es", new String[] { "Hola", "¡Hola, %s!" }, // Spanish
57 "fr", new String[] { "Bonjour", "Bonjour, %s!" }, // French
58 "ar", new String[] { "مرحبا", "مرحبا، %s!" }, // Arabic
59 "bn", new String[] { "হ্যালো", "হ্যালো, %s!" }, // Bengali
60 "ru", new String[] { "Привет", "Привет, %s!" }, // Russian
61 "pt", new String[] { "Olá", "Olá, %s!" }, // Portuguese
62 "ur", new String[] { "سلام", "سلام، %s!" } // Urdu
63 );
64
65 private static final String DEFAULT_LANG = "en";
66
68 super(JSON_CODEC);
69 }
70
71 @Override
72 protected String basePath() {
73 return "/hello";
74 }
75
76 @Override
77 protected List<Route> routes() {
78 return List.of(Route.of("/", ALL_METHODS));
79 }
80
81 @Override
82 public Set<String> supportedMethods() {
83 return ALL_METHODS;
84 }
85
86 @Override
87 public boolean get(final HttpExchange x) {
88 return respond(x, 200);
89 }
90
91 @Override
92 public boolean post(final HttpExchange x) {
93 return respond(x, 201);
94 }
95
96 @Override
97 public boolean put(final HttpExchange x) {
98 return respond(x, 200);
99 }
100
101 @Override
102 public boolean delete(final HttpExchange x) {
103 return respond(x, 200);
104 }
105
106 @Override
107 public boolean patch(final HttpExchange x) {
108 return respond(x, 200);
109 }
110
111 private static boolean respond(final HttpExchange x, final int status) {
112 final var jx = asJetty(x);
113
114 final var lang = resolve(x.queryFirst("lang"), DEFAULT_LANG);
115 final var name = x.queryFirst("name");
116 final var greeting = buildGreeting(lang, name);
117
118 final var body = new LinkedHashMap<String, Object>();
119 body.put("message", greeting);
120 body.put("lang", lang);
121 body.put("service", "ether");
122 body.put("method", x.method());
123 body.put("path", x.path());
124 body.put("timestamp", Instant.now().toString());
125
126 RESPONSES.json(jx.response(), jx.callback(), status, body);
127 return true;
128 }
129
130 private static String buildGreeting(final String lang, final String name) {
131 final var phrases = GREETINGS.getOrDefault(lang, GREETINGS.get(DEFAULT_LANG));
132 if (name != null && !name.isBlank()) {
133 return String.format(phrases[1], name.trim());
134 }
135 return phrases[0];
136 }
137
138 private static String resolve(final String value, final String fallback) {
139 if (value == null || value.isBlank()) {
140 return fallback;
141 }
142 final var normalized = value.trim().toLowerCase();
143 return GREETINGS.containsKey(normalized) ? normalized : fallback;
144 }
145
146 private static JettyHttpExchange asJetty(final HttpExchange x) {
147 return (JettyHttpExchange) x;
148 }
149}
void json(final Response response, final Callback callback, final int status, final Object body)