Class BaseBoxContext

java.lang.Object
ortus.boxlang.runtime.context.BaseBoxContext
All Implemented Interfaces:
Serializable, IBoxContext, IBoxAttachable
Direct Known Subclasses:
ApplicationBoxContext, ClassBoxContext, ContainerBoxContext, CustomTagBoxContext, FunctionBoxContext, InterfaceBoxContext, ParentPassthroughBoxContext, RequestBoxContext, RuntimeBoxContext, SessionBoxContext, StaticClassBoxContext, ThreadBoxContext

public class BaseBoxContext extends Object implements IBoxContext
This context represents the context of ANYTHING that can execute in BoxLang
See Also:
  • Field Details

    • nullIsUndefined

      public static boolean nullIsUndefined
      A flag to control whether null is considered undefined or not. Used by the compat module
    • parent

      protected IBoxContext parent
      Any context can have a parent it can delegate to
    • templates

      protected ArrayDeque<ResolvedFilePath> templates
      A way to discover the current executing template. We're storing the path directly instead of the ITemplateRunnable instance to avoid memory leaks by keepin Box Classes in memory since all we really need is static data from them
    • currentImports

      protected List<ImportDefinition> currentImports
      A way to discover the imports tied to the original source of the current template. This should always match the top current template stack
    • components

      protected ArrayDeque<IStruct> components
      A way to discover the current executing componenet
    • queryLoops

      protected LinkedHashMap<Query,Integer> queryLoops
      A way to track query loops
    • buffers

      protected ArrayDeque<StringBuffer> buffers
      A buffer to write output to
  • Constructor Details

    • BaseBoxContext

      public BaseBoxContext(IBoxContext parent)
      Creates a new execution context with a bounded execution template and parent context
      Parameters:
      parent - The parent context
    • BaseBoxContext

      public BaseBoxContext()
      Creates a new execution context with no execution template
  • Method Details

    • getLogger

      public BoxLangLogger getLogger()
      Get the context logger
    • pushTemplate

      public IBoxContext pushTemplate(IBoxRunnable template)
      Push a template to the stack
      Specified by:
      pushTemplate in interface IBoxContext
      Parameters:
      template - The template that this execution context is bound to
      Returns:
      IBoxContext
    • pushTemplate

      public IBoxContext pushTemplate(ResolvedFilePath template)
      Push a template to the stack
      Specified by:
      pushTemplate in interface IBoxContext
      Parameters:
      template - The template that this execution context is bound to
      Returns:
      IBoxContext
    • popTemplate

      public ResolvedFilePath popTemplate()
      Pop a template from the stack
      Specified by:
      popTemplate in interface IBoxContext
      Returns:
      The template that this execution context is bound to
    • getTemplates

      public ResolvedFilePath[] getTemplates()
      Get templates
      Specified by:
      getTemplates in interface IBoxContext
      Returns:
      The templates
    • pushComponent

      public IBoxContext pushComponent(IStruct executionState)
      Push a Component to the stack
      Specified by:
      pushComponent in interface IBoxContext
      Parameters:
      executionState - The state for this component execution
      Returns:
      This context
    • popComponent

      public IBoxContext popComponent()
      Pop a template from the stack
      Specified by:
      popComponent in interface IBoxContext
      Returns:
      This context
    • isInOutputComponent

      public boolean isInOutputComponent()
      Is there at least one output component on the stack
      Specified by:
      isInOutputComponent in interface IBoxContext
      Returns:
      True if there is at least one output component, else false
    • findClosestComponent

      public IStruct findClosestComponent(Key name, int offset)
      Gets the execution state for the closest component.
      Specified by:
      findClosestComponent in interface IBoxContext
      Returns:
      The execution state for the closest component, null if none was found
    • findClosestComponent

      public IStruct findClosestComponent(Key name)
      Gets the execution state for the closest component.
      Specified by:
      findClosestComponent in interface IBoxContext
      Returns:
      The execution state for the closest component, null if none was found
    • findClosestComponent

      public IStruct findClosestComponent(Key name, int offset, Predicate<IStruct> predicate)
      Gets the execution state for the closest component with a predicate to filter.
      Specified by:
      findClosestComponent in interface IBoxContext
      Returns:
      The execution state for the closest component, null if none was found
    • findClosestComponent

      public IStruct findClosestComponent(Key name, Predicate<IStruct> predicate)
      Gets the execution state for the closest component with a predicate to filter.
      Specified by:
      findClosestComponent in interface IBoxContext
      Returns:
      The execution state for the closest component, null if none was found
    • getComponents

      public IStruct[] getComponents()
      Get the stack of components as an array
      Specified by:
      getComponents in interface IBoxContext
      Returns:
      This context
    • hasTemplates

      public boolean hasTemplates()
      Has the execution context been bound to a template?
      Specified by:
      hasTemplates in interface IBoxContext
      Returns:
      True if bound, else false
    • findClosestTemplate

      public ResolvedFilePath findClosestTemplate()
      Finds the closest template
      Specified by:
      findClosestTemplate in interface IBoxContext
      Returns:
      The template instance if found, null if this code is not called from a template
    • findBaseTemplate

      public ResolvedFilePath findBaseTemplate()
      Finds the base (first) template in this request
      Specified by:
      findBaseTemplate in interface IBoxContext
      Returns:
      The template instance if found, null if this code is not called from a template
    • rethrow

      public void rethrow()
      rethrows the closest exception
      Specified by:
      rethrow in interface IBoxContext
    • getParent

      public IBoxContext getParent()
      Returns the parent box context. Null if none.
      Specified by:
      getParent in interface IBoxContext
      Returns:
      The parent box context. Null if none.
    • setParent

      public IBoxContext setParent(IBoxContext parentContext)
      Sets the parent box context.
      Specified by:
      setParent in interface IBoxContext
      Parameters:
      parentContext - The parent context to set
      Returns:
      This context
    • injectParentContext

      public IBoxContext injectParentContext(IBoxContext parentContext)
      Inject a parent context, moving the current parent to the grandparent Any existing parent in the passed context will be overwritten with the current parent
      Specified by:
      injectParentContext in interface IBoxContext
      Parameters:
      parentContext - The parent context to inject
      Returns:
      This context
    • injectTopParentContext

      public IBoxContext injectTopParentContext(IBoxContext parentContext)
      Inject a top parent context above the request-type context, moving the request context's current parent to its grandparent
      Specified by:
      injectTopParentContext in interface IBoxContext
      Parameters:
      parentContext - The parent context to inject
      Returns:
      This context
    • removeParentContext

      public IBoxContext removeParentContext(Class<? extends IBoxContext> type)
      Remove ancestor contexts of this type
      Specified by:
      removeParentContext in interface IBoxContext
      Parameters:
      type - The type of context to remove
      Returns:
      This context
    • hasParent

      public Boolean hasParent()
      Verifies if a parent context is attached to this context
      Specified by:
      hasParent in interface IBoxContext
      Returns:
      True if a parent context is attached to this context, else false
    • invokeFunction

      public Object invokeFunction(Key name, Object[] positionalArguments)
      Invoke a function call such as foo() using positional args. Will check for a registered BIF first, then search known scopes for a UDF.
      Specified by:
      invokeFunction in interface IBoxContext
      Returns:
      Return value of the function call
    • invokeFunction

      public Object invokeFunction(Key name, Map<Key,Object> namedArguments)
      Invoke a function call such as foo() using named args. Will check for a registered BIF first, then search known scopes for a UDF.
      Specified by:
      invokeFunction in interface IBoxContext
      Returns:
      Return value of the function call
    • invokeFunction

      public Object invokeFunction(Key name)
      Invoke a function call such as foo() using no args.
      Specified by:
      invokeFunction in interface IBoxContext
      Returns:
      Return value of the function call
    • invokeComponent

      public Component.BodyResult invokeComponent(Key name, IStruct attributes, Component.ComponentBody componentBody)
      Invoke a component call
      Specified by:
      invokeComponent in interface IBoxContext
      Parameters:
      name - The name of the component to invoke
      attributes - The attributes to pass to the component
      componentBody - The body of the component
    • invokeFunction

      public Object invokeFunction(Object function, Object[] positionalArguments)
      Invoke a function expression such as (()=>{})() using positional args. This method will validate the incoming object is a function type.
      Specified by:
      invokeFunction in interface IBoxContext
      Returns:
      Return value of the function call
    • findBIF

      protected BIFDescriptor findBIF(Key name)
      Find out if the given function name is a BIF in the Function Service
      Parameters:
      name - The name of the function to find
      Returns:
      The BIFDescriptor if found, else null
    • invokeFunction

      public Object invokeFunction(Object function, Map<Key,Object> namedArguments)
      Invoke a function expression such as (()=>{})() using named args. This method will validate the incoming object is a function type.
      Specified by:
      invokeFunction in interface IBoxContext
      Returns:
      Return value of the function call
    • invokeFunction

      public Object invokeFunction(Object function)
      Invoke a function expression such as (()=>{})() using no args. This method will validate the incoming object is a function type.
      Specified by:
      invokeFunction in interface IBoxContext
      Returns:
      Return value of the function call
    • invokeFunction

      public Object invokeFunction(Function function, Key calledName, Object[] positionalArguments)
      Invoke a function expression such as (()=>{})() using named args.
      Returns:
      Return value of the function call
    • invokeFunction

      public Object invokeFunction(Function function, Key calledName, Map<Key,Object> namedArguments)
      Invoke a function expression such as (()=>{})() using named args.
      Returns:
      Return value of the function call
    • findFunction

      protected Function findFunction(Key name)
      Find a function in the corrent context. Will search known scopes for a UDF.
      Parameters:
      name - The name of the function to find
      Returns:
      The function instance
    • includeTemplate

      public void includeTemplate(String templatePath)
      Invoke a template in the current context
      Specified by:
      includeTemplate in interface IBoxContext
      Parameters:
      templatePath - A relateive template path
    • getVisibleScopes

      public IStruct getVisibleScopes()
      This is mostly for the debugger. It returns all visible scopes from this context.
      Specified by:
      getVisibleScopes in interface IBoxContext
      Returns:
      A struct containing all contextual and lexically visible scopes
    • getVisibleScopes

      public IStruct getVisibleScopes(IStruct scopes, boolean nearby, boolean shallow)
      This is mostly for the debugger. It returns all visible scopes from this context.
      Specified by:
      getVisibleScopes in interface IBoxContext
      Returns:
      A struct containing all contextual and lexically visible scopes
    • isKeyVisibleScope

      public boolean isKeyVisibleScope(Key key)
      Check if a key is visible in the current context as a scope name. This allows us to "reserve" known scope names to ensure arguments.foo will always look in the proper arguments scope and never in local.arguments.foo for example
      Specified by:
      isKeyVisibleScope in interface IBoxContext
      Parameters:
      key - The key to check for visibility
      Returns:
      True if the key is visible in the current context, else false
    • isKeyVisibleScope

      public boolean isKeyVisibleScope(Key key, boolean nearby, boolean shallow)
      Check if a key is visible in the current context as a scope name. This allows us to "reserve" known scope names to ensure arguments.foo will always look in the proper arguments scope and never in local.arguments.foo for example
      Specified by:
      isKeyVisibleScope in interface IBoxContext
      Parameters:
      key - The key to check for visibility
      nearby - true, check only scopes that are nearby to the current execution context
      shallow - true, do not delegate to parent or default scope if not found
      Returns:
      True if the key is visible in the current context, else false
    • getScope

      public IScope getScope(Key name) throws ScopeNotFoundException
      Get a scope from the context. If not found, the parent context is asked. Don't search for scopes which are nearby to an execution context
      Specified by:
      getScope in interface IBoxContext
      Parameters:
      name - The name of the scope to get
      Returns:
      The requested scope
      Throws:
      ScopeNotFoundException - If the scope was not found in any context
    • getScopeNearby

      public IScope getScopeNearby(Key name, boolean shallow) throws ScopeNotFoundException
      Get a scope from the context. If not found, the parent context is asked. Search all known scopes
      Specified by:
      getScopeNearby in interface IBoxContext
      Parameters:
      name - The name of the scope to get
      shallow - true, do not delegate to parent or default scope if not found
      Returns:
      The requested scope
      Throws:
      ScopeNotFoundException - If the scope was not found in any context
    • scopeFind

      public IBoxContext.ScopeSearchResult scopeFind(Key key, IScope defaultScope, boolean forAssign)
      Try to get the requested key from an unknown scope Meaning it needs to search scopes in order according to it's context. Unlike scopeFindNearby(), this version only searches trancedent scopes like cgi or server which are never encapsulated like variables is inside a class. If defaultScope is null and the key can't be found, a KeyNotFoundException will be thrown If defaultScope is not null, it will return a record with the default scope and null value if the key is not found
      Specified by:
      scopeFind in interface IBoxContext
      Parameters:
      key - The key to search for
      defaultScope - The default scope to return if the key is not found
      forAssign - true, this is for an assignment operation
      Returns:
      The value of the key if found
    • scopeFindNearby

      public IBoxContext.ScopeSearchResult scopeFindNearby(Key key, IScope defaultScope, boolean shallow, boolean forAssign)
      Try to get the requested key from an unknown scope Meaning it needs to search scopes in order according to it's context. A nearby lookup is used for the closest context to the executing code If defaultScope is null and the key can't be found, a KeyNotFoundException will be thrown If defaultScope is not null, it will return a record with the default scope and null value if the key is not found
      Specified by:
      scopeFindNearby in interface IBoxContext
      Parameters:
      key - The key to search for
      defaultScope - The default scope to return if the key is not found
      shallow - true, do not delegate to parent or default scope if not found
      forAssign - true, this is for an assignment operation
      Returns:
      The value of the key if found
    • isDefined

      public boolean isDefined(Object value, boolean forAssign)
      Decide if a value found in a scope is defined or not
      Specified by:
      isDefined in interface IBoxContext
      Parameters:
      value - The value to check, possibly null, possibly an instance of NullValue
      Returns:
      True if the value is defined, else false
    • queryFindNearby

      protected IBoxContext.ScopeSearchResult queryFindNearby(Key key)
      Search any query loops for a column name matching the uncscoped variable
      Parameters:
      key - The key to search for
      Returns:
      A ScopeSearchResult if found, else null
    • registerUDF

      public void registerUDF(UDF udf)
      Register a UDF with the local context. Will override any existing methods
      Specified by:
      registerUDF in interface IBoxContext
      Parameters:
      udf - The UDF to register
    • registerUDF

      public void registerUDF(UDF udf, boolean override)
      Register a UDF with the local context choosing to override.
      Specified by:
      registerUDF in interface IBoxContext
      Parameters:
      udf - The UDF to register
      override - true, override any existing UDF with the same name
    • getDefaultAssignmentScope

      public IScope getDefaultAssignmentScope()
      Get the default variable assignment scope for this context
      Specified by:
      getDefaultAssignmentScope in interface IBoxContext
      Returns:
      The scope reference to use
    • findClosestFunctionName

      public Key findClosestFunctionName()
      Finds the closest function call name
      Specified by:
      findClosestFunctionName in interface IBoxContext
      Returns:
      The called name of the function if found, null if this code is not called from a function
    • getFunctionParentContext

      public IBoxContext getFunctionParentContext()
      Get parent context for a function execution happening in this context
      Specified by:
      getFunctionParentContext in interface IBoxContext
      Returns:
      The context to use
    • getFunctionClass

      public IClassRunnable getFunctionClass()
      Get the class, if any, for a function invocation
      Specified by:
      getFunctionClass in interface IBoxContext
      Returns:
      The class to use, or null if none
    • getFunctionStaticClass

      public DynamicObject getFunctionStaticClass()
      Get the class, if any, for a function invocation
      Specified by:
      getFunctionStaticClass in interface IBoxContext
      Returns:
      The class to use, or null if none
    • getFunctionInterface

      public BoxInterface getFunctionInterface()
      Get the interface, if any, for a function invocation
      Specified by:
      getFunctionInterface in interface IBoxContext
      Returns:
      The interface to use, or null if none
    • scopeFindNearby

      public IBoxContext.ScopeSearchResult scopeFindNearby(Key key, IScope defaultScope, boolean forAssign)
      Try to get the requested key from an unkonwn scope but overriding the parent to check if not found
      Specified by:
      scopeFindNearby in interface IBoxContext
      Parameters:
      key - The key to search for
      defaultScope - The default scope to return if the key is not found
      forAssign - true, this is for an assignment operation
      Returns:
      The value of the key if found
    • getScopeNearby

      public IScope getScopeNearby(Key name) throws ScopeNotFoundException
      Get a scope from the context. If not found, the parent context is asked. Search all known scopes
      Specified by:
      getScopeNearby in interface IBoxContext
      Parameters:
      name - The name of the scope to get
      Returns:
      The requested scope
      Throws:
      ScopeNotFoundException - If the scope was not found in any context
    • getCurrentImports

      public List<ImportDefinition> getCurrentImports()
      Retrieve all known imports for the current template
      Specified by:
      getCurrentImports in interface IBoxContext
      Returns:
      List of import definitions
    • unwrapQueryColumn

      public Object unwrapQueryColumn(Object value)
      If input is a QueryColumn, unwrap it to the underlying value If input is not a QueryColumn, return it as-is
      Specified by:
      unwrapQueryColumn in interface IBoxContext
      Parameters:
      value - The value to unwrap
      Returns:
      The unwrapped value
    • getQueryRow

      public int getQueryRow(Query query)
      Get the current query row
      Specified by:
      getQueryRow in interface IBoxContext
      Parameters:
      query - The query to get the row from
      Returns:
      The current row
    • registerQueryLoop

      public void registerQueryLoop(Query query, int row)
      Register a query loop
      Specified by:
      registerQueryLoop in interface IBoxContext
      Parameters:
      query - The query to register
      row - The row to start at
    • unregisterQueryLoop

      public void unregisterQueryLoop(Query query)
      Unregister a query loop
      Specified by:
      unregisterQueryLoop in interface IBoxContext
      Parameters:
      query - The query to unregister
    • incrementQueryLoop

      public void incrementQueryLoop(Query query)
      Increment the query loop
      Specified by:
      incrementQueryLoop in interface IBoxContext
      Parameters:
      query - The query to increment
    • writeToBuffer

      public IBoxContext writeToBuffer(Object o, boolean force)
      Write output to this buffer. Any input object will be converted to a string If force is true, write even if the setting component has been used with enableOutputOnly=true
      Specified by:
      writeToBuffer in interface IBoxContext
      Parameters:
      o - The object to write
      force - true, write even if output is disabled
      Returns:
      This context
    • writeToBuffer

      public IBoxContext writeToBuffer(Object o)
      Write output to this buffer. Any input object will be converted to a string
      Specified by:
      writeToBuffer in interface IBoxContext
      Parameters:
      o - The object to write
      Returns:
      This context
    • canOutput

      public Boolean canOutput()
      Can the current context output to the response stream? Contexts tied to a specific object like a function or class may override this to return false based on their own logic.
      Specified by:
      canOutput in interface IBoxContext
    • flushBuffer

      public IBoxContext flushBuffer(boolean force)
      Flush the buffer to the output stream and then clears the local buffers
      Specified by:
      flushBuffer in interface IBoxContext
      Parameters:
      force - true, flush even if output is disabled
      Returns:
      This context
    • clearBuffer

      public IBoxContext clearBuffer()
      Clear the buffer
      Specified by:
      clearBuffer in interface IBoxContext
      Returns:
      This context
    • getBuffer

      public StringBuffer getBuffer()
      Get the buffer
      Specified by:
      getBuffer in interface IBoxContext
      Returns:
      The buffer
    • pushBuffer

      public IBoxContext pushBuffer(StringBuffer buffer)
      Push a buffer onto the stack. This is mostly so components can capture any output generated in their body
      Specified by:
      pushBuffer in interface IBoxContext
      Parameters:
      buffer - The buffer to push
      Returns:
      This context
    • popBuffer

      public IBoxContext popBuffer()
      Pop a buffer from the stack
      Specified by:
      popBuffer in interface IBoxContext
      Returns:
      This context
    • getConfig

      public IStruct getConfig()
      Get the contexual config struct. Each context has a chance to add in config of their own to the struct, or override existing config with a new struct of their own design. It depends on whether the context wants its changes to exist for the rest of the entire request or only for code that executes in the current context and below.
      Specified by:
      getConfig in interface IBoxContext
      Returns:
      A struct of configuration
    • clearConfigCache

      public void clearConfigCache()
      Contexts can optionallky cache their config. If so, they must override this method to clear the cache when requested, and propagate the request to their parent context
      Specified by:
      clearConfigCache in interface IBoxContext
    • getConfigItem

      public Object getConfigItem(Key itemKey)
      Convenience method to retrieve a single config item
      Specified by:
      getConfigItem in interface IBoxContext
      Parameters:
      itemKey - the object key to retrieve
      Returns:
      The object value of the key or null if not found
    • getConfigItems

      public Object getConfigItems(Key... itemKey)
      Convenience method to retrieve a config item(s). You can pass in multiple keys separated by commas. It will traverse the keys in order and return the last key requested..
       // Example:
       // config = { a: { b: { c: 1 } } }
       * // getConfigItems( a, b, c ) will return 1
       
      Specified by:
      getConfigItems in interface IBoxContext
      Parameters:
      itemKey - the object key(s)
      Returns:
      The object value of the key or null if not found
    • getConfigItem

      public Object getConfigItem(Key itemKey, Object defaultValue)
      Convenience method to retrieve a config item with with an optional default
      Specified by:
      getConfigItem in interface IBoxContext
      Parameters:
      itemKey - the object key
      defaultValue - a default value to return
      Returns:
      The object value of the key or the default value if not found
    • getRuntime

      public BoxRuntime getRuntime()
      Get the BoxLang runtime '
      Specified by:
      getRuntime in interface IBoxContext
      Returns:
      The runtime
    • getModuleSettings

      public IStruct getModuleSettings(Key name)
      Get a struct of module settings
      Specified by:
      getModuleSettings in interface IBoxContext
      Parameters:
      name - The name of the module
      Returns:
      The module settings struct
      Throws:
      BoxRuntimeException - If the module was not found
    • getModuleRecord

      public ModuleRecord getModuleRecord(Key name)
      Get a module record
      Specified by:
      getModuleRecord in interface IBoxContext
      Parameters:
      name - The name of the module
      Returns:
      The module record
      Throws:
      BoxRuntimeException - If the module was not found
    • getParentOfType

      public <T> T getParentOfType(Class<T> type)
      Serach for an ancestor context of the given type
      Specified by:
      getParentOfType in interface IBoxContext
      Type Parameters:
      T - The type of context to search for
      Returns:
      The matching parent context, or null if one is not found of this type.
    • getRequestContext

      public RequestBoxContext getRequestContext()
      Serach for an ancestor context of RequestBoxContext This is a convenience method for getParentOfType( RequestBoxContext.class ) since it is so common
      Specified by:
      getRequestContext in interface IBoxContext
      Returns:
      The matching parent RequestBoxContext, or null if one is not found of this type.
    • getApplicationContext

      public ApplicationBoxContext getApplicationContext()
      Serach for an ancestor context of ApplicationBoxContext This is a convenience method for getParentOfType( ApplicationBoxContext.class ) since it is so common
      Specified by:
      getApplicationContext in interface IBoxContext
      Returns:
      The matching parent ApplicationBoxContext, or null if one is not found of this type.
    • putAttachment

      public <T> T putAttachment(Key key, T value)
      -------------------------------------------------------------------------- Attachable Delegation --------------------------------------------------------------------------
      Specified by:
      putAttachment in interface IBoxAttachable
      Type Parameters:
      T - The type of the value to attach.
      Parameters:
      key - The key to attach the value to.
    • getAttachment

      public <T> T getAttachment(Key key)
      Description copied from interface: IBoxAttachable
      Get the attachment for the given key.
      Specified by:
      getAttachment in interface IBoxAttachable
      Parameters:
      key - The key to get the attachment for.
      Returns:
      The attachment for the given key, or null if there is none.
    • hasAttachment

      public boolean hasAttachment(Key key)
      Description copied from interface: IBoxAttachable
      Verify if an attachment is present for the given key.
      Specified by:
      hasAttachment in interface IBoxAttachable
      Parameters:
      key -
      Returns:
      true if an attachment is present for the given key, false otherwise.
    • removeAttachment

      public <T> T removeAttachment(Key key)
      Description copied from interface: IBoxAttachable
      Remove an attachment, returning its previous value.
      Specified by:
      removeAttachment in interface IBoxAttachable
      Parameters:
      key - The key to remove the attachment for.
      Returns:
      The previous value attached to the key, or null if there was none.
    • getAttachmentKeys

      public Key[] getAttachmentKeys()
      Description copied from interface: IBoxAttachable
      Get the keys of all attachments.
      Specified by:
      getAttachmentKeys in interface IBoxAttachable
    • computeAttachmentIfAbsent

      public <T> T computeAttachmentIfAbsent(Key key, Function<? super Key,? extends T> mappingFunction)
      Description copied from interface: IBoxAttachable
      Comput an attachment if it is not already present. If an attachment for this key was already set, return the original value.
      Specified by:
      computeAttachmentIfAbsent in interface IBoxAttachable
      Parameters:
      key - The key to attach the value to.
      mappingFunction - The function to compute the value to attach.