001package io.jstach.opt.spring.web;
002
003import java.io.IOException;
004import java.nio.charset.StandardCharsets;
005
006import org.springframework.http.HttpInputMessage;
007import org.springframework.http.HttpOutputMessage;
008import org.springframework.http.MediaType;
009import org.springframework.http.converter.AbstractHttpMessageConverter;
010import org.springframework.http.converter.HttpMessageNotReadableException;
011import org.springframework.http.converter.HttpMessageNotWritableException;
012import org.springframework.web.bind.annotation.ResponseBody;
013
014import io.jstach.jstachio.JStachio;
015import io.jstach.jstachio.Output;
016
017/**
018 * Typesafe way to use JStachio in Spring Web.
019 * <p>
020 * For this to work the controllers need to return JStache models and have the controller
021 * method return annotated with {@link ResponseBody}.
022 * <p>
023 * <strong>Example:</strong> <pre><code class="language-java">
024 * &#64;JStache
025 * public record HelloModel(String message){}
026 *
027 * &#64;GetMapping(value = "/")
028 * &#64;ResponseBody
029 * public HelloModel hello() {
030 *     return new HelloModel("Spring Boot is now JStachioed!");
031 * }
032 * </code> </pre>
033 *
034 * @author agentgt
035 *
036 */
037public class JStachioHttpMessageConverter extends AbstractHttpMessageConverter<Object> {
038
039        private final JStachio jstachio;
040
041        /**
042         * Create http converter from jstachio
043         * @param jstachio an instance usually created by spring
044         */
045        public JStachioHttpMessageConverter(JStachio jstachio) {
046                super(StandardCharsets.UTF_8, MediaType.TEXT_HTML);
047                this.jstachio = jstachio;
048        }
049
050        @Override
051        protected boolean supports(Class<?> clazz) {
052                return jstachio.supportsType(clazz);
053        }
054
055        @Override
056        public boolean canRead(Class<?> clazz, @SuppressWarnings("exports") MediaType mediaType) {
057                return false;
058        }
059
060        @Override
061        protected Object readInternal(Class<? extends Object> clazz, HttpInputMessage inputMessage)
062                        throws IOException, HttpMessageNotReadableException {
063                throw new HttpMessageNotReadableException("Input not supported by JStachio", inputMessage);
064
065        }
066
067        @Override
068        protected void writeInternal(Object t, HttpOutputMessage outputMessage)
069                        throws IOException, HttpMessageNotWritableException {
070                jstachio.write(t, Output.of(outputMessage.getBody(), getDefaultCharset()));
071        }
072
073}