001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.juneau.junit.bct; 018 019import java.util.*; 020 021/** 022 * Abstract interface for Bean-Centric Test (BCT) object conversion and property access. 023 * 024 * <p>This interface defines the core contract for converting objects to strings and lists, 025 * and for accessing object properties in a uniform way. It forms the foundation of the BCT 026 * testing framework, enabling consistent object introspection and value extraction across 027 * different object types and structures.</p> 028 * 029 * <h5 class='section'>Core Conversion Operations:</h5> 030 * <dl> 031 * <dt><b>{@link #stringify(Object)}</b></dt> 032 * <dd>Converts any object to its string representation, handling nested structures</dd> 033 * 034 * <dt><b>{@link #listify(Object)}</b></dt> 035 * <dd>Converts collection-like objects (arrays, Collections, Iterables, etc.) to List<Object></dd> 036 * 037 * <dt><b>{@link #swap(Object)}</b></dt> 038 * <dd>Pre-processes objects before conversion (e.g., unwrapping Optional, calling Supplier)</dd> 039 * 040 * <dt><b>{@link #getProperty(Object, String)}</b></dt> 041 * <dd>Accesses object properties using multiple fallback mechanisms</dd> 042 * </dl> 043 * 044 * <h5 class='section'>Property Access Strategy:</h5> 045 * <p>The {@link #getProperty(Object, String)} method uses a comprehensive fallback approach:</p> 046 * 047 * <h5 class='section'>Usage in BCT Framework:</h5> 048 * <p>This interface is used internally by BCT assertion methods like:</p> 049 * <ul> 050 * <li>{@link BctAssertions#assertBean(Object, String, String)}</li> 051 * <li>{@link BctAssertions#assertMapped(Object, java.util.function.BiFunction, String, String)}</li> 052 * <li>{@link BctAssertions#assertList(List, Object...)}</li> 053 * <li>{@link BctAssertions#assertBeans(Collection, String, String...)}</li> 054 * </ul> 055 * 056 * @see BasicBeanConverter 057 * @see BctAssertions 058 */ 059public interface BeanConverter { 060 061 /** 062 * Determines if an object can be converted to a list. 063 * 064 * @param o The object to test. May be null. 065 * @return True if the object can be listified, false if null or cannot be listified 066 */ 067 boolean canListify(Object o); 068 069 /** 070 * Extracts a nested property value using structured field access syntax. 071 * 072 * @param o The object to extract nested properties from. May be null. 073 * @param token The parsed token containing the property access structure. Must not be null. 074 * @return A formatted string representation of the extracted nested values 075 * @throws IllegalArgumentException if the token is null 076 */ 077 String getNested(Object o, NestedTokenizer.Token token); 078 079 /** 080 * Accesses a named property or field from an object. 081 * 082 * @param object The object to access properties from 083 * @param name The property/field name to access 084 * @return The property value 085 * @throws RuntimeException if the property cannot be found or accessed 086 */ 087 Object getProperty(Object object, String name); 088 089 /** 090 * Retrieves a configuration setting value with a fallback default. 091 * 092 * @param <T> The type of the setting value 093 * @param key The setting key to retrieve 094 * @param defaultValue The value to return if the setting is not found 095 * @return The setting value if found, otherwise the default value 096 */ 097 <T> T getSetting(String key, T defaultValue); 098 099 /** 100 * Converts a collection-like object to a standardized List<Object> format. 101 * 102 * @param o The object to convert to a list. Must not be null. 103 * @return A List containing the elements 104 * @throws IllegalArgumentException if the object is null or cannot be converted to a list 105 */ 106 List<Object> listify(Object o); 107 108 /** 109 * Computes the size of an object. 110 * 111 * <p> 112 * This method determines the size of collection-like objects for test assertions. 113 * The size is computed based on registered {@link Sizer} implementations, with 114 * built-in support for collections, maps, arrays, and strings. 115 * 116 * @param o The object to compute the size of. Must not be <jk>null</jk>. 117 * @return The size of the object. 118 * @throws IllegalArgumentException if the object's size cannot be determined. 119 */ 120 int size(Object o); 121 122 /** 123 * Converts an object to its string representation for testing purposes. 124 * 125 * @param o The object to stringify 126 * @return The string representation of the object 127 */ 128 String stringify(Object o); 129 130 /** 131 * Pre-processes objects before conversion operations. 132 * 133 * @param o The object to swap 134 * @return The swapped object, or the original object if no swapping is needed 135 */ 136 Object swap(Object o); 137}