Skip to content

Commit

Permalink
feat: 1.improve template engine use by mvel, 2.upgrade springboot to 3.3
Browse files Browse the repository at this point in the history
  • Loading branch information
ClearXs committed May 28, 2024
1 parent bec01c1 commit 0646013
Show file tree
Hide file tree
Showing 21 changed files with 454 additions and 42 deletions.
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

0 comments on commit 0646013

Please sign in to comment.