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.http.client.converter;
017
018import lombok.NonNull;
019
020import java.net.http.HttpResponse;
021import java.util.Optional;
022
023/**
024 * Content converter for transforming HTTP response bodies into typed objects with proper BodyHandler support.
025 * <p>
026 * This interface provides both content conversion and appropriate BodyHandler selection,
027 * allowing ResilientHttpHandler to leverage Java HTTP Client's type-safe body handling.
028 * The raw response type is an implementation detail hidden from clients.
029 * <p>
030 * Implementations should handle conversion errors gracefully by returning Optional.empty()
031 * when conversion fails or when there is no meaningful content to convert.
032 *
033 * @param <T> the target type for content conversion
034 * @author Oliver Wolff
035 * @since 1.0
036 */
037public interface HttpContentConverter<T> {
038
039    /**
040     * Converts raw HTTP response body to the target type.
041     * <p>
042     * Returns Optional.empty() when:
043     * <ul>
044     *   <li>Conversion fails due to malformed content</li>
045     *   <li>Content is empty or null</li>
046     *   <li>Content cannot be meaningfully converted</li>
047     * </ul>
048     *
049     * @param rawContent the raw HTTP response body (may be null or empty)
050     * @return Optional containing converted content, or empty if conversion fails
051     */
052    Optional<T> convert(Object rawContent);
053
054    /**
055     * Provides the appropriate BodyHandler for this converter.
056     * <p>
057     * This method enables proper leveraging of Java HTTP Client's type-safe body handling,
058     * avoiding unnecessary intermediate conversions and preserving data integrity.
059     * The raw type is handled internally by the implementation.
060     * <p>
061     * Examples:
062     * <ul>
063     *   <li>For JSON/XML: HttpResponse.BodyHandlers.ofString(charset)</li>
064     *   <li>For binary data: HttpResponse.BodyHandlers.ofByteArray()</li>
065     *   <li>For large content: HttpResponse.BodyHandlers.ofInputStream()</li>
066     * </ul>
067     *
068     * @return the BodyHandler appropriate for this converter
069     */
070    @SuppressWarnings("java:S1452")
071    HttpResponse.BodyHandler<?> getBodyHandler();
072
073    /**
074     * Provides a semantically correct empty value for this content type.
075     * <p>
076     * This method should return a meaningful "empty" representation that makes sense
077     * for the target type T, rather than trying to convert meaningless input.
078     * <p>
079     * Examples:
080     * <ul>
081     *   <li>For JSON: empty JsonNode or empty object</li>
082     *   <li>For String: empty string</li>
083     *   <li>For Collections: empty collection</li>
084     *   <li>For custom objects: default/empty instance</li>
085     * </ul>
086     *
087     * @return semantically correct empty value for type T, never null
088     */
089    @NonNull
090    T emptyValue();
091}