From d54e8103ea72b6027ebff7b02768d40deab739e6 Mon Sep 17 00:00:00 2001 From: Alexander Goussas Date: Mon, 1 Jun 2026 22:32:19 -0500 Subject: [PATCH] feat: add support for multilang definitions --- collections/larousse API/Define a word.yml | 5 +++- collections/larousse API/Translate a word.yml | 5 +++- .../java/net/frustratedfunctor/core/Lang.java | 28 ++++++++++++++++++ ...va => FrenchWordDefinitionRepository.java} | 2 +- .../LanguageAwareDefinitionsRepository.java | 29 +++++++++++++++++++ .../definitions/WordDefinitionResource.java | 12 ++++---- .../definitions/WordDefinitionService.java | 12 ++++---- .../net/frustratedfunctor/ui/UiResource.java | 7 +++-- .../resources/templates/pub/contributing.html | 3 +- src/main/resources/templates/pub/index.html | 5 ++++ 10 files changed, 88 insertions(+), 20 deletions(-) create mode 100644 src/main/java/net/frustratedfunctor/core/Lang.java rename src/main/java/net/frustratedfunctor/definitions/{JsoupWordDefinitionRepository.java => FrenchWordDefinitionRepository.java} (91%) create mode 100644 src/main/java/net/frustratedfunctor/definitions/LanguageAwareDefinitionsRepository.java diff --git a/collections/larousse API/Define a word.yml b/collections/larousse API/Define a word.yml index 96fcef1..905fda1 100644 --- a/collections/larousse API/Define a word.yml +++ b/collections/larousse API/Define a word.yml @@ -5,8 +5,11 @@ info: http: method: GET - url: "{{api.base_url}}/words/:word/definition" + url: "{{api.base_url}}/words/:word/definition?lang=de" params: + - name: lang + value: de + type: query - name: word value: voiture type: path diff --git a/collections/larousse API/Translate a word.yml b/collections/larousse API/Translate a word.yml index 9f08930..9e31518 100644 --- a/collections/larousse API/Translate a word.yml +++ b/collections/larousse API/Translate a word.yml @@ -5,8 +5,11 @@ info: http: method: GET - url: "{{api.base_url}}/words/:word/translation" + url: "{{api.base_url}}/words/:word/translation?lang=de" params: + - name: lang + value: de + type: query - name: word value: voiture type: path diff --git a/src/main/java/net/frustratedfunctor/core/Lang.java b/src/main/java/net/frustratedfunctor/core/Lang.java new file mode 100644 index 0000000..a58a4ae --- /dev/null +++ b/src/main/java/net/frustratedfunctor/core/Lang.java @@ -0,0 +1,28 @@ +package net.frustratedfunctor.core; + +import java.util.Optional; + +public enum Lang { + French("fr"), + German("de"); + + public final String code; + + public final static Lang DEFAULT = French; + + Lang(String code) { + this.code = code; + } + + public static Optional parse(String s) { + return Optional.ofNullable(switch (s.toLowerCase()) { + case "fr" -> Lang.French; + case "de" -> Lang.German; + default -> null; + }); + } + + public static Lang parseOrDefault(String s) { + return parse(s).orElse(DEFAULT); + } +} diff --git a/src/main/java/net/frustratedfunctor/definitions/JsoupWordDefinitionRepository.java b/src/main/java/net/frustratedfunctor/definitions/FrenchWordDefinitionRepository.java similarity index 91% rename from src/main/java/net/frustratedfunctor/definitions/JsoupWordDefinitionRepository.java rename to src/main/java/net/frustratedfunctor/definitions/FrenchWordDefinitionRepository.java index 96e7d78..0b26252 100644 --- a/src/main/java/net/frustratedfunctor/definitions/JsoupWordDefinitionRepository.java +++ b/src/main/java/net/frustratedfunctor/definitions/FrenchWordDefinitionRepository.java @@ -10,7 +10,7 @@ import java.util.ArrayList; import java.util.List; @ApplicationScoped -public class JsoupWordDefinitionRepository implements WordDefinitionRepository { +public class FrenchWordDefinitionRepository implements WordDefinitionRepository { @Override public List definitionsForWord(String word) { try { diff --git a/src/main/java/net/frustratedfunctor/definitions/LanguageAwareDefinitionsRepository.java b/src/main/java/net/frustratedfunctor/definitions/LanguageAwareDefinitionsRepository.java new file mode 100644 index 0000000..fd43308 --- /dev/null +++ b/src/main/java/net/frustratedfunctor/definitions/LanguageAwareDefinitionsRepository.java @@ -0,0 +1,29 @@ +package net.frustratedfunctor.definitions; + +import jakarta.annotation.Priority; +import jakarta.enterprise.context.ApplicationScoped; +import net.frustratedfunctor.core.Lang; + +import java.util.List; + +@Priority(1) +@ApplicationScoped +public class LanguageAwareDefinitionsRepository implements WordDefinitionRepository { + private final FrenchWordDefinitionRepository french; + + public LanguageAwareDefinitionsRepository(FrenchWordDefinitionRepository french) { + this.french = french; + } + + @Override + public List definitionsForWord(String word) { + return french.definitionsForWord(word); + } + + public List definitionsForWord(String word, String lang) { + return switch (Lang.parseOrDefault(lang)) { + case French -> french.definitionsForWord(word); + case German -> List.of("OOPS! NOT IMPLEMENTED"); + }; + } +} diff --git a/src/main/java/net/frustratedfunctor/definitions/WordDefinitionResource.java b/src/main/java/net/frustratedfunctor/definitions/WordDefinitionResource.java index 6f3b78d..7e9e9b1 100644 --- a/src/main/java/net/frustratedfunctor/definitions/WordDefinitionResource.java +++ b/src/main/java/net/frustratedfunctor/definitions/WordDefinitionResource.java @@ -1,9 +1,6 @@ package net.frustratedfunctor.definitions; -import jakarta.ws.rs.GET; -import jakarta.ws.rs.Path; -import jakarta.ws.rs.PathParam; -import jakarta.ws.rs.Produces; +import jakarta.ws.rs.*; import jakarta.ws.rs.core.MediaType; @Path("/words") @@ -18,8 +15,11 @@ public class WordDefinitionResource { @Path("/{word}/definition") @GET @Produces(MediaType.APPLICATION_JSON) - public WordDefinition definition(@PathParam("word") String word) { - return definitions.define(word); + public WordDefinition definition( + @PathParam("word") String word, + @QueryParam("lang") String lang + ) { + return definitions.define(word, lang); } } diff --git a/src/main/java/net/frustratedfunctor/definitions/WordDefinitionService.java b/src/main/java/net/frustratedfunctor/definitions/WordDefinitionService.java index 44696e2..564aafa 100644 --- a/src/main/java/net/frustratedfunctor/definitions/WordDefinitionService.java +++ b/src/main/java/net/frustratedfunctor/definitions/WordDefinitionService.java @@ -5,17 +5,15 @@ import jakarta.enterprise.context.ApplicationScoped; @ApplicationScoped public class WordDefinitionService { - private final WordDefinitionRepository definitions; + private final LanguageAwareDefinitionsRepository definitions; - public WordDefinitionService(WordDefinitionRepository definitions) { + public WordDefinitionService(LanguageAwareDefinitionsRepository definitions) { this.definitions = definitions; } - public WordDefinition define(String word) { - return new WordDefinition( - word, - definitions.definitionsForWord(word) - ); + public WordDefinition define(String word, String lang) { + final var defs = definitions.definitionsForWord(word, lang); + return new WordDefinition(word, defs); } } diff --git a/src/main/java/net/frustratedfunctor/ui/UiResource.java b/src/main/java/net/frustratedfunctor/ui/UiResource.java index 0fe5dc2..00e688d 100644 --- a/src/main/java/net/frustratedfunctor/ui/UiResource.java +++ b/src/main/java/net/frustratedfunctor/ui/UiResource.java @@ -28,10 +28,13 @@ public class UiResource { @Path("getTranslationsDefinitions") @POST @Produces(MediaType.TEXT_HTML) - public TemplateInstance getTranslationsDefinitions(@FormParam("word") String word) { + public TemplateInstance getTranslationsDefinitions( + @FormParam("word") String word, + @FormParam("lang") String lang + ) { final var data = new WordTranslationsDefinitions( translations.translate(word).translations(), - definitions.define(word).definitions() + definitions.define(word, lang).definitions() ); return index.data("translationsDefinitions", data); } diff --git a/src/main/resources/templates/pub/contributing.html b/src/main/resources/templates/pub/contributing.html index 78b98b3..80d1079 100644 --- a/src/main/resources/templates/pub/contributing.html +++ b/src/main/resources/templates/pub/contributing.html @@ -56,8 +56,7 @@ You can send me a patch implementing support for your language. Take a look at the codebase. I think everything is pretty self-explanatory. You should create a new implementation of the - WordDefinitionRepository and WordTranslationRepository interfaces and add it to the - corresponding composite classes. + WordDefinitionRepository and WordTranslationRepository interfaces.

The patches should be sent over email with the subject [larousseapi] PATCH: description diff --git a/src/main/resources/templates/pub/index.html b/src/main/resources/templates/pub/index.html index 34bcd6f..69ad8cb 100644 --- a/src/main/resources/templates/pub/index.html +++ b/src/main/resources/templates/pub/index.html @@ -54,6 +54,11 @@

+ +
-- 2.43.0