You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2021/12/13 17:11:29 UTC
[isis] branch master updated: ISIS-2918: plug user preferred Locale into framework interactions
This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git
The following commit(s) were added to refs/heads/master by this push:
new 87440ba ISIS-2918: plug user preferred Locale into framework interactions
87440ba is described below
commit 87440bae5255a2955560189033ee5d78e6f96b8d
Author: andi-huber <ah...@apache.org>
AuthorDate: Mon Dec 13 18:11:19 2021 +0100
ISIS-2918: plug user preferred Locale into framework interactions
---
.../applib/services/iactnlayer/InteractionContext.java | 13 ++++++++++---
.../apache/isis/applib/services/user/UserMemento.java | 17 ++++++++++++-----
.../runtimeservices/wrapper/WrapperFactoryDefault.java | 2 +-
.../UserMementoRefinerFromApplicationUser.java | 12 ++++++++----
4 files changed, 31 insertions(+), 13 deletions(-)
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/iactnlayer/InteractionContext.java b/api/applib/src/main/java/org/apache/isis/applib/services/iactnlayer/InteractionContext.java
index d6eace9..ddda757 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/iactnlayer/InteractionContext.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/iactnlayer/InteractionContext.java
@@ -21,6 +21,7 @@ package org.apache.isis.applib.services.iactnlayer;
import java.io.Serializable;
import java.time.ZoneId;
import java.util.Locale;
+import java.util.Optional;
import java.util.function.UnaryOperator;
import java.util.stream.Stream;
@@ -61,7 +62,6 @@ public class InteractionContext implements Serializable {
return InteractionContext.builder()
.user(user)
.clock(VirtualClock.system())
- .locale(Locale.getDefault())
.timeZone(ZoneId.systemDefault())
.build();
}
@@ -87,8 +87,15 @@ public class InteractionContext implements Serializable {
@With @Getter @Builder.Default
final @NonNull VirtualClock clock = VirtualClock.system();
- @With @Getter @Builder.Default
- final @NonNull Locale locale = Locale.getDefault();
+ @With Locale locale;
+ public Locale getLocale(){
+ if(locale!=null) {
+ return locale; // if set, overrides any user preferences
+ }
+ return Optional.ofNullable(getUser())
+ .map(UserMemento::getLocale)
+ .orElseGet(Locale::getDefault);
+ }
@With @Getter @Builder.Default
final @NonNull ZoneId timeZone = ZoneId.systemDefault();
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/user/UserMemento.java b/api/applib/src/main/java/org/apache/isis/applib/services/user/UserMemento.java
index 5a2bf1b..b581068 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/user/UserMemento.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/user/UserMemento.java
@@ -23,12 +23,12 @@ import java.io.ObjectInputStream;
import java.io.Serializable;
import java.net.URL;
import java.util.List;
+import java.util.Locale;
import java.util.stream.Stream;
-import org.springframework.lang.Nullable;
-
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
+import org.springframework.lang.Nullable;
import org.apache.isis.applib.IsisModuleApplib;
import org.apache.isis.applib.annotation.Collection;
@@ -69,7 +69,7 @@ public class UserMemento implements Serializable {
public static class TitleUiEvent extends IsisModuleApplib.TitleUiEvent<UserMemento> {}
- private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
+ private void readObject(final ObjectInputStream ois) throws ClassNotFoundException, IOException {
ois.defaultReadObject();
}
@@ -147,7 +147,7 @@ public class UserMemento implements Serializable {
public static class UiSubscriber {
@Order(PriorityPrecedence.LATE)
@EventListener(UserMemento.TitleUiEvent.class)
- public void on(UserMemento.TitleUiEvent ev) {
+ public void on(final UserMemento.TitleUiEvent ev) {
val userMemento = ev.getSource();
assert userMemento != null;
val title = String.format("%s %s", userMemento.getName(), userMemento.isImpersonating() ? " (impersonating)" : "");
@@ -178,6 +178,12 @@ public class UserMemento implements Serializable {
@Nullable
URL avatarUrl;
+ @Property(optionality = Optionality.OPTIONAL)
+ @PropertyLayout(fieldSetId = "details", sequence = "3")
+ @Getter @With(onMethod_ = {@Programmatic})
+ @Nullable
+ Locale locale;
+
/**
* To support external security mechanisms such as keycloak,
* where the validity of the session is defined by headers in the request.
@@ -253,7 +259,7 @@ public class UserMemento implements Serializable {
@Programmatic
- public UserMemento withRoleAdded(String role) {
+ public UserMemento withRoleAdded(final String role) {
return asBuilder()
.roles(roles.add(new RoleMemento(role)))
.build();
@@ -294,6 +300,7 @@ public class UserMemento implements Serializable {
.authenticationCode(authenticationCode)
.authenticationSource(authenticationSource)
.avatarUrl(avatarUrl)
+ .locale(locale)
.impersonating(impersonating)
.realName(realName)
.multiTenancyToken(multiTenancyToken)
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/WrapperFactoryDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/WrapperFactoryDefault.java
index e4c91a4..6adc11b 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/WrapperFactoryDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/WrapperFactoryDefault.java
@@ -454,7 +454,7 @@ public class WrapperFactoryDefault implements WrapperFactory {
return InteractionContext.builder()
.clock(Optional.ofNullable(asyncControl.getClock()).orElseGet(interactionContext::getClock))
- .locale(Optional.ofNullable(asyncControl.getLocale()).orElseGet(interactionContext::getLocale))
+ .locale(Optional.ofNullable(asyncControl.getLocale()).orElse(null)) // if not set in asyncControl use defaults (set override to null)
.timeZone(Optional.ofNullable(asyncControl.getTimeZone()).orElseGet(interactionContext::getTimeZone))
.user(Optional.ofNullable(asyncControl.getUser()).orElseGet(interactionContext::getUser))
.build();
diff --git a/extensions/security/secman/integration/src/main/java/org/apache/isis/extensions/secman/integration/usermementorefiner/UserMementoRefinerFromApplicationUser.java b/extensions/security/secman/integration/src/main/java/org/apache/isis/extensions/secman/integration/usermementorefiner/UserMementoRefinerFromApplicationUser.java
index f4da58c..1b72721 100644
--- a/extensions/security/secman/integration/src/main/java/org/apache/isis/extensions/secman/integration/usermementorefiner/UserMementoRefinerFromApplicationUser.java
+++ b/extensions/security/secman/integration/src/main/java/org/apache/isis/extensions/secman/integration/usermementorefiner/UserMementoRefinerFromApplicationUser.java
@@ -28,19 +28,23 @@ import org.apache.isis.core.security.authentication.manager.UserMementoRefiner;
import org.apache.isis.extensions.secman.applib.user.dom.ApplicationUserRepository;
import lombok.RequiredArgsConstructor;
-import lombok.extern.log4j.Log4j2;
@Service
-@Log4j2
+//@Log4j2
@RequiredArgsConstructor(onConstructor_ = {@Inject})
public class UserMementoRefinerFromApplicationUser implements UserMementoRefiner {
final Provider<ApplicationUserRepository> applicationUserRepositoryProvider;
@Override
- public UserMemento refine(UserMemento userMemento) {
+ public UserMemento refine(final UserMemento userMemento) {
return applicationUserRepositoryProvider.get().findByUsername(userMemento.getName())
- .map(applicationUser -> userMemento.withMultiTenancyToken(applicationUser.getAtPath()))
+ .map(applicationUser ->
+ userMemento.asBuilder()
+ .multiTenancyToken(applicationUser.getAtPath())
+ .locale(applicationUser.getLocale())
+ .build()
+ )
.orElse(userMemento);
}
}