From bec01c18e21a3649995eeb35ee3f2d05d25584a0 Mon Sep 17 00:00:00 2001 From: "j.x" Date: Fri, 3 May 2024 21:59:28 +0800 Subject: [PATCH] feat: 1.[uno-core]: update uno-core pom.xml. 2.[uno-core]: add mvel as ExpressionTemplate replacement. 3.fixed some dependency and code problem --- uno-bom/pom.xml | 6 ++ uno-core/pom.xml | 22 ++++-- .../allio/uno/core/api/OptionalContext.java | 12 +-- .../{ObjectWrapper.java => BeanWrapper.java} | 47 +++++++++-- .../cc/allio/uno/core/bean/ValueWrapper.java | 4 +- .../java/cc/allio/uno/core/bus/TopicKey.java | 4 +- .../uno/core/bus/event/ExecutorEventNode.java | 77 ------------------- .../function/lambda/SerializedLambda.java | 30 ++++---- .../convert/AbstractJsonConverter.java | 6 +- .../convert/AbstractRichConverter.java | 6 +- .../metadata/convert/ConverterFactory.java | 12 +-- .../allio/uno/core/type/EnumTypeOperator.java | 6 +- .../cc/allio/uno/core/util/StringUtils.java | 2 +- .../util/template/ExpressionTemplate.java | 55 ++++++++++--- .../template/ExpressionTemplateNavigator.java | 37 +++++++++ .../core/util/template/TemplateContext.java | 51 ++++++++++++ .../uno/core/util/template/Tokenizer.java | 4 + .../BaseInterchange.java | 6 +- .../BeanInterchange.java | 9 +-- .../{expression => internal}/Engine.java | 4 +- .../{ => internal}/GenericTokenParser.java | 3 +- .../{expression => internal}/Interchange.java | 4 +- .../KeyInterchange.java | 2 +- .../template/{ => internal}/LangValue.java | 3 +- .../{expression => internal}/Layer.java | 2 +- .../ListInterchange.java | 4 +- .../ListableInterchange.java | 2 +- .../MapInterchange.java | 2 +- .../PlaceholderExpressionTemplate.java | 28 +++---- .../SymbolEngine.java | 4 +- .../template/{ => internal}/TokenHandler.java | 2 +- .../template/{ => internal}/TokenParser.java | 4 +- .../template/mvel/MVELExpressionTemplate.java | 31 ++++++++ .../uno/core/bus => resources}/event-bus.puml | 0 ...tWrapperTest.java => BeanWrapperTest.java} | 10 +-- .../metadata/source/TestSourceConverter.java | 4 +- .../BeanInterchangeTest.java | 2 +- .../ListInterchangeTest.java | 2 +- .../MapInterchangeTest.java | 2 +- ...PlaceholderExpressionTemplateBaseTest.java | 9 +-- .../SymbolEngineTest.java | 5 +- .../uno/data/orm/dsl/helper/PojoWrapper.java | 6 +- .../uno/data/query/param/AddDiluteAction.java | 6 +- uno-http/pom.xml | 8 +- uno-kafka/pom.xml | 4 +- uno-netty/pom.xml | 4 +- .../main/java/cc/allio/uno/rule/api/Fact.java | 4 +- .../cc/allio/uno/rule/api/RuleAttrImpl.java | 2 +- uno-sequential/pom.xml | 4 +- .../sequnetial/process/DefaultProcessor.java | 4 +- .../convert/TestSequentialConvert.java | 4 +- uno-websocket/pom.xml | 4 +- .../uno/websocket/WebSocketEndpoint.java | 6 +- 53 files changed, 355 insertions(+), 226 deletions(-) rename uno-core/src/main/java/cc/allio/uno/core/bean/{ObjectWrapper.java => BeanWrapper.java} (79%) delete mode 100644 uno-core/src/main/java/cc/allio/uno/core/bus/event/ExecutorEventNode.java create mode 100644 uno-core/src/main/java/cc/allio/uno/core/util/template/ExpressionTemplateNavigator.java create mode 100644 uno-core/src/main/java/cc/allio/uno/core/util/template/TemplateContext.java rename uno-core/src/main/java/cc/allio/uno/core/util/template/{expression => internal}/BaseInterchange.java (93%) rename uno-core/src/main/java/cc/allio/uno/core/util/template/{expression => internal}/BeanInterchange.java (75%) rename uno-core/src/main/java/cc/allio/uno/core/util/template/{expression => internal}/Engine.java (87%) rename uno-core/src/main/java/cc/allio/uno/core/util/template/{ => internal}/GenericTokenParser.java (96%) rename uno-core/src/main/java/cc/allio/uno/core/util/template/{expression => internal}/Interchange.java (86%) rename uno-core/src/main/java/cc/allio/uno/core/util/template/{expression => internal}/KeyInterchange.java (72%) rename uno-core/src/main/java/cc/allio/uno/core/util/template/{ => internal}/LangValue.java (77%) rename uno-core/src/main/java/cc/allio/uno/core/util/template/{expression => internal}/Layer.java (91%) rename uno-core/src/main/java/cc/allio/uno/core/util/template/{expression => internal}/ListInterchange.java (86%) rename uno-core/src/main/java/cc/allio/uno/core/util/template/{expression => internal}/ListableInterchange.java (73%) rename uno-core/src/main/java/cc/allio/uno/core/util/template/{expression => internal}/MapInterchange.java (91%) rename uno-core/src/main/java/cc/allio/uno/core/util/template/{ => internal}/PlaceholderExpressionTemplate.java (76%) rename uno-core/src/main/java/cc/allio/uno/core/util/template/{expression => internal}/SymbolEngine.java (96%) rename uno-core/src/main/java/cc/allio/uno/core/util/template/{ => internal}/TokenHandler.java (90%) rename uno-core/src/main/java/cc/allio/uno/core/util/template/{ => internal}/TokenParser.java (85%) create mode 100644 uno-core/src/main/java/cc/allio/uno/core/util/template/mvel/MVELExpressionTemplate.java rename uno-core/src/main/{java/cc/allio/uno/core/bus => resources}/event-bus.puml (100%) rename uno-core/src/test/java/cc/allio/uno/core/bean/{ObjectWrapperTest.java => BeanWrapperTest.java} (86%) rename uno-core/src/test/java/cc/allio/uno/core/util/template/{expression => internal}/BeanInterchangeTest.java (93%) rename uno-core/src/test/java/cc/allio/uno/core/util/template/{expression => internal}/ListInterchangeTest.java (90%) rename uno-core/src/test/java/cc/allio/uno/core/util/template/{expression => internal}/MapInterchangeTest.java (95%) rename uno-core/src/test/java/cc/allio/uno/core/util/template/{ => internal}/PlaceholderExpressionTemplateBaseTest.java (93%) rename uno-core/src/test/java/cc/allio/uno/core/util/template/{expression => internal}/SymbolEngineTest.java (98%) diff --git a/uno-bom/pom.xml b/uno-bom/pom.xml index 1ce9b0fc..113c8e35 100644 --- a/uno-bom/pom.xml +++ b/uno-bom/pom.xml @@ -65,6 +65,7 @@ 5.17.0 3.27.1 + 2.5.0.Final @@ -396,6 +397,11 @@ redisson ${redisson.version} + + org.mvel + mvel2 + ${mvel.version} + diff --git a/uno-core/pom.xml b/uno-core/pom.xml index 6c5e64b7..b1a35d62 100644 --- a/uno-core/pom.xml +++ b/uno-core/pom.xml @@ -10,6 +10,13 @@ 4.0.0 uno-core + uno pivotal is the core library. + + + 22 + 22 + UTF-8 + @@ -40,6 +47,10 @@ org.apache.commons commons-lang3 + + io.netty + netty-common + cglib @@ -82,12 +93,14 @@ reactor-core - io.projectreactor - reactor-test + org.mvel + mvel2 + - io.projectreactor.netty - reactor-netty + io.projectreactor + reactor-test + test org.junit.jupiter @@ -100,5 +113,4 @@ test - \ No newline at end of file diff --git a/uno-core/src/main/java/cc/allio/uno/core/api/OptionalContext.java b/uno-core/src/main/java/cc/allio/uno/core/api/OptionalContext.java index fc00c804..1da8f619 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/api/OptionalContext.java +++ b/uno-core/src/main/java/cc/allio/uno/core/api/OptionalContext.java @@ -210,13 +210,12 @@ default boolean match(Class type) { .stream() .anyMatch(p -> { Class leftHand = p.getClass(); - Class rightHand = type; if (leftHand.isInterface()) { - return ClassUtils.isAssignable(leftHand, rightHand); - } else if (rightHand.isInterface()) { - return ClassUtils.isAssignable(rightHand, leftHand); + return ClassUtils.isAssignable(leftHand, type); + } else if (type.isInterface()) { + return ClassUtils.isAssignable(type, leftHand); } - return leftHand.isNestmateOf(rightHand); + return leftHand.isNestmateOf(type); }); } @@ -280,9 +279,6 @@ static ImmutableOptionalContext immutable(OptionalContext other, Map context; diff --git a/uno-core/src/main/java/cc/allio/uno/core/bean/ObjectWrapper.java b/uno-core/src/main/java/cc/allio/uno/core/bean/BeanWrapper.java similarity index 79% rename from uno-core/src/main/java/cc/allio/uno/core/bean/ObjectWrapper.java rename to uno-core/src/main/java/cc/allio/uno/core/bean/BeanWrapper.java index ff12e3cb..d9ee147b 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/bean/ObjectWrapper.java +++ b/uno-core/src/main/java/cc/allio/uno/core/bean/BeanWrapper.java @@ -1,6 +1,7 @@ package cc.allio.uno.core.bean; import cc.allio.uno.core.exception.Exceptions; +import cc.allio.uno.core.type.Types; import cc.allio.uno.core.util.CollectionUtils; import com.google.common.collect.Maps; import reactor.core.publisher.Flux; @@ -19,7 +20,7 @@ * @date 2022/5/21 10:17 * @since 1.0 */ -public class ObjectWrapper implements ValueWrapper { +public class BeanWrapper implements ValueWrapper { /** * 解析的目标对象 @@ -27,19 +28,20 @@ public class ObjectWrapper implements ValueWrapper { private final Object instance; private final BeanInfoWrapper wrapper; - public ObjectWrapper(Object instance) { + public BeanWrapper(Object instance) { if (Objects.isNull(instance)) { throw new NullPointerException("Instance Must not null"); } + Class beanClass = (Class) instance.getClass(); try { - this.wrapper = new BeanInfoWrapper<>((Class) instance.getClass()); + this.wrapper = new BeanInfoWrapper<>(beanClass); this.instance = instance; } catch (IntrospectionException ex) { throw Exceptions.unchecked(ex); } } - public ObjectWrapper(Class instanceClass) { + public BeanWrapper(Class instanceClass) { if (Objects.isNull(instanceClass)) { throw new NullPointerException("InstanceClass Must not null"); } @@ -170,7 +172,7 @@ public Object getTarget() { * @param value value */ public static void setValue(Object instance, String name, Object... value) { - ObjectWrapper wrapper = new ObjectWrapper(instance); + BeanWrapper wrapper = new BeanWrapper(instance); if (Boolean.TRUE.equals(wrapper.contains(name))) { wrapper.setForce(name, value); } @@ -184,7 +186,7 @@ public static void setValue(Object instance, String name, Object... value) { * @return value or null */ public static Object getValue(Object instance, String name) { - ObjectWrapper wrapper = new ObjectWrapper(instance); + BeanWrapper wrapper = new BeanWrapper(instance); if (Boolean.TRUE.equals(wrapper.contains(name))) { return wrapper.getForce(name); } @@ -199,10 +201,41 @@ public static Object getValue(Object instance, String name) { * @return value or null */ public static T getValue(Object instance, String name, Class fieldType) { - ObjectWrapper wrapper = new ObjectWrapper(instance); + BeanWrapper wrapper = new BeanWrapper(instance); if (Boolean.TRUE.equals(wrapper.contains(name))) { return wrapper.getForce(name, fieldType); } return null; } + + /** + * create a new {@link BeanWrapper} from bean instance + * + * @param beanInstance the bean instance + * @return {@link BeanWrapper} instance + * @throws NullPointerException if bean instance is null + */ + public static BeanWrapper of(Object beanInstance) { + if (beanInstance == null) { + throw Exceptions.unNull("bean instance is not null"); + } + Class beanClass = beanInstance.getClass(); + if (!Types.isBean(beanClass)) { + throw Exceptions.unOperate("bean must be a bean"); + } + return new BeanWrapper(beanInstance); + } + + /** + * create a new {@link BeanWrapper} from bean class + * + * @param beanClass the bean class + * @return {@link BeanWrapper} instance + */ + public static BeanWrapper of(Class beanClass) { + if (!Types.isBean(beanClass)) { + throw Exceptions.unOperate("bean must be a bean"); + } + return new BeanWrapper(beanClass); + } } diff --git a/uno-core/src/main/java/cc/allio/uno/core/bean/ValueWrapper.java b/uno-core/src/main/java/cc/allio/uno/core/bean/ValueWrapper.java index 1f6f54e2..918d82d0 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/bean/ValueWrapper.java +++ b/uno-core/src/main/java/cc/allio/uno/core/bean/ValueWrapper.java @@ -22,7 +22,7 @@ * @author j.x * @date 2023/4/17 18:39 * @see BeanInfoWrapper 根据{@link BeanInfo}提取bean对象的属性进而实现值提取动作 - * @see ObjectWrapper 接收某个具体的对象(一般为pojo) + * @see BeanWrapper 接收某个具体的对象(一般为pojo) * @see MapWrapper 基于{@link Map}实现 * @since 1.1.4 */ @@ -294,7 +294,7 @@ static Object restore(Object ori) { */ static ValueWrapper get(Object o) { if (Types.isBean(o.getClass())) { - return new ObjectWrapper(o); + return new BeanWrapper(o); } else if (Types.isMap(o.getClass())) { return new MapWrapper((Map) o); } diff --git a/uno-core/src/main/java/cc/allio/uno/core/bus/TopicKey.java b/uno-core/src/main/java/cc/allio/uno/core/bus/TopicKey.java index 655b2ea2..ee6482f7 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/bus/TopicKey.java +++ b/uno-core/src/main/java/cc/allio/uno/core/bus/TopicKey.java @@ -1,7 +1,7 @@ package cc.allio.uno.core.bus; import cc.allio.uno.core.StringPool; -import cc.allio.uno.core.bean.ObjectWrapper; +import cc.allio.uno.core.bean.BeanWrapper; import cc.allio.uno.core.util.ObjectUtils; import cc.allio.uno.core.util.StringUtils; import lombok.Getter; @@ -70,7 +70,7 @@ static TopicKey create(Class clazz, String[] appends) { * @return TopicKey */ static TopicKey create(String prefix, Object pojo) { - ObjectWrapper wrapper = new ObjectWrapper(pojo); + BeanWrapper wrapper = new BeanWrapper(pojo); return create(prefix, wrapper.findMapValuesForce().values().stream().map(Object::toString).toArray(String[]::new)); } diff --git a/uno-core/src/main/java/cc/allio/uno/core/bus/event/ExecutorEventNode.java b/uno-core/src/main/java/cc/allio/uno/core/bus/event/ExecutorEventNode.java deleted file mode 100644 index b468bc56..00000000 --- a/uno-core/src/main/java/cc/allio/uno/core/bus/event/ExecutorEventNode.java +++ /dev/null @@ -1,77 +0,0 @@ -package cc.allio.uno.core.bus.event; - -import com.google.common.collect.Queues; -import io.netty.util.concurrent.DefaultEventExecutorGroup; -import io.netty.util.concurrent.DefaultThreadFactory; -import io.netty.util.concurrent.EventExecutor; -import io.netty.util.concurrent.EventExecutorGroup; -import lombok.extern.slf4j.Slf4j; -import reactor.core.publisher.Mono; - -import java.util.Queue; - -/** - * 基于{@link EventExecutor}的事件回调处理 - * - * @author j.x - * @date 2023/5/19 13:23 - * @since 1.1.4 - */ -@Slf4j -public class ExecutorEventNode extends EventNode { - - /** - * 有序任务序列,在多线程环境下,任务执行顺序可能是乱序状态,以此来提供有序任务 - */ - private final Queue> tasks = Queues.newConcurrentLinkedQueue(); - - public ExecutorEventNode(Long subscribeId, String topic) { - super(subscribeId, topic); - } - - @Override - public Mono update(Listener[] listeners, Context eventContext) { - for (Listener listener : listeners) { - tasks.offer(listener); - } - Listener listener; - while ((listener = tasks.poll()) != null) { - new AsyncSubscriber<>(this, listener).publishEvent(eventContext); - } - return Mono.just(eventContext.getSource()); - } - - /** - * 异步订阅者,提供异步回调监听 - */ - static class AsyncSubscriber { - - /** - * 默认事件执行器 - */ - private static final EventExecutorGroup DISPATCHER = - // 默认为拒绝策略 - new DefaultEventExecutorGroup( - Runtime.getRuntime().availableProcessors() * 2, - new DefaultThreadFactory("eventNode")); - - private final Listener listener; - private final AbstractEventNode node; - - public AsyncSubscriber(AbstractEventNode node, Listener listener) { - this.listener = listener; - this.node = node; - } - - void publishEvent(Context eventContext) { - DISPATCHER.execute(() -> { - try { - listener.listen(node, eventContext.getSource()); - } catch (Throwable ex) { - // Ignore Just Record Exception - log.error("Listener Callback error, Belong Topic: {}", node.getTopic(), ex); - } - }); - } - } -} diff --git a/uno-core/src/main/java/cc/allio/uno/core/function/lambda/SerializedLambda.java b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/SerializedLambda.java index 4fb27e02..93f43131 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/function/lambda/SerializedLambda.java +++ b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/SerializedLambda.java @@ -110,19 +110,21 @@ public String getFieldName() { * @return SerializedLambda实例 */ public static SerializedLambda of(Object lambda) { - return cache.computeIfAbsent(lambda.getClass(), clazz -> { - Method writeReplace = ClassUtils.getMethod(clazz, "writeReplace"); - SerializedLambda serializedLambda; - try { - ClassUtils.setAccessible(writeReplace); - serializedLambda = new SerializedLambda((java.lang.invoke.SerializedLambda) writeReplace.invoke(lambda)); - } catch (IllegalAccessException | InvocationTargetException e) { - throw new UnsupportedOperationException(e); - } - if (serializedLambda.getMethodName().startsWith("lambda$")) { - throw new UnsupportedOperationException("请使用方法引用,例如: UserEntity::getName"); - } - return serializedLambda; - }); + return cache.computeIfAbsent( + lambda.getClass(), + clazz -> { + Method writeReplace = ClassUtils.getMethod(clazz, "writeReplace"); + SerializedLambda serializedLambda; + try { + ClassUtils.setAccessible(writeReplace); + serializedLambda = new SerializedLambda((java.lang.invoke.SerializedLambda) writeReplace.invoke(lambda)); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new UnsupportedOperationException(e); + } + if (serializedLambda.getMethodName().startsWith("lambda$")) { + throw new UnsupportedOperationException("请使用方法引用,例如: UserEntity::getName"); + } + return serializedLambda; + }); } } diff --git a/uno-core/src/main/java/cc/allio/uno/core/metadata/convert/AbstractJsonConverter.java b/uno-core/src/main/java/cc/allio/uno/core/metadata/convert/AbstractJsonConverter.java index aea42423..266c3967 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/metadata/convert/AbstractJsonConverter.java +++ b/uno-core/src/main/java/cc/allio/uno/core/metadata/convert/AbstractJsonConverter.java @@ -1,6 +1,6 @@ package cc.allio.uno.core.metadata.convert; -import cc.allio.uno.core.bean.ObjectWrapper; +import cc.allio.uno.core.bean.BeanWrapper; import cc.allio.uno.core.metadata.mapping.MappingMetadata; import cc.allio.uno.core.serializer.JsonNodeEnhancer; import cc.allio.uno.core.util.JsonUtils; @@ -96,7 +96,7 @@ public T execute(JsonNode root, T metadata) throws Throwable { * @param excludeNotNecessaryFilter 排除必要过滤数据 */ protected void executeAssignmentAction(JsonNode root, T metadata, boolean excludeNotNecessaryFilter) { - ObjectWrapper wrapper = new ObjectWrapper(metadata); + BeanWrapper wrapper = new BeanWrapper(metadata); JsonNodeEnhancer jsonEnhancer = new JsonNodeEnhancer(root); MappingMetadata mappingMetadata = metadata.getMapping(); Flux.fromStream(mappingMetadata.entrySet().stream()) @@ -117,6 +117,6 @@ protected void executeAssignmentAction(JsonNode root, T metadata, boolean exclud * @param metadata 元数据 * @param wrapper sequential对象包装器 */ - protected abstract Mono executeAssignmentDefaultAction(T metadata, ObjectWrapper wrapper); + protected abstract Mono executeAssignmentDefaultAction(T metadata, BeanWrapper wrapper); } diff --git a/uno-core/src/main/java/cc/allio/uno/core/metadata/convert/AbstractRichConverter.java b/uno-core/src/main/java/cc/allio/uno/core/metadata/convert/AbstractRichConverter.java index 172dff75..01cb36c3 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/metadata/convert/AbstractRichConverter.java +++ b/uno-core/src/main/java/cc/allio/uno/core/metadata/convert/AbstractRichConverter.java @@ -1,6 +1,6 @@ package cc.allio.uno.core.metadata.convert; -import cc.allio.uno.core.bean.ObjectWrapper; +import cc.allio.uno.core.bean.BeanWrapper; import cc.allio.uno.core.metadata.mapping.MappingField; import cc.allio.uno.core.metadata.mapping.MappingFieldConverter; import cc.allio.uno.core.metadata.mapping.MappingMetadata; @@ -45,7 +45,7 @@ protected Mono executeAssignmentAction(String name, Object expected, T metadata, boolean excludeNotNecessaryFilter) { - return executeAssignmentAction(name, expected, metadata, new ObjectWrapper(metadata), excludeNotNecessaryFilter); + return executeAssignmentAction(name, expected, metadata, new BeanWrapper(metadata), excludeNotNecessaryFilter); } /** @@ -61,7 +61,7 @@ protected Mono executeAssignmentAction(String name, protected Mono executeAssignmentAction(String name, Object expected, T metadata, - ObjectWrapper sequentialWrapper, + BeanWrapper sequentialWrapper, boolean excludeNotNecessaryFilter) { Mono mono = Mono.just(name); if (!excludeNotNecessaryFilter) { diff --git a/uno-core/src/main/java/cc/allio/uno/core/metadata/convert/ConverterFactory.java b/uno-core/src/main/java/cc/allio/uno/core/metadata/convert/ConverterFactory.java index 2b13f4ca..9b52f74c 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/metadata/convert/ConverterFactory.java +++ b/uno-core/src/main/java/cc/allio/uno/core/metadata/convert/ConverterFactory.java @@ -1,6 +1,6 @@ package cc.allio.uno.core.metadata.convert; -import cc.allio.uno.core.bean.ObjectWrapper; +import cc.allio.uno.core.bean.BeanWrapper; import cc.allio.uno.core.metadata.Metadata; import reactor.core.publisher.Mono; @@ -44,7 +44,7 @@ public static DefaultConverter createConverter(Class * @param consumer Function数据 * @return Converter实例 */ - public static FunctionConverter createConverter(Class type, Consumer consumer) { + public static FunctionConverter createConverter(Class type, Consumer consumer) { return new FunctionConverter<>(type, consumer); } @@ -52,15 +52,15 @@ public static FunctionConverter createConverter(Class * 进行赋值动作时增加使用方进行操作 */ public static class FunctionConverter extends AbstractJsonConverter { - private final Consumer consumer; + private final Consumer consumer; - public FunctionConverter(Class convertType, Consumer consumer) { + public FunctionConverter(Class convertType, Consumer consumer) { super(convertType); this.consumer = consumer; } @Override - protected Mono executeAssignmentDefaultAction(T metadata, ObjectWrapper wrapper) { + protected Mono executeAssignmentDefaultAction(T metadata, BeanWrapper wrapper) { consumer.accept(wrapper); return Mono.empty(); } @@ -76,7 +76,7 @@ public DefaultConverter(Class convertType) { } @Override - protected Mono executeAssignmentDefaultAction(T metadata, ObjectWrapper wrapper) { + protected Mono executeAssignmentDefaultAction(T metadata, BeanWrapper wrapper) { // TODO NOTHING return Mono.empty(); } diff --git a/uno-core/src/main/java/cc/allio/uno/core/type/EnumTypeOperator.java b/uno-core/src/main/java/cc/allio/uno/core/type/EnumTypeOperator.java index 3f7a8dfd..cde7d6fe 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/type/EnumTypeOperator.java +++ b/uno-core/src/main/java/cc/allio/uno/core/type/EnumTypeOperator.java @@ -1,6 +1,6 @@ package cc.allio.uno.core.type; -import cc.allio.uno.core.bean.ObjectWrapper; +import cc.allio.uno.core.bean.BeanWrapper; import cc.allio.uno.core.function.lambda.MethodReferenceColumn; import java.util.Arrays; @@ -40,7 +40,7 @@ public T convert(Object target, Class maybeType) { if (target.equals(name)) { return true; } - ObjectWrapper constantWrapper = new ObjectWrapper(constant); + BeanWrapper constantWrapper = new BeanWrapper(constant); for (String maybeValueText : maybeValueTexts) { Object force = constantWrapper.getForce(maybeValueText); if (target.equals(force)) { @@ -99,7 +99,7 @@ public T convert(Object target, Class maybeType, String valueText) { Object[] enumConstants = maybeType.getEnumConstants(); return (T) Arrays.stream(enumConstants) .filter(constant -> { - Object force = new ObjectWrapper(constant).getForce(valueText); + Object force = new BeanWrapper(constant).getForce(valueText); return target.equals(force); }) .findFirst() diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/StringUtils.java b/uno-core/src/main/java/cc/allio/uno/core/util/StringUtils.java index cb4652ff..04516747 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/util/StringUtils.java +++ b/uno-core/src/main/java/cc/allio/uno/core/util/StringUtils.java @@ -1,7 +1,7 @@ package cc.allio.uno.core.util; import cc.allio.uno.core.StringPool; -import cc.allio.uno.core.util.template.GenericTokenParser; +import cc.allio.uno.core.util.template.internal.GenericTokenParser; import cc.allio.uno.core.util.template.Tokenizer; import com.google.common.collect.Lists; import lombok.Data; diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/template/ExpressionTemplate.java b/uno-core/src/main/java/cc/allio/uno/core/util/template/ExpressionTemplate.java index c73f7c74..32ee450c 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/util/template/ExpressionTemplate.java +++ b/uno-core/src/main/java/cc/allio/uno/core/util/template/ExpressionTemplate.java @@ -1,6 +1,10 @@ package cc.allio.uno.core.util.template; +import cc.allio.uno.core.bean.BeanWrapper; 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 com.google.common.collect.Maps; import org.springframework.core.io.UrlResource; import reactor.util.function.Tuple2; @@ -34,11 +38,24 @@ public interface ExpressionTemplate { * 解析模板,当发生错误时将保持原样 * * @param template 模板 - * @param target 填充于模版的目标对象,要求是一个POJO对象 + * @param context as parse template context. contains variables * @return 解析完成的字符串 * @throws NullPointerException template target为空时抛出 */ - String parseTemplate(String template, Object target); + String parseTemplate(String template, TemplateContext context); + + /** + * 解析模板,当发生错误时将保持原样 + * + * @param template 模板 + * @param bean the bean instance + * @return 解析完成的字符串 + * @throws NullPointerException template target为空时抛出 + */ + default String parseTemplate(String template, Object bean) { + Map vars = BeanWrapper.of(bean).findMapValuesForce(); + return parseTemplate(template, vars); + } /** * 解析模板 @@ -75,7 +92,7 @@ default String parseTemplate(String template, String k1, Object v1, String k2, O * @param k2 模板变量k2 * @param v2 模板变量v2 * @param k3 模板变量k3 - * @param v3 模板变量v2 + * @param v3 模板变量v3 * @return 解析完成的字符串 */ default String parseTemplate(String template, String k1, Object v1, String k2, Object v2, String k3, Object v3) { @@ -90,7 +107,8 @@ default String parseTemplate(String template, String k1, Object v1, String k2, O * @return 解析完成的字符串 */ default String parseTemplate(String template, Tuple2 kv) { - return parseTemplate(template, Collections.singletonMap(kv.getT1(), kv.getT2())); + Map vars = Collections.singletonMap(kv.getT1(), kv.getT2()); + return parseTemplate(template, vars); } /** @@ -122,6 +140,19 @@ default String parseTemplate(String template, Tuple6 vars) { + TemplateContext templateContext = new TemplateContext(); + templateContext.putAll(vars); + return parseTemplate(template, templateContext); + } + /** * 解析文件模板 * @@ -139,8 +170,9 @@ default String parseFileTemplate(String file, Object target) throws IOException UrlResource resource = new UrlResource(url); String template = IoUtils.readToString(resource.getInputStream()); return parseTemplate(template, target); + } else { + throw new FileNotFoundException(String.format("%s file not found", file)); } - throw new FileNotFoundException(String.format("%s file not found", file)); } /** @@ -149,11 +181,11 @@ default String parseFileTemplate(String file, Object target) throws IOException * @return ExpressionTemplate实例 * @see PlaceholderExpressionTemplate * @see Tokenizer - * @see Tokenizer#HASH_BRACE + * @see Tokenizer#AT_BRACE * @see #createTemplate(Tokenizer) */ static ExpressionTemplate defaultTemplate() { - return createTemplate(Tokenizer.HASH_BRACE); + return createTemplate(Tokenizer.AT_BRACE); } /** @@ -165,7 +197,7 @@ static ExpressionTemplate defaultTemplate() { * @see Tokenizer */ static ExpressionTemplate createTemplate(Tokenizer tokenizer) { - return new PlaceholderExpressionTemplate(tokenizer); + return new ExpressionTemplateNavigator(tokenizer); } /** @@ -178,7 +210,7 @@ static ExpressionTemplate createTemplate(Tokenizer tokenizer) { * @see Tokenizer */ static ExpressionTemplate createTemplate(Tokenizer tokenizer, boolean langsym) { - return new PlaceholderExpressionTemplate(tokenizer, langsym); + return new ExpressionTemplateNavigator(tokenizer, langsym); } /** @@ -192,10 +224,11 @@ static TokenParser createParse(Tokenizer tokenizer) { } /** - * @see #parseTemplate(String, Object) + * @see #parseTemplate(String, TemplateContext) */ static String parse(String template, Object target) { - return defaultTemplate().parseTemplate(template, target); + Map vars = BeanWrapper.of(target).findMapValuesForce(); + return defaultTemplate().parseTemplate(template, vars); } /** diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/template/ExpressionTemplateNavigator.java b/uno-core/src/main/java/cc/allio/uno/core/util/template/ExpressionTemplateNavigator.java new file mode 100644 index 00000000..2ac83ce9 --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/util/template/ExpressionTemplateNavigator.java @@ -0,0 +1,37 @@ +package cc.allio.uno.core.util.template; + +import cc.allio.uno.core.api.OptionalContext; +import cc.allio.uno.core.util.template.internal.PlaceholderExpressionTemplate; +import cc.allio.uno.core.util.template.mvel.MVELExpressionTemplate; +import lombok.Getter; + +/** + * compatible {@link PlaceholderExpressionTemplate} and new mvel {@link MVELExpressionTemplate} + *

if {@link Tokenizer#AT_BRACE} then use {@link MVELExpressionTemplate} otherwise {@link PlaceholderExpressionTemplate}

+ * + * @author j.x + * @date 2024/5/3 21:32 + * @since 1.1.9 + */ +public class ExpressionTemplateNavigator implements ExpressionTemplate { + + private final ExpressionTemplate internal; + @Getter + private final Tokenizer tokenizer; + + public ExpressionTemplateNavigator(Tokenizer tokenizer, Object... args) { + if (Tokenizer.AT_BRACE == tokenizer) { + this.internal = new MVELExpressionTemplate(); + } else { + Boolean langsym = OptionalContext.immutable(args).getTypeFirst(Boolean.class).orElse(false); + this.internal = new PlaceholderExpressionTemplate(tokenizer, langsym); + } + this.tokenizer = tokenizer; + } + + + @Override + public String parseTemplate(String template, TemplateContext context) { + return internal.parseTemplate(template, context); + } +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/template/TemplateContext.java b/uno-core/src/main/java/cc/allio/uno/core/util/template/TemplateContext.java new file mode 100644 index 00000000..bb6e227b --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/util/template/TemplateContext.java @@ -0,0 +1,51 @@ +package cc.allio.uno.core.util.template; + +import cc.allio.uno.core.api.OptionalContext; +import cc.allio.uno.core.type.Types; +import com.google.common.collect.Maps; +import lombok.Getter; +import org.springframework.context.ApplicationContext; + +import java.util.Map; +import java.util.Optional; + +/** + * parse template for context + * + * @author j.x + * @date 2024/5/3 20:12 + * @since 1.1.9 + */ +public class TemplateContext implements OptionalContext { + + final Map vars = Maps.newConcurrentMap(); + + @Getter + final Map inputs = Maps.newConcurrentMap(); + + @Override + public Optional get(String key) { + return Optional.ofNullable(vars.get(key)); + } + + @Override + public Optional getApplicationContext() { + return Optional.empty(); + } + + @Override + public Map getAll() { + return vars; + } + + @Override + public void putAttribute(String key, Object obj) { + if (obj != null) { + Class valueClass = obj.getClass(); + vars.put(key, obj); + if (Types.isBean(valueClass)) { + inputs.put(key, valueClass); + } + } + } +} \ No newline at end of file diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/template/Tokenizer.java b/uno-core/src/main/java/cc/allio/uno/core/util/template/Tokenizer.java index 2cab216a..d03d18b3 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/util/template/Tokenizer.java +++ b/uno-core/src/main/java/cc/allio/uno/core/util/template/Tokenizer.java @@ -1,6 +1,7 @@ package cc.allio.uno.core.util.template; import cc.allio.uno.core.StringPool; +import cc.allio.uno.core.util.template.internal.TokenParser; import lombok.AllArgsConstructor; import lombok.Getter; @@ -26,6 +27,8 @@ public interface Tokenizer { Tokenizer SMALL_BRACKETS = () -> TokenSymbol.SMALL_BRACKETS_SYMBOL; // TOKEN = () Tokenizer DOUBLE_BRACKET = () -> TokenSymbol.DOUBLE_BRACKET; + // TOKEN = @{} + Tokenizer AT_BRACE = () -> TokenSymbol.AT_BRACE; /** * 获取Token数组列表 @@ -72,6 +75,7 @@ class TokenSymbol { public static final TokenSymbol HASH_BRACE_SYMBOL = new TokenSymbol(StringPool.HASH_LEFT_BRACE, StringPool.RIGHT_BRACE); public static final TokenSymbol SMALL_BRACKETS_SYMBOL = new TokenSymbol(StringPool.LEFT_SMALL_BRACKETS, StringPool.RIGHT_SMALL_BRACKETS); public static final TokenSymbol DOUBLE_BRACKET = new TokenSymbol(StringPool.LEFT_BRACKET, StringPool.RIGHT_BRACKET); + public static final TokenSymbol AT_BRACE = new TokenSymbol(StringPool.AT + StringPool.LEFT_BRACE, StringPool.RIGHT_BRACE); // token left private final String open; diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/template/expression/BaseInterchange.java b/uno-core/src/main/java/cc/allio/uno/core/util/template/internal/BaseInterchange.java similarity index 93% rename from uno-core/src/main/java/cc/allio/uno/core/util/template/expression/BaseInterchange.java rename to uno-core/src/main/java/cc/allio/uno/core/util/template/internal/BaseInterchange.java index 4768e3fe..8221736f 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/util/template/expression/BaseInterchange.java +++ b/uno-core/src/main/java/cc/allio/uno/core/util/template/internal/BaseInterchange.java @@ -1,6 +1,4 @@ -package cc.allio.uno.core.util.template.expression; - -import cc.allio.uno.core.util.template.LangValue; +package cc.allio.uno.core.util.template.internal; /** * 抽象的交换 @@ -12,7 +10,7 @@ public abstract class BaseInterchange implements Interchange { @Override - public Object change(String text, Object value, boolean langsym) throws Throwable { + public Object change(String text, Object value, boolean langsym) { boolean check = onCheck(value); // 受检查失败,抛出异常 if (!check) { diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/template/expression/BeanInterchange.java b/uno-core/src/main/java/cc/allio/uno/core/util/template/internal/BeanInterchange.java similarity index 75% rename from uno-core/src/main/java/cc/allio/uno/core/util/template/expression/BeanInterchange.java rename to uno-core/src/main/java/cc/allio/uno/core/util/template/internal/BeanInterchange.java index b4a9ffc7..91d46838 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/util/template/expression/BeanInterchange.java +++ b/uno-core/src/main/java/cc/allio/uno/core/util/template/internal/BeanInterchange.java @@ -1,6 +1,6 @@ -package cc.allio.uno.core.util.template.expression; +package cc.allio.uno.core.util.template.internal; -import cc.allio.uno.core.bean.ObjectWrapper; +import cc.allio.uno.core.bean.BeanWrapper; import cc.allio.uno.core.type.Types; /** @@ -14,7 +14,7 @@ public class BeanInterchange extends BaseInterchange implements KeyInterchange { @Override protected Object onChange(String text, Object value, boolean langsym) { - ObjectWrapper wrapper = new ObjectWrapper(value); + BeanWrapper wrapper = new BeanWrapper(value); return reValue(wrapper.getForce(text), langsym); } @@ -22,5 +22,4 @@ protected Object onChange(String text, Object value, boolean langsym) { protected boolean onCheck(Object value) { return Types.isBean(value.getClass()); } - -} +} \ No newline at end of file diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/template/expression/Engine.java b/uno-core/src/main/java/cc/allio/uno/core/util/template/internal/Engine.java similarity index 87% rename from uno-core/src/main/java/cc/allio/uno/core/util/template/expression/Engine.java rename to uno-core/src/main/java/cc/allio/uno/core/util/template/internal/Engine.java index 0e53eb35..322155cf 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/util/template/expression/Engine.java +++ b/uno-core/src/main/java/cc/allio/uno/core/util/template/internal/Engine.java @@ -1,4 +1,4 @@ -package cc.allio.uno.core.util.template.expression; +package cc.allio.uno.core.util.template.internal; /** * 表达式替换引擎 @@ -18,5 +18,5 @@ public interface Engine { * @return 结果 * @throws Throwable 运行过程中出现错误时抛出 */ - String run(String expression, Object value, boolean langsym) throws Throwable; + String run(String expression, Object value, boolean langsym); } diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/template/GenericTokenParser.java b/uno-core/src/main/java/cc/allio/uno/core/util/template/internal/GenericTokenParser.java similarity index 96% rename from uno-core/src/main/java/cc/allio/uno/core/util/template/GenericTokenParser.java rename to uno-core/src/main/java/cc/allio/uno/core/util/template/internal/GenericTokenParser.java index fa92f5de..9dca5f63 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/util/template/GenericTokenParser.java +++ b/uno-core/src/main/java/cc/allio/uno/core/util/template/internal/GenericTokenParser.java @@ -1,6 +1,7 @@ -package cc.allio.uno.core.util.template; +package cc.allio.uno.core.util.template.internal; import cc.allio.uno.core.StringPool; +import cc.allio.uno.core.util.template.Tokenizer; /** * 通用Token解析器,指定Token解析成指定的内容,比如说:#{token}替换成指定的内容 diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/template/expression/Interchange.java b/uno-core/src/main/java/cc/allio/uno/core/util/template/internal/Interchange.java similarity index 86% rename from uno-core/src/main/java/cc/allio/uno/core/util/template/expression/Interchange.java rename to uno-core/src/main/java/cc/allio/uno/core/util/template/internal/Interchange.java index 058de090..0bf30b3d 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/util/template/expression/Interchange.java +++ b/uno-core/src/main/java/cc/allio/uno/core/util/template/internal/Interchange.java @@ -1,4 +1,4 @@ -package cc.allio.uno.core.util.template.expression; +package cc.allio.uno.core.util.template.internal; import cc.allio.uno.core.StringPool; import cc.allio.uno.core.type.Types; @@ -20,7 +20,7 @@ public interface Interchange { * @param langsym 语言值 * @return 替换后的值 */ - Object change(String text, Object value, boolean langsym) throws Throwable; + Object change(String text, Object value, boolean langsym) ; /** * 获取语言类型值,如String 2 = "2" char 2 = '2' diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/template/expression/KeyInterchange.java b/uno-core/src/main/java/cc/allio/uno/core/util/template/internal/KeyInterchange.java similarity index 72% rename from uno-core/src/main/java/cc/allio/uno/core/util/template/expression/KeyInterchange.java rename to uno-core/src/main/java/cc/allio/uno/core/util/template/internal/KeyInterchange.java index f582fbc0..dba04e65 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/util/template/expression/KeyInterchange.java +++ b/uno-core/src/main/java/cc/allio/uno/core/util/template/internal/KeyInterchange.java @@ -1,4 +1,4 @@ -package cc.allio.uno.core.util.template.expression; +package cc.allio.uno.core.util.template.internal; /** * Key结构 diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/template/LangValue.java b/uno-core/src/main/java/cc/allio/uno/core/util/template/internal/LangValue.java similarity index 77% rename from uno-core/src/main/java/cc/allio/uno/core/util/template/LangValue.java rename to uno-core/src/main/java/cc/allio/uno/core/util/template/internal/LangValue.java index 62dc1c06..d08f6230 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/util/template/LangValue.java +++ b/uno-core/src/main/java/cc/allio/uno/core/util/template/internal/LangValue.java @@ -1,6 +1,5 @@ -package cc.allio.uno.core.util.template; +package cc.allio.uno.core.util.template.internal; -import cc.allio.uno.core.util.template.expression.BaseInterchange; import lombok.Data; import lombok.experimental.Accessors; diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/template/expression/Layer.java b/uno-core/src/main/java/cc/allio/uno/core/util/template/internal/Layer.java similarity index 91% rename from uno-core/src/main/java/cc/allio/uno/core/util/template/expression/Layer.java rename to uno-core/src/main/java/cc/allio/uno/core/util/template/internal/Layer.java index 807b842f..c892d0ca 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/util/template/expression/Layer.java +++ b/uno-core/src/main/java/cc/allio/uno/core/util/template/internal/Layer.java @@ -1,4 +1,4 @@ -package cc.allio.uno.core.util.template.expression; +package cc.allio.uno.core.util.template.internal; import lombok.Data; diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/template/expression/ListInterchange.java b/uno-core/src/main/java/cc/allio/uno/core/util/template/internal/ListInterchange.java similarity index 86% rename from uno-core/src/main/java/cc/allio/uno/core/util/template/expression/ListInterchange.java rename to uno-core/src/main/java/cc/allio/uno/core/util/template/internal/ListInterchange.java index 38fbd160..23adca1c 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/util/template/expression/ListInterchange.java +++ b/uno-core/src/main/java/cc/allio/uno/core/util/template/internal/ListInterchange.java @@ -1,7 +1,5 @@ -package cc.allio.uno.core.util.template.expression; +package cc.allio.uno.core.util.template.internal; -import cc.allio.uno.core.util.template.GenericTokenParser; -import cc.allio.uno.core.util.template.TokenParser; import cc.allio.uno.core.util.template.Tokenizer; import cc.allio.uno.core.type.Types; diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/template/expression/ListableInterchange.java b/uno-core/src/main/java/cc/allio/uno/core/util/template/internal/ListableInterchange.java similarity index 73% rename from uno-core/src/main/java/cc/allio/uno/core/util/template/expression/ListableInterchange.java rename to uno-core/src/main/java/cc/allio/uno/core/util/template/internal/ListableInterchange.java index a4725b47..9dd74290 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/util/template/expression/ListableInterchange.java +++ b/uno-core/src/main/java/cc/allio/uno/core/util/template/internal/ListableInterchange.java @@ -1,4 +1,4 @@ -package cc.allio.uno.core.util.template.expression; +package cc.allio.uno.core.util.template.internal; /** * 列表结构 diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/template/expression/MapInterchange.java b/uno-core/src/main/java/cc/allio/uno/core/util/template/internal/MapInterchange.java similarity index 91% rename from uno-core/src/main/java/cc/allio/uno/core/util/template/expression/MapInterchange.java rename to uno-core/src/main/java/cc/allio/uno/core/util/template/internal/MapInterchange.java index df540d3e..a671e462 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/util/template/expression/MapInterchange.java +++ b/uno-core/src/main/java/cc/allio/uno/core/util/template/internal/MapInterchange.java @@ -1,4 +1,4 @@ -package cc.allio.uno.core.util.template.expression; +package cc.allio.uno.core.util.template.internal; import cc.allio.uno.core.type.Types; diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/template/PlaceholderExpressionTemplate.java b/uno-core/src/main/java/cc/allio/uno/core/util/template/internal/PlaceholderExpressionTemplate.java similarity index 76% rename from uno-core/src/main/java/cc/allio/uno/core/util/template/PlaceholderExpressionTemplate.java rename to uno-core/src/main/java/cc/allio/uno/core/util/template/internal/PlaceholderExpressionTemplate.java index 233ed389..6085de43 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/util/template/PlaceholderExpressionTemplate.java +++ b/uno-core/src/main/java/cc/allio/uno/core/util/template/internal/PlaceholderExpressionTemplate.java @@ -1,11 +1,12 @@ -package cc.allio.uno.core.util.template; +package cc.allio.uno.core.util.template.internal; import cc.allio.uno.core.StringPool; -import cc.allio.uno.core.util.template.expression.Engine; -import cc.allio.uno.core.util.template.expression.SymbolEngine; +import cc.allio.uno.core.util.template.*; import lombok.NonNull; import lombok.extern.slf4j.Slf4j; +import java.util.Map; + /** * 使用{@link TokenParser}完成模板解析 *

定义:模板解析方式

@@ -43,25 +44,24 @@ public class PlaceholderExpressionTemplate implements ExpressionTemplate { private final Engine engine; private final boolean langsym; - PlaceholderExpressionTemplate(Tokenizer tokenizer) { + public PlaceholderExpressionTemplate(Tokenizer tokenizer) { this(tokenizer, false); } - PlaceholderExpressionTemplate(Tokenizer tokenizer, boolean langsym) { + public PlaceholderExpressionTemplate(Tokenizer tokenizer, boolean langsym) { this.tokenParser = new GenericTokenParser(tokenizer); this.engine = new SymbolEngine(StringPool.DOT); this.langsym = langsym; } @Override - public String parseTemplate(@NonNull String template, @NonNull Object target) { - return tokenParser.parse(template, expression -> { - try { - return engine.run(expression, target, langsym); - } catch (Throwable e) { - return expression; - } - }); + public String parseTemplate(@NonNull String template, TemplateContext context) { + return tokenParser.parse( + template, + expression -> { + Map vars = context.getAll(); + return engine.run(expression, vars, langsym); + }); } -} +} \ No newline at end of file diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/template/expression/SymbolEngine.java b/uno-core/src/main/java/cc/allio/uno/core/util/template/internal/SymbolEngine.java similarity index 96% rename from uno-core/src/main/java/cc/allio/uno/core/util/template/expression/SymbolEngine.java rename to uno-core/src/main/java/cc/allio/uno/core/util/template/internal/SymbolEngine.java index 6d2a4d82..d06c82c4 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/util/template/expression/SymbolEngine.java +++ b/uno-core/src/main/java/cc/allio/uno/core/util/template/internal/SymbolEngine.java @@ -1,4 +1,4 @@ -package cc.allio.uno.core.util.template.expression; +package cc.allio.uno.core.util.template.internal; import cc.allio.uno.core.StringPool; import cc.allio.uno.core.type.Types; @@ -21,7 +21,7 @@ public SymbolEngine(String symbol) { } @Override - public String run(String expression, Object value, boolean langsym) throws Throwable { + public String run(String expression, Object value, boolean langsym) { String[] texts = expression.split(symbol); Object layerValue = value; for (String layer : texts) { diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/template/TokenHandler.java b/uno-core/src/main/java/cc/allio/uno/core/util/template/internal/TokenHandler.java similarity index 90% rename from uno-core/src/main/java/cc/allio/uno/core/util/template/TokenHandler.java rename to uno-core/src/main/java/cc/allio/uno/core/util/template/internal/TokenHandler.java index e5a959c7..4150eec4 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/util/template/TokenHandler.java +++ b/uno-core/src/main/java/cc/allio/uno/core/util/template/internal/TokenHandler.java @@ -1,4 +1,4 @@ -package cc.allio.uno.core.util.template; +package cc.allio.uno.core.util.template.internal; import java.util.function.Function; diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/template/TokenParser.java b/uno-core/src/main/java/cc/allio/uno/core/util/template/internal/TokenParser.java similarity index 85% rename from uno-core/src/main/java/cc/allio/uno/core/util/template/TokenParser.java rename to uno-core/src/main/java/cc/allio/uno/core/util/template/internal/TokenParser.java index 03e24f84..ac805681 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/util/template/TokenParser.java +++ b/uno-core/src/main/java/cc/allio/uno/core/util/template/internal/TokenParser.java @@ -1,4 +1,6 @@ -package cc.allio.uno.core.util.template; +package cc.allio.uno.core.util.template.internal; + +import cc.allio.uno.core.util.template.Tokenizer; /** * 按照指定的Token标识符号(如#{}、{{}})等等TOKEN来对文本内容进行解析 diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/template/mvel/MVELExpressionTemplate.java b/uno-core/src/main/java/cc/allio/uno/core/util/template/mvel/MVELExpressionTemplate.java new file mode 100644 index 00000000..dc3746c2 --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/util/template/mvel/MVELExpressionTemplate.java @@ -0,0 +1,31 @@ +package cc.allio.uno.core.util.template.mvel; + +import cc.allio.uno.core.util.template.ExpressionTemplate; +import cc.allio.uno.core.util.template.TemplateContext; +import org.mvel2.ParserContext; +import org.mvel2.templates.CompiledTemplate; +import org.mvel2.templates.TemplateCompiler; +import org.mvel2.templates.TemplateRuntime; + +import java.util.Map; + +/** + * according to mvel {@link TemplateRuntime} as parser + * + * @author j.x + * @date 2024/5/3 20:07 + * @since 1.1.9 + */ +public class MVELExpressionTemplate implements ExpressionTemplate { + + @Override + public String parseTemplate(String template, TemplateContext context) { + // 1. compile the template + ParserContext parserContext = new ParserContext(); + Map inputs = context.getInputs(); + parserContext.addInputs(inputs); + CompiledTemplate compiledTemplate = TemplateCompiler.compileTemplate(template, parserContext); + Object execute = TemplateRuntime.execute(compiledTemplate, context.getAll()); + return execute.toString(); + } +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/bus/event-bus.puml b/uno-core/src/main/resources/event-bus.puml similarity index 100% rename from uno-core/src/main/java/cc/allio/uno/core/bus/event-bus.puml rename to uno-core/src/main/resources/event-bus.puml diff --git a/uno-core/src/test/java/cc/allio/uno/core/bean/ObjectWrapperTest.java b/uno-core/src/test/java/cc/allio/uno/core/bean/BeanWrapperTest.java similarity index 86% rename from uno-core/src/test/java/cc/allio/uno/core/bean/ObjectWrapperTest.java rename to uno-core/src/test/java/cc/allio/uno/core/bean/BeanWrapperTest.java index 6eb7b1ff..cab24d25 100644 --- a/uno-core/src/test/java/cc/allio/uno/core/bean/ObjectWrapperTest.java +++ b/uno-core/src/test/java/cc/allio/uno/core/bean/BeanWrapperTest.java @@ -6,13 +6,13 @@ import java.util.Map; -public class ObjectWrapperTest { +public class BeanWrapperTest { @Test void testGet() { User user = new User(); user.setName("name"); - ObjectWrapper wrapper = new ObjectWrapper(user); + BeanWrapper wrapper = new BeanWrapper(user); wrapper.get("name") .as(StepVerifier::create) .expectNext("name") @@ -22,7 +22,7 @@ void testGet() { @Test void testSet() { User user = new User(); - ObjectWrapper wrapper = new ObjectWrapper(user); + BeanWrapper wrapper = new BeanWrapper(user); wrapper.set("name", "name") .map(o -> ((User) o).getName()) .as(StepVerifier::create) @@ -34,7 +34,7 @@ void testSet() { void testSetCoverage() { User user = new User(); user.setName("name"); - ObjectWrapper wrapper = new ObjectWrapper(user); + BeanWrapper wrapper = new BeanWrapper(user); wrapper.setCoverage("name", false, "name1") .map(o -> ((User) o).getName()) .as(StepVerifier::create) @@ -52,7 +52,7 @@ void testGetAllValues() { User user = new User(); user.setName("name"); user.setType("type"); - ObjectWrapper wrapper = new ObjectWrapper(user); + BeanWrapper wrapper = new BeanWrapper(user); Map allValuesForce = wrapper.findMapValuesForce(); System.out.println(allValuesForce); diff --git a/uno-core/src/test/java/cc/allio/uno/core/metadata/source/TestSourceConverter.java b/uno-core/src/test/java/cc/allio/uno/core/metadata/source/TestSourceConverter.java index 5e091ea3..68c9c2f3 100644 --- a/uno-core/src/test/java/cc/allio/uno/core/metadata/source/TestSourceConverter.java +++ b/uno-core/src/test/java/cc/allio/uno/core/metadata/source/TestSourceConverter.java @@ -1,6 +1,6 @@ package cc.allio.uno.core.metadata.source; -import cc.allio.uno.core.bean.ObjectWrapper; +import cc.allio.uno.core.bean.BeanWrapper; import cc.allio.uno.core.metadata.UserMetadata; import cc.allio.uno.core.metadata.convert.AbstractJsonConverter; import cc.allio.uno.core.metadata.convert.Converter; @@ -21,7 +21,7 @@ public UserMetadata doConvert(ApplicationContext context, JsonNode value) throws Converter converter = new AbstractJsonConverter(UserMetadata.class) { @Override - protected Mono executeAssignmentDefaultAction(UserMetadata metadata, ObjectWrapper wrapper) { + protected Mono executeAssignmentDefaultAction(UserMetadata metadata, BeanWrapper wrapper) { return Mono.defer(() -> { metadata.setId("id"); return Mono.empty(); diff --git a/uno-core/src/test/java/cc/allio/uno/core/util/template/expression/BeanInterchangeTest.java b/uno-core/src/test/java/cc/allio/uno/core/util/template/internal/BeanInterchangeTest.java similarity index 93% rename from uno-core/src/test/java/cc/allio/uno/core/util/template/expression/BeanInterchangeTest.java rename to uno-core/src/test/java/cc/allio/uno/core/util/template/internal/BeanInterchangeTest.java index 1959540f..9ab3f3c1 100644 --- a/uno-core/src/test/java/cc/allio/uno/core/util/template/expression/BeanInterchangeTest.java +++ b/uno-core/src/test/java/cc/allio/uno/core/util/template/internal/BeanInterchangeTest.java @@ -1,4 +1,4 @@ -package cc.allio.uno.core.util.template.expression; +package cc.allio.uno.core.util.template.internal; import cc.allio.uno.core.BaseTestCase; import cc.allio.uno.core.User; diff --git a/uno-core/src/test/java/cc/allio/uno/core/util/template/expression/ListInterchangeTest.java b/uno-core/src/test/java/cc/allio/uno/core/util/template/internal/ListInterchangeTest.java similarity index 90% rename from uno-core/src/test/java/cc/allio/uno/core/util/template/expression/ListInterchangeTest.java rename to uno-core/src/test/java/cc/allio/uno/core/util/template/internal/ListInterchangeTest.java index 10b215cd..7011e4da 100644 --- a/uno-core/src/test/java/cc/allio/uno/core/util/template/expression/ListInterchangeTest.java +++ b/uno-core/src/test/java/cc/allio/uno/core/util/template/internal/ListInterchangeTest.java @@ -1,4 +1,4 @@ -package cc.allio.uno.core.util.template.expression; +package cc.allio.uno.core.util.template.internal; import cc.allio.uno.core.BaseTestCase; import com.google.common.collect.Lists; diff --git a/uno-core/src/test/java/cc/allio/uno/core/util/template/expression/MapInterchangeTest.java b/uno-core/src/test/java/cc/allio/uno/core/util/template/internal/MapInterchangeTest.java similarity index 95% rename from uno-core/src/test/java/cc/allio/uno/core/util/template/expression/MapInterchangeTest.java rename to uno-core/src/test/java/cc/allio/uno/core/util/template/internal/MapInterchangeTest.java index ee8359c2..e92a05a1 100644 --- a/uno-core/src/test/java/cc/allio/uno/core/util/template/expression/MapInterchangeTest.java +++ b/uno-core/src/test/java/cc/allio/uno/core/util/template/internal/MapInterchangeTest.java @@ -1,4 +1,4 @@ -package cc.allio.uno.core.util.template.expression; +package cc.allio.uno.core.util.template.internal; import cc.allio.uno.core.BaseTestCase; import com.google.common.collect.Maps; diff --git a/uno-core/src/test/java/cc/allio/uno/core/util/template/PlaceholderExpressionTemplateBaseTest.java b/uno-core/src/test/java/cc/allio/uno/core/util/template/internal/PlaceholderExpressionTemplateBaseTest.java similarity index 93% rename from uno-core/src/test/java/cc/allio/uno/core/util/template/PlaceholderExpressionTemplateBaseTest.java rename to uno-core/src/test/java/cc/allio/uno/core/util/template/internal/PlaceholderExpressionTemplateBaseTest.java index 21140d9b..00c18111 100644 --- a/uno-core/src/test/java/cc/allio/uno/core/util/template/PlaceholderExpressionTemplateBaseTest.java +++ b/uno-core/src/test/java/cc/allio/uno/core/util/template/internal/PlaceholderExpressionTemplateBaseTest.java @@ -1,6 +1,8 @@ -package cc.allio.uno.core.util.template; +package cc.allio.uno.core.util.template.internal; import cc.allio.uno.core.BaseTestCase; +import cc.allio.uno.core.util.template.ExpressionTemplate; +import cc.allio.uno.core.util.template.Tokenizer; import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test; @@ -70,11 +72,6 @@ void testTemplateMap() { }); } - @Override - protected void onDown() throws Throwable { - - } - @Data public static class User { private String id; diff --git a/uno-core/src/test/java/cc/allio/uno/core/util/template/expression/SymbolEngineTest.java b/uno-core/src/test/java/cc/allio/uno/core/util/template/internal/SymbolEngineTest.java similarity index 98% rename from uno-core/src/test/java/cc/allio/uno/core/util/template/expression/SymbolEngineTest.java rename to uno-core/src/test/java/cc/allio/uno/core/util/template/internal/SymbolEngineTest.java index 07d6a6be..5d9e29e2 100644 --- a/uno-core/src/test/java/cc/allio/uno/core/util/template/expression/SymbolEngineTest.java +++ b/uno-core/src/test/java/cc/allio/uno/core/util/template/internal/SymbolEngineTest.java @@ -1,4 +1,4 @@ -package cc.allio.uno.core.util.template.expression; +package cc.allio.uno.core.util.template.internal; import cc.allio.uno.core.BaseTestCase; import cc.allio.uno.core.StringPool; @@ -118,5 +118,4 @@ public static class Level { private Map map; private List list; } - -} +} \ No newline at end of file diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/helper/PojoWrapper.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/helper/PojoWrapper.java index 7cc23a1e..65e76093 100644 --- a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/helper/PojoWrapper.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/helper/PojoWrapper.java @@ -3,7 +3,7 @@ import cc.allio.uno.core.StringPool; import cc.allio.uno.core.api.Step; import cc.allio.uno.core.bean.MapWrapper; -import cc.allio.uno.core.bean.ObjectWrapper; +import cc.allio.uno.core.bean.BeanWrapper; import cc.allio.uno.core.bean.ValueWrapper; import cc.allio.uno.core.type.TypeOperatorFactory; import cc.allio.uno.core.type.Types; @@ -97,7 +97,7 @@ public class PojoWrapper implements ValueWrapper { if (Types.isMap(pojo.getClass())) { this.valueWrapper = new MapWrapper((Map) pojo); } else { - this.valueWrapper = new ObjectWrapper(pojo); + this.valueWrapper = new BeanWrapper(pojo); } this.pojo = pojo; init(pojo.getClass()); @@ -107,7 +107,7 @@ public class PojoWrapper implements ValueWrapper { if (Types.isMap(pojoClass)) { this.valueWrapper = new MapWrapper(); } else { - this.valueWrapper = new ObjectWrapper(pojoClass); + this.valueWrapper = new BeanWrapper(pojoClass); } init(pojoClass); } diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/param/AddDiluteAction.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/param/AddDiluteAction.java index 3d77aa49..dd2771d5 100644 --- a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/param/AddDiluteAction.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/param/AddDiluteAction.java @@ -1,6 +1,6 @@ package cc.allio.uno.data.query.param; -import cc.allio.uno.core.bean.ObjectWrapper; +import cc.allio.uno.core.bean.BeanWrapper; import cc.allio.uno.core.type.TypeOperatorFactory; import cc.allio.uno.data.query.QueryWrapper; import lombok.extern.slf4j.Slf4j; @@ -20,9 +20,9 @@ public void trigger(QueryWrapper queryWrapper, Object o, Object t) { String[] dataFields = queryWrapper.getDataFields(); for (String dataField : dataFields) { try { - ObjectWrapper oWrapper = new ObjectWrapper(o); + BeanWrapper oWrapper = new BeanWrapper(o); Object oField = oWrapper.getForce(dataField); - ObjectWrapper tWrapper = new ObjectWrapper(t); + BeanWrapper tWrapper = new BeanWrapper(t); Object tField = tWrapper.getForce(dataField); Object result = TypeOperatorFactory.translator((Class) oField.getClass()).add(oField, tField); oWrapper.setForce(dataField, result); diff --git a/uno-http/pom.xml b/uno-http/pom.xml index 5d654dca..96067923 100644 --- a/uno-http/pom.xml +++ b/uno-http/pom.xml @@ -12,8 +12,8 @@ uno-http - 21 - 21 + 22 + 22 UTF-8 @@ -26,6 +26,10 @@ org.springframework spring-webflux + + io.projectreactor.netty + reactor-netty + io.swagger.core.v3 swagger-models diff --git a/uno-kafka/pom.xml b/uno-kafka/pom.xml index 7955e9d1..86bb107f 100644 --- a/uno-kafka/pom.xml +++ b/uno-kafka/pom.xml @@ -12,8 +12,8 @@ uno-kafka - 21 - 21 + 22 + 22 UTF-8 diff --git a/uno-netty/pom.xml b/uno-netty/pom.xml index 2d3632bc..dfa9971b 100644 --- a/uno-netty/pom.xml +++ b/uno-netty/pom.xml @@ -12,8 +12,8 @@ uno-netty - 21 - 21 + 22 + 22 UTF-8 diff --git a/uno-rule/src/main/java/cc/allio/uno/rule/api/Fact.java b/uno-rule/src/main/java/cc/allio/uno/rule/api/Fact.java index 8ce71d8e..6014cb56 100644 --- a/uno-rule/src/main/java/cc/allio/uno/rule/api/Fact.java +++ b/uno-rule/src/main/java/cc/allio/uno/rule/api/Fact.java @@ -1,6 +1,6 @@ package cc.allio.uno.rule.api; -import cc.allio.uno.core.bean.ObjectWrapper; +import cc.allio.uno.core.bean.BeanWrapper; import reactor.util.function.Tuple2; import reactor.util.function.Tuple4; import reactor.util.function.Tuple6; @@ -57,7 +57,7 @@ static Fact from(Rule rule) { * @return Fact instance */ static Fact from(Rule rule, Object pojo) { - ObjectWrapper wrapper = new ObjectWrapper(pojo); + BeanWrapper wrapper = new BeanWrapper(pojo); return from(rule, wrapper.findMapValuesForce()); } diff --git a/uno-rule/src/main/java/cc/allio/uno/rule/api/RuleAttrImpl.java b/uno-rule/src/main/java/cc/allio/uno/rule/api/RuleAttrImpl.java index eb6317ad..c69d9445 100644 --- a/uno-rule/src/main/java/cc/allio/uno/rule/api/RuleAttrImpl.java +++ b/uno-rule/src/main/java/cc/allio/uno/rule/api/RuleAttrImpl.java @@ -1,7 +1,7 @@ package cc.allio.uno.rule.api; import cc.allio.uno.core.type.Types; -import cc.allio.uno.core.util.template.LangValue; +import cc.allio.uno.core.util.template.internal.LangValue; import com.google.common.collect.Maps; import lombok.Data; import lombok.Getter; diff --git a/uno-sequential/pom.xml b/uno-sequential/pom.xml index 10ef86f5..20082094 100644 --- a/uno-sequential/pom.xml +++ b/uno-sequential/pom.xml @@ -12,8 +12,8 @@ uno-sequential - 21 - 21 + 22 + 22 UTF-8 diff --git a/uno-sequential/src/main/java/cc/allio/uno/sequnetial/process/DefaultProcessor.java b/uno-sequential/src/main/java/cc/allio/uno/sequnetial/process/DefaultProcessor.java index b2a31558..82ef9ebf 100644 --- a/uno-sequential/src/main/java/cc/allio/uno/sequnetial/process/DefaultProcessor.java +++ b/uno-sequential/src/main/java/cc/allio/uno/sequnetial/process/DefaultProcessor.java @@ -2,7 +2,7 @@ import java.util.*; -import cc.allio.uno.core.bean.ObjectWrapper; +import cc.allio.uno.core.bean.BeanWrapper; import cc.allio.uno.core.bus.EventBusFactory; import cc.allio.uno.core.bus.event.Node; import cc.allio.uno.core.spi.Loader; @@ -122,7 +122,7 @@ private Flux onProcess(SequentialContext context) { .map(tuple2 -> { // 时序处理过程中,时序数据必须是一个唯一确定的sequential类型。所以CompositeSequential需要转换成指定的类型 if (sequential instanceof BaseCompositeSequential) { - ObjectWrapper wrapper = new ObjectWrapper(context.getClass()); + BeanWrapper wrapper = new BeanWrapper(context.getClass()); wrapper.setForce("sequential", tuple2.getT1()); } DefaultProcessPipeline pipeline = diff --git a/uno-sequential/src/test/java/cc/allio/uno/sequential/convert/TestSequentialConvert.java b/uno-sequential/src/test/java/cc/allio/uno/sequential/convert/TestSequentialConvert.java index c3fba370..96ecca48 100644 --- a/uno-sequential/src/test/java/cc/allio/uno/sequential/convert/TestSequentialConvert.java +++ b/uno-sequential/src/test/java/cc/allio/uno/sequential/convert/TestSequentialConvert.java @@ -1,6 +1,6 @@ package cc.allio.uno.sequential.convert; -import cc.allio.uno.core.bean.ObjectWrapper; +import cc.allio.uno.core.bean.BeanWrapper; import cc.allio.uno.core.metadata.convert.AbstractJsonConverter; import cc.allio.uno.sequnetial.Sequential; import reactor.core.publisher.Mono; @@ -12,7 +12,7 @@ public TestSequentialConvert(Class convertType) { } @Override - protected Mono executeAssignmentDefaultAction(Sequential sequential, ObjectWrapper wrapper) { + protected Mono executeAssignmentDefaultAction(Sequential sequential, BeanWrapper wrapper) { return Mono.empty(); } } diff --git a/uno-websocket/pom.xml b/uno-websocket/pom.xml index cffa5d01..1785ca93 100644 --- a/uno-websocket/pom.xml +++ b/uno-websocket/pom.xml @@ -13,8 +13,8 @@ 提供封装的websocket,包含鉴权、心跳、连接管理、实现方只需要关注消息的处理 - 21 - 21 + 22 + 22 UTF-8 diff --git a/uno-websocket/src/main/java/cc/allio/uno/websocket/WebSocketEndpoint.java b/uno-websocket/src/main/java/cc/allio/uno/websocket/WebSocketEndpoint.java index dd6f52c2..a5bc46d9 100644 --- a/uno-websocket/src/main/java/cc/allio/uno/websocket/WebSocketEndpoint.java +++ b/uno-websocket/src/main/java/cc/allio/uno/websocket/WebSocketEndpoint.java @@ -5,6 +5,7 @@ import cc.allio.uno.core.util.template.Tokenizer; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; +import com.google.common.collect.Maps; import jakarta.websocket.Session; import jakarta.websocket.server.ServerEndpoint; import org.springframework.beans.factory.NoSuchBeanDefinitionException; @@ -89,7 +90,10 @@ default EndpointKey getEndpointKey() { } // 如果有占位符则进行替换 ExpressionTemplate expressionTemplate = ExpressionTemplate.createTemplate(Tokenizer.BRACE); - String endpoint = expressionTemplate.parseTemplate(annotation.value(), getSession().getPathParameters()); + Map pathParameters = getSession().getPathParameters(); + Map vars = Maps.newHashMap(); + vars.putAll(pathParameters); + String endpoint = expressionTemplate.parseTemplate(annotation.value(), vars); return new EndpointKey(endpoint); }