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&lt;Object&gt;</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    * Converts an object to its string representation for testing purposes.
063    *
064    * @param o The object to stringify
065    * @return The string representation of the object
066    */
067   String stringify(Object o);
068
069   /**
070    * Converts a collection-like object to a standardized List&lt;Object&gt; format.
071    *
072    * @param o The object to convert to a list. Must not be null.
073    * @return A List containing the elements
074    * @throws IllegalArgumentException if the object is null or cannot be converted to a list
075    */
076   List<Object> listify(Object o);
077
078   /**
079    * Determines if an object can be converted to a list.
080    *
081    * @param o The object to test. May be null.
082    * @return True if the object can be listified, false if null or cannot be listified
083    */
084   boolean canListify(Object o);
085
086   /**
087    * Pre-processes objects before conversion operations.
088    *
089    * @param o The object to swap
090    * @return The swapped object, or the original object if no swapping is needed
091    */
092   Object swap(Object o);
093
094   /**
095    * Accesses a named property or field from an object.
096    *
097    * @param object The object to access properties from
098    * @param name The property/field name to access
099    * @return The property value
100    * @throws RuntimeException if the property cannot be found or accessed
101    */
102   Object getProperty(Object object, String name);
103
104   /**
105    * Retrieves a configuration setting value with a fallback default.
106    *
107    * @param <T> The type of the setting value
108    * @param key The setting key to retrieve
109    * @param defaultValue The value to return if the setting is not found
110    * @return The setting value if found, otherwise the default value
111    */
112   <T> T getSetting(String key, T defaultValue);
113
114   /**
115    * Extracts a nested property value using structured field access syntax.
116    *
117    * @param o The object to extract nested properties from. May be null.
118    * @param token The parsed token containing the property access structure. Must not be null.
119    * @return A formatted string representation of the extracted nested values
120    * @throws IllegalArgumentException if the token is null
121    */
122   String getNested(Object o, NestedTokenizer.Token token);
123}