diff --git a/pom.xml b/pom.xml index d266b56..6889666 100644 --- a/pom.xml +++ b/pom.xml @@ -60,12 +60,6 @@ 2.23.0 - - org.jtwig - jtwig-core - 5.87.0.RELEASE - - org.reflections reflections @@ -95,6 +89,13 @@ 1.8 + + + org.jtwig + jtwig-core + 5.87.0.RELEASE + + diff --git a/src/main/java/io/github/gasparbarancelli/NativeQueryInfo.java b/src/main/java/io/github/gasparbarancelli/NativeQueryInfo.java index 4baaed7..7ce5b0c 100644 --- a/src/main/java/io/github/gasparbarancelli/NativeQueryInfo.java +++ b/src/main/java/io/github/gasparbarancelli/NativeQueryInfo.java @@ -1,8 +1,7 @@ package io.github.gasparbarancelli; +import io.github.gasparbarancelli.engine.jtwig.JtwigTemplateEngineSQLProcessor; import org.aopalliance.intercept.MethodInvocation; -import org.jtwig.JtwigModel; -import org.jtwig.JtwigTemplate; import org.springframework.core.io.ClassPathResource; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -13,6 +12,7 @@ import javax.persistence.Entity; import java.io.File; import java.io.Serializable; +import java.lang.reflect.Method; import java.lang.reflect.Parameter; import java.util.*; @@ -54,32 +54,33 @@ private NativeQueryInfo() { public static NativeQueryInfo of(Class classe, MethodInvocation invocation) { NativeQueryInfo info = new NativeQueryInfo(); - info.useSqlInline = invocation.getMethod().isAnnotationPresent(NativeQuerySql.class); + Method method = invocation.getMethod(); + info.useSqlInline = method.isAnnotationPresent(NativeQuerySql.class); if (info.useSqlInline) { - info.sqlInline = invocation.getMethod().getAnnotation(NativeQuerySql.class).value(); + info.sqlInline = method.getAnnotation(NativeQuerySql.class).value(); } else { setFile(classe, invocation, info); } - info.useJdbcTemplate = invocation.getMethod().isAnnotationPresent(NativeQueryUseJdbcTemplate.class); + info.useJdbcTemplate = method.isAnnotationPresent(NativeQueryUseJdbcTemplate.class); if (info.useJdbcTemplate) { - NativeQueryUseJdbcTemplate jdbcTemplate = invocation.getMethod().getAnnotation(NativeQueryUseJdbcTemplate.class); + NativeQueryUseJdbcTemplate jdbcTemplate = method.getAnnotation(NativeQueryUseJdbcTemplate.class); info.useTenant = jdbcTemplate.useTenant(); } - if (invocation.getMethod().isAnnotationPresent(NativeQueryReplaceSql.class)) { - if (invocation.getMethod().getAnnotation(NativeQueryReplaceSql.class).values().length > 0) { - for (NativeQueryReplaceSqlParams value : invocation.getMethod().getAnnotation(NativeQueryReplaceSql.class).values()) { + if (method.isAnnotationPresent(NativeQueryReplaceSql.class)) { + if (method.getAnnotation(NativeQueryReplaceSql.class).values().length > 0) { + for (NativeQueryReplaceSqlParams value : method.getAnnotation(NativeQueryReplaceSql.class).values()) { info.replaceSql.put(value.key(), value.value()); } - info.processorSqlList.addAll(Arrays.asList(invocation.getMethod().getAnnotation(NativeQueryReplaceSql.class).processorParams())); + info.processorSqlList.addAll(Arrays.asList(method.getAnnotation(NativeQueryReplaceSql.class).processorParams())); } } - info.returnType = invocation.getMethod().getReturnType(); + info.returnType = method.getReturnType(); info.returnTypeIsIterable = Iterable.class.isAssignableFrom(info.returnType); - if (info.returnTypeIsIterable || info.returnType.getSimpleName().equals(Optional.class.getSimpleName())) { - TypeInformation componentType = ClassTypeInformation.fromReturnTypeOf(invocation.getMethod()).getComponentType(); + if (info.returnTypeIsIterable || info.returnTypeIsOptional()) { + TypeInformation componentType = ClassTypeInformation.fromReturnTypeOf(method).getComponentType(); info.aliasToBean = Objects.requireNonNull(componentType).getType(); } else { info.aliasToBean = info.returnType; @@ -144,58 +145,59 @@ private static void setFile(Class classe, MethodInvocatio } } - private JtwigTemplate getJtwigTemplate() { - if (useSqlInline) { - return JtwigTemplate.inlineTemplate(sqlInline, JtwigTemplateConfig.get()); + String getSql() { + if (sql != null) { + return sql; } - return JtwigTemplate.classpathTemplate(file, JtwigTemplateConfig.get()); - } - String getSql() { - if (sql == null) { - JtwigTemplate template = getJtwigTemplate(); - JtwigModel model = JtwigModel.newModel(); - parameterList.forEach(p -> model.with(p.getName(), p.getValue())); - sql = template.render(model); - - for (Class aClass : processorSqlList) { - try { - ProcessorSql processor = aClass.newInstance(); - processor.execute(sql, replaceSql); - } catch (Exception e) { - throw new RuntimeException(e.getMessage()); - } - } + sql = getSqlProcessed(); - for (Map.Entry replaceSqlEntry : replaceSql.entrySet()) { - sql = sql.replaceAll("\\$\\{"+replaceSqlEntry.getKey()+"}", replaceSqlEntry.getValue()); + for (Class aClass : processorSqlList) { + try { + ProcessorSql processor = aClass.newInstance(); + processor.execute(sql, replaceSql); + } catch (Exception e) { + throw new RuntimeException(e.getMessage()); } + } - if (sort != null) { - StringBuilder orderBuilder = new StringBuilder(); - for (Sort.Order order : sort) { - if (orderBuilder.length() == 0) { - orderBuilder.append(" ORDER BY "); - } else { - orderBuilder.append(", "); - } - orderBuilder.append(order.getProperty()) - .append(" ") - .append(order.getDirection().name()); - } + for (Map.Entry replaceSqlEntry : replaceSql.entrySet()) { + sql = sql.replaceAll("\\$\\{"+replaceSqlEntry.getKey()+"}", replaceSqlEntry.getValue()); + } - sql += orderBuilder.toString(); + if (sort != null) { + StringBuilder orderBuilder = new StringBuilder(); + for (Sort.Order order : sort) { + if (orderBuilder.length() == 0) { + orderBuilder.append(" ORDER BY "); + } else { + orderBuilder.append(", "); + } + orderBuilder.append(order.getProperty()) + .append(" ") + .append(order.getDirection().name()); } - if (useTenant) { - NativeQueryTenantNamedParameterJdbcTemplateInterceptor tenantJdbcTemplate = ApplicationContextProvider.getApplicationContext().getBean(NativeQueryTenantNamedParameterJdbcTemplateInterceptor.class); - sql = sql.replace(":SCHEMA", tenantJdbcTemplate.getTenant()); - } + sql += orderBuilder.toString(); + } + + if (useTenant) { + NativeQueryTenantNamedParameterJdbcTemplateInterceptor tenantJdbcTemplate = ApplicationContextProvider.getApplicationContext().getBean(NativeQueryTenantNamedParameterJdbcTemplateInterceptor.class); + sql = sql.replace(":SCHEMA", tenantJdbcTemplate.getTenant()); } return sql; } + private String getSqlProcessed() { + return new JtwigTemplateEngineSQLProcessor() + .setParameter(parameterList) + .inline(useSqlInline) + .setClasspathTemplate(file) + .setInlineTemplate(sqlInline) + .getSql(); + } + String getSqlTotalRecord() { return "select count(*) as totalRecords from (" + getSql() + ") x"; } diff --git a/src/main/java/io/github/gasparbarancelli/NativeQueryParameter.java b/src/main/java/io/github/gasparbarancelli/NativeQueryParameter.java index fe97110..c704877 100644 --- a/src/main/java/io/github/gasparbarancelli/NativeQueryParameter.java +++ b/src/main/java/io/github/gasparbarancelli/NativeQueryParameter.java @@ -8,7 +8,7 @@ import java.util.List; import java.util.Map; -class NativeQueryParameter implements Serializable, Cloneable { +public class NativeQueryParameter implements Serializable, Cloneable { private final String name; diff --git a/src/main/java/io/github/gasparbarancelli/engine/TemplateEngineSQLProcessor.java b/src/main/java/io/github/gasparbarancelli/engine/TemplateEngineSQLProcessor.java new file mode 100644 index 0000000..21bf3e4 --- /dev/null +++ b/src/main/java/io/github/gasparbarancelli/engine/TemplateEngineSQLProcessor.java @@ -0,0 +1,49 @@ +package io.github.gasparbarancelli.engine; + +import io.github.gasparbarancelli.NativeQueryParameter; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public abstract class TemplateEngineSQLProcessor { + + private String inlineTemplate; + private String classpathTemplate; + private boolean inline; + private Map parameters; + + protected abstract String processInline(String sql); + + protected abstract String processFile(String classpathTemplate); + + public final TemplateEngineSQLProcessor inline(boolean inline) { + this.inline = inline; + return this; + } + + public final TemplateEngineSQLProcessor setClasspathTemplate(String classpathTemplate) { + this.classpathTemplate = classpathTemplate; + return this; + } + + public final TemplateEngineSQLProcessor setInlineTemplate(String inlineTemplate) { + this.inlineTemplate = inlineTemplate; + return this; + } + + public final TemplateEngineSQLProcessor setParameter(List parameters) { + this.parameters = parameters.stream() + .collect(HashMap::new, (m, v) -> m.put(v.getName(), v.getValue()), HashMap::putAll); + return this; + } + + protected Map getParameters() { + return Collections.unmodifiableMap(parameters); + } + + public final String getSql() { + return inline ? processInline(inlineTemplate) : processFile(classpathTemplate); + } +} diff --git a/src/main/java/io/github/gasparbarancelli/JtwigTemplateConfig.java b/src/main/java/io/github/gasparbarancelli/engine/jtwig/JtwigTemplateConfig.java similarity index 93% rename from src/main/java/io/github/gasparbarancelli/JtwigTemplateConfig.java rename to src/main/java/io/github/gasparbarancelli/engine/jtwig/JtwigTemplateConfig.java index 97483ee..39558a4 100644 --- a/src/main/java/io/github/gasparbarancelli/JtwigTemplateConfig.java +++ b/src/main/java/io/github/gasparbarancelli/engine/jtwig/JtwigTemplateConfig.java @@ -1,4 +1,4 @@ -package io.github.gasparbarancelli; +package io.github.gasparbarancelli.engine.jtwig; import org.jtwig.environment.EnvironmentConfiguration; import org.jtwig.environment.EnvironmentConfigurationBuilder; diff --git a/src/main/java/io/github/gasparbarancelli/engine/jtwig/JtwigTemplateEngineSQLProcessor.java b/src/main/java/io/github/gasparbarancelli/engine/jtwig/JtwigTemplateEngineSQLProcessor.java new file mode 100644 index 0000000..a339fcc --- /dev/null +++ b/src/main/java/io/github/gasparbarancelli/engine/jtwig/JtwigTemplateEngineSQLProcessor.java @@ -0,0 +1,26 @@ +package io.github.gasparbarancelli.engine.jtwig; + +import io.github.gasparbarancelli.engine.TemplateEngineSQLProcessor; +import org.jtwig.JtwigModel; +import org.jtwig.JtwigTemplate; + +public class JtwigTemplateEngineSQLProcessor extends TemplateEngineSQLProcessor { + + @Override + protected String processInline(String sql) { + return render(JtwigTemplate.inlineTemplate(sql, JtwigTemplateConfig.get())); + } + + @Override + protected String processFile(String classpathTemplate) { + return render(JtwigTemplate.classpathTemplate(classpathTemplate, JtwigTemplateConfig.get())); + } + + private String render(JtwigTemplate jtwigTemplate) { + JtwigModel model = JtwigModel.newModel(); + getParameters().forEach(model::with); + + return jtwigTemplate.render(model); + } + +}