001/*
002 * Copyright © 2025 CUI-OpenSource-Software (info@cuioss.de)
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package de.cuioss.test.generator;
017
018/**
019 * A generator creates instances of type T for testing purposes.
020 * Implementations must ensure thread-safety and handle null values appropriately.
021 *
022 * <p>
023 * The method {@link #getType()} provides a default implementation using {@link #next()} and reading the
024 * concrete {@link Class} of the returned element.
025 * This approach assumes that {@link #next()} returns a non-null value at least once.
026 * If your generator may return null values, you should override
027 * {@link #getType()} to provide the correct type information.
028 * </p>
029 *
030 * <p><em>Usage example from tests:</em></p>
031 * <pre>
032 * {@code
033 * // Create a generator
034 * TypedGenerator<String> generator = Generators.nonEmptyStrings();
035 * 
036 * // Generate values
037 * String value = generator.next();
038 * 
039 * // Get type information
040 * Class<String> type = generator.getType();
041 * }
042 * </pre>
043 *
044 * @param <T> The type of objects to be generated. Can be any Java type including primitives,
045 *            objects, collections, and custom types. The actual constraints on the type depend
046 *            on the specific implementation.
047 * @author Oliver Wolff
048 * @since 1.0
049 */
050public interface TypedGenerator<T> {
051
052    /**
053     * Provides type information about what kind of objects this generator creates.
054     * The default implementation uses the first non-null result from {@link #next()}
055     * to determine the type.
056     *
057     * <p><strong>Note:</strong> If your generator may return null values or the generated
058     * type differs from the actual instance type, you should override this method.</p>
059     *
060     * @return The class information indicating which type this generator is responsible for.
061     * @throws IllegalStateException if the generator cannot determine the type, for example
062     *                               if {@link #next()} consistently returns null
063     */
064    @SuppressWarnings("unchecked") // the implicit providing of the type is the actual idea
065    default Class<T> getType() {
066        return (Class<T>) next().getClass();
067    }
068
069    /**
070     * Generates the next instance based on the generator's configuration.
071     * Implementations must ensure thread-safety.
072     *
073     * @return A newly created instance. May be null if the generator explicitly supports
074     * null value generation.
075     */
076    T next();
077}