Class DefaultEntityHelper

java.lang.Object
io.fluxzero.sdk.modeling.DefaultEntityHelper
All Implemented Interfaces:
EntityHelper

public class DefaultEntityHelper extends Object implements EntityHelper
The DefaultEntityHelper provides the default implementation of the EntityHelper interface.

It is responsible for orchestrating the behavior of domain model entities with respect to: - Intercepting messages using @InterceptApply handlers - Applying updates or events via @Apply handlers - Validating updates and asserting legal state transitions using @AssertLegal handlers

This helper is heavily used during message handling and event sourcing to delegate message processing and validation logic to methods annotated on the entity class or its nested members.

The class supports efficient handler resolution through memoized lookups, enabling fast, repeatable application of complex domain behaviors.

  • Constructor Details

    • DefaultEntityHelper

      public DefaultEntityHelper(List<ParameterResolver<? super DeserializingMessage>> parameterResolvers, boolean disablePayloadValidation)
      Creates a new helper using the given parameter resolvers and configuration.
      Parameters:
      parameterResolvers - Resolvers used to inject values into annotated handler methods
      disablePayloadValidation - If true, disables bean validation of payloads
    • DefaultEntityHelper

      public DefaultEntityHelper(List<ParameterResolver<? super DeserializingMessage>> parameterResolvers, boolean disablePayloadValidation, boolean assertCurrentDefault)
      Creates a helper with an application-resolved interceptor validation default.
  • Method Details

    • getRootAnnotation

      public static Aggregate getRootAnnotation(Class<?> type)
      Returns the cached or default @Aggregate annotation for a given type.
    • requireAggregateType

      public static void requireAggregateType(Class<?> type)
      Requires a persistent aggregate root type to declare or inherit Aggregate. An annotation on an enclosing class does not mark a nested type. Plain members and side-effect-free entity wrappers need no such marker.
      Throws:
      IllegalArgumentException - if the type has no aggregate marker
    • requireAggregateRoot

      public static void requireAggregateRoot(Entity<?> root)
      Validates a persistent aggregate root once its type is known. Only an empty, untyped root may temporarily use Object; its first non-null value must have an aggregate marker.
      Throws:
      IllegalArgumentException - if the root's known type has no aggregate marker
    • getRootConfiguration

      public static EntityMetadata.RootConfiguration getRootConfiguration(Class<?> type)
      Returns the shared persistence configuration for a model or aggregate root.

      Unannotated side-effect-free values retain the default configuration. An unknown Object root keeps the historical non-caching default used while an aggregate type is still being inferred from its first event.

    • getAggregateRootConfiguration

      public static EntityMetadata.RootConfiguration getAggregateRootConfiguration(Class<?> type)
      Returns the legacy Aggregate defaults even when an Aggregate fallback load is attempted for a Model type.
    • interceptForValidation

      public void interceptForValidation(Object value, Entity<?> entity, BiConsumer<Object,Boolean> consumer)
      Description copied from interface: EntityHelper
      Consumes intercepted updates for a validating operation. The consumer's second argument indicates whether legality assertions for that exact update have already run during interception. Custom helpers retain their existing interception behavior by default. The stream is consumed within this call; its ownership remains with the custom helper.
      Specified by:
      interceptForValidation in interface EntityHelper
    • validateModelApplyMethods

      public static void validateModelApplyMethods(Class<?> type)
      Validates model apply methods discovered on the given type.

      This method is intended for model registration and handler discovery. A void apply declared by a model, or a void apply with a model parameter, cannot identify the independently stored target state and is therefore rejected. Aggregate-only handler types retain their existing mutable-entity behavior.

      Parameters:
      type - model or apply-handler type to validate
      Throws:
      IllegalStateException - if the type contains a void apply targeting a model
    • applyHandlerConfiguration

      protected static HandlerConfiguration<DefaultEntityHelper.DeserializingMessageWithEntity> applyHandlerConfiguration(boolean checkCompatibility, EntityParameterResolver entityParameterResolver)
    • intercept

      public Stream<?> intercept(Object value, Entity<?> entity)
      Intercepts the given value using @InterceptApply methods defined on the entity. Interceptors may transform or replace the original message.
      Specified by:
      intercept in interface EntityHelper
      Parameters:
      value - the value to be intercepted, typically the payload of a message
      entity - the entity receiving the value
      Returns:
      a stream of intercepted values or messages to be applied
    • getInterceptInvoker

      Recursively resolves the best-matching interceptor method, including nested members.
    • applyInvoker

      public Optional<HandlerInvoker> applyInvoker(DeserializingMessage event, Entity<?> entity, boolean searchChildren, boolean checkCompatibility)
      Finds a handler method annotated with @Apply and wraps it to preserve apply context flags.
      Specified by:
      applyInvoker in interface EntityHelper
      Parameters:
      event - the event to apply
      entity - the root or intermediate entity
      searchChildren - whether to search nested child entities for applicable handlers
      checkCompatibility - whether to check if the entity state is compatible with the event being applied
      Returns:
      a handler invoker if a suitable method is located
    • assertLegal

      public <E extends Exception> void assertLegal(Object value, Entity<?> entity) throws E
      Performs a validation check using @AssertLegal handlers for the provided payload. This method is called both before and after the handler completes, depending on the annotation's settings.
      Specified by:
      assertLegal in interface EntityHelper
      Type Parameters:
      E - the type of exception that may be thrown
      Parameters:
      value - the value to validate
      entity - the current entity state
      Throws:
      E - if the value is deemed illegal
    • checkLegality

      public <E extends Exception> Optional<E> checkLegality(Object value, Entity<?> entity)
      Returns an exception if the value is illegal for the current entity, or Optional.empty() if legal.
      Specified by:
      checkLegality in interface EntityHelper
      Type Parameters:
      E - the type of exception
      Parameters:
      value - the value to validate
      entity - the entity context
      Returns:
      an exception if illegal, or an empty Optional if legal
    • isLegal

      public boolean isLegal(Object value, Entity<?> entity)
      Convenience method that returns true if checkLegality(Object, Entity) yields no error.
      Specified by:
      isLegal in interface EntityHelper
      Parameters:
      value - the value to check
      entity - the entity context
      Returns:
      true if legal, false otherwise