Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 1.improve template engine use by mvel, 2.upgrade springboot to 3.3 #22

Merged
merged 1 commit into from
May 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,15 @@
<module>uno-netty</module>
<module>uno-sequential</module>
<module>uno-websocket</module>
<module>uno-ai</module>
</modules>

<properties>
<java.version>22</java.version>
<drools.version>9.44.0.Final</drools.version>
<reactor-bom>2023.0.3</reactor-bom>
<spring.boot.version>3.2.5</spring.boot.version>
<reactor-bom>2023.0.6</reactor-bom>
<spring.boot.version>3.3.0</spring.boot.version>
<spring-ai.version>0.8.1-SNAPSHOT</spring-ai.version>
<maven-source-plugin.version>3.2.1</maven-source-plugin.version>
<maven-plugin.version>3.8.1</maven-plugin.version>
<maven-jar-plugin.version>3.1.0</maven-jar-plugin.version>
Expand Down Expand Up @@ -98,6 +100,13 @@
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>${spring-ai.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

Expand Down
21 changes: 21 additions & 0 deletions uno-ai/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cc.allio</groupId>
<artifactId>uno</artifactId>
<version>1.1.9</version>
</parent>

<artifactId>uno-ai</artifactId>
<description>Through the capabilities of Spring AI, one can delve into artificial intelligence and endow abilities.</description>

<properties>
<maven.compiler.source>22</maven.compiler.source>
<maven.compiler.target>22</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

</project>
2 changes: 1 addition & 1 deletion uno-bom/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.5</version>
<version>3.3.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>

Expand Down
11 changes: 11 additions & 0 deletions uno-core/src/main/java/cc/allio/uno/core/util/DateUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,17 @@ public static Date now() {
return new Date();
}

/**
* get format date by {@link #PATTERN_DATETIME}
*
* @return format string date
* @see #now()
* @see #format(Date, String)
*/
public static String formatNow() {
return format(now(), PATTERN_DATETIME);
}

/**
* 添加年
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package cc.allio.uno.core.util.template;

import cc.allio.uno.core.bean.BeanWrapper;
import cc.allio.uno.core.bean.ValueWrapper;
import cc.allio.uno.core.util.IoUtils;
import cc.allio.uno.core.util.template.internal.GenericTokenParser;
import cc.allio.uno.core.util.template.internal.PlaceholderExpressionTemplate;
import cc.allio.uno.core.util.template.internal.TokenParser;
import cc.allio.uno.core.util.template.mvel.MVELExpressionTemplate;
import com.google.common.collect.Maps;
import org.springframework.core.io.UrlResource;
import reactor.util.function.Tuple2;
Expand All @@ -24,7 +26,11 @@
*
* @author j.x
* @date 2021/12/25 16:40
* @modify 1.1.9
* @see PlaceholderExpressionTemplate
* @see #createMVEL() create a {@link MVELExpressionTemplate}
* @see #defaultTemplate() use internal {@link PlaceholderExpressionTemplate}
* @see ExpressionTemplateNavigator
* @since 1.0
*/
public interface ExpressionTemplate {
Expand All @@ -48,12 +54,13 @@ public interface ExpressionTemplate {
* 解析模板,当发生错误时将保持原样
*
* @param template 模板
* @param bean the bean instance
* @param target the target instance
* @return 解析完成的字符串
* @throws NullPointerException template target为空时抛出
*/
default String parseTemplate(String template, Object bean) {
Map<String, Object> vars = BeanWrapper.of(bean).findMapValuesForce();
default String parseTemplate(String template, Object target) {
ValueWrapper valueWrapper = ValueWrapper.get(target);
Map<String, Object> vars = valueWrapper.findMapValuesForce();
return parseTemplate(template, vars);
}

Expand Down Expand Up @@ -180,12 +187,11 @@ default String parseFileTemplate(String file, Object target) throws IOException
*
* @return ExpressionTemplate实例
* @see PlaceholderExpressionTemplate
* @see Tokenizer
* @see Tokenizer#AT_BRACE
* @see Tokenizer#HASH_BRACE
* @see #createTemplate(Tokenizer)
*/
static ExpressionTemplate defaultTemplate() {
return createTemplate(Tokenizer.AT_BRACE);
return createTemplate(Tokenizer.HASH_BRACE);
}

/**
Expand Down Expand Up @@ -213,6 +219,15 @@ static ExpressionTemplate createTemplate(Tokenizer tokenizer, boolean langsym) {
return new ExpressionTemplateNavigator(tokenizer, langsym);
}

/**
* create {@link MVELExpressionTemplate} instance
*
* @return {@link MVELExpressionTemplate} instance
*/
static MVELExpressionTemplate createMVEL() {
return new MVELExpressionTemplate();
}

/**
* 根据指定的{@link Tokenizer}创建{@link TokenParser}实例
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ public ExpressionTemplateNavigator(Tokenizer tokenizer, Object... args) {
this.tokenizer = tokenizer;
}


@Override
public String parseTemplate(String template, TemplateContext context) {
return internal.parseTemplate(template, context);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

import cc.allio.uno.core.api.OptionalContext;
import cc.allio.uno.core.type.Types;
import cc.allio.uno.core.util.BeanUtils;
import cc.allio.uno.core.util.ClassUtils;
import cc.allio.uno.core.util.DateUtil;
import cc.allio.uno.core.util.JsonUtils;
import com.google.common.collect.Maps;
import lombok.Getter;
import org.springframework.context.ApplicationContext;
Expand All @@ -11,17 +15,50 @@

/**
* parse template for context
* <p>system practical utility tools</p>
* <ul>
* <li>date: refer to {@link DateUtil}</li>
* <li>json: refer to {@link JsonUtils}</li>
* <li>bean: refer to {@link BeanUtils}</li>
* <li>class: refer to {@link ClassUtils}</li>
* </ul>
*
* @author j.x
* @date 2024/5/3 20:12
* @since 1.1.9
*/
public class TemplateContext implements OptionalContext {

final Map<String, Object> vars = Maps.newConcurrentMap();

private final Map<String, Object> vars;
@Getter
private final Map<String, Class> inputs;
@Getter
final Map<String, Class> inputs = Maps.newConcurrentMap();
private final Map<String, Class> imports;
@Getter
private final Map<Class<?>, VariableResolve<?, ?>> variableResolveMap;

private static final String DATE_UTILITY_NAME = "date";
private static final String JSON_UTILITY_NAME = "json";
private static final String BEAN_UTILITY_NAME = "bean";
private static final String CLASS_UTILITY_NAME = "class";

public TemplateContext() {
this.vars = Maps.newConcurrentMap();
this.inputs = Maps.newConcurrentMap();
this.imports = Maps.newConcurrentMap();
this.variableResolveMap = Maps.newConcurrentMap();
initial();
}

/**
* initial system practical utility
*/
void initial() {
addImport(DATE_UTILITY_NAME, DateUtil.class);
addImport(JSON_UTILITY_NAME, JsonUtils.class);
addImport(BEAN_UTILITY_NAME, BeanUtils.class);
addImport(CLASS_UTILITY_NAME, ClassUtils.class);
}

@Override
public Optional<Object> get(String key) {
Expand All @@ -48,4 +85,45 @@ public void putAttribute(String key, Object obj) {
}
}
}

/**
* add key and input class use for parse template
*
* @param key the key
* @param inputClass the input class
*/
public void addInput(String key, Class inputClass) {
this.inputs.put(key, inputClass);
}

/**
* add import class to mvel imports
*
* @param importClass the import class
*/
public void addImport(Class importClass) {
this.imports.put(importClass.getSimpleName(), importClass);
}

/**
* add import key and class to mvel imports
*
* @param key the import key
* @param importClass the import class
*/
public void addImport(String key, Class importClass) {
this.imports.put(key, importClass);
}

/**
* add {@link VariableResolve} instance
*
* @param variableType the {@link T} class type
* @param variableResolve the {@link VariableResolve} instance
* @param <T> variable type
* @param <R> translate type
*/
public <T, R> void addVariableResolve(Class<T> variableType, VariableResolve<T, R> variableResolve) {
this.variableResolveMap.put(variableType, variableResolve);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package cc.allio.uno.core.util.template;

import cc.allio.uno.core.function.lambda.MethodFunction;

/**
* get specific type {@link T} translate type {@link R}
*
* @param <T> type T
* @param <R> translate R
* @author j.x
* @date 2024/5/4 14:12
* @since 1.1.9
*/
public interface VariableResolve<T, R> extends MethodFunction<T, R> {
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,5 +63,4 @@ public String parseTemplate(@NonNull String template, TemplateContext context) {
return engine.run(expression, vars, langsym);
});
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@

import cc.allio.uno.core.util.template.ExpressionTemplate;
import cc.allio.uno.core.util.template.TemplateContext;
import lombok.extern.slf4j.Slf4j;
import org.mvel2.ParserContext;
import org.mvel2.templates.CompiledTemplate;
import org.mvel2.templates.TemplateCompiler;
import org.mvel2.templates.TemplateRuntime;

import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
Expand All @@ -16,16 +19,35 @@
* @date 2024/5/3 20:07
* @since 1.1.9
*/
@Slf4j
public class MVELExpressionTemplate implements ExpressionTemplate {

@Override
public String parseTemplate(String template, TemplateContext context) {
// 1. compile the template
ParserContext parserContext = new ParserContext();

// add inputs
Map<String, Class> inputs = context.getInputs();
parserContext.addInputs(inputs);

// add import
Map<String, Class> imports = context.getImports();
for (Map.Entry<String, Class> importEntry : imports.entrySet()) {
parserContext.addImport(importEntry.getKey(), importEntry.getValue());
}
CompiledTemplate compiledTemplate = TemplateCompiler.compileTemplate(template, parserContext);
Object execute = TemplateRuntime.execute(compiledTemplate, context.getAll());
return execute.toString();

// 2. execute parse template
ByteArrayOutputStream out = new ByteArrayOutputStream();

// use customize VariableResolverFactory
TemplateContextVariableResolverFactory variableResolverFactory = new TemplateContextVariableResolverFactory(context);
try {
TemplateRuntime.execute(compiledTemplate, null, variableResolverFactory, out);
} catch (Throwable ex) {
log.error("Failed to mvel parse template {}", template, ex);
}
return out.toString(StandardCharsets.UTF_8);
}
}
Loading
Loading