Class AbstractSerializer<I>

java.lang.Object
io.fluxzero.sdk.common.serialization.AbstractSerializer<I>
Type Parameters:
I - the internal intermediate format (e.g., JsonNode) used during downcasting
All Implemented Interfaces:
ContentFilter, Serializer
Direct Known Subclasses:
JacksonSerializer

public abstract class AbstractSerializer<I> extends Object implements Serializer
Abstract base implementation of the Serializer interface.

This class provides common functionality for serialization frameworks including:

  • Upcasting and downcasting of serialized data based on revision
  • Support for multiple serialization formats
  • Lazy deserialization with memoization
  • Type upcasting via explicit mappings

Concrete subclasses must implement the core logic for serializing and deserializing objects using a specific format (e.g., JSON or Protobuf). This includes:

Thread-safe and reusable. Used throughout the Fluxzero framework for all (de)serialization needs.

  • Constructor Details

    • AbstractSerializer

      protected AbstractSerializer(Collection<?> casterCandidates, io.fluxzero.common.serialization.Converter<byte[],I> converter, String format)
      Constructs a new serializer with the provided caster candidates and converter.
      Parameters:
      casterCandidates - a collection of objects providing up/down-casting functionality
      converter - a converter used to assist in interpreting serialized data
      format - the default serialization format name (e.g., "json")
  • Method Details

    • serialize

      public io.fluxzero.common.api.Data<byte[]> serialize(Object object, String format)
      Serializes the given object into a byte-based Data object, using the specified format.
      Specified by:
      serialize in interface Serializer
      Parameters:
      object - the object to serialize
      format - the desired serialization format
      Returns:
      a Data<byte[]> object containing the serialized bytes
    • normalize

      public io.fluxzero.common.api.SerializedObject<byte[]> normalize(io.fluxzero.common.api.SerializedObject<?> serializedObject)
      Description copied from interface: Serializer
      Normalizes an already-serialized object to the target byte-based representation of this serializer.
      Specified by:
      normalize in interface Serializer
      Parameters:
      serializedObject - the serialized object to normalize
      Returns:
      the normalized byte-based serialized object
    • serializeToOtherFormat

      protected io.fluxzero.common.api.Data<byte[]> serializeToOtherFormat(Object object, String format)
      Converts common simple object types (e.g., String, byte[]) to the requested alternative format. Used when the object cannot be serialized using the current default format.
    • getType

      protected Type getType(Object object)
      Determines the full type signature of the given object.
    • asString

      protected String asString(Type type)
      Converts a Type to a readable string name.
    • getTypeString

      protected String getTypeString(Object object)
      Resolves the effective string representation of an object's type, including generic parameters if applicable.
    • doSerialize

      protected abstract byte[] doSerialize(Object object) throws Exception
      Hook for serializing the object to bytes using the primary format. Must be implemented by subclasses.
      Throws:
      Exception
    • deserialize

      public <S extends io.fluxzero.common.api.SerializedObject<byte[]>> Stream<DeserializingObject<byte[],S>> deserialize(Stream<S> dataStream, UnknownTypeStrategy unknownTypeStrategy)
      Deserializes a stream of SerializedObject values into deserialized objects. Applies upcasters, format detection, and lazy deserialization as needed.
      Specified by:
      deserialize in interface Serializer
      Type Parameters:
      S - the type of the serialized object
      Parameters:
      dataStream - data input stream to deserialize
      unknownTypeStrategy - value that determines what to do when encountering unknown types
      Returns:
      a stream containing deserialization results
    • deserializeFirstMessage

      public Optional<DeserializingMessage> deserializeFirstMessage(io.fluxzero.common.api.SerializedMessage message, io.fluxzero.common.MessageType messageType, String topic)
      Description copied from interface: Serializer
      Deserializes one SerializedMessage into the first resulting DeserializingMessage.

      This preserves the same semantics as deserializeMessages(Stream.of(message), ...).findAny(): upcasters that drop a message return Optional.empty(), and upcasters that split a message contribute only their first result.

      Specified by:
      deserializeFirstMessage in interface Serializer
      Parameters:
      message - the serialized message
      messageType - the type of message (COMMAND, EVENT, etc.)
      topic - the topic of the message if the type is CUSTOM or DOCUMENT, otherwise null
      Returns:
      the first deserialized message, if any
    • deserializeFirstMessageOrNull

      public DeserializingMessage deserializeFirstMessageOrNull(io.fluxzero.common.api.SerializedMessage message, io.fluxzero.common.MessageType messageType, String topic)
      Description copied from interface: Serializer
      Deserializes one SerializedMessage into the first resulting DeserializingMessage, or null if no result remains.

      This preserves the same semantics as deserializeMessages(Stream.of(message), ...).findAny(): upcasters that drop a message return null, and upcasters that split a message contribute only their first result.

      Specified by:
      deserializeFirstMessageOrNull in interface Serializer
      Parameters:
      message - the serialized message
      messageType - the type of message (COMMAND, EVENT, etc.)
      topic - the topic of the message if the type is CUSTOM or DOCUMENT, otherwise null
      Returns:
      the first deserialized message, or null
    • convert

      public <V> V convert(Object value, Type type)
      Converts the given object to the specified target type.
      Specified by:
      convert in interface Serializer
      Type Parameters:
      V - the result type
      Parameters:
      value - the input value
      type - the target type
      Returns:
      the converted value
    • clone

      public <V> V clone(Object value)
      Creates a deep copy of the object. For known types (collections, maps, etc.) a shallow copy is made; otherwise, uses doClone(Object).
      Specified by:
      clone in interface Serializer
      Type Parameters:
      V - the type of the value
      Parameters:
      value - the object to clone
      Returns:
      a deep copy
    • registerUpcasters

      public io.fluxzero.common.Registration registerUpcasters(Object... casterCandidates)
      Registers custom upcasters for handling older serialized formats.
      Specified by:
      registerUpcasters in interface Serializer
      Parameters:
      casterCandidates - beans with upcasting logic
      Returns:
      a registration handle
    • registerDowncasters

      public io.fluxzero.common.Registration registerDowncasters(Object... casterCandidates)
      Registers custom downcasters for transforming newer object states to older revisions.
      Specified by:
      registerDowncasters in interface Serializer
      Parameters:
      casterCandidates - beans with downcasting logic
      Returns:
      a registration handle
    • registerTypeCaster

      public io.fluxzero.common.Registration registerTypeCaster(String oldType, String newType)
      Registers a type mapping for upcasting old type names to new ones.
      Specified by:
      registerTypeCaster in interface Serializer
      Parameters:
      oldType - the legacy type name
      newType - the canonical or updated type name
      Returns:
      a registration handle
    • registerTypeAlias

      public io.fluxzero.common.Registration registerTypeAlias(String oldType, String newType)
      Description copied from interface: Serializer
      Registers an exact alias from a serialized type name to its current type name.

      This is the preferred name for Serializer.registerTypeCaster(String, String). Multiple aliases may be registered and chained. Exact aliases take precedence over package aliases.

      Specified by:
      registerTypeAlias in interface Serializer
      Parameters:
      oldType - the legacy serialized type name
      newType - the current type name
      Returns:
      a registration handle
    • registerPackageAlias

      public io.fluxzero.common.Registration registerPackageAlias(String oldPackage, String newPackage)
      Description copied from interface: Serializer
      Registers an alias from a legacy package and all its subpackages to a current package.

      Implementations that support package aliases should preserve the class-name suffix and prefer the longest matching package prefix when multiple aliases match.

      Specified by:
      registerPackageAlias in interface Serializer
      Parameters:
      oldPackage - the legacy package name, without a trailing wildcard
      newPackage - the current package name, without a trailing wildcard
      Returns:
      a registration handle
    • upcastType

      public String upcastType(String type)
      Resolves the current type from potentially chained exact and package aliases.
      Specified by:
      upcastType in interface Serializer
      Parameters:
      type - the original type
      Returns:
      the remapped (or unchanged) type name
    • hasTypeAliases

      protected boolean hasTypeAliases()
      Indicates whether exact or package aliases are currently registered.
    • downcast

      public Object downcast(Object object, int desiredRevision)
      Downcasts a deserialized object to the desired revision number.
      Specified by:
      downcast in interface Serializer
      Parameters:
      object - the object to downcast
      desiredRevision - the target revision
      Returns:
      a revisioned form of the object
    • downcast

      public Object downcast(io.fluxzero.common.api.Data<?> object, int desiredRevision)
      Downcasts an object already in Data form.
      Specified by:
      downcast in interface Serializer
      Parameters:
      object - the serialized data
      desiredRevision - the target revision number
      Returns:
      a transformed object matching the older revision
    • doClone

      protected abstract Object doClone(Object value)
      Hook to clone a deserialized object. Subclasses must implement this if custom cloning is needed.
    • doConvert

      protected abstract <V> V doConvert(Object value, Type type)
      Converts a deserialized object to the desired target type. May delegate to a type mapping library.
    • isKnownType

      protected boolean isKnownType(String type)
      Checks whether a given serialized type is recognized on the classpath.
    • deserializeOtherFormat

      protected Stream<DeserializingObject<byte[],?>> deserializeOtherFormat(io.fluxzero.common.api.SerializedObject<byte[]> s)
      Handles deserialization of objects in formats other than the current default (e.g., fallback string deserialization).
    • deserializeUnknownType

      protected Stream<DeserializingObject<byte[],?>> deserializeUnknownType(io.fluxzero.common.api.SerializedObject<?> serializedObject)
      Hook for handling deserialization of unknown types. Subclasses can override to log or recover gracefully.
    • doDeserialize

      protected abstract Object doDeserialize(io.fluxzero.common.api.Data<?> data, String type) throws Exception
      Core method to deserialize the given Data with an explicit type hint. Must be implemented by concrete subclasses.
      Throws:
      Exception
    • asIntermediateValue

      protected abstract I asIntermediateValue(Object input)
      Converts an object into its intermediate form (e.g., JsonNode) used for revision downcasting. Must be implemented by concrete serializers.