Class BasicBeanConverter

java.lang.Object
org.apache.juneau.junit.bct.BasicBeanConverter
All Implemented Interfaces:
BeanConverter

public class BasicBeanConverter extends Object implements BeanConverter
Default implementation of BeanConverter for Bean-Centric Test (BCT) object conversion.

This class provides a comprehensive, extensible framework for converting Java objects to strings and lists, with sophisticated property access capabilities. It's the core engine behind BCT testing assertions, handling complex object introspection and value extraction with high performance through intelligent caching and optimized lookup strategies.

Key Features:
  • Extensible Type Handlers: Pluggable stringifiers, listifiers, and swappers for custom types
  • Performance Optimization: ConcurrentHashMap caching for type-to-handler mappings
  • Comprehensive Defaults: Built-in support for all common Java types and structures
  • Configurable Settings: Customizable formatting, delimiters, and display options
  • Thread Safety: Fully thread-safe implementation suitable for concurrent testing
Architecture Overview:

The converter uses four types of pluggable handlers:

Stringifiers:
Convert objects to string representations with custom formatting rules
Listifiers:
Convert collection-like objects to List<Object> for uniform iteration
Swappers:
Pre-process objects before conversion (unwrap Optional, call Supplier, etc.)
PropertyExtractors:
Define custom property access strategies for nested field navigation (e.g., "user.address.city")

PropertyExtractors use a chain-of-responsibility pattern, where each extractor in the chain is tried until one can handle the property access. The framework includes built-in extractors for:

  • JavaBean properties: Standard getter methods and public fields
  • Collection/Array access: Numeric indices and size/length properties
  • Map access: Key-based property retrieval and size property
Default Type Support:

Out-of-the-box stringification support includes:

  • Collections: List, Set, Queue → "[item1,item2,item3]" format
  • Maps: Map, Properties → "{key1=value1,key2=value2}" format
  • Map Entries: Map.Entry → "key=value" format
  • Arrays: All array types → "[element1,element2]" format
  • Dates: Date, Calendar → ISO-8601 format
  • Files/Streams: File, InputStream, Reader → content as hex or text
  • Reflection: Class, Method, Constructor → human-readable signatures
  • Enums: Enum values → name() format

Default listification support includes:

  • Collection types: List, Set, Queue, and all subtypes
  • Iterable objects: Any Iterable implementation
  • Iterators: Iterator and Enumeration (consumed to list)
  • Streams: Stream objects (terminated to list)
  • Optional: Empty list or single-element list
  • Maps: Converted to list of Map.Entry objects

Default swapping support includes:

  • Optional: Unwrapped to contained value or null
  • Supplier: Called to get supplied value
  • Future: Extracts completed result or returns "<pending>" for incomplete futures (via Swappers.futureSwapper())
Configuration Settings:

The converter supports extensive customization via settings:

nullValue
String representation for null values (default: "<null>")
selfValue
Special property name that returns the object itself (default: "<self>")
emptyValue
String representation for empty collections (default: "<empty>")
fieldSeparator
Delimiter between collection elements and map entries (default: ",")
collectionPrefix/Suffix
Brackets around collection content (default: "[" and "]")
mapPrefix/Suffix
Brackets around map content (default: "{" and "}")
mapEntrySeparator
Separator between map keys and values (default: "=")
calendarFormat
DateTimeFormatter for calendar objects (default: ISO_INSTANT)
classNameFormat
Format for class names: "simple", "canonical", or "full" (default: "simple")
Usage Examples:

Basic Usage with Defaults:

// Use default converter var converter = BasicBeanConverter.DEFAULT; var result = converter.stringify(myObject);

Custom Configuration:

// Build custom converter var converter = BasicBeanConverter.builder() .defaultSettings() .addSetting(SETTING_nullValue, "<null>") .addSetting(SETTING_fieldSeparator, " | ") .addStringifier(MyClass.class, (obj, conv) -> "MyClass[" + obj.getName() + "]") .addListifier(MyIterable.class, (obj, conv) -> obj.toList()) .addSwapper(MyWrapper.class, (obj, conv) -> obj.getWrapped()) .build();

Complex Property Access:

// Extract nested properties var name = converter.getEntry(user, "name"); var city = converter.getEntry(user, "address.city"); var firstOrder = converter.getEntry(user, "orders.0.id"); var orderCount = converter.getEntry(user, "orders.length");

Special Property Values:

// Use special property names var userObj = converter.getEntry(user, "<self>"); // Returns the user object itself var nullValue = converter.getEntry(user, "<null>"); // Returns null // Custom self value var customConverter = BasicBeanConverter.builder() .defaultSettings() .addSetting(SETTING_selfValue, "this") .build(); var selfRef = customConverter.getEntry(user, "this"); // Returns user object

Performance Characteristics:
  • Handler Lookup: O(1) average case via ConcurrentHashMap caching
  • Type Registration: Handlers checked in reverse registration order (last wins)
  • Inheritance Support: Handlers support class inheritance and interface implementation
  • Thread Safety: Full concurrency support with no locking overhead after initialization
  • Memory Efficiency: Minimal object allocation during normal operation
Extension Patterns:

Custom Type Stringification:

builder.addStringifier(LocalDateTime.class, (dt, conv) -> dt.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));

Custom Collection Handling:

builder.addListifier(MyCustomCollection.class, (coll, conv) -> coll.stream().map(conv::swap).toList());

Custom Object Transformation:

builder.addSwapper(LazyValue.class, (lazy, conv) -> lazy.isEvaluated() ? lazy.getValue() : "<unevaluated>");

Integration with BCT:

This class is used internally by all BCT assertion methods in BctAssertions:

See Also: