= InteractionService
:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR  CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

A low-level service to programmatically "connect" (or create a session, or interact with; choose your term) the framework's runtime.

This service is used internally by the framework itself, for example when a viewer receives a request a new xref:refguide:applib:index/services/iactnlayer/InteractionLayer.adoc[InteractionLayer] is created for the duration of the users's interaction. It is also used by integration tests, to be able to connect to the database.

You could think of this as analogous to an `HttpRequest` , or a JPA `EntityManager` or JDO `PersistenceManager` .

There are two main APIs exposed. One is to _#openInteraction(InteractionContext) open_ a new xref:refguide:applib:index/services/iactnlayer/InteractionLayer.adoc[InteractionLayer] , to be _#closeInteractionLayers() closed later_ . The other is to execute a _Callable_ or xref:refguide:commons:index/functional/ThrowingRunnable.adoc[ThrowingRunnable] within the duration of an xref:refguide:applib:index/services/iactnlayer/InteractionLayer.adoc[InteractionLayer] , wrapping up automatically. This is what is used by _org.apache.causeway.applib.services.sudo.SudoService_ , for example.

== API

[source,java]
.InteractionService.java
----
interface InteractionService {
  InteractionLayer openInteraction()     // <.>
  InteractionLayer openInteraction(InteractionContext interactionContext)     // <.>
  void closeInteractionLayers()     // <.>
  boolean isInInteraction()     // <.>
  R call(InteractionContext interactionContext, Callable<R> callable)     // <.>
  void run(InteractionContext interactionContext, ThrowingRunnable runnable)     // <.>
  R callAnonymous(Callable<R> callable)     // <.>
  void runAnonymous(ThrowingRunnable runnable)     // <.>
  Try<R> callAndCatch(InteractionContext interactionContext, Callable<R> callable)     // <.>
  Try<Void> runAndCatch(InteractionContext interactionContext, ThrowingRunnable runnable)     // <.>
  Try<R> callAnonymousAndCatch(Callable<R> callable)     // <.>
  Try<Void> runAnonymousAndCatch(ThrowingRunnable runnable)     // <.>
  InteractionLayer nextInteraction()     // <.>
  InteractionLayer nextInteraction(InteractionContext interactionContext)     // <.>
}
----

<.> xref:#openInteraction_[openInteraction()]
+
--
If present, reuses the current top level xref:refguide:applib:index/services/iactnlayer/InteractionLayer.adoc[InteractionLayer] , otherwise creates a new anonymous one.
--
<.> xref:#openInteraction_InteractionContext[openInteraction(InteractionContext)]
+
--
Returns a new or reused xref:refguide:applib:index/services/iactnlayer/InteractionLayer.adoc[InteractionLayer] that is a holder of the xref:refguide:applib:index/services/iactnlayer/InteractionContext.adoc[InteractionContext] on top of the current thread's interaction layer stack.
--
<.> xref:#closeInteractionLayers_[closeInteractionLayers()]
+
--
closes all open xref:refguide:applib:index/services/iactnlayer/InteractionLayer.adoc[InteractionLayer] (s) as stacked on the current thread
--
<.> xref:#isInInteraction_[isInInteraction()]
<.> xref:#call_InteractionContext_Callable[call(InteractionContext, Callable)]
+
--
Executes a block of code with a new or reused xref:refguide:applib:index/services/iactnlayer/InteractionContext.adoc[InteractionContext] using a new or reused xref:refguide:applib:index/services/iactnlayer/InteractionLayer.adoc[InteractionLayer] .
--
<.> xref:#run_InteractionContext_ThrowingRunnable[run(InteractionContext, ThrowingRunnable)]
+
--
Variant of _#call(InteractionContext, Callable)_ that takes a runnable.
--
<.> xref:#callAnonymous_Callable[callAnonymous(Callable)]
+
--
As per _#call(InteractionContext, Callable)_ , but (normally) using an anonymous xref:refguide:applib:index/services/iactnlayer/InteractionContext.adoc[InteractionContext] .
--
<.> xref:#runAnonymous_ThrowingRunnable[runAnonymous(ThrowingRunnable)]
+
--
As per _#run(InteractionContext, ThrowingRunnable)_ , but (normally) using an anonymous xref:refguide:applib:index/services/iactnlayer/InteractionContext.adoc[InteractionContext] .
--
<.> xref:#callAndCatch_InteractionContext_Callable[callAndCatch(InteractionContext, Callable)]
+
--
Variant of _#call(InteractionContext, Callable)_ that wraps the return value with a xref:refguide:commons:index/functional/Try.adoc[Try] , also catching any exception, that might have occurred.
--
<.> xref:#runAndCatch_InteractionContext_ThrowingRunnable[runAndCatch(InteractionContext, ThrowingRunnable)]
+
--
Variant of _#run(InteractionContext, ThrowingRunnable)_ that returns a xref:refguide:commons:index/functional/Try.adoc[Try] of _Result_ , also catching any exception, that might have occurred.
--
<.> xref:#callAnonymousAndCatch_Callable[callAnonymousAndCatch(Callable)]
+
--
Variant of _#callAnonymous(Callable)_ that wraps the return value with a xref:refguide:commons:index/functional/Try.adoc[Try] , also catching any exception, that might have occurred.
--
<.> xref:#runAnonymousAndCatch_ThrowingRunnable[runAnonymousAndCatch(ThrowingRunnable)]
+
--
Variant of _#runAnonymous(ThrowingRunnable)_ that returns a xref:refguide:commons:index/functional/Try.adoc[Try] of _Try_ , also catching any exception, that might have occurred.
--
<.> xref:#nextInteraction_[nextInteraction()]
+
--
Primarily for testing, closes the current interaction and opens a new one.
--
<.> xref:#nextInteraction_InteractionContext[nextInteraction(InteractionContext)]
+
--
Primarily for testing, closes the current interaction and opens a new one with the specified xref:refguide:applib:index/services/iactnlayer/InteractionContext.adoc[InteractionContext] .
--

== Members

[#openInteraction_]
=== openInteraction()

If present, reuses the current top level xref:refguide:applib:index/services/iactnlayer/InteractionLayer.adoc[InteractionLayer] , otherwise creates a new anonymous one.

[#openInteraction_InteractionContext]
=== openInteraction(InteractionContext)

Returns a new or reused xref:refguide:applib:index/services/iactnlayer/InteractionLayer.adoc[InteractionLayer] that is a holder of the xref:refguide:applib:index/services/iactnlayer/InteractionContext.adoc[InteractionContext] on top of the current thread's interaction layer stack.

If available reuses an existing xref:refguide:applib:index/services/iactnlayer/InteractionContext.adoc[InteractionContext] , otherwise creates a new one.

The xref:refguide:applib:index/services/iactnlayer/InteractionLayer.adoc[InteractionLayer] represents a user's span of activities interacting with the application. These can be stacked (usually temporarily), for example for a sudo session or to mock the clock. The stack is later closed using _#closeInteractionLayers()_ .

[#closeInteractionLayers_]
=== closeInteractionLayers()

closes all open xref:refguide:applib:index/services/iactnlayer/InteractionLayer.adoc[InteractionLayer] (s) as stacked on the current thread

[#isInInteraction_]
=== isInInteraction()

[#call_InteractionContext_Callable]
=== call(InteractionContext, Callable)

Executes a block of code with a new or reused xref:refguide:applib:index/services/iactnlayer/InteractionContext.adoc[InteractionContext] using a new or reused xref:refguide:applib:index/services/iactnlayer/InteractionLayer.adoc[InteractionLayer] .

If there is currently no xref:refguide:applib:index/services/iactnlayer/InteractionLayer.adoc[InteractionLayer] a new one is created.

If there is currently an xref:refguide:applib:index/services/iactnlayer/InteractionLayer.adoc[InteractionLayer] that has an equal xref:refguide:applib:index/services/iactnlayer/InteractionContext.adoc[InteractionContext] to the given one, it is reused, otherwise a new one is created.

[#run_InteractionContext_ThrowingRunnable]
=== run(InteractionContext, ThrowingRunnable)

Variant of _#call(InteractionContext, Callable)_ that takes a runnable.

[#callAnonymous_Callable]
=== callAnonymous(Callable)

As per _#call(InteractionContext, Callable)_ , but (normally) using an anonymous xref:refguide:applib:index/services/iactnlayer/InteractionContext.adoc[InteractionContext] .

However, if an _#isInInteraction() interaction (session)_ already exists (with possibly some other non-anonymous xref:refguide:applib:index/services/iactnlayer/InteractionContext.adoc[InteractionContext] ), then this is used instead.

[#runAnonymous_ThrowingRunnable]
=== runAnonymous(ThrowingRunnable)

As per _#run(InteractionContext, ThrowingRunnable)_ , but (normally) using an anonymous xref:refguide:applib:index/services/iactnlayer/InteractionContext.adoc[InteractionContext] .

However, if an _#isInInteraction() interaction (session)_ already exists (with possibly some other non-anonymous xref:refguide:applib:index/services/iactnlayer/InteractionContext.adoc[InteractionContext] ), then this is used instead.

[#callAndCatch_InteractionContext_Callable]
=== callAndCatch(InteractionContext, Callable)

Variant of _#call(InteractionContext, Callable)_ that wraps the return value with a xref:refguide:commons:index/functional/Try.adoc[Try] , also catching any exception, that might have occurred.

[#runAndCatch_InteractionContext_ThrowingRunnable]
=== runAndCatch(InteractionContext, ThrowingRunnable)

Variant of _#run(InteractionContext, ThrowingRunnable)_ that returns a xref:refguide:commons:index/functional/Try.adoc[Try] of _Result_ , also catching any exception, that might have occurred.

[#callAnonymousAndCatch_Callable]
=== callAnonymousAndCatch(Callable)

Variant of _#callAnonymous(Callable)_ that wraps the return value with a xref:refguide:commons:index/functional/Try.adoc[Try] , also catching any exception, that might have occurred.

[#runAnonymousAndCatch_ThrowingRunnable]
=== runAnonymousAndCatch(ThrowingRunnable)

Variant of _#runAnonymous(ThrowingRunnable)_ that returns a xref:refguide:commons:index/functional/Try.adoc[Try] of _Try_ , also catching any exception, that might have occurred.

[#nextInteraction_]
=== nextInteraction()

Primarily for testing, closes the current interaction and opens a new one.

In tests, this is a good way to simulate multiple interactions within a scenario. If you use the popular given/when/then structure, consider using at the end of each "given" or "when" block.

[#nextInteraction_InteractionContext]
=== nextInteraction(InteractionContext)

Primarily for testing, closes the current interaction and opens a new one with the specified xref:refguide:applib:index/services/iactnlayer/InteractionContext.adoc[InteractionContext] .

include::hooks/InteractionService_010-implementation.adoc[]
