diff --git a/README.md b/README.md index 19faeb9..a3327de 100644 --- a/README.md +++ b/README.md @@ -7,20 +7,68 @@ This project requires Java 21 compiler. ## Usage -Include Launchpad to your project: - -```xml - +- Include Launchpad to your project: + ```xml + de.focus-shift launchpad ... - + + ``` + - Choose the right version of Launchpad for your Spring Boot version: + - 3.x is using spring boot 4.x as a parent + - 1.x is using spring boot 3.x as a parent + - 0.x is using spring boot 2.x as a parent +- Configure launchpad apps in your `application.yml` + ```yaml + launchpad: + name-default-locale: de + apps[0]: + icon: data:image/png;base64,xxxxxxx + name: + de: name-1-de + en: name-1-en + url: https://link-1 + apps[1]: + icon: /static/images/app-icon.png + name: + de: name-2-de + en: name-2-en + url: https://link-2 + ``` +- Assign `HasLaunchpad` to all Controllers you want the launchpad to be available + +### Advanced + +#### Launchpad on Error Pages + +Create a custom `ErrorControllerAdvice` and use the `LaunchpadModelAttributeAppender` +to prepare the required launchpad model attributes. + +Example: + +```java +@ControllerAdvice(assignableTypes = ErrorController.class) +@Conditional(LaunchpadAutoConfiguration.LaunchpadAppsCondition.class) +class ErrorControllerAdvice { + + private final LaunchpadModelAttributeAppender launchpadModelAttributeAppender; + + ErrorControllerAdvice(LaunchpadModelAttributeAppender launchpadModelAttributeAppender) { + this.launchpadModelAttributeAppender = launchpadModelAttributeAppender; + } + + @ModelAttribute + public void addAttributes(Model model, Locale locale, Authentication authentication) { + launchpadModelAttributeAppender.addModelAttribute(model, locale, authentication); + } +} ``` -Choose the right version of Launchpad for your Spring Boot version: -* 3.x is using spring boot 4.x as a parent -* 1.x is using spring boot 3.x as a parent -* 0.x is using spring boot 2.x as a parent +You can inject `HttpServletRequest` to check the requested URL with +`request.getAttribute("jakarta.servlet.error.request_uri")` and only call the +`LaunchpadModelAttributeAppender` if the requested URL matches your condition. + ## License diff --git a/src/main/java/de/focus_shift/launchpad/core/LaunchpadAutoConfiguration.java b/src/main/java/de/focus_shift/launchpad/core/LaunchpadAutoConfiguration.java index 8380210..906ed0b 100644 --- a/src/main/java/de/focus_shift/launchpad/core/LaunchpadAutoConfiguration.java +++ b/src/main/java/de/focus_shift/launchpad/core/LaunchpadAutoConfiguration.java @@ -27,8 +27,15 @@ public class LaunchpadAutoConfiguration { static class LaunchpadConfig { @Bean - LaunchpadControllerAdvice launchpadControllerAdvice(LaunchpadService launchpadService) { - return new LaunchpadControllerAdvice(launchpadService); + LaunchpadModelAttributeAppender launchpadModelAttributeAppender( + LaunchpadService launchpadService) { + return new LaunchpadModelAttributeAppender(launchpadService); + } + + @Bean + LaunchpadControllerAdvice launchpadControllerAdvice( + LaunchpadModelAttributeAppender launchpadModelAttributeAppender) { + return new LaunchpadControllerAdvice(launchpadModelAttributeAppender); } @Bean @@ -48,7 +55,7 @@ LaunchpadAppUrlCustomizer appUrlCustomizer() { /** Checks if 'launchpad.apps' are configured appropriate. */ // copied and adjusted from // org.springframework.boot.autoconfigure.condition.OnPropertyListCondition - static class LaunchpadAppsCondition extends SpringBootCondition { + public static class LaunchpadAppsCondition extends SpringBootCondition { private static final Bindable> APP_LIST = Bindable.listOf(LaunchpadConfigProperties.App.class); private static final String PROPERTY_NAME = "launchpad.apps"; diff --git a/src/main/java/de/focus_shift/launchpad/core/LaunchpadControllerAdvice.java b/src/main/java/de/focus_shift/launchpad/core/LaunchpadControllerAdvice.java index f183813..63d3840 100644 --- a/src/main/java/de/focus_shift/launchpad/core/LaunchpadControllerAdvice.java +++ b/src/main/java/de/focus_shift/launchpad/core/LaunchpadControllerAdvice.java @@ -1,7 +1,6 @@ package de.focus_shift.launchpad.core; import de.focus_shift.launchpad.api.HasLaunchpad; -import java.util.List; import java.util.Locale; import org.springframework.security.core.Authentication; import org.springframework.ui.Model; @@ -11,27 +10,14 @@ @ControllerAdvice(assignableTypes = {HasLaunchpad.class}) public class LaunchpadControllerAdvice { - private final LaunchpadService launchpadService; + private final LaunchpadModelAttributeAppender modelAttributeAppender; - LaunchpadControllerAdvice(LaunchpadService launchpadService) { - this.launchpadService = launchpadService; + LaunchpadControllerAdvice(LaunchpadModelAttributeAppender modelAttributeAppender) { + this.modelAttributeAppender = modelAttributeAppender; } @ModelAttribute public void addAttributes(Model model, Locale locale, Authentication authentication) { - - final Launchpad launchpad = launchpadService.getLaunchpad(authentication); - - final List appDtos = - launchpad.getApps().stream() - .map( - app -> - new AppDto( - app.getUrl().toString(), app.getAppName().get(locale), app.getIcon())) - .toList(); - - if (!appDtos.isEmpty()) { - model.addAttribute("launchpad", new LaunchpadDto(appDtos)); - } + modelAttributeAppender.addModelAttribute(model, locale, authentication); } } diff --git a/src/main/java/de/focus_shift/launchpad/core/LaunchpadModelAttributeAppender.java b/src/main/java/de/focus_shift/launchpad/core/LaunchpadModelAttributeAppender.java new file mode 100644 index 0000000..23c3906 --- /dev/null +++ b/src/main/java/de/focus_shift/launchpad/core/LaunchpadModelAttributeAppender.java @@ -0,0 +1,32 @@ +package de.focus_shift.launchpad.core; + +import java.util.List; +import java.util.Locale; +import org.springframework.security.core.Authentication; +import org.springframework.ui.Model; + +public class LaunchpadModelAttributeAppender { + + private final LaunchpadService launchpadService; + + LaunchpadModelAttributeAppender(LaunchpadService launchpadService) { + this.launchpadService = launchpadService; + } + + public void addModelAttribute(Model model, Locale locale, Authentication authentication) { + + final Launchpad launchpad = launchpadService.getLaunchpad(authentication); + + final List appDtos = + launchpad.getApps().stream() + .map( + app -> + new AppDto( + app.getUrl().toString(), app.getAppName().get(locale), app.getIcon())) + .toList(); + + if (!appDtos.isEmpty()) { + model.addAttribute("launchpad", new LaunchpadDto(appDtos)); + } + } +} diff --git a/src/test/java/de/focus_shift/launchpad/core/LaunchpadControllerAdviceIT.java b/src/test/java/de/focus_shift/launchpad/core/LaunchpadControllerAdviceIT.java index 3b9f180..263857e 100644 --- a/src/test/java/de/focus_shift/launchpad/core/LaunchpadControllerAdviceIT.java +++ b/src/test/java/de/focus_shift/launchpad/core/LaunchpadControllerAdviceIT.java @@ -26,7 +26,7 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; -@SpringBootTest(classes = {LaunchpadControllerAdvice.class}) +@SpringBootTest(classes = {LaunchpadControllerAdvice.class, LaunchpadModelAttributeAppender.class}) @ContextConfiguration(classes = {LaunchpadControllerAdviceIT.TestConfig.class}) @AutoConfigureMockMvc class LaunchpadControllerAdviceIT {