001package io.jstach.opt.spring; 002 003import java.util.List; 004import java.util.ServiceLoader; 005 006import org.springframework.core.env.Environment; 007 008import io.jstach.jstachio.Template; 009import io.jstach.jstachio.TemplateInfo; 010import io.jstach.jstachio.spi.JStachioConfig; 011import io.jstach.jstachio.spi.JStachioExtensionProvider; 012import io.jstach.jstachio.spi.JStachioTemplateFinder; 013 014/** 015 * JStachio services based on Spring notably the {@link #provideConfig() config} and 016 * {@link #provideTemplateFinder() template finding}. 017 * 018 * @apiNote Although this is an extension it is not designed to be loaded by the 019 * {@link ServiceLoader}. 020 * @author agentgt 021 * 022 */ 023public class SpringJStachioExtension implements JStachioExtensionProvider { 024 025 private final Environment environment; 026 027 private final List<Template<?>> templates; 028 029 /** 030 * Constructor for injection 031 * @param environment springs environment to be used for {@link JStachioConfig} 032 * @param templates templates found via spring 033 */ 034 public SpringJStachioExtension(@SuppressWarnings("exports") Environment environment, List<Template<?>> templates) { 035 super(); 036 this.environment = environment; 037 this.templates = templates; 038 } 039 040 /** 041 * {@inheritDoc} The config comes from Spring {@link Environment} abstraction. 042 */ 043 @Override 044 public JStachioConfig provideConfig() { 045 return prop -> environment.getProperty(prop); 046 } 047 048 /** 049 * {@inheritDoc} The provided template finder instead of using reflection delegates to 050 * the templates wired in via spring. 051 */ 052 @Override 053 public JStachioTemplateFinder provideTemplateFinder() { 054 055 return new JStachioTemplateFinder() { 056 057 @Override 058 public TemplateInfo findTemplate(Class<?> modelType) throws Exception { 059 /* 060 * TODO should we do reflection based lookup if this fails? 061 */ 062 for (var t : templates) { 063 if (t.supportsType(modelType)) { 064 return t; 065 } 066 } 067 throw new RuntimeException("template not found for type: " + modelType); 068 } 069 070 @Override 071 public boolean supportsType(Class<?> modelType) { 072 for (var t : templates) { 073 if (t.supportsType(modelType)) { 074 return true; 075 } 076 } 077 return false; 078 } 079 }; 080 081 } 082 083}