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 2020/12/06 09:28:32 UTC

[isis] branch master updated: ISIS-2464: InteractionFactory: be more specific what the methods do (java-doc)

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 6e4742f  ISIS-2464: InteractionFactory: be more specific what the methods do (java-doc)
6e4742f is described below

commit 6e4742f811b214af457e47a7eea4eb2220de774e
Author: Andi Huber <ah...@apache.org>
AuthorDate: Sun Dec 6 10:24:09 2020 +0100

    ISIS-2464: InteractionFactory: be more specific what the methods do
    (java-doc)
    
    implement accordingly
---
 .../core/runtime/iactn/InteractionFactory.java     | 30 ++++++----
 ...alisationSession.java => AnonymousSession.java} |  4 +-
 .../session/InteractionFactoryDefault.java         | 70 +++++++++++++++++-----
 3 files changed, 76 insertions(+), 28 deletions(-)

diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/iactn/InteractionFactory.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/iactn/InteractionFactory.java
index 9b06067..89c13e8 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/iactn/InteractionFactory.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/iactn/InteractionFactory.java
@@ -43,8 +43,8 @@ public interface InteractionFactory {
     AuthenticationLayer openInteraction();
     
     /**
-     * Returns a new {@link AuthenticationLayer} that is a holder of {@link Authentication} on top 
-     * of the current thread's authentication layer stack.
+     * Returns a new or reused {@link AuthenticationLayer} that is a holder of {@link Authentication} 
+     * on top of the current thread's authentication layer stack.
      * <p>
      * If available reuses an existing {@link InteractionSession}, otherwise creates a new one.
      * <p> 
@@ -61,7 +61,7 @@ public interface InteractionFactory {
     AuthenticationLayer openInteraction(@NonNull Authentication authentication);
 
     /**
-     * @return whether the calling thread is within the context of an open IsisInteractionSession
+     * @return whether the calling thread is within the context of an open {@link InteractionSession} 
      */
     boolean isInInteractionSession();
 
@@ -69,11 +69,16 @@ public interface InteractionFactory {
      * @return whether the calling thread is within the context of an open IsisTransactionSession
      */
     boolean isInTransaction();
-
     
     /**
-     * Executes a piece of code in a new (possibly nested) IsisInteraction.
-     *
+     * Executes a block of code with a new or reused {@link InteractionSession} using a new or 
+     * reused {@link AuthenticationLayer}.
+     * <p>
+     * If there is currently no {@link InteractionSession} a new one is created.
+     * <p>
+     * If there is currently an {@link AuthenticationLayer} that has an equal {@link Authentication}
+     * to the given one, it is reused, otherwise a new one is created.
+     * 
      * @param authentication - the user details to run under (non-null)
      * @param callable - the piece of code to run (non-null)
      * 
@@ -85,14 +90,15 @@ public interface InteractionFactory {
      * @param authentication - the user details to run under (non-null)
      * @param runnable (non-null)
      */
-    default void runAuthenticated(@NonNull Authentication authentication, @NonNull ThrowingRunnable runnable) {
-        callAuthenticated(authentication, ThrowingRunnable.toCallable(runnable));
-    }
+    void runAuthenticated(@NonNull Authentication authentication, @NonNull ThrowingRunnable runnable);
 
     /**
-     * Executes a piece of code in a (possibly reused) {@link InteractionSession}.
-     * If there is already an open session stacked on the current thread then that one is used, 
-     * otherwise an anonymous session is created.
+     * Executes a block of code with a new or reused {@link InteractionSession} using a new or 
+     * reused {@link AuthenticationLayer}.
+     * <p>
+     * If there is currently no {@link InteractionSession} a new one is created and a new 
+     * anonymous {@link AuthenticationLayer} is returned. Otherwise both, session and layer are reused.
+     * 
      * @param <R>
      * @param callable (non-null)
      */
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/session/InitialisationSession.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/session/AnonymousSession.java
similarity index 92%
rename from core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/session/InitialisationSession.java
rename to core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/session/AnonymousSession.java
index 0063d77..35338cd 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/session/InitialisationSession.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/session/AnonymousSession.java
@@ -22,14 +22,14 @@ import org.apache.isis.applib.services.iactn.ExecutionContext;
 import org.apache.isis.applib.services.user.UserMemento;
 import org.apache.isis.core.security.authentication.AuthenticationAbstract;
 
-final class InitialisationSession extends AuthenticationAbstract {
+final class AnonymousSession extends AuthenticationAbstract {
 
     private static final long serialVersionUID = 1L;
 
     private static final ExecutionContext INITIALISATION_CONTEXT = 
             ExecutionContext.ofUserWithSystemDefaults(UserMemento.system());
 
-    public InitialisationSession() {
+    public AnonymousSession() {
         super(INITIALISATION_CONTEXT, AuthenticationAbstract.DEFAULT_AUTH_VALID_CODE);
     }
     
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/session/InteractionFactoryDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/session/InteractionFactoryDefault.java
index 9309d98..dd7b3d8 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/session/InteractionFactoryDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/session/InteractionFactoryDefault.java
@@ -21,6 +21,7 @@ package org.apache.isis.core.runtimeservices.session;
 
 import java.io.File;
 import java.sql.Timestamp;
+import java.util.Objects;
 import java.util.Optional;
 import java.util.Stack;
 import java.util.UUID;
@@ -149,13 +150,28 @@ implements InteractionFactory, InteractionTracker {
     
     @Override
     public AuthenticationLayer openInteraction() {
-        return openInteraction(new InitialisationSession());
+        return currentAuthenticationLayer()
+                // or else create an anonymous authentication layer
+                .orElseGet(()->openInteraction(new AnonymousSession())); 
     }
     
     @Override
     public AuthenticationLayer openInteraction(final @NonNull Authentication authToUse) {
 
         val interactionSession = getOrCreateInteractionSession();
+        
+        // check whether we should reuse any current authenticationLayer, 
+        // that is, if current authentication and authToUse are equal
+        
+        val reuseCurrentLayer = currentAuthentication()
+                .map(currentAuthentication->Objects.equals(currentAuthentication, authToUse))
+                .orElse(false);
+        
+        if(reuseCurrentLayer) {
+            // we are done, just return the stack's top
+            return authenticationStack.get().peek();
+        }
+        
         val authenticationLayer = new AuthenticationLayer(interactionSession, authToUse);
         
         authenticationStack.get().push(authenticationLayer);
@@ -188,13 +204,15 @@ implements InteractionFactory, InteractionTracker {
                 authenticationStack.get().size(),
                 _Probe.currentThreadId());
 
-        closeInteractionStackDownToStackSize(0);
+        closeSessionStackDownToStackSize(0);
     }
 
 	@Override
     public Optional<AuthenticationLayer> currentAuthenticationLayer() {
     	val stack = authenticationStack.get();
-    	return stack.isEmpty() ? Optional.empty() : Optional.of(stack.lastElement());
+    	return stack.isEmpty() 
+    	        ? Optional.empty() 
+                : Optional.of(stack.lastElement());
     }
 
     @Override
@@ -217,6 +235,8 @@ implements InteractionFactory, InteractionTracker {
 
     }
 
+    // -- AUTHENTICATED EXECUTION
+    
     @Override
     @SneakyThrows
     public <R> R callAuthenticated(
@@ -230,18 +250,38 @@ implements InteractionFactory, InteractionTracker {
             serviceInjector.injectServicesInto(callable);
             return callable.call();
         } finally {
-            closeInteractionStackDownToStackSize(stackSizeWhenEntering);
+            closeSessionStackDownToStackSize(stackSizeWhenEntering);
+        }
+
+    }
+    
+    @Override
+    @SneakyThrows
+    public void runAuthenticated(
+            @NonNull final Authentication authentication, 
+            @NonNull final ThrowingRunnable runnable) {
+        
+        final int stackSizeWhenEntering = authenticationStack.get().size();
+        openInteraction(authentication);
+        
+        try {
+            serviceInjector.injectServicesInto(runnable);
+            runnable.run();
+        } finally {
+            closeSessionStackDownToStackSize(stackSizeWhenEntering);
         }
 
     }
 
+    // -- ANONYMOUS EXECUTION
+    
     @SneakyThrows
-    public <R> R callAnonymous(Callable<R> callable) {
+    public <R> R callAnonymous(@NonNull final Callable<R> callable) {
         if(isInInteractionSession()) {
             serviceInjector.injectServicesInto(callable);
             return callable.call(); // reuse existing session
         }
-        return callAuthenticated(new InitialisationSession(), callable);
+        return callAuthenticated(new AnonymousSession(), callable);
     }
 
     /**
@@ -249,15 +289,17 @@ implements InteractionFactory, InteractionTracker {
      * @param runnable
      */
     @SneakyThrows
-    public void runAnonymous(ThrowingRunnable runnable) {
+    public void runAnonymous(@NonNull final ThrowingRunnable runnable) {
         if(isInInteractionSession()) {
             serviceInjector.injectServicesInto(runnable);
             runnable.run(); // reuse existing session
             return;
         }
-        runAuthenticated(new InitialisationSession(), runnable);
+        runAuthenticated(new AnonymousSession(), runnable);
     }
 
+    // -- CONVERSATION ID
+    
     private final ThreadLocal<UUID> conversationId = ThreadLocal.withInitial(()->null);
     
     @Override
@@ -272,19 +314,19 @@ implements InteractionFactory, InteractionTracker {
     	return authenticationStack.get().size()==1; 
     }
     
-    private void postSessionOpened(InteractionSession newIsisInteraction) {
+    private void postSessionOpened(InteractionSession session) {
         conversationId.set(UUID.randomUUID());
-        runtimeEventService.fireInteractionHasStarted(newIsisInteraction); // only fire on top-level session
+        runtimeEventService.fireInteractionHasStarted(session); // only fire on top-level session
     }
     
-    private void preSessionClosed(InteractionSession isisInteraction) {
+    private void preSessionClosed(InteractionSession session) {
         completeAndPublishCurrentCommand();
-        runtimeEventService.fireInteractionIsEnding(isisInteraction); // only fire on top-level session 
+        runtimeEventService.fireInteractionIsEnding(session); // only fire on top-level session 
         isisInteractionScopeCloseListener.preTopLevelIsisInteractionClose(); // cleanup the isis-session scope
-        isisInteraction.close(); // do this last
+        session.close(); // do this last
     }
     
-    private void closeInteractionStackDownToStackSize(int downToStackSize) {
+    private void closeSessionStackDownToStackSize(int downToStackSize) {
         
         log.debug("about to close IsisInteraction stack down to size {} (conversation-id={}, total-sessions-on-stack={}, {})",
                 downToStackSize,