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.*;
020import java.util.function.*;
021
022/**
023 * Functional interface for converting collection-like objects to standardized List<Object> format.
024 *
025 * <p>Listifiers enable the Bean-Centric Testing framework to treat diverse collection-like
026 * objects uniformly during property access and iteration. They convert various iterable
027 * structures into a common List format for consistent processing.</p>
028 *
029 * <h5 class='section'>Common Use Cases:</h5>
030 * <ul>
031 *    <li><b>Arrays:</b> Convert primitive and object arrays to lists</li>
032 *    <li><b>Streams:</b> Materialize Stream objects to lists</li>
033 *    <li><b>Custom collections:</b> Extract elements from domain-specific collections</li>
034 *    <li><b>Map entries:</b> Convert Maps to lists of entry objects</li>
035 *    <li><b>Iterables:</b> Handle any Iterable implementation</li>
036 * </ul>
037 *
038 * <h5 class='section'>Usage Examples:</h5>
039 * <p class='bjava'>
040 *    <jc>// Custom collection handling</jc>
041 *    Listifier&lt;ResultSet&gt; <jv>resultSetListifier</jv> = (<jp>conv</jp>, <jp>rs</jp>) -&gt; {
042 *       <jk>var</jk> <jv>results</jv> = <jk>new</jk> ArrayList&lt;&gt;();
043 *       <jk>while</jk> (<jp>rs</jp>.next()) {
044 *          <jv>results</jv>.add(<jp>rs</jp>.getRowData()); <jc>// Custom row extraction</jc>
045 *       }
046 *       <jk>return</jk> <jv>results</jv>;
047 *    };
048 *
049 *    <jc>// Stream processing with side effects</jc>
050 *    Listifier&lt;Stream&gt; <jv>streamListifier</jv> = (<jp>conv</jp>, <jp>stream</jp>) -&gt;
051 *       <jp>stream</jp>.peek(<jv>logProcessor</jv>::log).collect(toList());
052 *
053 *    <jc>// Custom data structure</jc>
054 *    Listifier&lt;Tree&gt; <jv>treeListifier</jv> = (<jp>conv</jp>, <jp>tree</jp>) -&gt;
055 *       <jp>tree</jp>.traversePreOrder().collect(toList());
056 * </p>
057 *
058 * <h5 class='section'>Registration:</h5>
059 * <p class='bjava'>
060 *    <jk>var</jk> <jv>converter</jv> = BasicBeanConverter.<jsm>builder</jsm>()
061 *       .defaultSettings()
062 *       .addListifier(ResultSet.<jk>class</jk>, <jv>resultSetListifier</jv>)
063 *       .addListifier(Stream.<jk>class</jk>, <jv>streamListifier</jv>)
064 *       .addListifier(Tree.<jk>class</jk>, <jv>treeListifier</jv>)
065 *       .build();
066 * </p>
067 *
068 * <h5 class='section'>Best Practices:</h5>
069 * <ul>
070 *    <li><b>Preserve order</b> when the original collection has meaningful ordering</li>
071 *    <li><b>Handle empty cases</b> gracefully (return empty list, not null)</li>
072 *    <li><b>Consider performance</b> for large collections (avoid full materialization when possible)</li>
073 *    <li><b>Use converter parameter</b> for swapping/transforming individual elements</li>
074 * </ul>
075 *
076 * @param <T> The type of collection-like object this listifier handles
077 * @see BasicBeanConverter.Builder#addListifier(Class, Listifier)
078 * @see BeanConverter#listify(Object)
079 */
080@FunctionalInterface
081public interface Listifier<T> extends BiFunction<BeanConverter,T,List<Object>> {}