Record Class NaftahObject

java.lang.Object
java.lang.Record
org.daiitech.naftah.builtin.lang.NaftahObject
Record Components:
fromJava - whether this object originates from a Java instance
javaObject - the wrapped Java object if fromJava is true; otherwise null
type - the Java class type of the wrapped object or declared structure
objectFields - the field definitions if this object is a declarative Naftah object; otherwise null

public record NaftahObject(boolean fromJava, Object javaObject, Class<?> type, Map<String,DeclaredVariable> objectFields) extends Record
Represents a dynamic "Naftah" object — a flexible wrapper that can encapsulate either a native Java object or a declarative structure of named fields.

This record provides utilities to:

  • Wrap Java objects and expose their structure as nested maps
  • Recursively serialize Java objects, records, arrays, and collections into a Map
  • Transliterate field or key names into Arabic script for user-facing representation
  • Distinguish between Java-backed and declaratively defined Naftah objects

When fromJava is true, the instance wraps a native Java object. Otherwise, it wraps a map of DeclaredVariables describing a Naftah object structure.

Author:
Chakib Daii
  • Field Details

    • fromJava

      private final boolean fromJava
      The field for the fromJava record component.
    • javaObject

      private final Object javaObject
      The field for the javaObject record component.
    • type

      private final Class<?> type
      The field for the type record component.
    • objectFields

      private final Map<String,DeclaredVariable> objectFields
      The field for the objectFields record component.
    • MAX_DEPTH

      public static final int MAX_DEPTH
      Maximum depth allowed for Java object reflection mapping.
    • SKIP_NULLS

      public static final boolean SKIP_NULLS
      Whether null fields should be skipped during reflection mapping.
    • KEY_OR_FIELD_TRANSLITERATION_FORMAT

      public static final String KEY_OR_FIELD_TRANSLITERATION_FORMAT
      Format pattern used for transliterating field or key names into Arabic script. The resulting format will be "<arabic> (<latin>)".
      See Also:
    • FIELD_ERROR_FORMAT

      public static final String FIELD_ERROR_FORMAT
      Format pattern for field processing errors in Arabic: "[خطأ أثناء معالجة الحقل: %s]".
      See Also:
  • Constructor Details

    • NaftahObject

      public NaftahObject(boolean fromJava, Object javaObject, Class<?> type, Map<String,DeclaredVariable> objectFields)
      Canonical constructor with validation logic.

      Ensures that required fields are non-null based on fromJava:

      • If fromJava is true, javaObject must not be null.
      • If fromJava is false, objectFields must not be null.
      Throws:
      NullPointerException - if type is null, or if required fields are missing
  • Method Details

    • formatKeyOrFieldName

      public static String formatKeyOrFieldName(String keyOrFieldName)
      Formats a given key or field name into a bilingual representation using Arabic transliteration.
      Parameters:
      keyOrFieldName - the Latin field or key name
      Returns:
      a formatted string combining Arabic transliteration and Latin script
    • of

      public static NaftahObject of(Map<String,DeclaredVariable> objectFields)
      Creates a NaftahObject instance backed by declarative field definitions.
      Parameters:
      objectFields - a map of field names to declared variables
      Returns:
      a new NaftahObject representing a declarative object
      Throws:
      NullPointerException - if objectFields is null
    • of

      public static NaftahObject of(Object javaObject)
      Creates a NaftahObject instance backed by a Java object.
      Parameters:
      javaObject - the Java object to wrap
      Returns:
      a new NaftahObject representing a Java object
      Throws:
      NullPointerException - if javaObject is null
    • toMap

      public static Map<String,Object> toMap(Object obj)
      Converts an arbitrary Java object into a structured Map representation. Equivalent to calling toMap(Object, boolean) with skipNulls = false.
      Parameters:
      obj - the object to convert
      Returns:
      a map representation of the object, or null if the input is null
    • toMap

      public static Map<String,Object> toMap(Object obj, boolean skipNulls)
      Converts an arbitrary Java object into a structured Map representation, optionally skipping null values.
      Parameters:
      obj - the object to convert
      skipNulls - whether to exclude null values from the resulting map
      Returns:
      a map representation of the object, or null if the input is null
    • toMap

      private static Map<String,Object> toMap(Object obj, IdentityHashMap<Object,Boolean> visited, boolean skipNulls, int depth)
      Recursively resolves a Java object into a nested map structure, tracking visited instances to prevent infinite recursion from circular references.

      This method supports:

      • Records (via RecordComponent)
      • Plain old Java objects (POJOs)
      • Collections, maps, and arrays

      If a circular reference is detected, a special placeholder entry is added: "[circular-reference]" → <simple-class-name>.

    • convertValue

      private static Object convertValue(Object value, IdentityHashMap<Object,Boolean> visited, boolean skipNulls, int depth)
      Converts an arbitrary value (including nested collections, maps, or arrays) into a serializable representation suitable for mapping.
      Parameters:
      value - the value to convert
      visited - objects already visited during recursion to avoid cycles
      skipNulls - whether to skip null entries
      Returns:
      a converted value or map/list structure
    • get

      public static Object get(Object javaObject, boolean original)
      Returns a converted form of the given object suitable for Naftah representation.

      Performs recursive conversion for collections, maps, arrays, and custom objects. Leaves simple or built-in types unchanged.

      Parameters:
      javaObject - the object to process
      Returns:
      a converted object representation
    • get

      public Object get(boolean original)
      Returns the evaluated value represented by this NaftahObject.
      • If wrapping a Java object, recursively resolves it into a map, collection, or scalar value.
      • If wrapping declared fields, returns the underlying field map directly.
      Returns:
      the evaluated representation of this object
    • get

      public Object get()
      Returns the evaluated representation of this object.

      This is equivalent to calling get(boolean) with original = false.

      Returns:
      the evaluated representation of this object
    • equals

      public boolean equals(Object o)
      Compares this NaftahObject to another object for equality.

      Two NaftahObject instances are considered equal if and only if:

      • They are of the same runtime class, and
      • Their fromJava flags are identical, and
      • Their javaObject, type, and objectFields properties are equal according to Objects.equals(Object, Object).

      This ensures that equality reflects both the source (Java vs. declarative) and the internal data or type structure of the wrapped object.

      Specified by:
      equals in class Record
      Parameters:
      o - the object to compare with this instance
      Returns:
      true if the specified object is equal to this one; otherwise false
    • hashCode

      public int hashCode()
      Computes the hash code for this NaftahObject.

      The hash code is derived from the fromJava flag, the javaObject reference, the type of the object, and the objectFields map. This ensures that two NaftahObject instances considered equal will always produce the same hash code, satisfying the general contract of Object.hashCode().

      Specified by:
      hashCode in class Record
      Returns:
      a hash code value for this object
    • toString

      public String toString()
      Returns a string representation of this Naftah object.

      The format depends on whether it wraps a Java object or declared fields:

      • For collections, maps, and arrays → formatted collection output
      • For simple or built-in values → localized string representation
      • For complex Java objects → Arabic-labeled key-value pairs
      • For declarative Naftah objects → field map string representation
      Specified by:
      toString in class Record
      Returns:
      a human-readable Arabic/Latin mixed representation of the object
    • fromJava

      public boolean fromJava()
      Returns the value of the fromJava record component.
      Returns:
      the value of the fromJava record component
    • javaObject

      public Object javaObject()
      Returns the value of the javaObject record component.
      Returns:
      the value of the javaObject record component
    • type

      public Class<?> type()
      Returns the value of the type record component.
      Returns:
      the value of the type record component
    • objectFields

      public Map<String,DeclaredVariable> objectFields()
      Returns the value of the objectFields record component.
      Returns:
      the value of the objectFields record component