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.nio.charset.Charset; 022import java.nio.charset.StandardCharsets; 023import java.util.Optional; 024 025/** 026 * Base class for content converters that process String-based HTTP responses. 027 * <p> 028 * This converter is suitable for text-based content types such as JSON, XML, HTML, and plain text. 029 * It uses HttpResponse.BodyHandlers.ofString() with configurable charset support. 030 * <p> 031 * Subclasses need only implement the conversion logic and empty value provision. 032 * The String raw type handling is managed internally. 033 * 034 * @param <T> the target type for content conversion 035 * @author Oliver Wolff 036 * @since 1.0 037 */ 038public abstract class StringContentConverter<T> implements HttpContentConverter<T> { 039 040 private final Charset charset; 041 042 /** 043 * Creates a String content converter with UTF-8 charset. 044 */ 045 protected StringContentConverter() { 046 this(StandardCharsets.UTF_8); 047 } 048 049 /** 050 * Creates a String content converter with specified charset. 051 * 052 * @param charset the charset to use for String decoding 053 */ 054 protected StringContentConverter(@NonNull Charset charset) { 055 this.charset = charset; 056 } 057 058 @Override 059 public HttpResponse.BodyHandler<?> getBodyHandler() { 060 return HttpResponse.BodyHandlers.ofString(charset); 061 } 062 063 @Override 064 public Optional<T> convert(Object rawContent) { 065 // Cast to String since our BodyHandler produces String content 066 return convertString((String) rawContent); 067 } 068 069 /** 070 * Converts String content to the target type. 071 * This method is called by the public convert method after casting. 072 * 073 * @param rawContent the raw String content from HTTP response 074 * @return Optional containing converted content, or empty if conversion fails 075 */ 076 protected abstract Optional<T> convertString(String rawContent); 077 078 /** 079 * Identity converter for String content (no conversion needed). 080 * <p> 081 * This is the most basic String converter that returns the input unchanged, 082 * suitable for cases where the raw String response is the desired result. 083 * 084 * @return converter that returns the input String unchanged 085 */ 086 public static StringContentConverter<String> identity() { 087 return new StringContentConverter<String>() { 088 @Override 089 protected Optional<String> convertString(String rawContent) { 090 return Optional.ofNullable(rawContent); 091 } 092 093 @Override 094 @NonNull 095 public String emptyValue() { 096 return ""; 097 } 098 }; 099 } 100}