Class HookDecorator

java.lang.Object
com.launchdarkly.sdk.android.integrations.Hook
com.launchdarkly.sdk.android.integrations.HookDecorator
Direct Known Subclasses:
DedupingHook

public abstract class HookDecorator extends Hook
A hook that wraps another hook, forwarding every stage to it. A subclass adds behavior to a hook without changing it, and is registered in place of the hook it wraps.

Every stage forwards to the wrapped hook, so a subclass overrides only the stages it changes, and calls super to forward the ones it does. The stages it leaves alone still reach the wrapped hook.

An override that never calls super stops forwarding that stage, which for the identify and track stages is a decorator swallowing something it has no reason to: a DedupingHook inside such an override would stop being told to forget what it has reported, and would go on suppressing across an identify. Those three stages are CallSuper, so Android Lint reports an override of one that does not forward. The evaluation stages are not, because suppressing an evaluation series is what a decorator is for.


     public final class FlagFilteringHook extends HookDecorator {
         private final Set<String> flagKeys;

         public FlagFilteringHook(Hook delegate, Set<String> flagKeys) {
             super(delegate);
             this.flagKeys = flagKeys;
         }

         @Override
         public Map<String, Object> beforeEvaluation(EvaluationSeriesContext seriesContext,
                                                     Map<String, Object> seriesData) {
             return flagKeys.contains(seriesContext.flagKey)
                     ? super.beforeEvaluation(seriesContext, seriesData)
                     : seriesData;
         }
     }
 

That hook filters evaluations and still forwards identify and track, which it never mentions.

DedupingHook is the decorator the SDK ships: it forwards an evaluation series only when the flag's result is one its hook has not just been told about.

Decorators stack, so a hook may be wrapped in as many as it needs, each wrapping the one inside it:


     Components.hooks()
         .addHook(new DedupingHook(new FlagFilteringHook(new ObservabilityHook(), myFlagKeys)))
 

A decorator reports the wrapped hook's metadata as its own, so the SDK names the hook that a stage belongs to rather than the wrappers around it.

A decorator that suppresses a stage must suppress the whole evaluation series, because hooks pair their stages: an observability hook opens a span in Hook.beforeEvaluation(EvaluationSeriesContext, Map) and closes it in Hook.afterEvaluation(EvaluationSeriesContext, Map, EvaluationDetail), so suppressing only the after stage leaves that span open. To carry the decision from one stage to the other, return series data the after stage recognizes, the way DedupingHook does.

A decorator that does that belongs outermost, because the series data it returns replaces what it was given: a decorator outside it does not get back what it stored in its own before stage.

This class is not stable, and not subject to any backwards compatibility guarantees or semantic versioning. It is experimental.

  • Constructor Details

    • HookDecorator

      protected HookDecorator(Hook delegate)
      Wraps a hook, taking its name as this decorator's own.
      Parameters:
      delegate - the hook to forward each stage to
  • Method Details

    • getMetadata

      public HookMetadata getMetadata()
      Overrides:
      getMetadata in class Hook
      Returns:
      the wrapped hook's metadata, so that the SDK names the hook a stage belongs to
    • beforeEvaluation

      public Map<String,Object> beforeEvaluation(EvaluationSeriesContext seriesContext, Map<String,Object> seriesData)
      Forwards the stage to the wrapped hook.
      Overrides:
      beforeEvaluation in class Hook
      Parameters:
      seriesContext - container of parameters associated with this evaluation
      seriesData - immutable data from the previous stage in the evaluation series
      Returns:
      the wrapped hook's series data
    • afterEvaluation

      public Map<String,Object> afterEvaluation(EvaluationSeriesContext seriesContext, Map<String,Object> seriesData, EvaluationDetail<LDValue> evaluationDetail)
      Forwards the stage to the wrapped hook.
      Overrides:
      afterEvaluation in class Hook
      Parameters:
      seriesContext - container of parameters associated with this evaluation
      seriesData - data from the previous stage in the evaluation series
      evaluationDetail - the result of the evaluation
      Returns:
      the wrapped hook's series data
    • beforeIdentify

      @CallSuper public Map<String,Object> beforeIdentify(IdentifySeriesContext seriesContext, Map<String,Object> seriesData)
      Forwards the stage to the wrapped hook.
      Overrides:
      beforeIdentify in class Hook
      Parameters:
      seriesContext - container of parameters associated with this identify
      seriesData - immutable data from the previous stage in the identify series
      Returns:
      the wrapped hook's series data
    • afterIdentify

      @CallSuper public Map<String,Object> afterIdentify(IdentifySeriesContext seriesContext, Map<String,Object> seriesData, IdentifySeriesResult result)
      Forwards the stage to the wrapped hook.
      Overrides:
      afterIdentify in class Hook
      Parameters:
      seriesContext - container of parameters associated with this identify
      seriesData - data from the previous stage in the identify series
      result - the result of the identify operation
      Returns:
      the wrapped hook's series data
    • afterTrack

      @CallSuper public void afterTrack(TrackSeriesContext seriesContext)
      Forwards the stage to the wrapped hook.
      Overrides:
      afterTrack in class Hook
      Parameters:
      seriesContext - container of parameters associated with this track