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<ResultSet> <jv>resultSetListifier</jv> = (<jp>conv</jp>, <jp>rs</jp>) -> { 042 * <jk>var</jk> <jv>results</jv> = <jk>new</jk> ArrayList<>(); 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<Stream> <jv>streamListifier</jv> = (<jp>conv</jp>, <jp>stream</jp>) -> 051 * <jp>stream</jp>.peek(<jv>logProcessor</jv>::log).collect(toList()); 052 * 053 * <jc>// Custom data structure</jc> 054 * Listifier<Tree> <jv>treeListifier</jv> = (<jp>conv</jp>, <jp>tree</jp>) -> 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>> {}